Salome HOME
updated copyright message
[modules/gui.git] / src / Qtx / QtxWorkstack.h
index ac71afdc2401ea5fe000328fcd6d65697f7cc6ad..03278e3b34cac6e05c5e53b2ccb577e3ccaf3cef 100644 (file)
@@ -1,27 +1,53 @@
+// Copyright (C) 2007-2023  CEA, EDF, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
 // File:      QtxWorkstack.h
 // Author:    Sergey TELKOV
-
+//
 #ifndef QTXWORKSTACK_H
 #define QTXWORKSTACK_H
 
 #include "Qtx.h"
 
-#include <qhbox.h>
-#include <qwidget.h>
-#include <qtabbar.h>
-#include <qwidgetlist.h>
+#include <QMap>
+#include <QFrame>
+#include <QEvent>
+#include <QWidget>
+#include <QTabBar>
+#include <QPointer>
+#include <QSplitter>
+#include <QByteArray>
 
 class QAction;
-class QTabBar;
-class QPainter;
-class QSplitter;
-class QPushButton;
-class QWidgetStack;
+class QDataStream;
+class QRubberBand;
+class QStackedWidget;
+class QAbstractButton;
 
 class QtxWorkstackArea;
 class QtxWorkstackDrag;
 class QtxWorkstackChild;
 class QtxWorkstackTabBar;
+class QtxWorkstackSplitter;
 
 #ifdef WIN32
 #pragma warning( disable:4251 )
@@ -32,63 +58,106 @@ class QTX_EXPORT QtxWorkstack : public QWidget
   Q_OBJECT
 
 public:
-  enum { SplitVertical, SplitHorizontal, Close };
-    
-  enum SplitType {
-    SPLIT_STAY, //!< given widget stays in its workarea, others are moved into a new one
-    SPLIT_AT,   //!< widgets before a given widget stays in they workarea, others are moved into a new one
-    SPLIT_MOVE  //!< given widget is moved into a new workarea, others stay in an old one
+  //! Workstack actions (context menu items)
+  enum { SplitVertical    = 0x01,  //!< "Split vertically" menu item
+         SplitHorizontal  = 0x02,  //!< "Split horizontally" menu item
+         Close            = 0x04,  //!< "Close" menu item
+         Rename           = 0x08,  //!< "Rename" menu item
+         All = SplitVertical | SplitHorizontal |
+               Close | Rename      //!< all menu items
+  };
+
+  enum { VersionMarker = 0x01,
+               SplitMarker   = 0x02,
+               AreaMarker    = 0x04,
+               WidgetMarker  = 0x08
+  };
+
+  enum { Horizontal = 0x01,
+               Visible    = 0x02
+  };
+
+  //! Workstack splitting type
+  enum SplitType
+  {
+    SplitStay,  //!< selected widget stays in current workarea, others widgets are moved into a new workarea
+    SplitAt,    //!< all widgets before selected widget stay in current workarea, other widgess are moved into a new workarea
+    SplitMove   //!< selected widget is moved into a new workarea, all other widgets stay in an old workarea
   };
 
 public:
   QtxWorkstack( QWidget* = 0 );
   virtual ~QtxWorkstack();
 
-  QWidgetList         windowList() const;
+  QWidgetList         windowList( QWidget* = 0 ) const;
   QWidgetList         splitWindowList() const;
 
   QWidget*            activeWindow() const;
+  void                setActiveWindow( QWidget* );
 
   int                 accel( const int ) const;
   void                setAccel( const int, const int );
 
+  QIcon               icon( const int ) const;
+  void                setIcon( const int, const QIcon& );
+
+  void                setMenuActions( const int );
+  int                 menuActions() const;
+
+  void                stack();
   void                split( const int );
+  bool                move( QWidget* wid, QWidget* wid_to, const bool before );
+
+  QWidget*            addWindow( QWidget*, Qt::WindowFlags = 0 );
+
+  QByteArray          saveState( int ) const;
+  bool                restoreState( const QByteArray&, int );
+  
+  void                setOpaqueResize( bool = true );
+  bool                opaqueResize() const;
 
-  // STV: Useless function. wid->setFocus() should be used instead.
-  // void OnTop( QWidget* wid);
+  void                splittersVisible( QWidget*, bool = true );
 
   void Split( QWidget* wid, const Qt::Orientation o, const SplitType type );
   void Attract( QWidget* wid1, QWidget* wid2, const bool all );
   void SetRelativePosition( QWidget* wid, const Qt::Orientation o, const double pos );
   void SetRelativePositionInSplitter( QWidget* wid, const double pos );
 
+  void                updateState();
+
 signals:
   void                windowActivated( QWidget* );
 
 public slots:
   void                splitVertical();
   void                splitHorizontal();
-  
+
 private slots:
+  void                onRename();
   void                onCloseWindow();
   void                onDestroyed( QObject* );
   void                onWindowActivated( QWidget* );
-  void                onContextMenuRequested( QPoint );
+  void                onContextMenuRequested( QWidget*, QPoint );
   void                onDeactivated( QtxWorkstackArea* );
 
 protected:
-  virtual void        childEvent( QChildEvent* );
-  virtual void        customEvent( QCustomEvent* );
+  virtual void        customEvent( QEvent* );
+
+  QAction*            action( const int ) const;
+
+  void                saveState( QDataStream& ) const;
+  bool                restoreState( QDataStream& );
 
 private:
   QSplitter*          splitter( QtxWorkstackArea* ) const;
-  void                splitters( QSplitter*, QPtrList<QSplitter>&, const bool = false ) const;
-  void                areas( QSplitter*, QPtrList<QtxWorkstackArea>&, const bool = false ) const;
+  void                splitters( QSplitter*, QList<QSplitter*>&, const bool = false ) const;
+  void                areas( QSplitter*, QList<QtxWorkstackArea*>&, const bool = false ) const;
 
   QSplitter*          wrapSplitter( QtxWorkstackArea* );
   void                insertWidget( QWidget*, QWidget*, QWidget* );
 
   QtxWorkstackArea*   areaAt( const QPoint& ) const;
+  QtxWorkstackArea*   wgArea( QWidget* ) const;
 
   QtxWorkstackArea*   targetArea();
   QtxWorkstackArea*   activeArea() const;
@@ -99,36 +168,63 @@ private:
 
   QtxWorkstackArea*   createArea( QWidget* ) const;
 
-  void                updateState();
   void                updateState( QSplitter* );
 
+  void                splitterVisible(QWidget*, QList<QSplitter*>&, QSplitter*, bool );
+
   void                distributeSpace( QSplitter* ) const;
+
   int                 setPosition( QWidget* wid, QSplitter* split, const Qt::Orientation o,
-                                                          const int need_pos, const int splitter_pos );
+                                                           const int need_pos, const int splitter_pos );
 
 private:
-  QWidget*            myWin;
-  QtxWorkstackArea*   myArea;
-  QSplitter*          mySplit;
+  QPointer<QWidget>          myWin;        //!< active widget
+  QPointer<QtxWorkstackArea> myArea;       //!< active workarea
+  QtxWorkstackSplitter*      mySplit;      //!< tol-level splitter
+  QPointer<QWidget>          myWorkWin;    //!< widget where popup menu is invoked (used internally)
+  QPointer<QtxWorkstackArea> myWorkArea;   //!< workarea where popup menu is invoked (used internally)
 
-  QMap<int, QAction*> myActionsMap; //!< The map of the actions. Allows to get the QAction object by the key.
+  QMap<int, QAction*> myActionsMap; //!< actions map
 
   friend class QtxWorkstackArea;
   friend class QtxWorkstackDrag;
+  friend class QtxWorkstackAction;
+  friend class QtxWorkstackSplitter;
 };
 
-class QtxWorkstackArea : public QWidget
+class QtxWorkstackSplitter : public QSplitter
 {
   Q_OBJECT
 
+public:
+  QtxWorkstackSplitter( QWidget* = 0 );
+  virtual ~QtxWorkstackSplitter();
+
+  QtxWorkstack*       workstack() const;
+
+  void                saveState( QDataStream& ) const;
+  bool                restoreState( QDataStream&, QMap<QString, QtxWorkstackChild*>& );
+};
+
+class QTX_EXPORT QtxWorkstackArea : public QFrame
+{
+  Q_OBJECT
+
+  class WidgetEvent;
+  class RestoreEvent;
+
 public:
   QtxWorkstackArea( QWidget* );
   virtual ~QtxWorkstackArea();
 
+  bool                isNull() const;
   bool                isEmpty() const;
 
-  void                insertWidget( QWidget*, const int = -1 );
-  void                removeWidget( QWidget* );
+  QtxWorkstackChild*  insertWidget( QWidget*, const int = -1, Qt::WindowFlags = 0 );
+  void                removeWidget( QWidget*, const bool = true );
+
+  void                insertChild( QtxWorkstackChild*, const int = -1 );
+  void                removeChild( QtxWorkstackChild*, const bool = true );
 
   QWidget*            activeWidget() const;
   void                setActiveWidget( QWidget* );
@@ -136,6 +232,7 @@ public:
   bool                contains( QWidget* ) const;
 
   QWidgetList         widgetList() const;
+  QList<QtxWorkstackChild*> childList() const;
 
   bool                isActive() const;
   void                updateActiveState();
@@ -149,33 +246,41 @@ public:
 
   int                 tabAt( const QPoint& ) const;
 
+  void                saveState( QDataStream& ) const;
+  bool                restoreState( QDataStream&, QMap<QString, QtxWorkstackChild*>& );
+
+  void                showTabBar( bool = true);
+
 signals:
   void                activated( QWidget* );
-  void                contextMenuRequested( QPoint );
+  void                contextMenuRequested( QWidget*, QPoint );
   void                deactivated( QtxWorkstackArea* );
 
-public slots:
-  virtual void        show();
-  virtual void        hide();
-
 private slots:
   void                onClose();
-  void                onSelected( int );
+  void                onCurrentChanged( int );
 
-  void                onDragActiveTab();
   void                onChildDestroyed( QObject* );
   void                onChildShown( QtxWorkstackChild* );
-  void                onChildHided( QtxWorkstackChild* );
+  void                onChildHidden( QtxWorkstackChild* );
   void                onChildActivated( QtxWorkstackChild* );
   void                onChildCaptionChanged( QtxWorkstackChild* );
 
+  void                onDragActiveTab();
+  void                onContextMenuRequested( QPoint );
+
 protected:
-  virtual void        customEvent( QCustomEvent* );
+  virtual void        customEvent( QEvent* );
   virtual void        focusInEvent( QFocusEvent* );
   virtual void        mousePressEvent( QMouseEvent* );
 
 private:
-  enum { ActivateWidget = QEvent::User, FocusWidget, RemoveWidget };
+  //! Custom events
+  enum { ActivateWidget = QEvent::User,   //!< activate widget event
+               FocusWidget,                     //!< focus receiving widget event
+         MakeCurrent,
+         RestoreWidget
+  };
 
 private:
   void                updateState();
@@ -184,50 +289,48 @@ private:
 
   QWidget*            widget( const int ) const;
   int                 widgetId( QWidget* ) const;
-  bool                widgetVisibility( QWidget* ) const;
+
+  QtxWorkstackChild*  child( QWidget* ) const;
+  QtxWorkstackChild*  child( const int ) const;
 
   void                setWidgetActive( QWidget* );
-  void                setWidgetShown( QWidget*, const bool );
 
   int                 generateId() const;
 
-  bool                isBlocked( QWidget* ) const;
-  void                setBlocked( QWidget*, const bool );
-
-  QtxWorkstackChild*  child( QWidget* ) const;
-
 private:
-  typedef QMap<QWidget*, bool>               BlockMap;
-  typedef QMap<QWidget*, QtxWorkstackChild*> ChildMap;
-  typedef struct { int id; bool vis; }       WidgetInfo;
-  typedef QMap<QWidget*, WidgetInfo>         WidgetInfoMap;
+  typedef QList<QtxWorkstackChild*> ChildList;
 
 private:
-  QtxWorkstackTabBar* myBar;
-  QPushButton*        myClose;
-  QWidgetStack*       myStack;
-
-  QWidgetList         myList;
-  WidgetInfoMap       myInfo;
-  ChildMap            myChild;
-  BlockMap            myBlock;
+  QWidget*            myTop;     //!< workarea top widget
+  QtxWorkstackTabBar* myBar;     //!< workarea tab bar header
+  ChildList           myList;    //!< child widgets list
+  QAbstractButton*    myClose;   //!< close button
+  QStackedWidget*     myStack;   //!< widget stack
 };
 
-class QtxWorkstackChild : public QHBox
+class QtxWorkstackChild : public QWidget
 {
   Q_OBJECT
 
 public:
-  QtxWorkstackChild( QWidget*, QWidget* = 0 );
+  QtxWorkstackChild( QWidget*, QWidget* = 0, Qt::WindowFlags = 0 );
   virtual ~QtxWorkstackChild();
 
-  QWidget*            widget() const;
+  QWidget*            widget() const
+;
+
+  int                 id() const;
+  void                setId( const int );
+
+  bool                visibility();
+
+  QtxWorkstackArea*   area() const;
 
   virtual bool        eventFilter( QObject*, QEvent* );
 
 signals:
   void                shown( QtxWorkstackChild* );
-  void                hided( QtxWorkstackChild* );
+  void                hidden( QtxWorkstackChild* );
   void                activated( QtxWorkstackChild* );
   void                captionChanged( QtxWorkstackChild* );
 
@@ -238,7 +341,8 @@ protected:
   virtual void        childEvent( QChildEvent* );
 
 private:
-  QWidget*            myWidget;
+  int                 myId;       //!< id
+  QPointer<QWidget>   myWidget;   //!< child widget
 };
 
 class QtxWorkstackTabBar : public QTabBar
@@ -249,24 +353,32 @@ public:
   QtxWorkstackTabBar( QWidget* = 0 );
   virtual ~QtxWorkstackTabBar();
 
-  QRect               tabRect( const int ) const;
-
+  bool                isActive() const;
   void                setActive( const bool );
 
+  int                 tabId( const int ) const;
+  int                 indexOf( const int ) const;
+  void                setTabId( const int, const int );
+
+  void                updateActiveState();
+
 signals:
   void                dragActiveTab();
   void                contextMenuRequested( QPoint );
 
+private slots:
+  void                onCurrentChanged( int );
+
 protected:
+  virtual void        changeEvent( QEvent* );
   virtual void        mouseMoveEvent( QMouseEvent* );
   virtual void        mousePressEvent( QMouseEvent* );
   virtual void        mouseReleaseEvent( QMouseEvent* );
   virtual void        contextMenuEvent( QContextMenuEvent* );
 
-  virtual void        paintLabel( QPainter*, const QRect&, QTab*, bool ) const;
-
 private:
-  int                 myId;
+  int                 myId;         //!< current tab page index
+  bool                myActive;     //!< "active" status
 };
 
 class QtxWorkstackDrag : public QObject
@@ -291,17 +403,17 @@ private:
   void                startDrawRect();
 
 private:
-  QtxWorkstack*       myWS;
-  QtxWorkstackChild*  myChild;
+  QtxWorkstack*       myWS;          //!< parent workstack
+  QtxWorkstackChild*  myChild;       //!< workstack child widget container
 
-  int                 myTab;
-  QtxWorkstackArea*   myArea;
-  QPainter*           myPainter;
-  
+  int                 myTab;         //!< workarea tab page index
+  QtxWorkstackArea*   myArea;        //!< workarea
+  QRubberBand*        myTabRect;     //!< tab bar rubber band
+  QRubberBand*        myAreaRect;    //!< workarea rubber band
 };
 
 #ifdef WIN32
 #pragma warning( default:4251 )
 #endif
 
-#endif
+#endif   // QTXWORKSTACK_H