1 /**************************************************************************** 2 ** 3 ** Copyright (C) 2016 The Qt Company Ltd. 4 ** Contact: https://www.qt.io/licensing/ 5 ** 6 ** This file is part of the QtWidgets module of the Qt Toolkit. 7 ** 8 ** $QT_BEGIN_LICENSE:LGPL$ 9 ** Commercial License Usage 10 ** Licensees holding valid commercial Qt licenses may use this file in 11 ** accordance with the commercial license agreement provided with the 12 ** Software or, alternatively, in accordance with the terms contained in 13 ** a written agreement between you and The Qt Company. For licensing terms 14 ** and conditions see https://www.qt.io/terms-conditions. For further 15 ** information use the contact form at https://www.qt.io/contact-us. 16 ** 17 ** GNU Lesser General Public License Usage 18 ** Alternatively, this file may be used under the terms of the GNU Lesser 19 ** General Public License version 3 as published by the Free Software 20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the 21 ** packaging of this file. Please review the following information to 22 ** ensure the GNU Lesser General Public License version 3 requirements 23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. 24 ** 25 ** GNU General Public License Usage 26 ** Alternatively, this file may be used under the terms of the GNU 27 ** General Public License version 2.0 or (at your option) the GNU General 28 ** Public license version 3 or any later version approved by the KDE Free 29 ** Qt Foundation. The licenses are as published by the Free Software 30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 31 ** included in the packaging of this file. Please review the following 32 ** information to ensure the GNU General Public License requirements will 33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and 34 ** https://www.gnu.org/licenses/gpl-3.0.html. 35 ** 36 ** $QT_END_LICENSE$ 37 ** 38 ****************************************************************************/ 39 40 #ifndef QMDISUBWINDOW_P_H 41 #define QMDISUBWINDOW_P_H 42 43 // 44 // W A R N I N G 45 // ------------- 46 // 47 // This file is not part of the Qt API. It exists purely as an 48 // implementation detail. This header file may change from version to 49 // version without notice, or even be removed. 50 // 51 // We mean it. 52 // 53 54 #include <QtWidgets/private/qtwidgetsglobal_p.h> 55 #include "qmdisubwindow.h" 56 57 #include <QStyle> 58 #include <QStyleOptionTitleBar> 59 #if QT_CONFIG(menubar) 60 #include <QMenuBar> 61 #endif 62 #if QT_CONFIG(sizegrip) 63 #include <QSizeGrip> 64 #endif 65 #include <QPointer> 66 #include <QDebug> 67 #include <private/qwidget_p.h> 68 69 QT_REQUIRE_CONFIG(mdiarea); 70 71 QT_BEGIN_NAMESPACE 72 73 class QVBoxLayout; 74 class QMouseEvent; 75 76 namespace QMdi { 77 template<typename T> 78 class ControlElement : public T 79 { 80 public: ControlElement(QMdiSubWindow * child)81 ControlElement(QMdiSubWindow *child) : T(child, nullptr) 82 { 83 Q_ASSERT(child); 84 mdiChild = child; 85 } 86 qt_metacast(const char * classname)87 void *qt_metacast(const char *classname) override 88 { 89 if (classname && strcmp(classname, "ControlElement") == 0) 90 return this; 91 return nullptr; 92 } 93 94 QPointer<QMdiSubWindow> mdiChild; 95 }; 96 97 class ControlContainer : public QObject 98 { 99 public: 100 ControlContainer(QMdiSubWindow *mdiChild); 101 ~ControlContainer(); 102 103 #if QT_CONFIG(menubar) 104 void showButtonsInMenuBar(QMenuBar *menuBar); 105 void removeButtonsFromMenuBar(QMenuBar *menuBar = nullptr); menuBar()106 QMenuBar *menuBar() const { return m_menuBar; } 107 #endif 108 void updateWindowIcon(const QIcon &windowIcon); controllerWidget()109 QWidget *controllerWidget() const { return m_controllerWidget; } systemMenuLabel()110 QWidget *systemMenuLabel() const { return m_menuLabel; } 111 112 private: 113 QPointer<QWidget> previousLeft; 114 QPointer<QWidget> previousRight; 115 #if QT_CONFIG(menubar) 116 QPointer<QMenuBar> m_menuBar; 117 #endif 118 QPointer<QWidget> m_controllerWidget; 119 QPointer<QWidget> m_menuLabel; 120 QPointer<QMdiSubWindow> mdiChild; 121 }; 122 } // namespace QMdi 123 124 class QMdiSubWindowPrivate : public QWidgetPrivate 125 { 126 Q_DECLARE_PUBLIC(QMdiSubWindow) 127 public: 128 // Enums and typedefs. 129 enum Operation { 130 None, 131 Move, 132 TopResize, 133 BottomResize, 134 LeftResize, 135 RightResize, 136 TopLeftResize, 137 TopRightResize, 138 BottomLeftResize, 139 BottomRightResize 140 }; 141 142 enum ChangeFlag { 143 HMove = 0x01, 144 VMove = 0x02, 145 HResize = 0x04, 146 VResize = 0x08, 147 HResizeReverse = 0x10, 148 VResizeReverse = 0x20 149 }; 150 151 enum WindowStateAction { 152 RestoreAction, 153 MoveAction, 154 ResizeAction, 155 MinimizeAction, 156 MaximizeAction, 157 StayOnTopAction, 158 CloseAction, 159 /* Add new states _above_ this line! */ 160 NumWindowStateActions 161 }; 162 163 struct OperationInfo { 164 uint changeFlags; 165 Qt::CursorShape cursorShape; 166 QRegion region; 167 bool hover; 168 OperationInfo(uint changeFlags, Qt::CursorShape cursorShape, bool hover = true) changeFlagsOperationInfo169 : changeFlags(changeFlags), 170 cursorShape(cursorShape), 171 hover(hover) 172 {} 173 }; 174 175 typedef QMap<Operation, OperationInfo> OperationInfoMap; 176 177 QMdiSubWindowPrivate(); 178 179 // Variables. 180 QPointer<QWidget> baseWidget; 181 QPointer<QWidget> restoreFocusWidget; 182 QPointer<QMdi::ControlContainer> controlContainer; 183 #if QT_CONFIG(sizegrip) 184 QPointer<QSizeGrip> sizeGrip; 185 #endif 186 #if QT_CONFIG(rubberband) 187 QRubberBand *rubberBand; 188 #endif 189 QPoint mousePressPosition; 190 QRect oldGeometry; 191 QSize internalMinimumSize; 192 QSize userMinimumSize; 193 QSize restoreSize; 194 bool resizeEnabled; 195 bool moveEnabled; 196 bool isInInteractiveMode; 197 #if QT_CONFIG(rubberband) 198 bool isInRubberBandMode; 199 #endif 200 bool isShadeMode; 201 bool ignoreWindowTitleChange; 202 bool ignoreNextActivationEvent; 203 bool activationEnabled; 204 bool isShadeRequestFromMinimizeMode; 205 bool isMaximizeMode; 206 bool isWidgetHiddenByUs; 207 bool isActive; 208 bool isExplicitlyDeactivated; 209 int keyboardSingleStep; 210 int keyboardPageStep; 211 int resizeTimerId; 212 Operation currentOperation; 213 QStyle::SubControl hoveredSubControl; 214 QStyle::SubControl activeSubControl; 215 Qt::FocusReason focusInReason; 216 OperationInfoMap operationMap; 217 QPointer<QMenu> systemMenu; 218 #ifndef QT_NO_ACTION 219 QPointer<QAction> actions[NumWindowStateActions]; 220 #endif 221 QMdiSubWindow::SubWindowOptions options; 222 QString lastChildWindowTitle; 223 QPalette titleBarPalette; 224 QString windowTitle; 225 QFont font; 226 QIcon menuIcon; 227 QStyleOptionTitleBar cachedStyleOptions; 228 QString originalTitle; 229 230 // Slots. 231 void _q_updateStaysOnTopHint(); 232 void _q_enterInteractiveMode(); 233 void _q_processFocusChanged(QWidget *old, QWidget *now); 234 235 // Functions. 236 void leaveInteractiveMode(); 237 void removeBaseWidget(); 238 void initOperationMap(); 239 #if QT_CONFIG(menu) 240 void createSystemMenu(); 241 #endif 242 void updateCursor(); 243 void updateDirtyRegions(); 244 void updateGeometryConstraints(); 245 void updateMask(); 246 void setNewGeometry(const QPoint &pos); 247 void setMinimizeMode(); 248 void setNormalMode(); 249 void setMaximizeMode(); 250 void setActive(bool activate, bool changeFocus = true); 251 void processClickedSubControl(); 252 QRegion getRegion(Operation operation) const; 253 Operation getOperation(const QPoint &pos) const; 254 QStyleOptionTitleBar titleBarOptions() const; 255 void ensureWindowState(Qt::WindowState state); 256 int titleBarHeight(const QStyleOptionTitleBar &options) const; 257 void sizeParameters(int *margin, int *minWidth) const; 258 bool drawTitleBarWhenMaximized() const; 259 #if QT_CONFIG(menubar) 260 QMenuBar *menuBar() const; 261 void showButtonsInMenuBar(QMenuBar *menuBar); 262 void removeButtonsFromMenuBar(); 263 #endif 264 void updateWindowTitle(bool requestFromChild); 265 #if QT_CONFIG(rubberband) 266 void enterRubberBandMode(); 267 void leaveRubberBandMode(); 268 #endif 269 QPalette desktopPalette() const; 270 void updateActions(); 271 void setFocusWidget(); 272 bool restoreFocus(); 273 void storeFocusWidget(); 274 void setWindowFlags(Qt::WindowFlags windowFlags) override; 275 void setVisible(WindowStateAction, bool visible = true); 276 #ifndef QT_NO_ACTION 277 void setEnabled(WindowStateAction, bool enable = true); 278 #if QT_CONFIG(menu) 279 void addToSystemMenu(WindowStateAction, const QString &text, const char *slot); 280 #endif 281 #endif // QT_NO_ACTION 282 QSize iconSize() const; 283 #if QT_CONFIG(sizegrip) 284 void setSizeGrip(QSizeGrip *sizeGrip); 285 void setSizeGripVisible(bool visible = true) const; 286 #endif 287 void updateInternalWindowTitle(); 288 QString originalWindowTitle(); 289 void setNewWindowTitle(); 290 titleBarHeight()291 inline int titleBarHeight() const 292 { 293 Q_Q(const QMdiSubWindow); 294 if (!parent || q->windowFlags() & Qt::FramelessWindowHint 295 || (q->isMaximized() && !drawTitleBarWhenMaximized())) { 296 return 0; 297 } 298 QStyleOptionTitleBar options = titleBarOptions(); 299 int height = options.rect.height(); 300 if (hasBorder(options)) 301 height += q->isMinimized() ? 8 : 4; 302 return height; 303 } 304 getSubControl(const QPoint & pos)305 inline QStyle::SubControl getSubControl(const QPoint &pos) const 306 { 307 Q_Q(const QMdiSubWindow); 308 QStyleOptionTitleBar titleBarOptions = this->titleBarOptions(); 309 return q->style()->hitTestComplexControl(QStyle::CC_TitleBar, &titleBarOptions, pos, q); 310 } 311 setNewGeometry(QRect * geometry)312 inline void setNewGeometry(QRect *geometry) 313 { 314 Q_Q(QMdiSubWindow); 315 Q_ASSERT(parent); 316 geometry->setSize(geometry->size().expandedTo(internalMinimumSize)); 317 #if QT_CONFIG(rubberband) 318 if (isInRubberBandMode) 319 rubberBand->setGeometry(*geometry); 320 else 321 #endif 322 q->setGeometry(*geometry); 323 } 324 hasBorder(const QStyleOptionTitleBar & options)325 inline bool hasBorder(const QStyleOptionTitleBar &options) const 326 { 327 Q_Q(const QMdiSubWindow); 328 return !q->style()->styleHint(QStyle::SH_TitleBar_NoBorder, &options, q); 329 } 330 autoRaise()331 inline bool autoRaise() const 332 { 333 Q_Q(const QMdiSubWindow); 334 return q->style()->styleHint(QStyle::SH_TitleBar_AutoRaise, nullptr, q); 335 } 336 isResizeOperation()337 inline bool isResizeOperation() const 338 { 339 return currentOperation != None && currentOperation != Move; 340 } 341 isMoveOperation()342 inline bool isMoveOperation() const 343 { 344 return currentOperation == Move; 345 } 346 }; 347 348 QT_END_NAMESPACE 349 350 #endif // QMDISUBWINDOW_P_H 351