Salome HOME
b54cb372762b63a8727d53b9c00012ae7a2e7895
[modules/gui.git] / src / Qtx / QtxMainWindow.cxx
1 // File:      QtxMainWindow.cxx
2 // Author:    Sergey TELKOV
3
4 #include "QtxMainWindow.h"
5
6 #include "QtxToolBar.h"
7 #include "QtxResourceMgr.h"
8
9 #include <qlayout.h>
10 #include <qmenubar.h>
11 #include <qstatusbar.h>
12 #include <qapplication.h>
13
14 /*!
15     Class: QtxMainWindow::Filter [Internal]
16     Descr: Internal object with event filter for QtxMainWindow.
17 */
18
19 class QtxMainWindow::Filter : public QObject
20 {
21 public:
22   Filter( QWidget*, QtxMainWindow*, QObject* = 0 );
23   virtual ~Filter();
24
25   virtual bool eventFilter( QObject*, QEvent* );
26
27 private:
28   QMainWindow* myMain;
29   QWidget*     myWidget;
30 };
31
32 QtxMainWindow::Filter::Filter( QWidget* wid, QtxMainWindow* mw, QObject* parent )
33 : QObject( parent ),
34 myMain( mw ),
35 myWidget( wid )
36 {
37   myMain->installEventFilter( this );
38 };
39
40 QtxMainWindow::Filter::~Filter()
41 {
42 }
43
44 bool QtxMainWindow::Filter::eventFilter( QObject* o, QEvent* e )
45 {
46   if ( myMain == o && e->type() == QEvent::ChildRemoved &&
47        myWidget == ((QChildEvent*)e)->child() )
48     return true;
49
50   return QObject::eventFilter( o, e );
51 }
52
53 /*!
54     Class: QtxMainWindow [Public]
55     Descr: Main window with support of dockable menubar/status bar
56            and geometry store/retrieve.
57 */
58
59 QtxMainWindow::QtxMainWindow( QWidget* parent, const char* name, WFlags f )
60 : QMainWindow( parent, name, f ),
61 myMode( -1 ),
62 myMenuBar( NULL ),
63 myStatusBar( NULL )
64 {
65 }
66
67 QtxMainWindow::~QtxMainWindow()
68 {
69   setDockableMenuBar( false );
70   setDockableStatusBar( false );
71 }
72
73 bool QtxMainWindow::isDockableMenuBar() const
74 {
75   return myMenuBar;
76 }
77
78 void QtxMainWindow::setDockableMenuBar( const bool on )
79 {
80   if ( isDockableMenuBar() == on )
81     return;
82
83   QMenuBar* mb = menuBar();
84   if ( !mb )
85     return;
86
87   if ( on && !myMenuBar )
88   {
89     mb->setCaption( tr( "Menu bar" ) );
90     QtxToolBar* dockMb = new QtxToolBar( true, this, "menu bar container" );
91     myMenuBar = dockMb;
92     new Filter( mb, this, myMenuBar );
93     dockMb->setWidget( mb );
94     dockMb->setNewLine( true );
95     dockMb->setStretchable( true );
96     dockMb->setResizeEnabled( false );
97
98     moveDockWindow( dockMb, DockTop );
99     setDockEnabled( dockMb, Left, false );
100     setDockEnabled( dockMb, Right, false );
101
102     setAppropriate( dockMb, false );
103
104     connect( dockMb, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
105   }
106   else if ( !on && myMenuBar )
107   {
108     mb->reparent( this, QPoint( 0, 0 ), mb->isVisibleTo( mb->parentWidget() ) );
109     disconnect( myMenuBar, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
110     delete myMenuBar;
111     myMenuBar = 0;
112     QChildEvent ce( QEvent::ChildRemoved, mb );
113     QApplication::sendEvent( this, &ce );
114   }
115
116   setUpLayout();
117 }
118
119 bool QtxMainWindow::isDockableStatusBar() const
120 {
121   return myStatusBar;
122 }
123
124 void QtxMainWindow::setDockableStatusBar( const bool on )
125 {
126   if ( isDockableStatusBar() == on )
127     return;
128
129   QStatusBar* sb = statusBar();
130   if ( !sb )
131     return;
132
133   if ( on && !myStatusBar )
134   {
135     sb->setCaption( tr( "Status bar" ) );
136     QtxToolBar* dockSb = new QtxToolBar( true, this, "status bar container" );
137     myStatusBar = dockSb;
138     new Filter( sb, this, myStatusBar );
139     dockSb->setWidget( sb );
140     dockSb->setNewLine( true );
141     dockSb->setStretchable( true );
142     dockSb->setResizeEnabled( false );
143     sb->setMinimumWidth( 250 );
144
145     sb->setSizeGripEnabled( false );
146
147     moveDockWindow( dockSb, DockBottom );
148     setDockEnabled( dockSb, Left, false );
149     setDockEnabled( dockSb, Right, false );
150
151     setAppropriate( dockSb, false );
152
153     connect( dockSb, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
154   }
155   else if ( !on && myStatusBar )
156   {
157     sb->reparent( this, QPoint( 0, 0 ), sb->isVisibleTo( sb->parentWidget() ) );
158     disconnect( myStatusBar, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
159     delete myStatusBar;
160     myStatusBar = 0;
161     QChildEvent ce( QEvent::ChildRemoved, sb );
162     QApplication::sendEvent( this, &ce );
163
164     sb->setSizeGripEnabled( true );
165   }
166
167   setUpLayout();
168 }
169
170 void QtxMainWindow::loadGeometry( QtxResourceMgr* resMgr, const QString& section )
171 {
172   QString sec = section.stripWhiteSpace();
173   if ( !resMgr || sec.isEmpty() )
174     return;
175
176   int winState = -1;
177   if ( !resMgr->value( sec, "state", winState ) )
178   {
179     QString stateStr;
180     if ( resMgr->value( sec, "state", stateStr ) )
181       winState = windowState( stateStr );
182   }
183
184   int win_w = resMgr->integerValue( sec, "width", width() );
185   int win_h = resMgr->integerValue( sec, "height", height() );
186
187   int winPosX = windowPosition( resMgr->stringValue( sec, QString( "pos_x" ), QString::null ) );
188   int winPosY = windowPosition( resMgr->stringValue( sec, QString( "pos_y" ), QString::null ) );
189
190   QWidget* desk = QApplication::desktop();
191
192   int win_x = 0;
193   if ( winPosX == WP_Absolute )
194     win_x = resMgr->integerValue( sec, "pos_x", x() );
195   else if ( desk )
196     win_x = relativeCoordinate( winPosX, desk->width(), win_w );
197
198   int win_y = 0;
199   if ( winPosX == WP_Absolute )
200     win_y = resMgr->integerValue( sec, "pos_y", y() );
201   else if ( desk )
202     win_y = relativeCoordinate( winPosY, desk->height(), win_h );
203
204   bool vis = isVisibleTo( parentWidget() );
205
206   resize( win_w, win_h );
207   move( win_x, win_y );
208
209   myMode = winState;
210
211   vis ? show() : hide();
212 }
213
214 void QtxMainWindow::show()
215 {
216   int mode = myMode;
217
218   myMode = -1;
219
220   switch ( mode )
221   {
222   case WS_Normal:
223     showNormal();
224     break;
225   case WS_Minimized:
226     showMinimized();
227     break;
228   case WS_Maximized:
229     showMaximized();
230     break;
231   }
232
233   QMainWindow::show();
234 }
235
236 int QtxMainWindow::relativeCoordinate( const int type, const int WH, const int wh ) const
237 {
238   int res = 0;
239   switch ( type )
240   {
241   case WP_Center:
242     res = ( WH - wh ) / 2;
243     break;
244   case WP_Left:
245     res = 0;
246     break;
247   case WP_Right:
248     res = WH - wh;
249     break;
250   }
251   return res;
252 }
253
254 void QtxMainWindow::saveGeometry( QtxResourceMgr* resMgr, const QString& section ) const
255 {
256   QString sec = section.stripWhiteSpace();
257   if ( !resMgr || sec.isEmpty() )
258     return;
259
260   resMgr->setValue( sec, "pos_x", pos().x() );
261   resMgr->setValue( sec, "pos_y", pos().y() );
262   resMgr->setValue( sec, "width", width() );
263   resMgr->setValue( sec, "height", height() );
264
265   int winState = WS_Normal;
266   if ( isMinimized() )
267     winState = WS_Minimized;
268   else if ( isMaximized() )
269     winState = WS_Maximized;
270
271   resMgr->setValue( sec, "state", winState );
272 }
273
274 bool QtxMainWindow::eventFilter( QObject* o, QEvent* e )
275 {
276   return QMainWindow::eventFilter( o, e );
277 }
278
279 void QtxMainWindow::setAppropriate( QDockWindow* dw, bool a )
280 {
281   QMainWindow::setAppropriate( dw, myStatusBar != dw && myMenuBar != dw && a );
282 }
283
284 void QtxMainWindow::setUpLayout()
285 {
286   QMainWindow::setUpLayout();
287
288   if ( myMenuBar && layout() )
289     layout()->setMenuBar( 0 );
290 }
291
292 void QtxMainWindow::onDestroyed( QObject* obj )
293 {
294   QObject* o = 0;
295   if ( obj == myMenuBar )
296   {
297     myMenuBar = 0;
298     o = menuBar();
299   }
300   else if ( obj == myStatusBar )
301   {
302     myStatusBar = 0;
303     o = statusBar();
304   }
305
306   if ( o )
307   {
308     QChildEvent ce( QEvent::ChildRemoved, o );
309     QApplication::sendEvent( this, &ce );
310   }
311 }
312
313 int QtxMainWindow::windowState( const QString& str ) const
314 {
315   static QMap<QString, int> winStateMap;
316   if ( winStateMap.isEmpty() )
317   {
318     winStateMap["normal"]    = WS_Normal;
319     winStateMap["min"]       = WS_Minimized;
320     winStateMap["mini"]      = WS_Minimized;
321     winStateMap["minimized"] = WS_Minimized;
322     winStateMap["max"]       = WS_Maximized;
323     winStateMap["maxi"]      = WS_Maximized;
324     winStateMap["maximized"] = WS_Maximized;
325     winStateMap["hidden"]    = WS_Hidden;
326     winStateMap["hided"]     = WS_Hidden;
327     winStateMap["hide"]      = WS_Hidden;
328     winStateMap["invisible"] = WS_Hidden;
329   }
330
331   int res = -1;
332   QString stateStr = str.stripWhiteSpace().lower();
333   if ( winStateMap.contains( stateStr ) )
334     res = winStateMap[stateStr];
335   return res;
336 }
337
338 int QtxMainWindow::windowPosition( const QString& str ) const
339 {
340   static QMap<QString, int> winPosMap;
341   if ( winPosMap.isEmpty() )
342   {
343     winPosMap["center"] = WP_Center;
344     winPosMap["left"]   = WP_Left;
345     winPosMap["right"]  = WP_Right;
346     winPosMap["top"]    = WP_Top;
347     winPosMap["bottom"] = WP_Bottom;
348   }
349
350   int res = WP_Absolute;
351   QString posStr = str.stripWhiteSpace().lower();
352   if ( winPosMap.contains( posStr ) )
353     res = winPosMap[posStr];
354   return res;
355 }