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 QMDIAREA_P_H 41 #define QMDIAREA_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 "qmdiarea.h" 56 #include "qmdisubwindow.h" 57 58 QT_REQUIRE_CONFIG(mdiarea); 59 60 #include <QList> 61 #include <QVector> 62 #include <QRect> 63 #include <QPoint> 64 #include <QtWidgets/qapplication.h> 65 #include <private/qmdisubwindow_p.h> 66 #include <private/qabstractscrollarea_p.h> 67 68 QT_BEGIN_NAMESPACE 69 70 namespace QMdi { 71 class Rearranger 72 { 73 public: 74 enum Type { 75 RegularTiler, 76 SimpleCascader, 77 IconTiler 78 }; 79 80 // Rearranges widgets relative to domain. 81 virtual void rearrange(QList<QWidget *> &widgets, const QRect &domain) const = 0; 82 virtual Type type() const = 0; ~Rearranger()83 virtual ~Rearranger() {} 84 }; 85 86 class RegularTiler : public Rearranger 87 { 88 // Rearranges widgets according to a regular tiling pattern 89 // covering the entire domain. 90 // Both positions and sizes may change. 91 void rearrange(QList<QWidget *> &widgets, const QRect &domain) const override; type()92 Type type() const override { return Rearranger::RegularTiler; } 93 }; 94 95 class SimpleCascader : public Rearranger 96 { 97 // Rearranges widgets according to a simple, regular cascading pattern. 98 // Widgets are resized to minimumSize. 99 // Both positions and sizes may change. 100 void rearrange(QList<QWidget *> &widgets, const QRect &domain) const override; type()101 Type type() const override { return Rearranger::SimpleCascader; } 102 }; 103 104 class IconTiler : public Rearranger 105 { 106 // Rearranges icons (assumed to be the same size) according to a regular 107 // tiling pattern filling up the domain from the bottom. 108 // Only positions may change. 109 void rearrange(QList<QWidget *> &widgets, const QRect &domain) const override; type()110 Type type() const override { return Rearranger::IconTiler; } 111 }; 112 113 class Placer 114 { 115 public: 116 // Places the rectangle defined by 'size' relative to 'rects' and 'domain'. 117 // Returns the position of the resulting rectangle. 118 virtual QPoint place( 119 const QSize &size, const QVector<QRect> &rects, const QRect &domain) const = 0; ~Placer()120 virtual ~Placer() {} 121 }; 122 123 class MinOverlapPlacer : public Placer 124 { 125 QPoint place(const QSize &size, const QVector<QRect> &rects, const QRect &domain) const override; 126 static int accumulatedOverlap(const QRect &source, const QVector<QRect> &rects); 127 static QRect findMinOverlapRect(const QVector<QRect> &source, const QVector<QRect> &rects); 128 static QVector<QRect> getCandidatePlacements(const QSize &size, const QVector<QRect> &rects, const QRect &domain); 129 static QPoint findBestPlacement(const QRect &domain, const QVector<QRect> &rects, QVector<QRect> &source); 130 static QVector<QRect> findNonInsiders(const QRect &domain, QVector<QRect> &source); 131 static QVector<QRect> findMaxOverlappers(const QRect &domain, const QVector<QRect> &source); 132 }; 133 } // namespace QMdi 134 135 class QMdiAreaTabBar; 136 class QMdiAreaPrivate : public QAbstractScrollAreaPrivate 137 { 138 Q_DECLARE_PUBLIC(QMdiArea) 139 public: 140 QMdiAreaPrivate(); 141 142 // Variables. 143 QMdi::Rearranger *cascader; 144 QMdi::Rearranger *regularTiler; 145 QMdi::Rearranger *iconTiler; 146 QMdi::Placer *placer; 147 #if QT_CONFIG(rubberband) 148 QRubberBand *rubberBand; 149 #endif 150 QMdiAreaTabBar *tabBar; 151 QList<QMdi::Rearranger *> pendingRearrangements; 152 QVector< QPointer<QMdiSubWindow> > pendingPlacements; 153 QVector< QPointer<QMdiSubWindow> > childWindows; 154 QVector<int> indicesToActivatedChildren; 155 QPointer<QMdiSubWindow> active; 156 QPointer<QMdiSubWindow> aboutToBecomeActive; 157 QBrush background; 158 QMdiArea::WindowOrder activationOrder; 159 QMdiArea::AreaOptions options; 160 QMdiArea::ViewMode viewMode; 161 #if QT_CONFIG(tabbar) 162 bool documentMode; 163 bool tabsClosable; 164 bool tabsMovable; 165 #endif 166 #if QT_CONFIG(tabwidget) 167 QTabWidget::TabShape tabShape; 168 QTabWidget::TabPosition tabPosition; 169 #endif 170 bool ignoreGeometryChange; 171 bool ignoreWindowStateChange; 172 bool isActivated; 173 bool isSubWindowsTiled; 174 bool showActiveWindowMaximized; 175 bool tileCalledFromResizeEvent; 176 bool updatesDisabledByUs; 177 bool inViewModeChange; 178 int indexToNextWindow; 179 int indexToPreviousWindow; 180 int indexToHighlighted; 181 int indexToLastActiveTab; 182 int resizeTimerId; 183 int tabToPreviousTimerId; 184 185 // Slots. 186 void _q_deactivateAllWindows(QMdiSubWindow *aboutToActivate = nullptr); 187 void _q_processWindowStateChanged(Qt::WindowStates oldState, Qt::WindowStates newState); 188 void _q_currentTabChanged(int index); 189 void _q_closeTab(int index); 190 void _q_moveTab(int from, int to); 191 192 // Functions. 193 void appendChild(QMdiSubWindow *child); 194 void place(QMdi::Placer *placer, QMdiSubWindow *child); 195 void rearrange(QMdi::Rearranger *rearranger); 196 void arrangeMinimizedSubWindows(); 197 void activateWindow(QMdiSubWindow *child); 198 void activateCurrentWindow(); 199 void activateHighlightedWindow(); 200 void emitWindowActivated(QMdiSubWindow *child); 201 void resetActiveWindow(QMdiSubWindow *child = nullptr); 202 void updateActiveWindow(int removedIndex, bool activeRemoved); 203 void updateScrollBars(); 204 void internalRaise(QMdiSubWindow *child) const; 205 bool scrollBarsEnabled() const; 206 bool lastWindowAboutToBeDestroyed() const; 207 void setChildActivationEnabled(bool enable = true, bool onlyNextActivationEvent = false) const; 208 QRect resizeToMinimumTileSize(const QSize &minSubWindowSize, int subWindowCount); 209 void scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy) override; // reimp 210 QMdiSubWindow *nextVisibleSubWindow(int increaseFactor, QMdiArea::WindowOrder, 211 int removed = -1, int fromIndex = -1) const; 212 void highlightNextSubWindow(int increaseFactor); 213 QList<QMdiSubWindow *> subWindowList(QMdiArea::WindowOrder, bool reversed = false) const; 214 void disconnectSubWindow(QObject *subWindow); 215 void setViewMode(QMdiArea::ViewMode mode); 216 #if QT_CONFIG(tabbar) 217 void updateTabBarGeometry(); 218 void refreshTabBar(); 219 #endif 220 startResizeTimer()221 inline void startResizeTimer() 222 { 223 Q_Q(QMdiArea); 224 if (resizeTimerId > 0) 225 q->killTimer(resizeTimerId); 226 resizeTimerId = q->startTimer(200); 227 } 228 startTabToPreviousTimer()229 inline void startTabToPreviousTimer() 230 { 231 Q_Q(QMdiArea); 232 if (tabToPreviousTimerId > 0) 233 q->killTimer(tabToPreviousTimerId); 234 tabToPreviousTimerId = q->startTimer(QApplication::keyboardInputInterval()); 235 } 236 windowStaysOnTop(QMdiSubWindow * subWindow)237 inline bool windowStaysOnTop(QMdiSubWindow *subWindow) const 238 { 239 if (!subWindow) 240 return false; 241 return subWindow->windowFlags() & Qt::WindowStaysOnTopHint; 242 } 243 isExplicitlyDeactivated(QMdiSubWindow * subWindow)244 inline bool isExplicitlyDeactivated(QMdiSubWindow *subWindow) const 245 { 246 if (!subWindow) 247 return true; 248 return subWindow->d_func()->isExplicitlyDeactivated; 249 } 250 251 inline void setActive(QMdiSubWindow *subWindow, bool active = true, bool changeFocus = true) const 252 { 253 if (subWindow) 254 subWindow->d_func()->setActive(active, changeFocus); 255 } 256 257 #if QT_CONFIG(rubberband) 258 void showRubberBandFor(QMdiSubWindow *subWindow); 259 hideRubberBand()260 inline void hideRubberBand() 261 { 262 if (rubberBand && rubberBand->isVisible()) 263 rubberBand->hide(); 264 indexToHighlighted = -1; 265 } 266 #endif // QT_CONFIG(rubberband) 267 }; 268 269 QT_END_NAMESPACE 270 271 #endif // QMDIAREA_P_H 272