1 // Copyright (C) 2007-2024 CEA, EDF, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include "SUIT_Application.h"
25 #include "SUIT_Study.h"
26 #include "SUIT_Session.h"
27 #include "SUIT_Desktop.h"
28 #include "SUIT_ResourceMgr.h"
29 #include "SUIT_ShortcutMgr.h"
34 #include <QApplication>
37 #include <QtxAction.h>
38 #include <QtxActionMenuMgr.h>
39 #include <QtxActionToolMgr.h>
44 \brief Status bar customization label. Used to workaroubd desktop resizing bug.
47 class StatusLabel : public QLabel
50 StatusLabel( QWidget* parent ) : QLabel( parent ) {}
51 QSize minimumSizeHint () const { return QSize( 0, QLabel::minimumSizeHint().height() ); }
57 SUIT_Application::SUIT_Application()
62 myPostRoutines( QList<PostRoutine>() )
64 if ( SUIT_Session::session() )
65 SUIT_Session::session()->insertApplication( this );
71 SUIT_Application::~SUIT_Application()
73 SUIT_Study* s = myStudy;
79 foreach ( PostRoutine routine, myPostRoutines )
84 \return main window of application (desktop)
86 SUIT_Desktop* SUIT_Application::desktop()
92 \return \c false if application can not be closed (because of non saved data for example).
93 This method called by SUIT_Session when closing of application was requested.
95 bool SUIT_Application::isPossibleToClose( bool& )
101 Performs some finalization of life cycle of this application.
102 For instance, the application can force its documents(s) to close.
104 void SUIT_Application::closeApplication()
106 emit applicationClosed( this );
110 \return active Study. If Application supports wirking with several studies this method should be redefined
112 SUIT_Study* SUIT_Application::activeStudy() const
118 \return version of application
120 QString SUIT_Application::applicationVersion() const
126 Shows the application's main widget. For non GUI application must be redefined.
128 void SUIT_Application::start()
133 // Initialize shortcut manager
134 SUIT_ShortcutMgr::Init();
138 Opens document into active Study. If Study is empty - creates it.
139 \param theFileName - name of document file
141 bool SUIT_Application::useFile( const QString& theFileName )
144 SUIT_Study* study = activeStudy();
146 bool status = study ? study->openDocument( theFileName ) : false;
158 Creates new empty Study if active Study = 0
160 void SUIT_Application::createEmptyStudy()
162 if ( !activeStudy() )
163 setActiveStudy( createNewStudy() );
167 \return number of Studies.
168 Must be redefined in Applications which support several studies for one Application instance.
170 int SUIT_Application::getNbStudies() const
172 return activeStudy() ? 1 : 0;
176 \return global resource manager
178 SUIT_ResourceMgr* SUIT_Application::resourceMgr() const
180 if ( !SUIT_Session::session() )
183 return SUIT_Session::session()->resourceMgr();
187 \brief Get access to shortcut manager.
188 \return global shortcut manager
190 SUIT_ShortcutMgr* SUIT_Application::shortcutMgr() const
192 return SUIT_ShortcutMgr::get();
195 #define DEFAULT_MESSAGE_DELAY 3000
198 Puts the message to the status bar
199 \param msg - text of message
200 \param msec - time in milliseconds, after that the status label will be cleared
202 void SUIT_Application::putInfo( const QString& msg, const int msec )
207 if ( !myStatusLabel )
209 myStatusLabel = new StatusLabel( desktop()->statusBar() );
210 desktop()->statusBar()->addWidget( myStatusLabel, 1 );
211 myStatusLabel->show();
214 QString prev = myStatusLabel->text();
216 myStatusLabel->setText( msg );
218 QTimer::singleShot( msec <= 0 ? DEFAULT_MESSAGE_DELAY : msec, this, SLOT( onInfoClear() ) );
221 emit infoChanged( msg );
225 Clear the information label in status bar after delay.
227 void SUIT_Application::onInfoClear()
229 if ( !myStatusLabel )
232 bool changed = !myStatusLabel->text().isEmpty();
233 myStatusLabel->clear();
235 emit infoChanged( QString() );
239 Update status of the registerd actions
241 void SUIT_Application::updateCommandsStatus()
246 Initialize with application arguments
247 \param argc - number of application arguments
248 \param argv - array of application arguments
250 SUIT_Application* SUIT_Application::startApplication( int argc, char** argv ) const
252 return startApplication( objectName(), argc, argv );
256 Initialize with application name and arguments
257 \param name - name of application
258 \param argc - number of application arguments
259 \param argv - array of application arguments
261 SUIT_Application* SUIT_Application::startApplication( const QString& name, int argc, char** argv ) const
263 SUIT_Session* session = SUIT_Session::session();
267 return session->startApplication( name, argc, argv );
271 Sets the main window of application
272 \param desk - new main window (desktop)
274 void SUIT_Application::setDesktop( SUIT_Desktop* desk )
276 if ( myDesktop == desk )
279 // >> VSR 09/06/2009: workaround about the Qt 4.5.0 bug: SIGSEGV on desktop delete
280 myDesktop->deleteLater(); // delete myDesktop;
284 connect( myDesktop, SIGNAL( activated() ), this, SLOT( onDesktopActivated() ) );
285 // connect( myDesktop, SIGNAL( moved() ), this, SLOT( onDesktopMoved() ) );
286 // Force desktop activation (NPAL16628)
287 QApplication::postEvent(myDesktop, new QEvent(QEvent::WindowActivate));
292 Creates new instance of study.
293 By default, it is called from createEmptyStudy()
294 \sa createEmptyStudy()
296 SUIT_Study* SUIT_Application::createNewStudy()
298 return new SUIT_Study( this );
303 \param study - instance of study to be set as active
305 void SUIT_Application::setActiveStudy( SUIT_Study* study )
307 if ( myStudy == study )
311 disconnect( myStudy, SIGNAL( studyModified( SUIT_Study* ) ),
312 this, SLOT( updateCommandsStatus() ) );
314 connect( study, SIGNAL( studyModified( SUIT_Study* ) ),
315 this, SLOT( updateCommandsStatus() ) );
322 \return identificator of new toolbar in tool manager
323 \param title - title of new toolbar
324 \param name - name (identifier) of new toolbar
326 int SUIT_Application::createTool( const QString& title, const QString& name )
328 if ( !desktop() || !desktop()->toolMgr() )
331 return desktop()->toolMgr()->createToolBar( title, name );
335 Creates new toolbutton
336 \return SUIT identificator of new action
338 \param tBar - identificator of toolbar
339 \param id - proposed SUIT identificator of action (if it is -1, then must be use any free)
340 \param idx - index in toolbar
342 int SUIT_Application::createTool( QAction* a, const int tBar, const int id, const int idx )
344 if ( !desktop() || !desktop()->toolMgr() )
347 int regId = registerAction( id, a );
348 int intId = desktop()->toolMgr()->insert( a, tBar, idx );
349 return intId != -1 ? regId : -1;
353 Creates new toolbutton
354 \return SUIT identificator of new action
356 \param tBar - name of toolbar
357 \param id - proposed SUIT identificator of action (if it is -1, then must be use any free)
358 \param idx - index in toolbar
360 int SUIT_Application::createTool( QAction* a, const QString& tBar, const int id, const int idx )
362 if ( !desktop() || !desktop()->toolMgr() )
365 int regId = registerAction( id, a );
366 int intId = desktop()->toolMgr()->insert( a, tBar, idx );
367 return intId != -1 ? regId : -1;
371 Creates new toolbutton
372 \return "id" if all right or -1 otherwise
373 \param id - SUIT identificator of action
374 \param tBar - identificator of toolbar
375 \param idx - index in toolbar
377 int SUIT_Application::createTool( const int id, const int tBar, const int idx )
379 if ( !desktop() || !desktop()->toolMgr() )
382 int intId = desktop()->toolMgr()->insert( action( id ), tBar, idx );
383 return intId != -1 ? id : -1;
387 Creates new toolbutton
388 \return "id" if all right or -1 otherwise
389 \param id - SUIT identificator of action
390 \param tBar - name of toolbar
391 \param idx - index in toolbar
393 int SUIT_Application::createTool( const int id, const QString& tBar, const int idx )
395 if ( !desktop() || !desktop()->toolMgr() )
398 int intId = desktop()->toolMgr()->insert( action( id ), tBar, idx );
399 return intId != -1 ? id : -1;
403 Clears given toolbar.
404 \param title - title of toolbar
406 void SUIT_Application::clearTool( const QString& title )
408 if ( desktop() && desktop()->toolMgr() )
409 desktop()->toolMgr()->clear( title );
413 Creates new menu item
414 \return identificator of new action in menu manager
415 \param subMenu - menu text of new item
416 \param menu - identificator of parent menu item
417 \param id - proposed identificator of action
418 \param group - group in menu manager
419 \param index - index in menu
421 int SUIT_Application::createMenu( const QString& subMenu, const int menu,
422 const int id, const int group, const int index )
424 if ( !desktop() || !desktop()->menuMgr() )
427 return desktop()->menuMgr()->insert( subMenu, menu, group, id, index );
431 Creates new menu item
432 \return identificator of new action in menu manager
433 \param subMenu - menu text of new item
434 \param menu - menu text of parent menu item
435 \param id - proposed identificator of action
436 \param group - group in menu manager
437 \param index - index in menu
439 int SUIT_Application::createMenu( const QString& subMenu, const QString& menu,
440 const int id, const int group, const int index )
442 if ( !desktop() || !desktop()->menuMgr() )
445 return desktop()->menuMgr()->insert( subMenu, menu, group, id, index );
449 Creates new menu item
450 \return SUIT identificator of new action
452 \param menu - identificator of parent menu item
453 \param id - proposed SUIT identificator of action
454 \param group - group in menu manager
455 \param index - index in menu
457 int SUIT_Application::createMenu( QAction* a, const int menu, const int id, const int group, const int index )
459 if ( !a || !desktop() || !desktop()->menuMgr() )
462 int regId = registerAction( id, a );
463 int intId = desktop()->menuMgr()->insert( a, menu, group, index );
464 return intId != -1 ? regId : -1;
468 Creates new menu item
469 \return SUIT identificator of new action
471 \param menu - menu text of parent menu item
472 \param id - proposed SUIT identificator of action
473 \param group - group in menu manager
474 \param index - index in menu
476 int SUIT_Application::createMenu( QAction* a, const QString& menu, const int id, const int group, const int index )
478 if ( !a || !desktop() || !desktop()->menuMgr() )
481 int regId = registerAction( id, a );
482 int intId = desktop()->menuMgr()->insert( a, menu, group, index );
483 return intId != -1 ? regId : -1;
487 Creates new menu item
488 \return identificator of new action in menu manager
489 \param id - SUIT identificator of action
490 \param menu - menu text of parent menu item
491 \param group - group in menu manager
492 \param index - index in menu
494 int SUIT_Application::createMenu( const int id, const int menu, const int group, const int index )
496 if ( !desktop() || !desktop()->menuMgr() )
499 int intId = desktop()->menuMgr()->insert( action( id ), menu, group, index );
500 return intId != -1 ? id : -1;
504 Creates new menu item
505 \return identificator of new action in menu manager
506 \param id - SUIT identificator of action
507 \param menu - menu text of parent menu item
508 \param group - group in menu manager
509 \param index - index in menu
511 int SUIT_Application::createMenu( const int id, const QString& menu, const int group, const int index )
513 if ( !desktop() || !desktop()->menuMgr() )
516 int intId = desktop()->menuMgr()->insert( action( id ), menu, group, index );
517 return intId != -1 ? id : -1;
521 Show/hide menu item corresponding to action
523 \param on - if it is \c true, the item will be shown, otherwise it will be hidden
525 void SUIT_Application::setMenuShown( QAction* a, const bool on )
527 if ( !a || !desktop() )
530 QtxActionMenuMgr* mMgr = desktop()->menuMgr();
532 mMgr->setShown( mMgr->actionId( a ), on );
536 Show/hide menu item corresponding to action
537 \param id - identificator of action in menu manager
538 \param on - if it is \c true, the item will be shown, otherwise it will be hidden
540 void SUIT_Application::setMenuShown( const int id, const bool on )
542 setMenuShown( action( id ), on );
546 Show/hide tool button corresponding to action
548 \param on - if it is \c true, the button will be shown, otherwise it will be hidden
550 void SUIT_Application::setToolShown( QAction* a, const bool on )
552 if ( !a || !desktop() )
555 QtxActionToolMgr* tMgr = desktop()->toolMgr();
557 tMgr->setShown( tMgr->actionId( a ), on );
561 Show/hide menu item corresponding to action
562 \param id - identificator of action in tool manager
563 \param on - if it is \c true, the button will be shown, otherwise it will be hidden
565 void SUIT_Application::setToolShown( const int id, const bool on )
567 setToolShown( action( id ), on );
571 Show/hide both menu item and tool button corresponding to action
573 \param on - if it is \c true, the item will be shown, otherwise it will be hidden
575 void SUIT_Application::setActionShown( QAction* a, const bool on )
577 setMenuShown( a, on );
578 setToolShown( a, on );
582 Show/hide both menu item and tool button corresponding to action
583 \param id - identificator in both menu manager and tool manager
584 \param on - if it is \c true, the item will be shown, otherwise it will be hidden
586 void SUIT_Application::setActionShown( const int id, const bool on )
588 setMenuShown( id, on );
589 setToolShown( id, on );
593 \return action by it's SUIT identificator
594 \param id - SUIT identificator
596 QAction* SUIT_Application::action( const int id ) const
599 if ( myActionMap.contains( id ) )
605 \return SUIT identificator of action
608 int SUIT_Application::actionId( const QAction* a ) const
611 for ( QMap<int, QAction*>::ConstIterator it = myActionMap.begin(); it != myActionMap.end() && id == -1; ++it )
613 if ( it.value() == a )
619 QList<QAction*> SUIT_Application::actions() const
621 return myActionMap.values();
624 QList<int> SUIT_Application::actionIds() const
626 return myActionMap.keys();
630 Creates action and registers it both in menu manager and tool manager
631 \return new instance of action
632 \param id - proposed SUIT identificator
633 \param text - description
634 \param icon - icon for toolbar
635 \param menu - menu text
636 \param tip - tool tip
637 \param key - shortcut
638 \param parent - parent object
639 \param toggle - if it is \c true the action will be a toggle action, otherwise it will be a command action
640 \param reciever - object that contains slot
641 \param member - slot to be called when action is activated
642 \param actionID - application-unique action ID. Required by SUIT_ShortcutMgr for shortcut customization. May be left blank.
644 QAction* SUIT_Application::createAction( const int id, const QString& text, const QIcon& icon,
645 const QString& menu, const QString& tip, const int key,
646 QObject* parent, const bool toggle, QObject* reciever,
647 const char* member, const QString& actionID )
649 return createAction( id, text, icon, menu, tip, QKeySequence(key), parent, toggle, reciever, member, actionID );
653 Creates action and registers it both in menu manager and tool manager
654 \return new instance of action
655 \param id - proposed SUIT identificator
656 \param text - description
657 \param icon - icon for toolbar
658 \param menu - menu text
659 \param tip - tool tip
660 \param key - shortcut
661 \param parent - parent object
662 \param toggle - if it is TRUE the action will be a toggle action, otherwise it will be a command action
663 \param reciever - object that contains slot
664 \param member - slot to be called when action is activated
665 \param actionID - application-unique action ID. Required by SUIT_ShortcutMgr for shortcut customization. May be left blank.
667 QAction* SUIT_Application::createAction( const int id, const QString& text, const QIcon& icon,
668 const QString& menu, const QString& tip, const QKeySequence& key,
669 QObject* parent, const bool toggle, QObject* reciever,
670 const char* member, const QString& actionID )
672 QtxAction* a = new QtxAction( text, icon, menu, key, parent, toggle, actionID );
673 a->setStatusTip( tip );
675 if ( reciever && member )
676 connect( a, SIGNAL( triggered( bool ) ), reciever, member );
678 registerAction( id, a );
684 Creates action and registers it both in menu manager and tool manager
685 \return new instance of action
686 \param id proposed SUIT identificator
687 \param parent parent object
688 \param toggle if it is TRUE the action will be a toggle action, otherwise it will be a command action
689 \param actionID application-unique action ID. Required by SUIT_ShortcutMgr for shortcut customization. May be left blank.
691 \param menuText can be later retrieved using QAction::text();
693 \param icon icon for toolbar
694 \param reciever object that contains slot
695 \param member slot to be called when action is activated
697 QAction* SUIT_Application::createAction( const int id, QObject* parent, const bool toggle, const QString& actionID,
698 const QString& toolTip, const QString& menuText, const QString& statusTip, const QIcon& icon,
699 QObject* reciever, const char* member )
701 QtxAction* a = new QtxAction( parent, toggle, actionID, toolTip, menuText, icon);
702 a->setStatusTip( statusTip );
704 if ( reciever && member )
705 connect( a, SIGNAL( triggered( bool ) ), reciever, member );
707 registerAction( id, a );
713 Registers action both in menu manager and tool manager
714 \param id - proposed SUIT identificator (if it is -1, auto generated one is used)
717 int SUIT_Application::registerAction( const int id, QAction* a )
719 int ident = actionId( a );
723 static int generatedId = -1;
724 ident = id == -1 ? --generatedId : id;
726 if ( action( ident ) )
727 qWarning( "Action registration id is already in use: %d", ident );
729 myActionMap.insert( ident, a );
731 if ( desktop() && desktop()->menuMgr() )
732 desktop()->menuMgr()->registerAction( a );
734 if ( desktop() && desktop()->toolMgr() )
735 desktop()->toolMgr()->registerAction( a );
737 if ( desktop() && a->shortcutContext() != Qt::WidgetShortcut &&
738 a->shortcutContext() != Qt::WidgetWithChildrenShortcut )
739 desktop()->addAction( a );
745 \return global action used as separator
747 QAction* SUIT_Application::separator()
749 return QtxActionMgr::separator();
753 SLOT: it is called when desktop is activated
756 void SUIT_Application::onDesktopActivated()
758 emit activated( this );
762 SLOT: it is called when desktop is moved
764 /*void SUIT_Application::onDesktopMoved()
769 SLOT: is used for Help browsing
771 void SUIT_Application::onHelpContextModule( const QString& /*theComponentName*/,
772 const QString& /*theFileName*/,
773 const QString& /*theContext*/ )
777 void SUIT_Application::addPostRoutine( PostRoutine theRoutine )
779 if ( !myPostRoutines.contains( theRoutine ) )
780 myPostRoutines << theRoutine;