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