]> SALOME platform Git repositories - modules/gui.git/blob - src/Qtx/QtxMainWindow.cxx
Salome HOME
39b385fea9ac449678443aadefe7caab8db49298
[modules/gui.git] / src / Qtx / QtxMainWindow.cxx
1 // Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
2 // 
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either 
6 // version 2.1 of the License.
7 // 
8 // This library is distributed in the hope that it will be useful 
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public  
14 // License along with this library; if not, write to the Free Software 
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/
18 //
19 // File:      QtxMainWindow.cxx
20 // Author:    Sergey TELKOV
21
22 #include "QtxMainWindow.h"
23
24 #include "QtxToolBar.h"
25 #include "QtxResourceMgr.h"
26
27 #include <qlayout.h>
28 #include <qmenubar.h>
29 #include <qstatusbar.h>
30 #include <qapplication.h>
31
32 /*!
33     Class: QtxMainWindow::Filter [Internal]
34     Descr: Internal object with event filter for QtxMainWindow.
35 */
36
37 class QtxMainWindow::Filter : public QObject
38 {
39 public:
40   Filter( QWidget*, QtxMainWindow*, QObject* = 0 );
41   virtual ~Filter();
42
43   virtual bool eventFilter( QObject*, QEvent* );
44
45 private:
46   QMainWindow* myMain;
47   QWidget*     myWidget;
48 };
49
50 /*!
51   Constructor
52 */
53 QtxMainWindow::Filter::Filter( QWidget* wid, QtxMainWindow* mw, QObject* parent )
54 : QObject( parent ),
55 myMain( mw ),
56 myWidget( wid )
57 {
58   myMain->installEventFilter( this );
59 };
60
61 /*!
62   Destructor
63 */
64 QtxMainWindow::Filter::~Filter()
65 {
66 }
67
68 /*!
69   Custom event filter
70 */
71 bool QtxMainWindow::Filter::eventFilter( QObject* o, QEvent* e )
72 {
73   if ( myMain == o && e->type() == QEvent::ChildRemoved &&
74        myWidget == ((QChildEvent*)e)->child() )
75     return true;
76
77   return QObject::eventFilter( o, e );
78 }
79
80 /*!
81     Class: QtxMainWindow [Public]
82     Descr: Main window with support of dockable menubar/status bar
83            and geometry store/retrieve.
84 */
85 QtxMainWindow::QtxMainWindow( QWidget* parent, const char* name, WFlags f )
86 : QMainWindow( parent, name, f ),
87 myMode( -1 ),
88 myMenuBar( NULL ),
89 myStatusBar( NULL )
90 {
91 }
92
93 /*!
94   Destructor
95 */
96 QtxMainWindow::~QtxMainWindow()
97 {
98   setDockableMenuBar( false );
99   setDockableStatusBar( false );
100 }
101
102 /*!
103   \return true if menu bar exists
104 */
105 bool QtxMainWindow::isDockableMenuBar() const
106 {
107   return myMenuBar;
108 }
109
110 /*!
111   Creates or deletes menu bar
112   \param on - if it is true, then to create, otherwise - to delete
113 */
114 void QtxMainWindow::setDockableMenuBar( const bool on )
115 {
116   if ( isDockableMenuBar() == on )
117     return;
118
119   QMenuBar* mb = menuBar();
120   if ( !mb )
121     return;
122
123   if ( on && !myMenuBar )
124   {
125     mb->setCaption( tr( "Menu bar" ) );
126     QtxToolBar* dockMb = new QtxToolBar( true, this, "menu bar container" );
127     myMenuBar = dockMb;
128     new Filter( mb, this, myMenuBar );
129     dockMb->setWidget( mb );
130     dockMb->setNewLine( true );
131     dockMb->setStretchable( true );
132     dockMb->setResizeEnabled( false );
133
134     moveDockWindow( dockMb, DockTop );
135     setDockEnabled( dockMb, Left, false );
136     setDockEnabled( dockMb, Right, false );
137
138     setAppropriate( dockMb, false );
139
140     connect( dockMb, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
141   }
142   else if ( !on && myMenuBar )
143   {
144     mb->reparent( this, QPoint( 0, 0 ), mb->isVisibleTo( mb->parentWidget() ) );
145     disconnect( myMenuBar, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
146     delete myMenuBar;
147     myMenuBar = 0;
148     QChildEvent ce( QEvent::ChildRemoved, mb );
149     QApplication::sendEvent( this, &ce );
150   }
151
152   setUpLayout();
153 }
154
155 /*!
156   \return true if status bar exists
157 */
158 bool QtxMainWindow::isDockableStatusBar() const
159 {
160   return myStatusBar;
161 }
162
163 /*!
164   Creates or deletes status bar
165   \param on - if it is true, then to create, otherwise - to delete
166 */
167 void QtxMainWindow::setDockableStatusBar( const bool on )
168 {
169   if ( isDockableStatusBar() == on )
170     return;
171
172   QStatusBar* sb = statusBar();
173   if ( !sb )
174     return;
175
176   if ( on && !myStatusBar )
177   {
178     sb->setCaption( tr( "Status bar" ) );
179     QtxToolBar* dockSb = new QtxToolBar( true, this, "status bar container" );
180     myStatusBar = dockSb;
181     new Filter( sb, this, myStatusBar );
182     dockSb->setWidget( sb );
183     dockSb->setNewLine( true );
184     dockSb->setStretchable( true );
185     dockSb->setResizeEnabled( false );
186     sb->setMinimumWidth( 250 );
187
188     sb->setSizeGripEnabled( false );
189
190     moveDockWindow( dockSb, DockBottom );
191     setDockEnabled( dockSb, Left, false );
192     setDockEnabled( dockSb, Right, false );
193
194     setAppropriate( dockSb, false );
195
196     connect( dockSb, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
197   }
198   else if ( !on && myStatusBar )
199   {
200     sb->reparent( this, QPoint( 0, 0 ), sb->isVisibleTo( sb->parentWidget() ) );
201     disconnect( myStatusBar, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
202     delete myStatusBar;
203     myStatusBar = 0;
204     QChildEvent ce( QEvent::ChildRemoved, sb );
205     QApplication::sendEvent( this, &ce );
206
207     sb->setSizeGripEnabled( true );
208   }
209
210   setUpLayout();
211 }
212
213 /*!
214   Retrieve the geometry information from the specified resource manager section.
215   \param resMgr - instance of ersource manager
216   \param section - section name
217 */
218 void QtxMainWindow::loadGeometry( QtxResourceMgr* resMgr, const QString& section )
219 {
220   QString sec = section.stripWhiteSpace();
221   if ( !resMgr || sec.isEmpty() )
222     return;
223
224   int winState = -1;
225   if ( !resMgr->value( sec, "state", winState ) )
226   {
227     QString stateStr;
228     if ( resMgr->value( sec, "state", stateStr ) )
229       winState = windowState( stateStr );
230   }
231
232   int win_w = resMgr->integerValue( sec, "width", width() );
233   int win_h = resMgr->integerValue( sec, "height", height() );
234
235   int winPosX = windowPosition( resMgr->stringValue( sec, QString( "pos_x" ), QString::null ) );
236   int winPosY = windowPosition( resMgr->stringValue( sec, QString( "pos_y" ), QString::null ) );
237
238   QWidget* desk = QApplication::desktop();
239
240   int win_x = 0;
241   if ( winPosX == WP_Absolute )
242     win_x = resMgr->integerValue( sec, "pos_x", x() );
243   else if ( desk )
244     win_x = relativeCoordinate( winPosX, desk->width(), win_w );
245
246   int win_y = 0;
247   if ( winPosX == WP_Absolute )
248     win_y = resMgr->integerValue( sec, "pos_y", y() );
249   else if ( desk )
250     win_y = relativeCoordinate( winPosY, desk->height(), win_h );
251
252   bool vis = isVisibleTo( parentWidget() );
253
254   resize( win_w, win_h );
255   move( win_x, win_y );
256
257   myMode = -1;
258
259   if ( vis )
260     QApplication::postEvent( this, new QCustomEvent( QEvent::User, (void*)winState ) );
261   else
262     myMode = winState;
263 }
264
265 /*!
266   Shows main window
267 */
268 void QtxMainWindow::show()
269 {
270   if ( myMode != -1 )
271     QApplication::postEvent( this, new QCustomEvent( QEvent::User, (void*)myMode ) );
272
273   myMode = -1;
274
275   QMainWindow::show();
276 }
277
278 /*!
279   Handler of custom events
280 */
281 void QtxMainWindow::customEvent( QCustomEvent* e )
282 {
283   QMainWindow::customEvent( e );
284
285   size_t mode = size_t(e->data());
286   switch ( mode )
287   {
288   case WS_Normal:
289     showNormal();
290     break;
291   case WS_Minimized:
292     showMinimized();
293     break;
294   case WS_Maximized:
295     showMaximized();
296     break;
297   }
298 }
299
300 /*!
301   \return relative co-ordinate by two points
302   \param type - type of result: WP_Center (center), WP_Left (left), WP_Right (right)
303   \param wh - left point
304   \param WH - right point
305 */
306 int QtxMainWindow::relativeCoordinate( const int type, const int WH, const int wh ) const
307 {
308   int res = 0;
309   switch ( type )
310   {
311   case WP_Center:
312     res = ( WH - wh ) / 2;
313     break;
314   case WP_Left:
315     res = 0;
316     break;
317   case WP_Right:
318     res = WH - wh;
319     break;
320   }
321   return res;
322 }
323
324 /*!
325   Store the geometry information into the specified resource manager section.
326   \param resMgr - instance of ersource manager
327   \param section - section name
328 */
329 void QtxMainWindow::saveGeometry( QtxResourceMgr* resMgr, const QString& section ) const
330 {
331   QString sec = section.stripWhiteSpace();
332   if ( !resMgr || sec.isEmpty() )
333     return;
334
335   resMgr->setValue( sec, "pos_x", pos().x() );
336   resMgr->setValue( sec, "pos_y", pos().y() );
337   resMgr->setValue( sec, "width", width() );
338   resMgr->setValue( sec, "height", height() );
339
340   int winState = WS_Normal;
341   if ( isMinimized() )
342     winState = WS_Minimized;
343   else if ( isMaximized() )
344     winState = WS_Maximized;
345
346   resMgr->setValue( sec, "state", winState );
347 }
348
349 /*!
350   Custom event filter
351 */
352 bool QtxMainWindow::eventFilter( QObject* o, QEvent* e )
353 {
354   return QMainWindow::eventFilter( o, e );
355 }
356
357 /*!
358   Controls whether or not the dw dock window's caption should appear
359   as a menu item on the dock window menu that lists the dock windows.
360   \param dw - window
361   \param a - if it is true, then it appears in menu
362 */
363 void QtxMainWindow::setAppropriate( QDockWindow* dw, bool a )
364 {
365   QMainWindow::setAppropriate( dw, myStatusBar != dw && myMenuBar != dw && a );
366 }
367
368 /*!
369   Sets up layout
370 */
371 void QtxMainWindow::setUpLayout()
372 {
373   QMainWindow::setUpLayout();
374
375   if ( myMenuBar && layout() )
376     layout()->setMenuBar( 0 );
377 }
378
379 /*!
380   SLOT: called on object destroyed, clears internal fields in case of deletion of menu bar or status bar
381 */
382 void QtxMainWindow::onDestroyed( QObject* obj )
383 {
384   QObject* o = 0;
385   if ( obj == myMenuBar )
386   {
387     myMenuBar = 0;
388     o = menuBar();
389   }
390   else if ( obj == myStatusBar )
391   {
392     myStatusBar = 0;
393     o = statusBar();
394   }
395
396   if ( o )
397   {
398     QChildEvent ce( QEvent::ChildRemoved, o );
399     QApplication::sendEvent( this, &ce );
400   }
401 }
402
403 /*!
404   \return flag of window state by it's name
405   \param str - name of flag
406 */
407 int QtxMainWindow::windowState( const QString& str ) const
408 {
409   static QMap<QString, int> winStateMap;
410   if ( winStateMap.isEmpty() )
411   {
412     winStateMap["normal"]    = WS_Normal;
413     winStateMap["min"]       = WS_Minimized;
414     winStateMap["mini"]      = WS_Minimized;
415     winStateMap["minimized"] = WS_Minimized;
416     winStateMap["max"]       = WS_Maximized;
417     winStateMap["maxi"]      = WS_Maximized;
418     winStateMap["maximized"] = WS_Maximized;
419     winStateMap["hidden"]    = WS_Hidden;
420     winStateMap["hided"]     = WS_Hidden;
421     winStateMap["hide"]      = WS_Hidden;
422     winStateMap["invisible"] = WS_Hidden;
423   }
424
425   int res = -1;
426   QString stateStr = str.stripWhiteSpace().lower();
427   if ( winStateMap.contains( stateStr ) )
428     res = winStateMap[stateStr];
429   return res;
430 }
431
432 /*!
433   \return flag of position by it's name
434   \param str - name of position
435 */
436 int QtxMainWindow::windowPosition( const QString& str ) const
437 {
438   static QMap<QString, int> winPosMap;
439   if ( winPosMap.isEmpty() )
440   {
441     winPosMap["center"] = WP_Center;
442     winPosMap["left"]   = WP_Left;
443     winPosMap["right"]  = WP_Right;
444     winPosMap["top"]    = WP_Top;
445     winPosMap["bottom"] = WP_Bottom;
446   }
447
448   int res = WP_Absolute;
449   QString posStr = str.stripWhiteSpace().lower();
450   if ( winPosMap.contains( posStr ) )
451     res = winPosMap[posStr];
452   return res;
453 }