Salome HOME
updated copyright message
[modules/gui.git] / src / Qtx / QtxWorkstack.h
1 // Copyright (C) 2007-2023  CEA, EDF, 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                splittersVisible( QWidget*, bool = true );
120
121   void Split( QWidget* wid, const Qt::Orientation o, const SplitType type );
122   void Attract( QWidget* wid1, QWidget* wid2, const bool all );
123   void SetRelativePosition( QWidget* wid, const Qt::Orientation o, const double pos );
124   void SetRelativePositionInSplitter( QWidget* wid, const double pos );
125
126   void                updateState();
127
128 signals:
129   void                windowActivated( QWidget* );
130
131 public slots:
132   void                splitVertical();
133   void                splitHorizontal();
134
135 private slots:
136   void                onRename();
137   void                onCloseWindow();
138   void                onDestroyed( QObject* );
139   void                onWindowActivated( QWidget* );
140   void                onContextMenuRequested( QWidget*, QPoint );
141   void                onDeactivated( QtxWorkstackArea* );
142
143 protected:
144   virtual void        customEvent( QEvent* );
145
146   QAction*            action( const int ) const;
147
148   void                saveState( QDataStream& ) const;
149   bool                restoreState( QDataStream& );
150
151 private:
152   QSplitter*          splitter( QtxWorkstackArea* ) const;
153   void                splitters( QSplitter*, QList<QSplitter*>&, const bool = false ) const;
154   void                areas( QSplitter*, QList<QtxWorkstackArea*>&, const bool = false ) const;
155
156   QSplitter*          wrapSplitter( QtxWorkstackArea* );
157   void                insertWidget( QWidget*, QWidget*, QWidget* );
158
159   QtxWorkstackArea*   areaAt( const QPoint& ) const;
160   QtxWorkstackArea*   wgArea( QWidget* ) const;
161
162   QtxWorkstackArea*   targetArea();
163   QtxWorkstackArea*   activeArea() const;
164   QtxWorkstackArea*   currentArea() const;
165
166   void                setActiveArea( QtxWorkstackArea* );
167   QtxWorkstackArea*   neighbourArea( QtxWorkstackArea* ) const;
168
169   QtxWorkstackArea*   createArea( QWidget* ) const;
170
171   void                updateState( QSplitter* );
172
173   void                splitterVisible(QWidget*, QList<QSplitter*>&, QSplitter*, bool );
174
175   void                distributeSpace( QSplitter* ) const;
176
177   int                 setPosition( QWidget* wid, QSplitter* split, const Qt::Orientation o,
178                                                            const int need_pos, const int splitter_pos );
179
180 private:
181   QPointer<QWidget>          myWin;        //!< active widget
182   QPointer<QtxWorkstackArea> myArea;       //!< active workarea
183   QtxWorkstackSplitter*      mySplit;      //!< tol-level splitter
184   QPointer<QWidget>          myWorkWin;    //!< widget where popup menu is invoked (used internally)
185   QPointer<QtxWorkstackArea> myWorkArea;   //!< workarea where popup menu is invoked (used internally)
186
187   QMap<int, QAction*> myActionsMap; //!< actions map
188
189   friend class QtxWorkstackArea;
190   friend class QtxWorkstackDrag;
191   friend class QtxWorkstackAction;
192   friend class QtxWorkstackSplitter;
193 };
194
195 class QtxWorkstackSplitter : public QSplitter
196 {
197   Q_OBJECT
198
199 public:
200   QtxWorkstackSplitter( QWidget* = 0 );
201   virtual ~QtxWorkstackSplitter();
202
203   QtxWorkstack*       workstack() const;
204
205   void                saveState( QDataStream& ) const;
206   bool                restoreState( QDataStream&, QMap<QString, QtxWorkstackChild*>& );
207 };
208
209 class QTX_EXPORT QtxWorkstackArea : public QFrame
210 {
211   Q_OBJECT
212
213   class WidgetEvent;
214   class RestoreEvent;
215
216 public:
217   QtxWorkstackArea( QWidget* );
218   virtual ~QtxWorkstackArea();
219
220   bool                isNull() const;
221   bool                isEmpty() const;
222
223   QtxWorkstackChild*  insertWidget( QWidget*, const int = -1, Qt::WindowFlags = 0 );
224   void                removeWidget( QWidget*, const bool = true );
225
226   void                insertChild( QtxWorkstackChild*, const int = -1 );
227   void                removeChild( QtxWorkstackChild*, const bool = true );
228
229   QWidget*            activeWidget() const;
230   void                setActiveWidget( QWidget* );
231
232   bool                contains( QWidget* ) const;
233
234   QWidgetList         widgetList() const;
235   QList<QtxWorkstackChild*> childList() const;
236
237   bool                isActive() const;
238   void                updateActiveState();
239
240   QtxWorkstack*       workstack() const;
241
242   virtual bool        eventFilter( QObject*, QEvent* );
243
244   QRect               floatRect() const;
245   QRect               floatTab( const int ) const;
246
247   int                 tabAt( const QPoint& ) const;
248
249   void                saveState( QDataStream& ) const;
250   bool                restoreState( QDataStream&, QMap<QString, QtxWorkstackChild*>& );
251
252   void                showTabBar( bool = true);
253
254 signals:
255   void                activated( QWidget* );
256   void                contextMenuRequested( QWidget*, QPoint );
257   void                deactivated( QtxWorkstackArea* );
258
259 private slots:
260   void                onClose();
261   void                onCurrentChanged( int );
262
263   void                onChildDestroyed( QObject* );
264   void                onChildShown( QtxWorkstackChild* );
265   void                onChildHidden( QtxWorkstackChild* );
266   void                onChildActivated( QtxWorkstackChild* );
267   void                onChildCaptionChanged( QtxWorkstackChild* );
268
269   void                onDragActiveTab();
270   void                onContextMenuRequested( QPoint );
271
272 protected:
273   virtual void        customEvent( QEvent* );
274   virtual void        focusInEvent( QFocusEvent* );
275   virtual void        mousePressEvent( QMouseEvent* );
276
277 private:
278   //! Custom events
279   enum { ActivateWidget = QEvent::User,   //!< activate widget event
280                FocusWidget,                     //!< focus receiving widget event
281          MakeCurrent,
282          RestoreWidget
283   };
284
285 private:
286   void                updateState();
287   void                updateCurrent();
288   void                updateTab( QWidget* );
289
290   QWidget*            widget( const int ) const;
291   int                 widgetId( QWidget* ) const;
292
293   QtxWorkstackChild*  child( QWidget* ) const;
294   QtxWorkstackChild*  child( const int ) const;
295
296   void                setWidgetActive( QWidget* );
297
298   int                 generateId() const;
299
300 private:
301   typedef QList<QtxWorkstackChild*> ChildList;
302
303 private:
304   QWidget*            myTop;     //!< workarea top widget
305   QtxWorkstackTabBar* myBar;     //!< workarea tab bar header
306   ChildList           myList;    //!< child widgets list
307   QAbstractButton*    myClose;   //!< close button
308   QStackedWidget*     myStack;   //!< widget stack
309 };
310
311 class QtxWorkstackChild : public QWidget
312 {
313   Q_OBJECT
314
315 public:
316   QtxWorkstackChild( QWidget*, QWidget* = 0, Qt::WindowFlags = 0 );
317   virtual ~QtxWorkstackChild();
318
319   QWidget*            widget() const
320 ;
321
322   int                 id() const;
323   void                setId( const int );
324
325   bool                visibility();
326
327   QtxWorkstackArea*   area() const;
328
329   virtual bool        eventFilter( QObject*, QEvent* );
330
331 signals:
332   void                shown( QtxWorkstackChild* );
333   void                hidden( QtxWorkstackChild* );
334   void                activated( QtxWorkstackChild* );
335   void                captionChanged( QtxWorkstackChild* );
336
337 private slots:
338   void                onDestroyed( QObject* );
339
340 protected:
341   virtual void        childEvent( QChildEvent* );
342
343 private:
344   int                 myId;       //!< id
345   QPointer<QWidget>   myWidget;   //!< child widget
346 };
347
348 class QtxWorkstackTabBar : public QTabBar
349 {
350   Q_OBJECT
351
352 public:
353   QtxWorkstackTabBar( QWidget* = 0 );
354   virtual ~QtxWorkstackTabBar();
355
356   bool                isActive() const;
357   void                setActive( const bool );
358
359   int                 tabId( const int ) const;
360   int                 indexOf( const int ) const;
361   void                setTabId( const int, const int );
362
363   void                updateActiveState();
364
365 signals:
366   void                dragActiveTab();
367   void                contextMenuRequested( QPoint );
368
369 private slots:
370   void                onCurrentChanged( int );
371
372 protected:
373   virtual void        changeEvent( QEvent* );
374   virtual void        mouseMoveEvent( QMouseEvent* );
375   virtual void        mousePressEvent( QMouseEvent* );
376   virtual void        mouseReleaseEvent( QMouseEvent* );
377   virtual void        contextMenuEvent( QContextMenuEvent* );
378
379 private:
380   int                 myId;         //!< current tab page index
381   bool                myActive;     //!< "active" status
382 };
383
384 class QtxWorkstackDrag : public QObject
385 {
386   Q_OBJECT
387
388 public:
389   QtxWorkstackDrag( QtxWorkstack*, QtxWorkstackChild* );
390   virtual ~QtxWorkstackDrag();
391
392   virtual bool        eventFilter( QObject*, QEvent* );
393
394 private:
395   void                dropWidget();
396
397   void                updateTarget( const QPoint& );
398   QtxWorkstackArea*   detectTarget( const QPoint&, int& ) const;
399   void                setTarget( QtxWorkstackArea*, const int );
400
401   void                drawRect();
402   void                endDrawRect();
403   void                startDrawRect();
404
405 private:
406   QtxWorkstack*       myWS;          //!< parent workstack
407   QtxWorkstackChild*  myChild;       //!< workstack child widget container
408
409   int                 myTab;         //!< workarea tab page index
410   QtxWorkstackArea*   myArea;        //!< workarea
411   QRubberBand*        myTabRect;     //!< tab bar rubber band
412   QRubberBand*        myAreaRect;    //!< workarea rubber band
413 };
414
415 #ifdef WIN32
416 #pragma warning( default:4251 )
417 #endif
418
419 #endif   // QTXWORKSTACK_H