itom 2.2.1
|
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