itom 2.2.1
K:/git-itom/sources/itom/Qitom/widgets/abstractDockWidget.h
00001 /* ********************************************************************
00002     itom software
00003     URL: http://www.uni-stuttgart.de/ito
00004     Copyright (C) 2016, Institut fuer Technische Optik (ITO),
00005     Universitaet Stuttgart, Germany
00006 
00007     This file is part of itom.
00008   
00009     itom is free software; you can redistribute it and/or modify it
00010     under the terms of the GNU Library General Public Licence as published by
00011     the Free Software Foundation; either version 2 of the Licence, or (at
00012     your option) any later version.
00013 
00014     itom is distributed in the hope that it will be useful, but
00015     WITHOUT ANY WARRANTY; without even the implied warranty of
00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library
00017     General Public Licence for more details.
00018 
00019     You should have received a copy of the GNU Library General Public License
00020     along with itom. If not, see <http://www.gnu.org/licenses/>.
00021 *********************************************************************** */
00022 
00023 #ifndef ABSTRACTDOCKWIDGET_H
00024 #define ABSTRACTDOCKWIDGET_H
00025 
00026 #include "../global.h"
00027 #include "../common/sharedStructures.h"
00028 
00029 #include <qmainwindow.h>
00030 #include <qdockwidget.h>
00031 #include <qmenubar.h>
00032 #include <qevent.h>
00033 #include <qmap.h>
00034 #include <qtoolbar.h>
00035 #include <qdebug.h>
00036 #include <qstring.h>
00037 #include <qaction.h>
00038 #include <qshortcut.h>
00039 #include <qrect.h>
00040 #include <qwidget.h>
00041 
00042 
00043 namespace ito
00044 {
00045     class AbstractDockWidget : public QDockWidget
00046     {
00047         Q_OBJECT
00048         
00049         //these properties are taken from QWidget in order to redirect them either to the QDockWidget or to the main window (depending on dock status)
00050         Q_PROPERTY(bool visible READ isVisible WRITE setVisible DESIGNABLE false)
00051         Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
00052 
00053         Q_PROPERTY(QRect geometry READ geometry WRITE setGeometry)
00054         Q_PROPERTY(QRect frameGeometry READ frameGeometry)
00055         Q_PROPERTY(QRect normalGeometry READ normalGeometry)
00056         Q_PROPERTY(int x READ x)
00057         Q_PROPERTY(int y READ y)
00058         Q_PROPERTY(QPoint pos READ pos WRITE move DESIGNABLE false STORED false)
00059         Q_PROPERTY(QSize frameSize READ frameSize)
00060         Q_PROPERTY(QSize size READ size WRITE resize DESIGNABLE false STORED false)
00061         Q_PROPERTY(int width READ width)
00062         Q_PROPERTY(int height READ height)
00063         Q_PROPERTY(QRect rect READ rect)
00064         Q_PROPERTY(QRect childrenRect READ childrenRect)
00065         Q_PROPERTY(QRegion childrenRegion READ childrenRegion)
00066         Q_PROPERTY(QString windowTitle READ windowTitle WRITE setWindowTitle)
00067 
00068         public:
00069 
00070             enum tFloatingStyle { floatingNone, floatingStandard, floatingWindow }; 
00071             enum tMovingStyle { movingDisabled, movingEnabled };    
00072             enum tTopLevelStyle { topLevelOverall, topLevelParentOnly, topLevelNothing };
00073 
00074             struct Toolbar
00075             {
00076                 Toolbar() : section(0), key(""), tb(NULL) {}
00077                 Qt::ToolBarArea area;
00078                 int section;
00079                 QString key;
00080                 QToolBar *tb;
00081             };
00082 
00083             AbstractDockWidget(bool docked, bool isDockAvailable, tFloatingStyle floatingStyle, tMovingStyle movingStyle, const QString &title = QString(), const QString &objName = QString(), QWidget *parent = 0);
00084             virtual ~AbstractDockWidget();
00085 
00086             inline bool docked() const { return m_docked; }    
00088             RetVal setAdvancedWindowTitle( QString newCompleteTitle = QString(), bool appendToBasicTitle = true );
00089 
00090             RetVal setTopLevel( tTopLevelStyle topLevel );
00091 
00092             void setParent ( QWidget * parent ) { m_overallParent = parent; QDockWidget::setParent(parent); }
00093 
00094             QWidget *getActiveInstance() 
00095             { 
00096                 if(!m_docked && m_floatingStyle == floatingWindow)
00097                 {
00098                     return m_pWindow;
00099                 }
00100                 return this;
00101             }
00102 
00103             //these methods are mainly redirected to QDockWidget or QMainWindow (depending on dock status)
00104             #define QWIDGETPROPGETTER(gettername) if(m_docked && m_dockAvailable) { return QDockWidget::gettername(); } else { return m_pWindow->gettername(); }
00105 
00106             #define QWIDGETPROPSETTER(settername,...) \
00107             if (m_docked) \
00108             { \
00109                 QDockWidget::settername(__VA_ARGS__);  \
00110             } \
00111             else \
00112             { \
00113                 if (m_floatingStyle == floatingWindow) \
00114                 { \
00115                     m_pWindow->settername(__VA_ARGS__); \
00116                     QDockWidget::settername(__VA_ARGS__); \
00117                 } \
00118                 else \
00119                 { \
00120                     QDockWidget::settername(__VA_ARGS__); \
00121                 } \
00122             }
00123 
00124             #define QWIDGETPROPSETTERSPECIAL(settername,...) \
00125             if (m_docked) \
00126             { \
00127                 QDockWidget::settername(__VA_ARGS__);  \
00128             } \
00129             else \
00130             { \
00131                 if (m_floatingStyle == floatingWindow) \
00132                 { \
00133                     m_pWindow->settername(__VA_ARGS__); \
00134                 } \
00135                 else \
00136                 { \
00137                     QDockWidget::settername(__VA_ARGS__); \
00138                 } \
00139             }
00140 
00141             QRect frameGeometry() const;
00142             const QRect &geometry() const;
00143             QRect normalGeometry() const;
00144 
00145             int x() const;
00146             int y() const;
00147             QPoint pos() const;
00148             QSize frameSize() const;
00149             QSize size() const;
00150             int width() const;
00151             int height() const;
00152             QRect rect() const;
00153             QRect childrenRect() const;
00154             QRegion childrenRegion() const;
00155 
00156             void move(int x, int y);
00157             void move(const QPoint &);
00158             void resize(int w, int h);
00159             void resize(const QSize &);
00160             void setGeometry(int x, int y, int w, int h);
00161             void setGeometry(const QRect &);
00162 
00163             QString windowTitle();
00164             void setWindowTitle(const QString &title);
00165 
00166             bool isEnabled() const;
00167             bool isVisible() const;
00168 
00169             void saveState(const QString &iniName) const;
00170             void restoreState(const QString &iniName);
00171 
00172             void synchronizeTopLevelState();
00173 
00174             virtual QSize sizeHint() const;
00175             virtual QSize minimumSizeHint() const;
00176 
00177         public Q_SLOTS:
00178             void setEnabled(bool);
00179             virtual void setVisible(bool visible);
00180    
00181         protected:
00182 
00183             class ShortcutAction : public QObject
00184             {
00185             public:
00186                 ShortcutAction(const QString &text, AbstractDockWidget *parent) : QObject(parent), m_action(NULL), m_shortcut(NULL)
00187                 {
00188                     m_action = new QAction(text, parent);
00189                     QString toolTipText = text;
00190                     toolTipText.replace("&", "");
00191                     m_action->setToolTip(toolTipText);
00192                 }
00193 
00194                 ShortcutAction(const QIcon &icon, const QString &text, AbstractDockWidget *parent) : QObject(parent), m_action(NULL), m_shortcut(NULL)
00195                 {
00196                     m_action = new QAction(icon, text, parent);
00197                     QString toolTipText = text;
00198                     toolTipText.replace("&", "");
00199                     m_action->setToolTip(toolTipText);
00200                 }
00201 
00202                 ShortcutAction(const QIcon &icon, const QString &text, AbstractDockWidget *parent, const QKeySequence &key, Qt::ShortcutContext context = Qt::WindowShortcut) : QObject(parent), m_action(NULL), m_shortcut(NULL)
00203                 {
00204                     QString text2 = text;
00205                     QString text3 = text;
00206                     text3.replace("&", "");
00207 
00208                     //some key sequences do not exist as default on all operating systems
00209                     if (key.isEmpty() == false)
00210                     {
00211                         text2 += "\t" + key.toString(QKeySequence::NativeText);
00212                         text3 += " (" + key.toString(QKeySequence::NativeText) + ")";
00213 
00214                         m_shortcut = new QShortcut(key, parent->getCanvas());
00215                         m_shortcut->setContext(context);
00216                     }
00217 
00218                     m_action = new QAction(icon, text2, parent);
00219                     m_action->setToolTip(text3);
00220                 }
00221 
00222                 ~ShortcutAction()
00223                 {
00224                     //do not delete action and shortcut here, since it will be deleted by common parent.
00225                 }
00226 
00227                 void connectTrigger(const QObject *receiver, const char *method, Qt::ConnectionType type = Qt::AutoConnection)
00228                 {
00229                     if(m_action)
00230                     {
00231                         QObject::connect(m_action, SIGNAL(triggered()), receiver, method, type);
00232                     }
00233                     if(m_shortcut)
00234                     {
00235                         QObject::connect(m_shortcut, SIGNAL(activated()), receiver, method, type);
00236                     }
00237                 }
00238 
00239                 void setEnabled(bool actionEnabled, bool shortcutEnabled)
00240                 {
00241                     if(m_action) 
00242                     {
00243                         m_action->setEnabled(actionEnabled);
00244                         if(m_shortcut) m_shortcut->setEnabled(shortcutEnabled);
00245                     }
00246                 }
00247 
00248                 void setEnabled(bool enabled)
00249                 {
00250                     setEnabled(enabled,enabled);
00251                 }
00252 
00253                 void setVisible(bool actionVisible, bool shortcutEnabled)
00254                 {
00255                     if(m_action) 
00256                     {
00257                         m_action->setVisible(actionVisible);
00258                         if(m_shortcut) m_shortcut->setEnabled(shortcutEnabled);
00259                     }
00260                 }
00261 
00262                 void setVisible(bool visible)
00263                 {
00264                     setVisible(visible,visible);
00265                 }
00266 
00267                 QAction* action() { return m_action; }
00268 
00269             private:
00270                 QAction *m_action;
00271                 QShortcut *m_shortcut;
00272                 
00273             };
00274 
00276 
00281             bool eventFilter(QObject *obj, QEvent *event)
00282             {
00283                 if (event->type() == QEvent::Close)
00284                 {
00285                     closeEvent((QCloseEvent*)event);
00286                     if(testAttribute(Qt::WA_DeleteOnClose) && event->isAccepted() ) //if window should be closed and dockwidget is assigned with WA_DeleteOnClose, delete this dockwidget first.
00287                     {
00288                        deleteLater();
00289                     }
00290                     
00291                     return true;
00292                 }
00293                 else
00294                 {
00295                     return QObject::eventFilter(obj,event);
00296                 }
00297             };
00298 
00299             void init();
00300 
00301             virtual void closeEvent(QCloseEvent *event);
00302 
00303             virtual void createActions() = 0;
00304             virtual void createMenus() = 0;
00305             virtual void createToolBars() = 0;
00306             virtual void createStatusBar() = 0;
00307             virtual void updateActions() {}
00308             virtual void updatePythonActions() = 0;
00309         
00310             Qt::WindowFlags modifyFlags(const Qt::WindowFlags &flags, const Qt::WindowFlags &setFlags, const Qt::WindowFlags &unsetFlags);
00311 
00312             virtual void windowStateChanged( bool /*windowNotToolbox*/ ) {}
00313 
00314             void setContentWidget(QWidget *widget);
00315             inline QWidget* getContentWidget() const { return m_pWindow->centralWidget(); }   
00316             inline QMainWindow* getCanvas() { return m_pWindow; }
00317 
00318             inline bool pythonBusy() const { return m_pythonBusy; }                    
00319             inline bool pythonDebugMode() const { return m_pythonDebugMode; }          
00320             inline bool pythonInWaitingMode() const { return m_pythonInWaitingMode; }  
00322             //RetVal addAndRegisterToolBar(QToolBar* tb, QString key);
00323             //RetVal unregisterToolBar(QString key);
00324             QToolBar* getToolBar(QString key) const;
00325             inline QMenuBar* getMenuBar() const { return (m_pWindow == NULL) ?  NULL : m_pWindow->menuBar(); }
00326 
00327             RetVal addToolBar(QToolBar *tb, const QString &key, Qt::ToolBarArea area = Qt::TopToolBarArea, int section = 1);
00328             RetVal removeToolBar(const QString &key);
00329 
00330             QAction *m_actStayOnTop;
00331             QAction *m_actStayOnTopOfApp;
00332 
00333         private:
00334 
00335             void contextMenuEvent(QContextMenuEvent *e)
00336             {
00337                 e->accept();
00338                 qDebug() << "context menu of abstractDockWidget clicked. [placeholder for (un)docking feature.] pos: " << e->pos();
00339             }
00340 
00341             QMainWindow *m_pWindow;
00342 
00343             bool m_docked;                      
00344             bool m_dockAvailable;               
00345             tFloatingStyle m_floatingStyle;     
00346             tMovingStyle m_movingStyle;         
00347             QString m_basicTitle;               
00348             QString m_completeTitle;            
00350             QMap<QString,QToolBar*> m_toolBars; 
00351             QList<Toolbar> m_toolbars;
00352 
00353             bool m_pythonBusy;                  
00354             bool m_pythonDebugMode;             
00355             bool m_pythonInWaitingMode;         
00357             QToolBar* m_dockToolbar;
00358             QAction* m_actDock;
00359             QAction* m_actUndock;
00360 
00361             QWidget* m_overallParent;           
00362             tTopLevelStyle m_recentTopLevelStyle;
00363 
00364             QSize m_oldMinSize;
00365             QSize m_oldMaxSize;
00366             QRect m_lastUndockedSize;
00367             QByteArray m_pendingGeometryState; //if the window has a loaded geometry state from the settings file, but has been hidden at startup, the geometry is saved here and applied once the window becomes visible. Then, this variable is cleared.
00368 
00369         public slots:
00370             virtual void dockedToMainWindow(AbstractDockWidget * /*widget*/){}
00371             virtual void removedFromMainWindow(AbstractDockWidget * /*widget*/){}
00372             virtual void pythonStateChanged(tPythonTransitions pyTransition);
00373 
00374             void raiseAndActivate();  
00376             void setDockSize(int newWidth, int newHeight);
00377 
00378             void dockWidget();
00379             void undockWidget(bool show_it = true);
00380 
00381         private slots:
00382             void mnuStayOnTop(bool checked);
00383             void mnuStayOnTopOfApp(bool checked);
00384 
00385             void returnToOldMinMaxSizes();
00386     };
00387 
00388 } //end namespace ito
00389 
00390 #endif
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Properties Friends