1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the QtGui 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 http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://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 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file.  Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #ifndef QDOCKAREALAYOUT_P_H
43 #define QDOCKAREALAYOUT_P_H
44 
45 //
46 //  W A R N I N G
47 //  -------------
48 //
49 // This file is not part of the Qt API.  It exists purely as an
50 // implementation detail.  This header file may change from version to
51 // version without notice, or even be removed.
52 //
53 // We mean it.
54 //
55 
56 #include "QtCore/qrect.h"
57 #include "QtCore/qpair.h"
58 #include "QtCore/qlist.h"
59 #include "QtCore/qvector.h"
60 #include "QtGui/qlayout.h"
61 
62 #ifndef QT_NO_DOCKWIDGET
63 
64 QT_BEGIN_NAMESPACE
65 
66 class QLayoutItem;
67 class QWidget;
68 class QLayoutItem;
69 class QDockAreaLayoutInfo;
70 class QPlaceHolderItem;
71 class QDockWidget;
72 class QMainWindow;
73 class QWidgetAnimator;
74 class QMainWindowLayout;
75 struct QLayoutStruct;
76 class QTabBar;
77 
78 // The classes in this file represent the tree structure that represents all the docks
79 // Also see the wiki internal documentation
80 // At the root of the tree is: QDockAreaLayout, which handles all 4 sides, so there is only one.
81 // For each side it has one QDockAreaLayoutInfo child. (See QDockAreaLayout::docks.)
82 // The QDockAreaLayoutInfo have QDockAreaLayoutItems as children (See QDockAreaLayoutInfo::item_list),
83 // which then has one QDockAreaLayoutInfo as a child. (QDockAreaLayoutItem::subInfo) or
84 // a widgetItem if this is a node of the tree (QDockAreaLayoutItem::widgetItem)
85 //
86 // A path indetifies uniquely one object in this tree, the first number being the side and all the following
87 // indexes into the QDockAreaLayoutInfo::item_list.
88 
89 struct QDockAreaLayoutItem
90 {
91     enum ItemFlags { NoFlags = 0, GapItem = 1, KeepSize = 2 };
92 
93     QDockAreaLayoutItem(QLayoutItem *_widgetItem = 0);
94     QDockAreaLayoutItem(QDockAreaLayoutInfo *_subinfo);
95     QDockAreaLayoutItem(QPlaceHolderItem *_placeHolderItem);
96     QDockAreaLayoutItem(const QDockAreaLayoutItem &other);
97     ~QDockAreaLayoutItem();
98 
99     QDockAreaLayoutItem &operator = (const QDockAreaLayoutItem &other);
100 
101     bool skip() const;
102     QSize minimumSize() const;
103     QSize maximumSize() const;
104     QSize sizeHint() const;
105     bool expansive(Qt::Orientation o) const;
106     bool hasFixedSize(Qt::Orientation o) const;
107 
108     QLayoutItem *widgetItem;
109     QDockAreaLayoutInfo *subinfo;
110     QPlaceHolderItem *placeHolderItem;
111     int pos;
112     int size;
113     uint flags;
114 };
115 
116 class Q_AUTOTEST_EXPORT QPlaceHolderItem
117 {
118 public:
QPlaceHolderItem()119     QPlaceHolderItem() : hidden(false), window(false) {}
120     QPlaceHolderItem(QWidget *w);
121 
122     QString objectName;
123     bool hidden, window;
124     QRect topLevelRect;
125 };
126 
127 class Q_AUTOTEST_EXPORT QDockAreaLayoutInfo
128 {
129 public:
130     QDockAreaLayoutInfo();
131     QDockAreaLayoutInfo(const int *_sep, QInternal::DockPosition _dockPos, Qt::Orientation _o,
132                         int tbhape, QMainWindow *window);
133 
134     QSize minimumSize() const;
135     QSize maximumSize() const;
136     QSize sizeHint() const;
137     QSize size() const;
138 
139     bool insertGap(const QList<int> &path, QLayoutItem *dockWidgetItem);
140     QLayoutItem *plug(const QList<int> &path);
141     QLayoutItem *unplug(const QList<int> &path);
142     enum TabMode { NoTabs, AllowTabs, ForceTabs };
143     QList<int> gapIndex(const QPoint &pos, bool nestingEnabled,
144                             TabMode tabMode) const;
145     void remove(const QList<int> &path);
146     void unnest(int index);
147     void split(int index, Qt::Orientation orientation, QLayoutItem *dockWidgetItem);
148     void tab(int index, QLayoutItem *dockWidgetItem);
149     QDockAreaLayoutItem &item(const QList<int> &path);
150     QDockAreaLayoutInfo *info(const QList<int> &path);
151     QDockAreaLayoutInfo *info(QWidget *widget);
152 
153     enum { // sentinel values used to validate state data
154         SequenceMarker = 0xfc,
155         TabMarker = 0xfa,
156         WidgetMarker = 0xfb
157     };
158     void saveState(QDataStream &stream) const;
159     bool restoreState(QDataStream &stream, QList<QDockWidget*> &widgets, bool testing);
160 
161     void fitItems();
162     bool expansive(Qt::Orientation o) const;
163     int changeSize(int index, int size, bool below);
164     QRect itemRect(int index) const;
165     QRect itemRect(const QList<int> &path) const;
166     QRect separatorRect(int index) const;
167     QRect separatorRect(const QList<int> &path) const;
168 
169     void clear();
170     bool isEmpty() const;
171     bool hasFixedSize() const;
172     QList<int> findSeparator(const QPoint &pos) const;
173     int next(int idx) const;
174     int prev(int idx) const;
175 
176     QList<int> indexOf(QWidget *widget) const;
177     QList<int> indexOfPlaceHolder(const QString &objectName) const;
178 
179     void apply(bool animate);
180 
181     void paintSeparators(QPainter *p, QWidget *widget, const QRegion &clip,
182                             const QPoint &mouse) const;
183     QRegion separatorRegion() const;
184     int separatorMove(int index, int delta);
185 
186     QLayoutItem *itemAt(int *x, int index) const;
187     QLayoutItem *takeAt(int *x, int index);
188     void deleteAllLayoutItems();
189 
190     QMainWindowLayout *mainWindowLayout() const;
191 
192     const int *sep;
193     mutable QVector<QWidget*> separatorWidgets;
194     QInternal::DockPosition dockPos;
195     Qt::Orientation o;
196     QRect rect;
197     QMainWindow *mainWindow;
198     QList<QDockAreaLayoutItem> item_list;
199 #ifndef QT_NO_TABBAR
200     void updateSeparatorWidgets() const;
201     QSet<QWidget*> usedSeparatorWidgets() const;
202 #endif //QT_NO_TABBAR
203 
204 #ifndef QT_NO_TABBAR
205     quintptr currentTabId() const;
206     void setCurrentTab(QWidget *widget);
207     void setCurrentTabId(quintptr id);
208     QRect tabContentRect() const;
209     bool tabbed;
210     QTabBar *tabBar;
211     int tabBarShape;
212 
213     bool updateTabBar() const;
214     void setTabBarShape(int shape);
215     QSize tabBarMinimumSize() const;
216     QSize tabBarSizeHint() const;
217 
218     QSet<QTabBar*> usedTabBars() const;
219 #endif // QT_NO_TABBAR
220 };
221 
222 class Q_AUTOTEST_EXPORT QDockAreaLayout
223 {
224 public:
225     enum { EmptyDropAreaSize = 80 }; // when a dock area is empty, how "wide" is it?
226 
227     Qt::DockWidgetArea corners[4]; // use a Qt::Corner for indexing
228     QRect rect;
229     QLayoutItem *centralWidgetItem;
230     QMainWindow *mainWindow;
231     QRect centralWidgetRect;
232     QDockAreaLayout(QMainWindow *win);
233     QDockAreaLayoutInfo docks[4];
234     int sep; // separator extent
235     bool fallbackToSizeHints; //determines if we should use the sizehint for the dock areas (true until the layout is restored or the central widget is set)
236     mutable QVector<QWidget*> separatorWidgets;
237 
238     bool isValid() const;
239 
240     enum { DockWidgetStateMarker = 0xfd };
241     void saveState(QDataStream &stream) const;
242     bool restoreState(QDataStream &stream, const QList<QDockWidget*> &widgets, bool testing = false);
243 
244     QList<int> indexOfPlaceHolder(const QString &objectName) const;
245     QList<int> indexOf(QWidget *dockWidget) const;
246     QList<int> gapIndex(const QPoint &pos) const;
247     QList<int> findSeparator(const QPoint &pos) const;
248 
249     QDockAreaLayoutItem &item(const QList<int> &path);
250     QDockAreaLayoutInfo *info(const QList<int> &path);
251     const QDockAreaLayoutInfo *info(const QList<int> &path) const;
252     QDockAreaLayoutInfo *info(QWidget *widget);
253     QRect itemRect(const QList<int> &path) const;
254     QRect separatorRect(int index) const;
255     QRect separatorRect(const QList<int> &path) const;
256 
257     bool insertGap(const QList<int> &path, QLayoutItem *dockWidgetItem);
258     QLayoutItem *plug(const QList<int> &path);
259     QLayoutItem *unplug(const QList<int> &path);
260     void remove(const QList<int> &path);
261 
262     void fitLayout();
263 
264     void clear();
265 
266     QSize sizeHint() const;
267     QSize minimumSize() const;
268 
269     void addDockWidget(QInternal::DockPosition pos, QDockWidget *dockWidget, Qt::Orientation orientation);
270     bool restoreDockWidget(QDockWidget *dockWidget);
271     void splitDockWidget(QDockWidget *after, QDockWidget *dockWidget,
272                          Qt::Orientation orientation);
273     void tabifyDockWidget(QDockWidget *first, QDockWidget *second);
274 
275     void apply(bool animate);
276 
277     void paintSeparators(QPainter *p, QWidget *widget, const QRegion &clip,
278                             const QPoint &mouse) const;
279     QRegion separatorRegion() const;
280     int separatorMove(const QList<int> &separator, const QPoint &origin, const QPoint &dest);
281 #ifndef QT_NO_TABBAR
282     void updateSeparatorWidgets() const;
283 #endif //QT_NO_TABBAR
284 
285     QLayoutItem *itemAt(int *x, int index) const;
286     QLayoutItem *takeAt(int *x, int index);
287     void deleteAllLayoutItems();
288 
289     void getGrid(QVector<QLayoutStruct> *ver_struct_list,
290                     QVector<QLayoutStruct> *hor_struct_list);
291     void setGrid(QVector<QLayoutStruct> *ver_struct_list,
292                     QVector<QLayoutStruct> *hor_struct_list);
293 
294     QRect gapRect(const QList<int> &path) const;
295 
296     void keepSize(QDockWidget *w);
297 #ifndef QT_NO_TABBAR
298     QSet<QTabBar*> usedTabBars() const;
299     QSet<QWidget*> usedSeparatorWidgets() const;
300 #endif //QT_NO_TABBAR
301     void styleChangedEvent();
302 };
303 
304 QT_END_NAMESPACE
305 
306 #endif // QT_NO_QDOCKWIDGET
307 
308 #endif // QDOCKAREALAYOUT_P_H
309