Salome HOME
Application::onLoadDoc() method implementation (for VISU batchmode tests)
[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 myMenuBar( NULL ),
62 myStatusBar( NULL )
63 {
64 }
65
66 QtxMainWindow::~QtxMainWindow()
67 {
68   setDockableMenuBar( false );
69   setDockableStatusBar( false );
70 }
71
72 bool QtxMainWindow::isDockableMenuBar() const
73 {
74   return myMenuBar;
75 }
76
77 void QtxMainWindow::setDockableMenuBar( const bool on )
78 {
79   if ( isDockableMenuBar() == on )
80     return;
81
82   QMenuBar* mb = menuBar();
83   if ( !mb )
84     return;
85
86   if ( on && !myMenuBar )
87   {
88     mb->setCaption( tr( "Menu bar" ) );
89     QtxToolBar* dockMb = new QtxToolBar( true, this, "menu bar container" );
90     myMenuBar = dockMb;
91     new Filter( mb, this, myMenuBar );
92     dockMb->setWidget( mb );
93     dockMb->setNewLine( true );
94     dockMb->setStretchable( true );
95     dockMb->setResizeEnabled( false );
96
97     moveDockWindow( dockMb, DockTop );
98     setDockEnabled( dockMb, Left, false );
99     setDockEnabled( dockMb, Right, false );
100
101     setAppropriate( dockMb, false );
102
103     connect( dockMb, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
104   }
105   else if ( !on && myMenuBar )
106   {
107     mb->reparent( this, QPoint( 0, 0 ), mb->isVisibleTo( mb->parentWidget() ) );
108     disconnect( myMenuBar, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
109     delete myMenuBar;
110     myMenuBar = 0;
111     QChildEvent ce( QEvent::ChildRemoved, mb );
112     QApplication::sendEvent( this, &ce );
113   }
114
115   setUpLayout();
116 }
117
118 bool QtxMainWindow::isDockableStatusBar() const
119 {
120   return myStatusBar;
121 }
122
123 void QtxMainWindow::setDockableStatusBar( const bool on )
124 {
125   if ( isDockableStatusBar() == on )
126     return;
127
128   QStatusBar* sb = statusBar();
129   if ( !sb )
130     return;
131
132   if ( on && !myStatusBar )
133   {
134     sb->setCaption( tr( "Status bar" ) );
135     QtxToolBar* dockSb = new QtxToolBar( true, this, "status bar container" );
136     myStatusBar = dockSb;
137     new Filter( sb, this, myStatusBar );
138     dockSb->setWidget( sb );
139     dockSb->setNewLine( true );
140     dockSb->setStretchable( true );
141     dockSb->setResizeEnabled( false );
142     sb->setMinimumWidth( 250 );
143
144     sb->setSizeGripEnabled( false );
145
146     moveDockWindow( dockSb, DockBottom );
147     setDockEnabled( dockSb, Left, false );
148     setDockEnabled( dockSb, Right, false );
149
150     setAppropriate( dockSb, false );
151
152     connect( dockSb, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
153   }
154   else if ( !on && myStatusBar )
155   {
156     sb->reparent( this, QPoint( 0, 0 ), sb->isVisibleTo( sb->parentWidget() ) );
157     disconnect( myStatusBar, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
158     delete myStatusBar;
159     myStatusBar = 0;
160     QChildEvent ce( QEvent::ChildRemoved, sb );
161     QApplication::sendEvent( this, &ce );
162
163     sb->setSizeGripEnabled( true );
164   }
165
166   setUpLayout();
167 }
168
169 void QtxMainWindow::loadGeometry( QtxResourceMgr* resMgr, const QString& section )
170 {
171   QString sec = section.stripWhiteSpace();
172   if ( !resMgr || sec.isEmpty() )
173     return;
174
175   int winState = -1;
176   if ( !resMgr->value( sec, "state", winState ) )
177   {
178     QString stateStr;
179     if ( resMgr->value( sec, "state", stateStr ) )
180       winState = windowState( stateStr );
181   }
182
183   int win_w = resMgr->integerValue( sec, "width", width() );
184   int win_h = resMgr->integerValue( sec, "height", height() );
185
186   int winPosX = windowPosition( resMgr->stringValue( sec, QString( "pos_x" ), QString::null ) );
187   int winPosY = windowPosition( resMgr->stringValue( sec, QString( "pos_y" ), QString::null ) );
188
189   QWidget* desk = QApplication::desktop();
190
191   int win_x = 0;
192   if ( winPosX == WP_Absolute )
193     win_x = resMgr->integerValue( sec, "pos_x", x() );
194   else if ( desk )
195     win_x = relativeCoordinate( winPosX, desk->width(), win_w );
196
197   int win_y = 0;
198   if ( winPosX == WP_Absolute )
199     win_y = resMgr->integerValue( sec, "pos_y", y() );
200   else if ( desk )
201     win_y = relativeCoordinate( winPosY, desk->height(), win_h );
202
203   bool vis = isVisibleTo( parentWidget() );
204
205   resize( win_w, win_h );
206   move( win_x, win_y );
207
208   switch ( winState )
209   {
210   case WS_Normal:
211     showNormal();
212     break;
213   case WS_Minimized:
214     showMinimized();
215     break;
216   case WS_Maximized:
217     showMaximized();
218     break;
219   case WS_Hidden:
220     vis = false;
221     break;
222   }
223
224   vis ? show() : hide();
225 }
226
227 int QtxMainWindow::relativeCoordinate( const int type, const int WH, const int wh ) const
228 {
229   int res = 0;
230   switch ( type )
231   {
232   case WP_Center:
233     res = ( WH - wh ) / 2;
234     break;
235   case WP_Left:
236     res = 0;
237     break;
238   case WP_Right:
239     res = WH - wh;
240     break;
241   }
242   return res;
243 }
244
245 void QtxMainWindow::saveGeometry( QtxResourceMgr* resMgr, const QString& section ) const
246 {
247   QString sec = section.stripWhiteSpace();
248   if ( !resMgr || sec.isEmpty() )
249     return;
250
251   resMgr->setValue( sec, "pos_x", pos().x() );
252   resMgr->setValue( sec, "pos_y", pos().y() );
253   resMgr->setValue( sec, "width", frameGeometry().width() );
254   resMgr->setValue( sec, "height",frameGeometry().height() );
255
256   int winState = WS_Normal;
257   if ( isMinimized() )
258     winState = WS_Minimized;
259   else if ( isMaximized() )
260     winState = WS_Maximized;
261
262   resMgr->setValue( sec, "state", winState );
263 }
264
265 bool QtxMainWindow::eventFilter( QObject* o, QEvent* e )
266 {
267   return QMainWindow::eventFilter( o, e );
268 }
269
270 void QtxMainWindow::setAppropriate( QDockWindow* dw, bool a )
271 {
272   QMainWindow::setAppropriate( dw, myStatusBar != dw && myMenuBar != dw && a );
273 }
274
275 void QtxMainWindow::setUpLayout()
276 {
277   QMainWindow::setUpLayout();
278
279   if ( myMenuBar && layout() )
280     layout()->setMenuBar( 0 );
281 }
282
283 void QtxMainWindow::onDestroyed( QObject* obj )
284 {
285   QObject* o = 0;
286   if ( obj == myMenuBar )
287   {
288     myMenuBar = 0;
289     o = menuBar();
290   }
291   else if ( obj == myStatusBar )
292   {
293     myStatusBar = 0;
294     o = statusBar();
295   }
296
297   if ( o )
298   {
299     QChildEvent ce( QEvent::ChildRemoved, o );
300     QApplication::sendEvent( this, &ce );
301   }
302 }
303
304 int QtxMainWindow::windowState( const QString& str ) const
305 {
306   static QMap<QString, int> winStateMap;
307   if ( winStateMap.isEmpty() )
308   {
309     winStateMap["normal"]    = WS_Normal;
310     winStateMap["min"]       = WS_Minimized;
311     winStateMap["mini"]      = WS_Minimized;
312     winStateMap["minimized"] = WS_Minimized;
313     winStateMap["max"]       = WS_Maximized;
314     winStateMap["maxi"]      = WS_Maximized;
315     winStateMap["maximized"] = WS_Maximized;
316     winStateMap["hidden"]    = WS_Hidden;
317     winStateMap["hided"]     = WS_Hidden;
318     winStateMap["hide"]      = WS_Hidden;
319     winStateMap["invisible"] = WS_Hidden;
320   }
321
322   int res = -1;
323   QString stateStr = str.stripWhiteSpace().lower();
324   if ( winStateMap.contains( stateStr ) )
325     res = winStateMap[stateStr];
326   return res;
327 }
328
329 int QtxMainWindow::windowPosition( const QString& str ) const
330 {
331   static QMap<QString, int> winPosMap;
332   if ( winPosMap.isEmpty() )
333   {
334     winPosMap["center"] = WP_Center;
335     winPosMap["left"]   = WP_Left;
336     winPosMap["right"]  = WP_Right;
337     winPosMap["top"]    = WP_Top;
338     winPosMap["bottom"] = WP_Bottom;
339   }
340
341   int res = WP_Absolute;
342   QString posStr = str.stripWhiteSpace().lower();
343   if ( winPosMap.contains( posStr ) )
344     res = winPosMap[posStr];
345   return res;
346 }