Salome HOME
no message
[modules/gui.git] / src / Qtx / QtxWorkstack.h
1 // File:      QtxWorkstack.h
2 // Author:    Sergey TELKOV
3
4 #ifndef QTXWORKSTACK_H
5 #define QTXWORKSTACK_H
6
7 #include "Qtx.h"
8
9 #include <qhbox.h>
10 #include <qwidget.h>
11 #include <qtabbar.h>
12 #include <qwidgetlist.h>
13
14 class QAction;
15 class QTabBar;
16 class QPainter;
17 class QSplitter;
18 class QPushButton;
19 class QWidgetStack;
20
21 class QtxWorkstackArea;
22 class QtxWorkstackDrag;
23 class QtxWorkstackChild;
24 class QtxWorkstackTabBar;
25
26 #ifdef WIN32
27 #pragma warning( disable:4251 )
28 #endif
29
30 class QTX_EXPORT QtxWorkstack : public QWidget
31 {
32   Q_OBJECT
33
34 public:
35   enum { SplitVertical, SplitHorizontal, Close, Rename };
36     
37   enum SplitType
38   {
39     SPLIT_STAY, //!< given widget stays in its workarea, others are moved into a new one
40     SPLIT_AT,   //!< widgets before a given widget stays in they workarea, others are moved into a new one
41     SPLIT_MOVE  //!< given widget is moved into a new workarea, others stay in an old one
42   };
43
44 public:
45   QtxWorkstack( QWidget* = 0 );
46   virtual ~QtxWorkstack();
47
48   QWidgetList         windowList() const;
49   QWidgetList         splitWindowList() const;
50
51   QWidget*            activeWindow() const;
52
53   int                 accel( const int ) const;
54   void                setAccel( const int, const int );
55
56   void                split( const int );
57
58   // STV: Useless function. wid->setFocus() should be used instead.
59   // void OnTop( QWidget* wid);
60
61   void Split( QWidget* wid, const Qt::Orientation o, const SplitType type );
62   void Attract( QWidget* wid1, QWidget* wid2, const bool all );
63   void SetRelativePosition( QWidget* wid, const Qt::Orientation o, const double pos );
64   void SetRelativePositionInSplitter( QWidget* wid, const double pos );
65
66 signals:
67   void                windowActivated( QWidget* );
68
69 public slots:
70   void                splitVertical();
71   void                splitHorizontal();
72   void                onRenameActive();
73   
74 private slots:
75   void                onRename();
76   void                onCloseWindow();
77   void                onDestroyed( QObject* );
78   void                onWindowActivated( QWidget* );
79   void                onContextMenuRequested( QWidget*, QPoint );
80   void                onDeactivated( QtxWorkstackArea* );
81
82 protected:
83   virtual void        childEvent( QChildEvent* );
84   virtual void        customEvent( QCustomEvent* );
85
86 private:
87   QSplitter*          splitter( QtxWorkstackArea* ) const;
88   void                splitters( QSplitter*, QPtrList<QSplitter>&, const bool = false ) const;
89   void                areas( QSplitter*, QPtrList<QtxWorkstackArea>&, const bool = false ) const;
90
91   QSplitter*          wrapSplitter( QtxWorkstackArea* );
92   void                insertWidget( QWidget*, QWidget*, QWidget* );
93   void                renameWindow( QWidget* );
94
95   QtxWorkstackArea*   areaAt( const QPoint& ) const;
96
97   QtxWorkstackArea*   targetArea();
98   QtxWorkstackArea*   activeArea() const;
99   QtxWorkstackArea*   currentArea() const;
100
101   void                setActiveArea( QtxWorkstackArea* );
102   QtxWorkstackArea*   neighbourArea( QtxWorkstackArea* ) const;
103
104   QtxWorkstackArea*   createArea( QWidget* ) const;
105
106   void                updateState();
107   void                updateState( QSplitter* );
108
109   void                distributeSpace( QSplitter* ) const;
110   int                 setPosition( QWidget* wid, QSplitter* split, const Qt::Orientation o,
111                                                            const int need_pos, const int splitter_pos );
112
113 private:
114   QWidget*            myWin;
115   QtxWorkstackArea*   myArea;
116   QSplitter*          mySplit;
117   QWidget*            myWorkWin;
118
119   QMap<int, QAction*> myActionsMap; //!< The map of the actions. Allows to get the QAction object by the key.
120
121   friend class QtxWorkstackArea;
122   friend class QtxWorkstackDrag;
123 };
124
125 class QtxWorkstackArea : public QWidget
126 {
127   Q_OBJECT
128
129 public:
130   QtxWorkstackArea( QWidget* );
131   virtual ~QtxWorkstackArea();
132
133   bool                isEmpty() const;
134
135   void                insertWidget( QWidget*, const int = -1 );
136   void                removeWidget( QWidget*, const bool = true );
137
138   QWidget*            activeWidget() const;
139   void                setActiveWidget( QWidget* );
140
141   bool                contains( QWidget* ) const;
142
143   QWidgetList         widgetList() const;
144
145   bool                isActive() const;
146   void                updateActiveState();
147
148   QtxWorkstack*       workstack() const;
149
150   virtual bool        eventFilter( QObject*, QEvent* );
151
152   QRect               floatRect() const;
153   QRect               floatTab( const int ) const;
154
155   int                 tabAt( const QPoint& ) const;
156
157 signals:
158   void                activated( QWidget* );
159   void                contextMenuRequested( QWidget*, QPoint );
160   void                deactivated( QtxWorkstackArea* );
161
162 public slots:
163   virtual void        show();
164   virtual void        hide();
165
166 private slots:
167   void                onClose();
168   void                onSelected( int );
169
170   void                onWidgetDestroyed();
171
172   void                onChildDestroyed( QObject* );
173   void                onChildShown( QtxWorkstackChild* );
174   void                onChildHided( QtxWorkstackChild* );
175   void                onChildActivated( QtxWorkstackChild* );
176   void                onChildCaptionChanged( QtxWorkstackChild* );
177
178   void                onDragActiveTab();
179   void                onContextMenuRequested( QPoint );
180
181 protected:
182   virtual void        customEvent( QCustomEvent* );
183   virtual void        focusInEvent( QFocusEvent* );
184   virtual void        mousePressEvent( QMouseEvent* );
185
186 private:
187   enum { ActivateWidget = QEvent::User, FocusWidget, RemoveWidget };
188
189 private:
190   void                updateState();
191   void                updateCurrent();
192   void                updateTab( QWidget* );
193
194   QWidget*            widget( const int ) const;
195   int                 widgetId( QWidget* ) const;
196   bool                widgetVisibility( QWidget* ) const;
197
198   void                setWidgetActive( QWidget* );
199   void                setWidgetShown( QWidget*, const bool );
200
201   int                 generateId() const;
202
203   bool                isBlocked( QWidget* ) const;
204   void                setBlocked( QWidget*, const bool );
205
206   QtxWorkstackChild*  child( QWidget* ) const;
207
208 private:
209   struct WidgetInfo
210   {
211     WidgetInfo() : id( 0 ), vis( false ) {}
212     int id; bool vis;
213   };
214
215   typedef QMap<QWidget*, bool>               BlockMap;
216   typedef QMap<QWidget*, QtxWorkstackChild*> ChildMap;
217   typedef QMap<QWidget*, WidgetInfo>         WidgetInfoMap;
218
219 private:
220   QtxWorkstackTabBar* myBar;
221   QPushButton*        myClose;
222   QWidgetStack*       myStack;
223
224   QWidgetList         myList;
225   WidgetInfoMap       myInfo;
226   ChildMap            myChild;
227   BlockMap            myBlock;
228 };
229
230 class QtxWorkstackChild : public QHBox
231 {
232   Q_OBJECT
233
234 public:
235   QtxWorkstackChild( QWidget*, QWidget* = 0 );
236   virtual ~QtxWorkstackChild();
237
238   QWidget*            widget() const;
239
240   virtual bool        eventFilter( QObject*, QEvent* );
241
242 signals:
243   void                shown( QtxWorkstackChild* );
244   void                hided( QtxWorkstackChild* );
245   void                activated( QtxWorkstackChild* );
246   void                captionChanged( QtxWorkstackChild* );
247
248 private slots:
249   void                onDestroyed( QObject* );
250
251 protected:
252   virtual void        childEvent( QChildEvent* );
253
254 private:
255   QWidget*            myWidget;
256 };
257
258 class QtxWorkstackTabBar : public QTabBar
259 {
260   Q_OBJECT
261
262 public:
263   QtxWorkstackTabBar( QWidget* = 0 );
264   virtual ~QtxWorkstackTabBar();
265
266   QRect               tabRect( const int ) const;
267
268   void                setActive( const bool );
269
270 signals:
271   void                dragActiveTab();
272   void                contextMenuRequested( QPoint );
273
274 protected:
275   virtual void        mouseMoveEvent( QMouseEvent* );
276   virtual void        mousePressEvent( QMouseEvent* );
277   virtual void        mouseReleaseEvent( QMouseEvent* );
278   virtual void        contextMenuEvent( QContextMenuEvent* );
279
280   virtual void        paintLabel( QPainter*, const QRect&, QTab*, bool ) const;
281
282 private:
283   int                 myId;
284 };
285
286 class QtxWorkstackDrag : public QObject
287 {
288   Q_OBJECT
289
290 public:
291   QtxWorkstackDrag( QtxWorkstack*, QtxWorkstackChild* );
292   virtual ~QtxWorkstackDrag();
293
294   virtual bool        eventFilter( QObject*, QEvent* );
295
296 private:
297   void                dropWidget();
298
299   void                updateTarget( const QPoint& );
300   QtxWorkstackArea*   detectTarget( const QPoint&, int& ) const;
301   void                setTarget( QtxWorkstackArea*, const int );
302
303   void                drawRect();
304   void                endDrawRect();
305   void                startDrawRect();
306
307 private:
308   QtxWorkstack*       myWS;
309   QtxWorkstackChild*  myChild;
310
311   int                 myTab;
312   QtxWorkstackArea*   myArea;
313   QPainter*           myPainter;
314   
315 };
316
317 #ifdef WIN32
318 #pragma warning( default:4251 )
319 #endif
320
321 #endif