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