Salome HOME
Merge branch V7_3_1_BR
[modules/gui.git] / src / Qtx / QtxWorkstack.h
1 // Copyright (C) 2007-2014  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, or (at your option) any later version.
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
23 // File:      QtxWorkstack.h
24 // Author:    Sergey TELKOV
25 //
26 #ifndef QTXWORKSTACK_H
27 #define QTXWORKSTACK_H
28
29 #include "Qtx.h"
30
31 #include <QMap>
32 #include <QFrame>
33 #include <QEvent>
34 #include <QWidget>
35 #include <QTabBar>
36 #include <QPointer>
37 #include <QSplitter>
38 #include <QByteArray>
39
40 class QAction;
41 class QDataStream;
42 class QRubberBand;
43 class QStackedWidget;
44 class QAbstractButton;
45
46 class QtxWorkstackArea;
47 class QtxWorkstackDrag;
48 class QtxWorkstackChild;
49 class QtxWorkstackTabBar;
50 class QtxWorkstackSplitter;
51
52 #ifdef WIN32
53 #pragma warning( disable:4251 )
54 #endif
55
56 class QTX_EXPORT QtxWorkstack : public QWidget
57 {
58   Q_OBJECT
59
60 public:
61   //! Workstack actions (context menu items)
62   enum { SplitVertical    = 0x01,  //!< "Split vertically" menu item
63          SplitHorizontal  = 0x02,  //!< "Split horizontally" menu item
64          Close            = 0x04,  //!< "Close" menu item
65          Rename           = 0x08,  //!< "Rename" menu item
66          All = SplitVertical | SplitHorizontal |
67                Close | Rename      //!< all menu items
68   };
69
70   enum { VersionMarker = 0x01,
71                SplitMarker   = 0x02,
72                AreaMarker    = 0x04,
73                WidgetMarker  = 0x08
74   };
75
76   enum { Horizontal = 0x01,
77                Visible    = 0x02
78   };
79
80   //! Workstack splitting type
81   enum SplitType
82   {
83     SplitStay,  //!< selected widget stays in current workarea, others widgets are moved into a new workarea
84     SplitAt,    //!< all widgets before selected widget stay in current workarea, other widgess are moved into a new workarea
85     SplitMove   //!< selected widget is moved into a new workarea, all other widgets stay in an old workarea
86   };
87
88 public:
89   QtxWorkstack( QWidget* = 0 );
90   virtual ~QtxWorkstack();
91
92   QWidgetList         windowList( QWidget* = 0 ) const;
93   QWidgetList         splitWindowList() const;
94
95   QWidget*            activeWindow() const;
96   void                setActiveWindow( QWidget* );
97
98   int                 accel( const int ) const;
99   void                setAccel( const int, const int );
100
101   QIcon               icon( const int ) const;
102   void                setIcon( const int, const QIcon& );
103
104   void                setMenuActions( const int );
105   int                 menuActions() const;
106
107   void                stack();
108   void                split( const int );
109   bool                move( QWidget* wid, QWidget* wid_to, const bool before );
110
111   QWidget*            addWindow( QWidget*, Qt::WindowFlags = 0 );
112
113   QByteArray          saveState( int ) const;
114   bool                restoreState( const QByteArray&, int );
115   
116   void                setOpaqueResize( bool = true );
117   bool                opaqueResize() const;
118
119   void Split( QWidget* wid, const Qt::Orientation o, const SplitType type );
120   void Attract( QWidget* wid1, QWidget* wid2, const bool all );
121   void SetRelativePosition( QWidget* wid, const Qt::Orientation o, const double pos );
122   void SetRelativePositionInSplitter( QWidget* wid, const double pos );
123
124 signals:
125   void                windowActivated( QWidget* );
126
127 public slots:
128   void                splitVertical();
129   void                splitHorizontal();
130
131 private slots:
132   void                onRename();
133   void                onCloseWindow();
134   void                onDestroyed( QObject* );
135   void                onWindowActivated( QWidget* );
136   void                onContextMenuRequested( QWidget*, QPoint );
137   void                onDeactivated( QtxWorkstackArea* );
138
139 protected:
140   virtual void        customEvent( QEvent* );
141
142   QAction*            action( const int ) const;
143
144   void                saveState( QDataStream& ) const;
145   bool                restoreState( QDataStream& );
146
147 private:
148   QSplitter*          splitter( QtxWorkstackArea* ) const;
149   void                splitters( QSplitter*, QList<QSplitter*>&, const bool = false ) const;
150   void                areas( QSplitter*, QList<QtxWorkstackArea*>&, const bool = false ) const;
151
152   QSplitter*          wrapSplitter( QtxWorkstackArea* );
153   void                insertWidget( QWidget*, QWidget*, QWidget* );
154
155   QtxWorkstackArea*   areaAt( const QPoint& ) const;
156   QtxWorkstackArea*   wgArea( QWidget* ) const;
157
158   QtxWorkstackArea*   targetArea();
159   QtxWorkstackArea*   activeArea() const;
160   QtxWorkstackArea*   currentArea() const;
161
162   void                setActiveArea( QtxWorkstackArea* );
163   QtxWorkstackArea*   neighbourArea( QtxWorkstackArea* ) const;
164
165   QtxWorkstackArea*   createArea( QWidget* ) const;
166
167   void                updateState();
168   void                updateState( QSplitter* );
169
170   void                distributeSpace( QSplitter* ) const;
171
172   int                 setPosition( QWidget* wid, QSplitter* split, const Qt::Orientation o,
173                                                            const int need_pos, const int splitter_pos );
174
175 private:
176   QPointer<QWidget>          myWin;        //!< active widget
177   QPointer<QtxWorkstackArea> myArea;       //!< active workarea
178   QtxWorkstackSplitter*      mySplit;      //!< tol-level splitter
179   QPointer<QWidget>          myWorkWin;    //!< widget where popup menu is invoked (used internally)
180   QPointer<QtxWorkstackArea> myWorkArea;   //!< workarea where popup menu is invoked (used internally)
181
182   QMap<int, QAction*> myActionsMap; //!< actions map
183
184   friend class QtxWorkstackArea;
185   friend class QtxWorkstackDrag;
186   friend class QtxWorkstackAction;
187   friend class QtxWorkstackSplitter;
188 };
189
190 class QtxWorkstackSplitter : public QSplitter
191 {
192   Q_OBJECT
193
194 public:
195   QtxWorkstackSplitter( QWidget* = 0 );
196   virtual ~QtxWorkstackSplitter();
197
198   QtxWorkstack*       workstack() const;
199
200   void                saveState( QDataStream& ) const;
201   bool                restoreState( QDataStream&, QMap<QString, QtxWorkstackChild*>& );
202 };
203
204 class QTX_EXPORT QtxWorkstackArea : public QFrame
205 {
206   Q_OBJECT
207
208   class WidgetEvent;
209   class RestoreEvent;
210
211 public:
212   QtxWorkstackArea( QWidget* );
213   virtual ~QtxWorkstackArea();
214
215   bool                isNull() const;
216   bool                isEmpty() const;
217
218   QtxWorkstackChild*  insertWidget( QWidget*, const int = -1, Qt::WindowFlags = 0 );
219   void                removeWidget( QWidget*, const bool = true );
220
221   void                insertChild( QtxWorkstackChild*, const int = -1 );
222   void                removeChild( QtxWorkstackChild*, const bool = true );
223
224   QWidget*            activeWidget() const;
225   void                setActiveWidget( QWidget* );
226
227   bool                contains( QWidget* ) const;
228
229   QWidgetList         widgetList() const;
230   QList<QtxWorkstackChild*> childList() const;
231
232   bool                isActive() const;
233   void                updateActiveState();
234
235   QtxWorkstack*       workstack() const;
236
237   virtual bool        eventFilter( QObject*, QEvent* );
238
239   QRect               floatRect() const;
240   QRect               floatTab( const int ) const;
241
242   int                 tabAt( const QPoint& ) const;
243
244   void                saveState( QDataStream& ) const;
245   bool                restoreState( QDataStream&, QMap<QString, QtxWorkstackChild*>& );
246
247 signals:
248   void                activated( QWidget* );
249   void                contextMenuRequested( QWidget*, QPoint );
250   void                deactivated( QtxWorkstackArea* );
251
252 private slots:
253   void                onClose();
254   void                onCurrentChanged( int );
255
256   void                onChildDestroyed( QObject* );
257   void                onChildShown( QtxWorkstackChild* );
258   void                onChildHidden( QtxWorkstackChild* );
259   void                onChildActivated( QtxWorkstackChild* );
260   void                onChildCaptionChanged( QtxWorkstackChild* );
261
262   void                onDragActiveTab();
263   void                onContextMenuRequested( QPoint );
264
265 protected:
266   virtual void        customEvent( QEvent* );
267   virtual void        focusInEvent( QFocusEvent* );
268   virtual void        mousePressEvent( QMouseEvent* );
269
270 private:
271   //! Custom events
272   enum { ActivateWidget = QEvent::User,   //!< activate widget event
273                FocusWidget,                     //!< focus receiving widget event
274          MakeCurrent,
275          RestoreWidget
276   };
277
278 private:
279   void                updateState();
280   void                updateCurrent();
281   void                updateTab( QWidget* );
282
283   QWidget*            widget( const int ) const;
284   int                 widgetId( QWidget* ) const;
285
286   QtxWorkstackChild*  child( QWidget* ) const;
287   QtxWorkstackChild*  child( const int ) const;
288
289   void                setWidgetActive( QWidget* );
290
291   int                 generateId() const;
292
293 private:
294   typedef QList<QtxWorkstackChild*> ChildList;
295
296 private:
297   QtxWorkstackTabBar* myBar;     //!< workarea tab bar header
298   ChildList           myList;    //!< child widgets list
299   QAbstractButton*    myClose;   //!< close button
300   QStackedWidget*     myStack;   //!< widget stack
301 };
302
303 class QtxWorkstackChild : public QWidget
304 {
305   Q_OBJECT
306
307 public:
308   QtxWorkstackChild( QWidget*, QWidget* = 0, Qt::WindowFlags = 0 );
309   virtual ~QtxWorkstackChild();
310
311   QWidget*            widget() const
312 ;
313
314   int                 id() const;
315   void                setId( const int );
316
317   bool                visibility();
318
319   QtxWorkstackArea*   area() const;
320
321   virtual bool        eventFilter( QObject*, QEvent* );
322
323 signals:
324   void                shown( QtxWorkstackChild* );
325   void                hidden( QtxWorkstackChild* );
326   void                activated( QtxWorkstackChild* );
327   void                captionChanged( QtxWorkstackChild* );
328
329 private slots:
330   void                onDestroyed( QObject* );
331
332 protected:
333   virtual void        childEvent( QChildEvent* );
334
335 private:
336   int                 myId;       //!< id
337   QPointer<QWidget>   myWidget;   //!< child widget
338 };
339
340 class QtxWorkstackTabBar : public QTabBar
341 {
342   Q_OBJECT
343
344 public:
345   QtxWorkstackTabBar( QWidget* = 0 );
346   virtual ~QtxWorkstackTabBar();
347
348   bool                isActive() const;
349   void                setActive( const bool );
350
351   int                 tabId( const int ) const;
352   int                 indexOf( const int ) const;
353   void                setTabId( const int, const int );
354
355   void                updateActiveState();
356
357 signals:
358   void                dragActiveTab();
359   void                contextMenuRequested( QPoint );
360
361 private slots:
362   void                onCurrentChanged( int );
363
364 protected:
365   virtual void        changeEvent( QEvent* );
366   virtual void        mouseMoveEvent( QMouseEvent* );
367   virtual void        mousePressEvent( QMouseEvent* );
368   virtual void        mouseReleaseEvent( QMouseEvent* );
369   virtual void        contextMenuEvent( QContextMenuEvent* );
370
371 private:
372   int                 myId;         //!< current tab page index
373   bool                myActive;     //!< "active" status
374 };
375
376 class QtxWorkstackDrag : public QObject
377 {
378   Q_OBJECT
379
380 public:
381   QtxWorkstackDrag( QtxWorkstack*, QtxWorkstackChild* );
382   virtual ~QtxWorkstackDrag();
383
384   virtual bool        eventFilter( QObject*, QEvent* );
385
386 private:
387   void                dropWidget();
388
389   void                updateTarget( const QPoint& );
390   QtxWorkstackArea*   detectTarget( const QPoint&, int& ) const;
391   void                setTarget( QtxWorkstackArea*, const int );
392
393   void                drawRect();
394   void                endDrawRect();
395   void                startDrawRect();
396
397 private:
398   QtxWorkstack*       myWS;          //!< parent workstack
399   QtxWorkstackChild*  myChild;       //!< workstack child widget container
400
401   int                 myTab;         //!< workarea tab page index
402   QtxWorkstackArea*   myArea;        //!< workarea
403   QRubberBand*        myTabRect;     //!< tab bar rubber band
404   QRubberBand*        myAreaRect;    //!< workarea rubber band
405 };
406
407 #ifdef WIN32
408 #pragma warning( default:4251 )
409 #endif
410
411 #endif   // QTXWORKSTACK_H