]> SALOME platform Git repositories - modules/gui.git/blob - src/SUIT/SUIT_Application.cxx
Salome HOME
042b6fc8c11492c3b2bd5bae5c13c2271535d035
[modules/gui.git] / src / SUIT / SUIT_Application.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
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.
10 //
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.
15 //
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
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 #include "SUIT_Application.h"
23
24 #include "SUIT_Study.h"
25 #include "SUIT_Session.h"
26 #include "SUIT_Desktop.h"
27 #include "SUIT_ResourceMgr.h"
28
29 #include <QTimer>
30 #include <QLabel>
31 #include <QStatusBar>
32 #include <QApplication>
33 #include <QSize>
34
35 #include <QtxAction.h>
36 #include <QtxActionMenuMgr.h>
37 #include <QtxActionToolMgr.h>
38
39 /*!
40   \class StatusLabel
41   \brief Status bar customization label. Used to workaroubd desktop resizing bug.
42   \internal
43 */
44 class StatusLabel : public QLabel
45 {
46 public:
47   StatusLabel( QWidget* parent ) : QLabel( parent ) {}
48   QSize minimumSizeHint () const { return QSize( 0, QLabel::minimumSizeHint().height() ); }
49 };
50
51 /*!
52   Default constructor
53 */
54 SUIT_Application::SUIT_Application()
55 : QObject( 0 ),
56   myStudy( 0 ),
57   myDesktop( 0 ),
58   myStatusLabel( 0 )
59 {
60   if ( SUIT_Session::session() )
61     SUIT_Session::session()->insertApplication( this );
62 }
63
64 /*!
65   Destructor
66 */
67 SUIT_Application::~SUIT_Application()
68 {
69   SUIT_Study* s = myStudy;
70   setActiveStudy( 0 );
71   delete s;
72
73   setDesktop( 0 );
74 }
75
76 /*!
77   \return main window of application (desktop)
78 */
79 SUIT_Desktop* SUIT_Application::desktop()
80 {
81   return myDesktop;
82 }
83
84 /*!
85    \return FALSE if application can not be closed (because of non saved data for example).
86    This method called by SUIT_Session whin closing of application was requested.
87 */
88 bool SUIT_Application::isPossibleToClose( bool& )
89 {
90   return true;
91 }
92
93 /*!
94   Performs some finalization of life cycle of this application.
95   For instance, the application can force its documents(s) to close.
96 */
97 void SUIT_Application::closeApplication()
98 {
99   emit applicationClosed( this );
100 }
101
102 /*!
103   \return active Study. If Application supports wirking with several studies this method should be redefined
104 */
105 SUIT_Study* SUIT_Application::activeStudy() const
106 {
107   return myStudy;
108 }
109
110 /*!
111   \return version of application
112 */
113 QString SUIT_Application::applicationVersion() const
114 {
115   return QString();
116 }
117
118 /*!
119   Shows the application's main widget. For non GUI application must be redefined.
120 */
121 void SUIT_Application::start()
122 {
123   if ( desktop() )
124     desktop()->show();
125 }
126
127 /*!
128   Opens document into active Study. If Study is empty - creates it.
129   \param theFileName - name of document file
130 */
131 bool SUIT_Application::useFile( const QString& theFileName )
132 {
133   createEmptyStudy();
134   SUIT_Study* study = activeStudy();
135
136   bool status = study ? study->openDocument( theFileName ) : false;
137
138   if ( !status )
139   {
140     setActiveStudy( 0 );
141     delete study;
142   }
143
144   return status;
145 }
146
147 /*!
148   Creates new empty Study if active Study = 0
149 */
150 void SUIT_Application::createEmptyStudy()
151 {
152   if ( !activeStudy() )
153     setActiveStudy( createNewStudy() );
154 }
155
156 /*!
157   \return number of Studies.
158   Must be redefined in Applications which support several studies for one Application instance.
159 */
160 int SUIT_Application::getNbStudies() const
161 {
162   return activeStudy() ? 1 : 0;
163 }
164
165 /*!
166   \return global resource manager
167 */
168 SUIT_ResourceMgr* SUIT_Application::resourceMgr() const
169 {
170   if ( !SUIT_Session::session() )
171     return 0;
172
173   return SUIT_Session::session()->resourceMgr();
174 }
175
176 #define DEFAULT_MESSAGE_DELAY 3000
177
178 /*!
179   Puts the message to the status bar
180   \param msg - text of message
181   \param msec - time in milliseconds, after that the status label will be cleared
182 */
183 void SUIT_Application::putInfo( const QString& msg, const int msec )
184 {
185   if ( !desktop() )
186     return;
187
188   if ( !myStatusLabel )
189   {
190     myStatusLabel = new StatusLabel( desktop()->statusBar() );
191     desktop()->statusBar()->addWidget( myStatusLabel, 1 );
192     myStatusLabel->show();
193   }
194
195   QString prev = myStatusLabel->text();
196
197   myStatusLabel->setText( msg );
198   if ( msec != -1 )
199     QTimer::singleShot( msec <= 0 ? DEFAULT_MESSAGE_DELAY : msec, this, SLOT( onInfoClear() ) );
200
201   if ( prev != msg )
202     emit infoChanged( msg );
203 }
204
205 /*!
206   Clear the information label in status bar after delay.
207 */
208 void SUIT_Application::onInfoClear()
209 {
210   if ( !myStatusLabel )
211     return;
212
213   bool changed = !myStatusLabel->text().isEmpty();
214   myStatusLabel->clear();
215   if ( changed )
216     emit infoChanged( QString() );
217 }
218
219 /*!
220   Update status of the registerd actions
221 */
222 void SUIT_Application::updateCommandsStatus()
223 {
224 }
225
226 /*!
227   Initialize with application arguments
228   \param argc - number of application arguments
229   \param argv - array of application arguments
230 */
231 SUIT_Application* SUIT_Application::startApplication( int argc, char** argv ) const
232 {
233   return startApplication( objectName(), argc, argv );
234 }
235
236 /*!
237   Initialize with application name and arguments
238   \param name - name of application
239   \param argc - number of application arguments
240   \param argv - array of application arguments
241 */
242 SUIT_Application* SUIT_Application::startApplication( const QString& name, int argc, char** argv ) const
243 {
244   SUIT_Session* session = SUIT_Session::session();
245   if ( !session )
246     return 0;
247
248   return session->startApplication( name, argc, argv );
249 }
250
251 /*!
252   Sets the main window of application
253   \param desk - new main window (desktop)
254 */
255 void SUIT_Application::setDesktop( SUIT_Desktop* desk )
256 {
257   if ( myDesktop == desk )
258     return;
259
260   delete myDesktop;
261   myDesktop = desk;
262   if ( myDesktop ) {
263     connect( myDesktop, SIGNAL( activated() ), this, SLOT( onDesktopActivated() ) );
264     // Force desktop activation (NPAL16628)
265     QApplication::postEvent(myDesktop, new QEvent(QEvent::WindowActivate));
266   }
267 }
268
269 /*!
270   Creates new instance of study.
271   By default, it is called from createEmptyStudy()
272   \sa createEmptyStudy()
273 */
274 SUIT_Study* SUIT_Application::createNewStudy()
275 {
276   return new SUIT_Study( this );
277 }
278
279 /*!
280   Sets study as active
281   \param study - instance of study to be set as active
282 */
283 void SUIT_Application::setActiveStudy( SUIT_Study* study )
284 {
285   if ( myStudy == study )
286     return;
287
288   if ( myStudy )
289     disconnect( myStudy, SIGNAL( studyModified( SUIT_Study* ) ),
290                 this, SLOT( updateCommandsStatus() ) );
291   if ( study )
292     connect( study, SIGNAL( studyModified( SUIT_Study* ) ),
293              this, SLOT( updateCommandsStatus() ) );
294
295   myStudy = study;
296 }
297
298 /*!
299   Creates new toolbar
300   \return identificator of new toolbar in tool manager
301   \param name - name of new toolbar
302 */
303 int SUIT_Application::createTool( const QString& name )
304 {
305   if ( !desktop() || !desktop()->toolMgr() )
306     return -1;
307
308   return desktop()->toolMgr()->createToolBar( name );
309 }
310
311 /*!
312   Creates new toolbutton
313   \return SUIT identificator of new action
314   \param a - action
315   \param tBar - identificator of toolbar
316   \param id - proposed SUIT identificator of action (if it is -1, then must be use any free)
317   \param idx - index in toolbar
318 */
319 int SUIT_Application::createTool( QAction* a, const int tBar, const int id, const int idx )
320 {
321   if ( !desktop() || !desktop()->toolMgr() )
322     return -1;
323
324   int regId = registerAction( id, a );
325   int intId = desktop()->toolMgr()->insert( a, tBar, idx );
326   return intId != -1 ? regId : -1;
327 }
328
329 /*!
330   Creates new toolbutton
331   \return SUIT identificator of new action
332   \param a - action
333   \param tBar - name of toolbar
334   \param id - proposed SUIT identificator of action (if it is -1, then must be use any free)
335   \param idx - index in toolbar
336 */
337 int SUIT_Application::createTool( QAction* a, const QString& tBar, const int id, const int idx )
338 {
339   if ( !desktop() || !desktop()->toolMgr() )
340     return -1;
341
342   int regId = registerAction( id, a );
343   int intId = desktop()->toolMgr()->insert( a, tBar, idx );
344   return intId != -1 ? regId : -1;
345 }
346
347 /*!
348   Creates new toolbutton
349   \return "id" if all right or -1 otherwise
350   \param id - SUIT identificator of action
351   \param tBar - identificator of toolbar
352   \param idx - index in toolbar
353 */
354 int SUIT_Application::createTool( const int id, const int tBar, const int idx )
355 {
356   if ( !desktop() || !desktop()->toolMgr() )
357     return -1;
358
359   int intId = desktop()->toolMgr()->insert( action( id ), tBar, idx );
360   return intId != -1 ? id : -1;
361 }
362
363 /*!
364   Creates new toolbutton
365   \return "id" if all right or -1 otherwise
366   \param id - SUIT identificator of action
367   \param tBar - name of toolbar
368   \param idx - index in toolbar
369 */
370 int SUIT_Application::createTool( const int id, const QString& tBar, const int idx )
371 {
372   if ( !desktop() || !desktop()->toolMgr() )
373     return -1;
374
375   int intId = desktop()->toolMgr()->insert( action( id ), tBar, idx );
376   return intId != -1 ? id : -1;
377 }
378
379 /*!
380   Creates new menu item
381   \return identificator of new action in menu manager
382   \param subMenu - menu text of new item
383   \param menu - identificator of parent menu item
384   \param id - proposed identificator of action
385   \param group - group in menu manager
386   \param index - index in menu
387 */
388 int SUIT_Application::createMenu( const QString& subMenu, const int menu,
389                                   const int id, const int group, const int index )
390 {
391   if ( !desktop() || !desktop()->menuMgr() )
392     return -1;
393
394   return desktop()->menuMgr()->insert( subMenu, menu, group, id, index );
395 }
396
397 /*!
398   Creates new menu item
399   \return identificator of new action in menu manager
400   \param subMenu - menu text of new item
401   \param menu - menu text of parent menu item
402   \param id - proposed identificator of action
403   \param group - group in menu manager
404   \param index - index in menu
405 */
406 int SUIT_Application::createMenu( const QString& subMenu, const QString& menu,
407                                   const int id, const int group, const int index )
408 {
409   if ( !desktop() || !desktop()->menuMgr() )
410     return -1;
411
412   return desktop()->menuMgr()->insert( subMenu, menu, group, id, index );
413 }
414
415 /*!
416   Creates new menu item
417   \return SUIT identificator of new action
418   \param a - action
419   \param menu - identificator of parent menu item
420   \param id - proposed SUIT identificator of action
421   \param group - group in menu manager
422   \param index - index in menu
423 */
424 int SUIT_Application::createMenu( QAction* a, const int menu, const int id, const int group, const int index )
425 {
426   if ( !a || !desktop() || !desktop()->menuMgr() )
427     return -1;
428
429   int regId = registerAction( id, a );
430   int intId = desktop()->menuMgr()->insert( a, menu, group, index );
431   return intId != -1 ? regId : -1;
432 }
433
434 /*!
435   Creates new menu item
436   \return SUIT identificator of new action
437   \param a - action
438   \param menu - menu text of parent menu item
439   \param id - proposed SUIT identificator of action
440   \param group - group in menu manager
441   \param index - index in menu
442 */
443 int SUIT_Application::createMenu( QAction* a, const QString& menu, const int id, const int group, const int index )
444 {
445   if ( !a || !desktop() || !desktop()->menuMgr() )
446     return -1;
447
448   int regId = registerAction( id, a );
449   int intId = desktop()->menuMgr()->insert( a, menu, group, index );
450   return intId != -1 ? regId : -1;
451 }
452
453 /*!
454   Creates new menu item
455   \return identificator of new action in menu manager
456   \param id - SUIT identificator of action
457   \param menu - menu text of parent menu item
458   \param group - group in menu manager
459   \param index - index in menu
460 */
461 int SUIT_Application::createMenu( const int id, const int menu, const int group, const int index )
462 {
463   if ( !desktop() || !desktop()->menuMgr() )
464     return -1;
465
466   int intId = desktop()->menuMgr()->insert( action( id ), menu, group, index );
467   return intId != -1 ? id : -1;
468 }
469
470 /*!
471   Creates new menu item
472   \return identificator of new action in menu manager
473   \param id - SUIT identificator of action
474   \param menu - menu text of parent menu item
475   \param group - group in menu manager
476   \param index - index in menu
477 */
478 int SUIT_Application::createMenu( const int id, const QString& menu, const int group, const int index )
479 {
480   if ( !desktop() || !desktop()->menuMgr() )
481     return -1;
482
483   int intId = desktop()->menuMgr()->insert( action( id ), menu, group, index );
484   return intId != -1 ? id : -1;
485 }
486
487 /*!
488   Show/hide menu item corresponding to action
489   \param a - action
490   \param on - if it is true, the item will be shown, otherwise it will be hidden
491 */
492 void SUIT_Application::setMenuShown( QAction* a, const bool on )
493 {
494   if ( !a || !desktop() )
495     return;
496
497   QtxActionMenuMgr* mMgr = desktop()->menuMgr();
498   if ( mMgr )
499     mMgr->setShown( mMgr->actionId( a ), on );
500 }
501
502 /*!
503   Show/hide menu item corresponding to action
504   \param id - identificator of action in menu manager
505   \param on - if it is true, the item will be shown, otherwise it will be hidden
506 */
507 void SUIT_Application::setMenuShown( const int id, const bool on )
508 {
509   setMenuShown( action( id ), on );
510 }
511
512 /*!
513   Show/hide tool button corresponding to action
514   \param a - action
515   \param on - if it is true, the button will be shown, otherwise it will be hidden
516 */
517 void SUIT_Application::setToolShown( QAction* a, const bool on )
518 {
519   if ( !a || !desktop() )
520     return;
521
522   QtxActionToolMgr* tMgr = desktop()->toolMgr();
523   if ( tMgr )
524     tMgr->setShown( tMgr->actionId( a ), on );
525 }
526
527 /*!
528   Show/hide menu item corresponding to action
529   \param id - identificator of action in tool manager
530   \param on - if it is true, the button will be shown, otherwise it will be hidden
531 */
532 void SUIT_Application::setToolShown( const int id, const bool on )
533 {
534   setToolShown( action( id ), on );
535 }
536
537 /*!
538   Show/hide both menu item and tool button corresponding to action
539   \param a - action
540   \param on - if it is true, the item will be shown, otherwise it will be hidden
541 */
542 void SUIT_Application::setActionShown( QAction* a, const bool on )
543 {
544   setMenuShown( a, on );
545   setToolShown( a, on );
546 }
547
548 /*!
549   Show/hide both menu item and tool button corresponding to action
550   \param id - identificator in both menu manager and tool manager
551   \param on - if it is true, the item will be shown, otherwise it will be hidden
552 */
553 void SUIT_Application::setActionShown( const int id, const bool on )
554 {
555   setMenuShown( id, on );
556   setToolShown( id, on );
557 }
558
559 /*!
560   \return action by it's SUIT identificator
561   \param id - SUIT identificator
562 */
563 QAction* SUIT_Application::action( const int id ) const
564 {
565   QAction* a = 0;
566   if ( myActionMap.contains( id ) )
567     a = myActionMap[id];
568   return a;
569 }
570
571 /*!
572   \return SUIT identificator of action
573   \param a - action
574 */
575 int SUIT_Application::actionId( const QAction* a ) const
576 {
577   int id = -1;
578   for ( QMap<int, QAction*>::ConstIterator it = myActionMap.begin(); it != myActionMap.end() && id == -1; ++it )
579   {
580     if ( it.value() == a )
581       id = it.key();
582   }
583   return id;
584 }
585
586 QList<QAction*> SUIT_Application::actions() const
587 {
588   return myActionMap.values();
589 }
590
591 QList<int> SUIT_Application::actionIds() const
592 {
593   return myActionMap.keys();
594 }
595
596 /*!
597   Creates action and registers it both in menu manager and tool manager
598   \return new instance of action
599   \param id - proposed SUIT identificator
600   \param text - description
601   \param icon - icon for toolbar
602   \param menu - menu text
603   \param tip - tool tip
604   \param key - shortcut
605   \param parent - parent object
606   \param toggle - if it is TRUE the action will be a toggle action, otherwise it will be a command action
607   \param reciever - object that contains slot
608   \param member - slot to be called when action is activated
609 */
610 QAction* SUIT_Application::createAction( const int id, const QString& text, const QIcon& icon,
611                                          const QString& menu, const QString& tip, const int key,
612                                          QObject* parent, const bool toggle, QObject* reciever, const char* member )
613 {
614   QtxAction* a = new QtxAction( text, icon, menu, key, parent, toggle );
615   a->setStatusTip( tip );
616
617   if ( reciever && member )
618     connect( a, SIGNAL( triggered( bool ) ), reciever, member );
619
620   registerAction( id, a );
621
622   return a;
623 }
624
625 /*!
626   Registers action both in menu manager and tool manager
627   \param id - proposed SUIT identificator (if it is -1, auto generated one is used)
628   \param a - action
629 */
630 int SUIT_Application::registerAction( const int id, QAction* a )
631 {
632   int ident = actionId( a );
633   if ( ident != -1 )
634     return ident;
635
636   static int generatedId = -1;
637   ident = id == -1 ? --generatedId : id;
638
639   if ( action( ident ) )
640     qWarning( "Action registration id is already in use: %d", ident );
641
642   myActionMap.insert( ident, a );
643
644   if ( desktop() && desktop()->menuMgr() )
645     desktop()->menuMgr()->registerAction( a );
646
647   if ( desktop() && desktop()->toolMgr() )
648     desktop()->toolMgr()->registerAction( a );
649
650   if ( desktop() )
651     desktop()->addAction( a );
652
653   return ident;
654 }
655
656 /*!
657   \return global action used as separator
658 */
659 QAction* SUIT_Application::separator()
660 {
661   return QtxActionMgr::separator();
662 }
663
664 /*!
665   SLOT: it is called when desktop is activated
666 */
667
668 void SUIT_Application::onDesktopActivated()
669 {
670   emit activated( this );
671 }
672
673 /*!
674   SLOT: is used for Help browsing
675 */
676 void SUIT_Application::onHelpContextModule( const QString& /*theComponentName*/,
677                                             const QString& /*theFileName*/,
678                                             const QString& /*theContext*/ )
679 {
680 }