widgets/qdockwidget.cpp

Source codeSwitch to Preprocessed file
LineSource CodeCoverage
1/****************************************************************************-
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/****************************************************************************
2** -
3** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -
4** Contact: http://www.qt-project.org/legal -
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 Digia. For licensing terms and -
14** conditions see http://qt.digia.com/licensing. For further information -
15** use the contact form at http://qt.digia.com/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 as published by the Free Software -
20** Foundation and appearing in the file LICENSE.LGPL included in the -
21** packaging of this file. Please review the following information to -
22** ensure the GNU Lesser General Public License version 2.1 requirements -
23** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -
24** -
25** In addition, as a special exception, Digia gives you certain additional -
26** rights. These rights are described in the Digia Qt LGPL Exception -
27** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -
28** -
29** GNU General Public License Usage -
30** Alternatively, this file may be used under the terms of the GNU -
31** General Public License version 3.0 as published by the Free Software -
32** Foundation and appearing in the file LICENSE.GPL included in the -
33** packaging of this file. Please review the following information to -
34** ensure the GNU General Public License version 3.0 requirements will be -
35** met: http://www.gnu.org/copyleft/gpl.html. -
36** -
37** -
38** $QT_END_LICENSE$ -
39** -
40****************************************************************************/ -
41 -
42#include "qdockwidget.h" -
43 -
44#ifndef QT_NO_DOCKWIDGET -
45#include <qaction.h> -
46#include <qapplication.h> -
47#include <qdesktopwidget.h> -
48#include <qdrawutil.h> -
49#include <qevent.h> -
50#include <qfontmetrics.h> -
51#include <qwindow.h> -
52#include <qmainwindow.h> -
53#include <qrubberband.h> -
54#include <qstylepainter.h> -
55#include <qtoolbutton.h> -
56#include <qdebug.h> -
57 -
58#include <qpa/qplatformwindow.h> -
59#include <private/qwidgetresizehandler_p.h> -
60 -
61#include "qdockwidget_p.h" -
62#include "qmainwindowlayout_p.h" -
63#ifdef Q_WS_MAC -
64#include <private/qapplication_p.h> -
65#include <private/qt_mac_p.h> -
66#include <private/qmacstyle_mac_p.h> -
67#endif -
68 -
69QT_BEGIN_NAMESPACE -
70 -
71extern QString qt_setWindowTitle_helperHelper(const QString&, const QWidget*); // qwidget.cpp -
72 -
73// qmainwindow.cpp -
74extern QMainWindowLayout *qt_mainwindow_layout(const QMainWindow *window); -
75 -
76static inline bool hasFeature(const QDockWidgetPrivate *priv, QDockWidget::DockWidgetFeature feature) -
77{ return (priv->features & feature) == feature; } -
78 -
79static inline bool hasFeature(const QDockWidget *dockwidget, QDockWidget::DockWidgetFeature feature) -
80{ return (dockwidget->features() & feature) == feature; } -
81 -
82 -
83/* -
84 A Dock Window: -
85 -
86 [+] is the float button -
87 [X] is the close button -
88 -
89 +-------------------------------+ -
90 | Dock Window Title [+][X]| -
91 +-------------------------------+ -
92 | | -
93 | place to put the single | -
94 | QDockWidget child (this space | -
95 | does not yet have a name) | -
96 | | -
97 | | -
98 | | -
99 | | -
100 | | -
101 | | -
102 | | -
103 | | -
104 | | -
105 +-------------------------------+ -
106 -
107*/ -
108 -
109/****************************************************************************** -
110** QDockWidgetTitleButton -
111*/ -
112 -
113class QDockWidgetTitleButton : public QAbstractButton -
114{ -
115 Q_OBJECT -
116 -
117public: -
118 QDockWidgetTitleButton(QDockWidget *dockWidget); -
119 -
120 QSize sizeHint() const; -
121 inline QSize minimumSizeHint() const -
122 { return sizeHint(); } -
123 -
124 void enterEvent(QEvent *event); -
125 void leaveEvent(QEvent *event); -
126 void paintEvent(QPaintEvent *event); -
127}; -
128 -
129 -
130QDockWidgetTitleButton::QDockWidgetTitleButton(QDockWidget *dockWidget) -
131 : QAbstractButton(dockWidget) -
132{ -
133 setFocusPolicy(Qt::NoFocus); -
134} -
135 -
136QSize QDockWidgetTitleButton::sizeHint() const -
137{ -
138 ensurePolished(); -
139 -
140 int size = 2*style()->pixelMetric(QStyle::PM_DockWidgetTitleBarButtonMargin, 0, this); -
141 if (!icon().isNull()) { -
142 int iconSize = style()->pixelMetric(QStyle::PM_SmallIconSize, 0, this); -
143 QSize sz = icon().actualSize(QSize(iconSize, iconSize)); -
144 size += qMax(sz.width(), sz.height()); -
145 } -
146 -
147 return QSize(size, size); -
148} -
149 -
150void QDockWidgetTitleButton::enterEvent(QEvent *event) -
151{ -
152 if (isEnabled()) update(); -
153 QAbstractButton::enterEvent(event); -
154} -
155 -
156void QDockWidgetTitleButton::leaveEvent(QEvent *event) -
157{ -
158 if (isEnabled()) update(); -
159 QAbstractButton::leaveEvent(event); -
160} -
161 -
162void QDockWidgetTitleButton::paintEvent(QPaintEvent *) -
163{ -
164 QPainter p(this); -
165 -
166 QStyleOptionToolButton opt; -
167 opt.init(this); -
168 opt.state |= QStyle::State_AutoRaise; -
169 -
170 if (style()->styleHint(QStyle::SH_DockWidget_ButtonsHaveFrame, 0, this)) -
171 { -
172 if (isEnabled() && underMouse() && !isChecked() && !isDown()) -
173 opt.state |= QStyle::State_Raised; -
174 if (isChecked()) -
175 opt.state |= QStyle::State_On; -
176 if (isDown()) -
177 opt.state |= QStyle::State_Sunken; -
178 style()->drawPrimitive(QStyle::PE_PanelButtonTool, &opt, &p, this); -
179 } -
180 -
181 opt.icon = icon(); -
182 opt.subControls = 0; -
183 opt.activeSubControls = 0; -
184 opt.features = QStyleOptionToolButton::None; -
185 opt.arrowType = Qt::NoArrow; -
186 int size = style()->pixelMetric(QStyle::PM_SmallIconSize, 0, this); -
187 opt.iconSize = QSize(size, size); -
188 style()->drawComplexControl(QStyle::CC_ToolButton, &opt, &p, this); -
189} -
190 -
191/****************************************************************************** -
192** QDockWidgetLayout -
193*/ -
194 -
195QDockWidgetLayout::QDockWidgetLayout(QWidget *parent) -
196 : QLayout(parent), verticalTitleBar(false), item_list(RoleCount, 0) -
197{ -
198} -
199 -
200QDockWidgetLayout::~QDockWidgetLayout() -
201{ -
202 qDeleteAll(item_list); -
203} -
204 -
205bool QDockWidgetLayout::nativeWindowDeco() const -
206{ -
207 return nativeWindowDeco(parentWidget()->isWindow()); -
208} -
209 -
210static bool isXcb() -
211{ -
212 static const bool xcb = !QGuiApplication::platformName().compare(QLatin1String("xcb"), Qt::CaseInsensitive); -
213 return xcb; -
214} -
215 -
216bool QDockWidgetLayout::nativeWindowDeco(bool floating) const -
217{ -
218#ifdef Q_OS_WINCE -
219 return false; -
220#else -
221 return !isXcb() && (floating && item_list[QDockWidgetLayout::TitleBar] == 0); -
222#endif -
223} -
224 -
225 -
226void QDockWidgetLayout::addItem(QLayoutItem*) -
227{ -
228 qWarning() << "QDockWidgetLayout::addItem(): please use QDockWidgetLayout::setWidget()"; -
229 return; -
230} -
231 -
232QLayoutItem *QDockWidgetLayout::itemAt(int index) const -
233{ -
234 int cnt = 0; -
235 for (int i = 0; i < item_list.count(); ++i) { -
236 QLayoutItem *item = item_list.at(i); -
237 if (item == 0) -
238 continue; -
239 if (index == cnt++) -
240 return item; -
241 } -
242 return 0; -
243} -
244 -
245QLayoutItem *QDockWidgetLayout::takeAt(int index) -
246{ -
247 int j = 0; -
248 for (int i = 0; i < item_list.count(); ++i) { -
249 QLayoutItem *item = item_list.at(i); -
250 if (item == 0) -
251 continue; -
252 if (index == j) { -
253 item_list[i] = 0; -
254 invalidate(); -
255 return item; -
256 } -
257 ++j; -
258 } -
259 return 0; -
260} -
261 -
262int QDockWidgetLayout::count() const -
263{ -
264 int result = 0; -
265 for (int i = 0; i < item_list.count(); ++i) { -
266 if (item_list.at(i)) -
267 ++result; -
268 } -
269 return result; -
270} -
271 -
272QSize QDockWidgetLayout::sizeFromContent(const QSize &content, bool floating) const -
273{ -
274 QSize result = content; -
275 -
276 if (verticalTitleBar) { -
277 result.setHeight(qMax(result.height(), minimumTitleWidth())); -
278 result.setWidth(qMax(content.width(), 0)); -
279 } else { -
280 result.setHeight(qMax(result.height(), 0)); -
281 result.setWidth(qMax(content.width(), minimumTitleWidth())); -
282 } -
283 -
284 QDockWidget *w = qobject_cast<QDockWidget*>(parentWidget()); -
285 const bool nativeDeco = nativeWindowDeco(floating); -
286 -
287 int fw = floating && !nativeDeco -
288 ? w->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, w) -
289 : 0; -
290 -
291 const int th = titleHeight(); -
292 if (!nativeDeco) { -
293 if (verticalTitleBar) -
294 result += QSize(th + 2*fw, 2*fw); -
295 else -
296 result += QSize(2*fw, th + 2*fw); -
297 } -
298 -
299 result.setHeight(qMin(result.height(), (int) QWIDGETSIZE_MAX)); -
300 result.setWidth(qMin(result.width(), (int) QWIDGETSIZE_MAX)); -
301 -
302 if (content.width() < 0) -
303 result.setWidth(-1); -
304 if (content.height() < 0) -
305 result.setHeight(-1); -
306 -
307 int left, top, right, bottom; -
308 w->getContentsMargins(&left, &top, &right, &bottom); -
309 //we need to subtract the contents margin (it will be added by the caller) -
310 QSize min = w->minimumSize() - QSize(left + right, top + bottom); -
311 QSize max = w->maximumSize() - QSize(left + right, top + bottom); -
312 -
313 /* A floating dockwidget will automatically get its minimumSize set to the layout's -
314 minimum size + deco. We're *not* interested in this, we only take minimumSize() -
315 into account if the user set it herself. Otherwise we end up expanding the result -
316 of a calculation for a non-floating dock widget to a floating dock widget's -
317 minimum size + window decorations. */ -
318 -
319 uint explicitMin = 0; -
320 uint explicitMax = 0; -
321 if (w->d_func()->extra != 0) { -
322 explicitMin = w->d_func()->extra->explicitMinSize; -
323 explicitMax = w->d_func()->extra->explicitMaxSize; -
324 } -
325 -
326 if (!(explicitMin & Qt::Horizontal) || min.width() == 0) -
327 min.setWidth(-1); -
328 if (!(explicitMin & Qt::Vertical) || min.height() == 0) -
329 min.setHeight(-1); -
330 -
331 if (!(explicitMax & Qt::Horizontal)) -
332 max.setWidth(QWIDGETSIZE_MAX); -
333 if (!(explicitMax & Qt::Vertical)) -
334 max.setHeight(QWIDGETSIZE_MAX); -
335 -
336 return result.boundedTo(max).expandedTo(min); -
337} -
338 -
339QSize QDockWidgetLayout::sizeHint() const -
340{ -
341 QDockWidget *w = qobject_cast<QDockWidget*>(parentWidget()); -
342 -
343 QSize content(-1, -1); -
344 if (item_list[Content] != 0) -
345 content = item_list[Content]->sizeHint(); -
346 -
347 return sizeFromContent(content, w->isFloating()); -
348} -
349 -
350QSize QDockWidgetLayout::maximumSize() const -
351{ -
352 if (item_list[Content] != 0) { -
353 const QSize content = item_list[Content]->maximumSize(); -
354 return sizeFromContent(content, parentWidget()->isWindow()); -
355 } else { -
356 return parentWidget()->maximumSize(); -
357 } -
358 -
359} -
360 -
361QSize QDockWidgetLayout::minimumSize() const -
362{ -
363 QDockWidget *w = qobject_cast<QDockWidget*>(parentWidget()); -
364 -
365 QSize content(0, 0); -
366 if (item_list[Content] != 0) -
367 content = item_list[Content]->minimumSize(); -
368 -
369 return sizeFromContent(content, w->isFloating()); -
370} -
371 -
372QWidget *QDockWidgetLayout::widgetForRole(Role r) const -
373{ -
374 QLayoutItem *item = item_list.at(r); -
375 return item == 0 ? 0 : item->widget(); -
376} -
377 -
378QLayoutItem *QDockWidgetLayout::itemForRole(Role r) const -
379{ -
380 return item_list.at(r); -
381} -
382 -
383void QDockWidgetLayout::setWidgetForRole(Role r, QWidget *w) -
384{ -
385 QWidget *old = widgetForRole(r); -
386 if (old != 0) { -
387 old->hide(); -
388 removeWidget(old); -
389 } -
390 -
391 if (w != 0) { -
392 addChildWidget(w); -
393 item_list[r] = new QWidgetItemV2(w); -
394 w->show(); -
395 } else { -
396 item_list[r] = 0; -
397 } -
398 -
399 invalidate(); -
400} -
401 -
402static inline int pick(bool vertical, const QSize &size) -
403{ -
404 return vertical ? size.height() : size.width(); -
405} -
406 -
407static inline int perp(bool vertical, const QSize &size) -
408{ -
409 return vertical ? size.width() : size.height(); -
410} -
411 -
412int QDockWidgetLayout::minimumTitleWidth() const -
413{ -
414 QDockWidget *q = qobject_cast<QDockWidget*>(parentWidget()); -
415 -
416 if (QWidget *title = widgetForRole(TitleBar)) -
417 return pick(verticalTitleBar, title->minimumSizeHint()); -
418 -
419 QSize closeSize(0, 0); -
420 QSize floatSize(0, 0); -
421 if (hasFeature(q, QDockWidget::DockWidgetClosable)) { -
422 if (QLayoutItem *item = item_list[CloseButton]) -
423 closeSize = item->widget()->sizeHint(); -
424 } -
425 if (hasFeature(q, QDockWidget::DockWidgetFloatable)) { -
426 if (QLayoutItem *item = item_list[FloatButton]) -
427 floatSize = item->widget()->sizeHint(); -
428 } -
429 -
430 int titleHeight = this->titleHeight(); -
431 -
432 int mw = q->style()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, 0, q); -
433 int fw = q->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, q); -
434 -
435 return pick(verticalTitleBar, closeSize) -
436 + pick(verticalTitleBar, floatSize) -
437 + titleHeight + 2*fw + 3*mw; -
438} -
439 -
440int QDockWidgetLayout::titleHeight() const -
441{ -
442 QDockWidget *q = qobject_cast<QDockWidget*>(parentWidget()); -
443 -
444 if (QWidget *title = widgetForRole(TitleBar)) -
445 return perp(verticalTitleBar, title->sizeHint()); -
446 -
447 QSize closeSize(0, 0); -
448 QSize floatSize(0, 0); -
449 if (QLayoutItem *item = item_list[CloseButton]) -
450 closeSize = item->widget()->sizeHint(); -
451 if (QLayoutItem *item = item_list[FloatButton]) -
452 floatSize = item->widget()->sizeHint(); -
453 -
454 int buttonHeight = qMax(perp(verticalTitleBar, closeSize), -
455 perp(verticalTitleBar, floatSize)); -
456 -
457 QFontMetrics titleFontMetrics = q->fontMetrics(); -
458#ifdef Q_WS_MAC -
459 if (qobject_cast<QMacStyle *>(q->style())) { -
460 //### this breaks on proxy styles. (But is this code still called?) -
461 QFont font = qt_app_fonts_hash()->value("QToolButton", q->font()); -
462 titleFontMetrics = QFontMetrics(font); -
463 } -
464#endif -
465 -
466 int mw = q->style()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, 0, q); -
467 -
468 return qMax(buttonHeight + 2, titleFontMetrics.height() + 2*mw); -
469} -
470 -
471void QDockWidgetLayout::setGeometry(const QRect &geometry) -
472{ -
473 QDockWidget *q = qobject_cast<QDockWidget*>(parentWidget()); -
474 -
475 bool nativeDeco = nativeWindowDeco(); -
476 -
477 int fw = q->isFloating() && !nativeDeco -
478 ? q->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, q) -
479 : 0; -
480 -
481 if (nativeDeco) { -
482 if (QLayoutItem *item = item_list[Content]) -
483 item->setGeometry(geometry); -
484 } else { -
485 int titleHeight = this->titleHeight(); -
486 -
487 if (verticalTitleBar) { -
488 _titleArea = QRect(QPoint(fw, fw), -
489 QSize(titleHeight, geometry.height() - (fw * 2))); -
490 } else { -
491 _titleArea = QRect(QPoint(fw, fw), -
492 QSize(geometry.width() - (fw * 2), titleHeight)); -
493 } -
494 -
495 if (QLayoutItem *item = item_list[TitleBar]) { -
496 item->setGeometry(_titleArea); -
497 } else { -
498 QStyleOptionDockWidgetV2 opt; -
499 q->initStyleOption(&opt); -
500 -
501 if (QLayoutItem *item = item_list[CloseButton]) { -
502 if (!item->isEmpty()) { -
503 QRect r = q->style() -
504 ->subElementRect(QStyle::SE_DockWidgetCloseButton, -
505 &opt, q); -
506 if (!r.isNull()) -
507 item->setGeometry(r); -
508 } -
509 } -
510 -
511 if (QLayoutItem *item = item_list[FloatButton]) { -
512 if (!item->isEmpty()) { -
513 QRect r = q->style() -
514 ->subElementRect(QStyle::SE_DockWidgetFloatButton, -
515 &opt, q); -
516 if (!r.isNull()) -
517 item->setGeometry(r); -
518 } -
519 } -
520 } -
521 -
522 if (QLayoutItem *item = item_list[Content]) { -
523 QRect r = geometry; -
524 if (verticalTitleBar) { -
525 r.setLeft(_titleArea.right() + 1); -
526 r.adjust(0, fw, -fw, -fw); -
527 } else { -
528 r.setTop(_titleArea.bottom() + 1); -
529 r.adjust(fw, 0, -fw, -fw); -
530 } -
531 item->setGeometry(r); -
532 } -
533 } -
534} -
535 -
536void QDockWidgetLayout::setVerticalTitleBar(bool b) -
537{ -
538 if (b == verticalTitleBar) -
539 return; -
540 verticalTitleBar = b; -
541 invalidate(); -
542 parentWidget()->update(); -
543} -
544 -
545/****************************************************************************** -
546** QDockWidgetItem -
547*/ -
548 -
549QDockWidgetItem::QDockWidgetItem(QDockWidget *dockWidget) -
550 : QWidgetItem(dockWidget) -
551{ -
552} -
553 -
554QSize QDockWidgetItem::minimumSize() const -
555{ -
556 QSize widgetMin(0, 0); -
557 if (QLayoutItem *item = dockWidgetChildItem()) -
558 widgetMin = item->minimumSize(); -
559 return dockWidgetLayout()->sizeFromContent(widgetMin, false); -
560} -
561 -
562QSize QDockWidgetItem::maximumSize() const -
563{ -
564 if (QLayoutItem *item = dockWidgetChildItem()) { -
565 return dockWidgetLayout()->sizeFromContent(item->maximumSize(), false); -
566 } else { -
567 return QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); -
568 } -
569} -
570 -
571 -
572QSize QDockWidgetItem::sizeHint() const -
573{ -
574 if (QLayoutItem *item = dockWidgetChildItem()) { -
575 return dockWidgetLayout()->sizeFromContent(item->sizeHint(), false); -
576 } else { -
577 return QWidgetItem::sizeHint(); -
578 } -
579} -
580 -
581/****************************************************************************** -
582** QDockWidgetPrivate -
583*/ -
584 -
585void QDockWidgetPrivate::init() -
586{ -
587 Q_Q(QDockWidget); -
588 -
589 QDockWidgetLayout *layout = new QDockWidgetLayout(q); -
590 layout->setSizeConstraint(QLayout::SetMinAndMaxSize); -
591 -
592 QAbstractButton *button = new QDockWidgetTitleButton(q); -
593 button->setObjectName(QLatin1String("qt_dockwidget_floatbutton")); -
594 QObject::connect(button, SIGNAL(clicked()), q, SLOT(_q_toggleTopLevel())); -
595 layout->setWidgetForRole(QDockWidgetLayout::FloatButton, button); -
596 -
597 button = new QDockWidgetTitleButton(q); -
598 button->setObjectName(QLatin1String("qt_dockwidget_closebutton")); -
599 QObject::connect(button, SIGNAL(clicked()), q, SLOT(close())); -
600 layout->setWidgetForRole(QDockWidgetLayout::CloseButton, button); -
601 -
602 resizer = new QWidgetResizeHandler(q); -
603 resizer->setMovingEnabled(false); -
604 resizer->setActive(false); -
605 -
606#ifndef QT_NO_ACTION -
607 toggleViewAction = new QAction(q); -
608 toggleViewAction->setCheckable(true); -
609 fixedWindowTitle = qt_setWindowTitle_helperHelper(q->windowTitle(), q); -
610 toggleViewAction->setText(fixedWindowTitle); -
611 QObject::connect(toggleViewAction, SIGNAL(triggered(bool)), -
612 q, SLOT(_q_toggleView(bool))); -
613#endif -
614 -
615 updateButtons(); -
616} -
617 -
618/*! -
619 Initialize \a option with the values from this QDockWidget. This method -
620 is useful for subclasses when they need a QStyleOptionDockWidget, but don't want -
621 to fill in all the information themselves. -
622 -
623 \sa QStyleOption::initFrom() -
624*/ -
625void QDockWidget::initStyleOption(QStyleOptionDockWidget *option) const -
626{ -
627 Q_D(const QDockWidget); -
628 -
629 if (!option) -
630 return; -
631 QDockWidgetLayout *dwlayout = qobject_cast<QDockWidgetLayout*>(layout()); -
632 -
633 option->initFrom(this); -
634 option->rect = dwlayout->titleArea(); -
635 option->title = d->fixedWindowTitle; -
636 option->closable = hasFeature(this, QDockWidget::DockWidgetClosable); -
637 option->movable = hasFeature(this, QDockWidget::DockWidgetMovable); -
638 option->floatable = hasFeature(this, QDockWidget::DockWidgetFloatable); -
639 -
640 QDockWidgetLayout *l = qobject_cast<QDockWidgetLayout*>(layout()); -
641 QStyleOptionDockWidgetV2 *v2 -
642 = qstyleoption_cast<QStyleOptionDockWidgetV2*>(option); -
643 if (v2 != 0) -
644 v2->verticalTitleBar = l->verticalTitleBar; -
645} -
646 -
647void QDockWidgetPrivate::_q_toggleView(bool b) -
648{ -
649 Q_Q(QDockWidget); -
650 if (b == q->isHidden()) { -
651 if (b) -
652 q->show(); -
653 else -
654 q->close(); -
655 } -
656} -
657 -
658void QDockWidgetPrivate::updateButtons() -
659{ -
660 Q_Q(QDockWidget); -
661 QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout); -
662 -
663 QStyleOptionDockWidget opt; -
664 q->initStyleOption(&opt); -
665 -
666 bool customTitleBar = dwLayout->widgetForRole(QDockWidgetLayout::TitleBar) != 0; -
667 bool nativeDeco = dwLayout->nativeWindowDeco(); -
668 bool hideButtons = nativeDeco || customTitleBar; -
669 -
670 bool canClose = hasFeature(this, QDockWidget::DockWidgetClosable); -
671 bool canFloat = hasFeature(this, QDockWidget::DockWidgetFloatable); -
672 -
673 QAbstractButton *button -
674 = qobject_cast<QAbstractButton*>(dwLayout->widgetForRole(QDockWidgetLayout::FloatButton)); -
675 button->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarNormalButton, &opt, q)); -
676 button->setVisible(canFloat && !hideButtons); -
677 -
678 button -
679 = qobject_cast <QAbstractButton*>(dwLayout->widgetForRole(QDockWidgetLayout::CloseButton)); -
680 button->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarCloseButton, &opt, q)); -
681 button->setVisible(canClose && !hideButtons); -
682 -
683 q->setAttribute(Qt::WA_ContentsPropagated, -
684 (canFloat || canClose) && !hideButtons); -
685 -
686 layout->invalidate(); -
687} -
688 -
689void QDockWidgetPrivate::_q_toggleTopLevel() -
690{ -
691 Q_Q(QDockWidget); -
692 q->setFloating(!q->isFloating()); -
693} -
694 -
695void QDockWidgetPrivate::initDrag(const QPoint &pos, bool nca) -
696{ -
697 if (state != 0) -
698 return; -
699 -
700 QMainWindow *win = qobject_cast<QMainWindow*>(parent); -
701 Q_ASSERT(win != 0); -
702 QMainWindowLayout *layout = qt_mainwindow_layout(win); -
703 Q_ASSERT(layout != 0); -
704 if (layout->pluggingWidget != 0) // the main window is animating a docking operation -
705 return; -
706 -
707 state = new QDockWidgetPrivate::DragState; -
708 state->pressPos = pos; -
709 state->dragging = false; -
710 state->widgetItem = 0; -
711 state->ownWidgetItem = false; -
712 state->nca = nca; -
713 state->ctrlDrag = false; -
714} -
715 -
716void QDockWidgetPrivate::startDrag() -
717{ -
718 Q_Q(QDockWidget); -
719 -
720 if (state == 0 || state->dragging) -
721 return; -
722 -
723 QMainWindowLayout *layout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget())); -
724 Q_ASSERT(layout != 0); -
725 -
726 state->widgetItem = layout->unplug(q); -
727 if (state->widgetItem == 0) { -
728 /* I have a QMainWindow parent, but I was never inserted with -
729 QMainWindow::addDockWidget, so the QMainWindowLayout has no -
730 widget item for me. :( I have to create it myself, and then -
731 delete it if I don't get dropped into a dock area. */ -
732 state->widgetItem = new QDockWidgetItem(q); -
733 state->ownWidgetItem = true; -
734 } -
735 -
736 if (state->ctrlDrag) -
737 layout->restore(); -
738 -
739 state->dragging = true; -
740} -
741 -
742void QDockWidgetPrivate::endDrag(bool abort) -
743{ -
744 Q_Q(QDockWidget); -
745 Q_ASSERT(state != 0); -
746 -
747 q->releaseMouse(); -
748 -
749 if (state->dragging) { -
750 QMainWindowLayout *mwLayout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget())); -
751 Q_ASSERT(mwLayout != 0); -
752 -
753 if (abort || !mwLayout->plug(state->widgetItem)) { -
754 if (hasFeature(this, QDockWidget::DockWidgetFloatable)) { -
755 if (state->ownWidgetItem) -
756 delete state->widgetItem; -
757 mwLayout->restore(); -
758 if (isXcb()) { -
759 // get rid of the X11BypassWindowManager window flag and activate the resizer -
760 Qt::WindowFlags flags = q->windowFlags(); -
761 flags &= ~Qt::X11BypassWindowManagerHint; -
762 q->setWindowFlags(flags); -
763 resizer->setActive(QWidgetResizeHandler::Resize, true); -
764 q->show(); -
765 } else { -
766 QDockWidgetLayout *myLayout -
767 = qobject_cast<QDockWidgetLayout*>(layout); -
768 resizer->setActive(QWidgetResizeHandler::Resize, -
769 myLayout->widgetForRole(QDockWidgetLayout::TitleBar) != 0); -
770 } -
771 undockedGeometry = q->geometry(); -
772 q->activateWindow(); -
773 } else { -
774 mwLayout->revert(state->widgetItem); -
775 } -
776 } -
777 } -
778 delete state; -
779 state = 0; -
780} -
781 -
782bool QDockWidgetPrivate::isAnimating() const -
783{ -
784 Q_Q(const QDockWidget); -
785 -
786 QMainWindow *mainWin = qobject_cast<QMainWindow*>(parent); -
787 if (mainWin == 0) -
788 return false; -
789 -
790 QMainWindowLayout *mainWinLayout = qt_mainwindow_layout(mainWin); -
791 if (mainWinLayout == 0) -
792 return false; -
793 -
794 return (void*)mainWinLayout->pluggingWidget == (void*)q; -
795} -
796 -
797bool QDockWidgetPrivate::mousePressEvent(QMouseEvent *event) -
798{ -
799#if !defined(QT_NO_MAINWINDOW) -
800 Q_Q(QDockWidget); -
801 -
802 QDockWidgetLayout *dwLayout -
803 = qobject_cast<QDockWidgetLayout*>(layout); -
804 -
805 if (!dwLayout->nativeWindowDeco()) { -
806 QRect titleArea = dwLayout->titleArea(); -
807 -
808 if (event->button() != Qt::LeftButton || -
809 !titleArea.contains(event->pos()) || -
810 // check if the tool window is movable... do nothing if it -
811 // is not (but allow moving if the window is floating) -
812 (!hasFeature(this, QDockWidget::DockWidgetMovable) && !q->isFloating()) || -
813 qobject_cast<QMainWindow*>(parent) == 0 || -
814 isAnimating() || state != 0) { -
815 return false; -
816 } -
817 -
818 initDrag(event->pos(), false); -
819 -
820 if (state) -
821 state->ctrlDrag = hasFeature(this, QDockWidget::DockWidgetFloatable) && event->modifiers() & Qt::ControlModifier; -
822 -
823 return true; -
824 } -
825 -
826#endif // !defined(QT_NO_MAINWINDOW) -
827 return false; -
828} -
829 -
830bool QDockWidgetPrivate::mouseDoubleClickEvent(QMouseEvent *event) -
831{ -
832 QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout); -
833 -
834 if (!dwLayout->nativeWindowDeco()) { -
835 QRect titleArea = dwLayout->titleArea(); -
836 -
837 if (event->button() == Qt::LeftButton && titleArea.contains(event->pos()) && -
838 hasFeature(this, QDockWidget::DockWidgetFloatable)) { -
839 _q_toggleTopLevel(); -
840 return true; -
841 } -
842 } -
843 return false; -
844} -
845 -
846bool QDockWidgetPrivate::mouseMoveEvent(QMouseEvent *event) -
847{ -
848 bool ret = false; -
849#if !defined(QT_NO_MAINWINDOW) -
850 Q_Q(QDockWidget); -
851 -
852 if (!state) -
853 return ret; -
854 -
855 QDockWidgetLayout *dwlayout -
856 = qobject_cast<QDockWidgetLayout *>(layout); -
857 QMainWindowLayout *mwlayout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget())); -
858 if (!dwlayout->nativeWindowDeco()) { -
859 if (!state->dragging -
860 && mwlayout->pluggingWidget == 0 -
861 && (event->pos() - state->pressPos).manhattanLength() -
862 > QApplication::startDragDistance()) { -
863 startDrag(); -
864#ifdef Q_WS_WIN -
865 grabMouseWhileInWindow(); -
866#else -
867 q->grabMouse(); -
868#endif -
869 ret = true; -
870 } -
871 } -
872 -
873 if (state->dragging && !state->nca) { -
874 QPoint pos = event->globalPos() - state->pressPos; -
875 q->move(pos); -
876 -
877 if (!state->ctrlDrag) -
878 mwlayout->hover(state->widgetItem, event->globalPos()); -
879 -
880 ret = true; -
881 } -
882 -
883#endif // !defined(QT_NO_MAINWINDOW) -
884 return ret; -
885} -
886 -
887bool QDockWidgetPrivate::mouseReleaseEvent(QMouseEvent *event) -
888{ -
889#if !defined(QT_NO_MAINWINDOW) -
890 -
891 if (event->button() == Qt::LeftButton && state && !state->nca) { -
892 endDrag(); -
893 return true; //filter out the event -
894 } -
895 -
896#endif // !defined(QT_NO_MAINWINDOW) -
897 return false; -
898} -
899 -
900void QDockWidgetPrivate::nonClientAreaMouseEvent(QMouseEvent *event) -
901{ -
902 Q_Q(QDockWidget); -
903 -
904 int fw = q->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, q); -
905 -
906 QRect geo = q->geometry(); -
907 QRect titleRect = q->frameGeometry(); -
908#ifdef Q_WS_MAC -
909 if ((features & QDockWidget::DockWidgetVerticalTitleBar)) { -
910 titleRect.setTop(geo.top()); -
911 titleRect.setBottom(geo.bottom()); -
912 titleRect.setRight(geo.left() - 1); -
913 } else -
914#endif -
915 { -
916 titleRect.setLeft(geo.left()); -
917 titleRect.setRight(geo.right()); -
918 titleRect.setBottom(geo.top() - 1); -
919 titleRect.adjust(0, fw, 0, 0); -
920 } -
921 -
922 switch (event->type()) { -
923 case QEvent::NonClientAreaMouseButtonPress: -
924 if (!titleRect.contains(event->globalPos())) -
925 break; -
926 if (state != 0) -
927 break; -
928 if (qobject_cast<QMainWindow*>(parent) == 0) -
929 break; -
930 if (isAnimating()) -
931 break; -
932 initDrag(event->pos(), true); -
933 if (state == 0) -
934 break; -
935#ifdef Q_WS_WIN -
936 // On Windows, NCA mouse events don't contain modifier info -
937 state->ctrlDrag = GetKeyState(VK_CONTROL) & 0x8000; -
938#else -
939 state->ctrlDrag = event->modifiers() & Qt::ControlModifier; -
940#endif -
941 startDrag(); -
942 break; -
943 case QEvent::NonClientAreaMouseMove: -
944 if (state == 0 || !state->dragging) -
945 break; -
946 -
947#ifndef Q_OS_MAC -
948 if (state->nca) { -
949 endDrag(); -
950 } -
951#endif -
952 break; -
953 case QEvent::NonClientAreaMouseButtonRelease: -
954#ifdef Q_OS_MAC -
955 if (state) -
956 endDrag(); -
957#endif -
958 break; -
959 case QEvent::NonClientAreaMouseButtonDblClick: -
960 _q_toggleTopLevel(); -
961 break; -
962 default: -
963 break; -
964 } -
965} -
966 -
967void QDockWidgetPrivate::moveEvent(QMoveEvent *event) -
968{ -
969 Q_Q(QDockWidget); -
970 -
971 if (state == 0 || !state->dragging || !state->nca || !q->isWindow()) -
972 return; -
973 -
974 // When the native window frame is being dragged, all we get is these mouse -
975 // move events. -
976 -
977 if (state->ctrlDrag) -
978 return; -
979 -
980 QMainWindowLayout *layout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget())); -
981 Q_ASSERT(layout != 0); -
982 -
983 QPoint globalMousePos = event->pos() + state->pressPos; -
984 layout->hover(state->widgetItem, globalMousePos); -
985} -
986 -
987void QDockWidgetPrivate::unplug(const QRect &rect) -
988{ -
989 Q_Q(QDockWidget); -
990 QRect r = rect; -
991 r.moveTopLeft(q->mapToGlobal(QPoint(0, 0))); -
992 QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout); -
993 if (dwLayout->nativeWindowDeco(true)) -
994 r.adjust(0, dwLayout->titleHeight(), 0, 0); -
995 setWindowState(true, true, r); -
996} -
997 -
998void QDockWidgetPrivate::plug(const QRect &rect) -
999{ -
1000 setWindowState(false, false, rect); -
1001} -
1002 -
1003static void setFrameStrutEventsEnabled(const QWidget *w, bool enabled) -
1004{ -
1005 if (const QWindow *window = w->windowHandle())
never evaluated: const QWindow *window = w->windowHandle()
0
1006 if (QPlatformWindow *platformWindow = window->handle())
never evaluated: QPlatformWindow *platformWindow = window->handle()
0
1007 if (platformWindow->frameStrutEventsEnabled() != enabled)
never evaluated: platformWindow->frameStrutEventsEnabled() != enabled
0
1008 platformWindow->setFrameStrutEventsEnabled(enabled);
never executed: platformWindow->setFrameStrutEventsEnabled(enabled);
0
1009}
never executed: }
0
1010 -
1011void QDockWidgetPrivate::setWindowState(bool floating, bool unplug, const QRect &rect) -
1012{ -
1013 Q_Q(QDockWidget);
executed (the execution status of this line is deduced): QDockWidget * const q = q_func();
-
1014 -
1015 if (!floating && parent) {
evaluated: !floating
TRUEFALSE
yes
Evaluation Count:10
yes
Evaluation Count:13
evaluated: parent
TRUEFALSE
yes
Evaluation Count:9
yes
Evaluation Count:1
1-13
1016 QMainWindowLayout *mwlayout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget()));
executed (the execution status of this line is deduced): QMainWindowLayout *mwlayout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget()));
-
1017 if (mwlayout && mwlayout->dockWidgetArea(q) == Qt::NoDockWidgetArea)
partially evaluated: mwlayout
TRUEFALSE
yes
Evaluation Count:9
no
Evaluation Count:0
evaluated: mwlayout->dockWidgetArea(q) == Qt::NoDockWidgetArea
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:8
0-9
1018 return; // this dockwidget can't be redocked
executed: return;
Execution Count:1
1
1019 }
executed: }
Execution Count:8
8
1020 -
1021 bool wasFloating = q->isFloating();
executed (the execution status of this line is deduced): bool wasFloating = q->isFloating();
-
1022 bool hidden = q->isHidden();
executed (the execution status of this line is deduced): bool hidden = q->isHidden();
-
1023 -
1024 if (q->isVisible())
evaluated: q->isVisible()
TRUEFALSE
yes
Evaluation Count:14
yes
Evaluation Count:8
8-14
1025 q->hide();
executed: q->hide();
Execution Count:14
14
1026 -
1027 Qt::WindowFlags flags = floating ? Qt::Tool : Qt::Widget;
evaluated: floating
TRUEFALSE
yes
Evaluation Count:13
yes
Evaluation Count:9
9-13
1028 -
1029 QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout);
executed (the execution status of this line is deduced): QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout);
-
1030 const bool nativeDeco = dwLayout->nativeWindowDeco(floating);
executed (the execution status of this line is deduced): const bool nativeDeco = dwLayout->nativeWindowDeco(floating);
-
1031 -
1032 if (nativeDeco) {
partially evaluated: nativeDeco
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:22
0-22
1033 flags |= Qt::CustomizeWindowHint | Qt::WindowTitleHint;
never executed (the execution status of this line is deduced): flags |= Qt::CustomizeWindowHint | Qt::WindowTitleHint;
-
1034 if (hasFeature(this, QDockWidget::DockWidgetClosable))
never evaluated: hasFeature(this, QDockWidget::DockWidgetClosable)
0
1035 flags |= Qt::WindowCloseButtonHint;
never executed: flags |= Qt::WindowCloseButtonHint;
0
1036 } else {
never executed: }
0
1037 flags |= Qt::FramelessWindowHint;
executed (the execution status of this line is deduced): flags |= Qt::FramelessWindowHint;
-
1038 }
executed: }
Execution Count:22
22
1039 -
1040 if (unplug)
evaluated: unplug
TRUEFALSE
yes
Evaluation Count:3
yes
Evaluation Count:19
3-19
1041 flags |= Qt::X11BypassWindowManagerHint;
executed: flags |= Qt::X11BypassWindowManagerHint;
Execution Count:3
3
1042 -
1043 q->setWindowFlags(flags);
executed (the execution status of this line is deduced): q->setWindowFlags(flags);
-
1044 -
1045 -
1046 if (!rect.isNull())
evaluated: !rect.isNull()
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:21
1-21
1047 q->setGeometry(rect);
executed: q->setGeometry(rect);
Execution Count:1
1
1048 -
1049 updateButtons();
executed (the execution status of this line is deduced): updateButtons();
-
1050 -
1051 if (!hidden)
evaluated: !hidden
TRUEFALSE
yes
Evaluation Count:17
yes
Evaluation Count:5
5-17
1052 q->show();
executed: q->show();
Execution Count:17
17
1053 -
1054 if (floating != wasFloating) {
evaluated: floating != wasFloating
TRUEFALSE
yes
Evaluation Count:14
yes
Evaluation Count:8
8-14
1055 emit q->topLevelChanged(floating);
executed (the execution status of this line is deduced): q->topLevelChanged(floating);
-
1056 if (!floating && parent) {
evaluated: !floating
TRUEFALSE
yes
Evaluation Count:6
yes
Evaluation Count:8
evaluated: parent
TRUEFALSE
yes
Evaluation Count:5
yes
Evaluation Count:1
1-8
1057 QMainWindowLayout *mwlayout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget()));
executed (the execution status of this line is deduced): QMainWindowLayout *mwlayout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget()));
-
1058 if (mwlayout)
partially evaluated: mwlayout
TRUEFALSE
yes
Evaluation Count:5
no
Evaluation Count:0
0-5
1059 emit q->dockLocationChanged(mwlayout->dockWidgetArea(q));
executed: q->dockLocationChanged(mwlayout->dockWidgetArea(q));
Execution Count:5
5
1060 }
executed: }
Execution Count:5
5
1061 }
executed: }
Execution Count:14
14
1062 -
1063 if (floating && nativeDeco)
evaluated: floating
TRUEFALSE
yes
Evaluation Count:13
yes
Evaluation Count:9
partially evaluated: nativeDeco
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:13
0-13
1064 if (const QWindow *window = q->windowHandle())0
if (QPlatformWindow *platformWindow = window->handle())
platformWindow->setFrameStrutEventsEnabled(q, true);
never executed: setFrameStrutEventsEnabled(q, true);
1065 -
1066 resizer->setActive(QWidgetResizeHandler::Resize, !unplug && floating && !nativeDeco);
executed (the execution status of this line is deduced): resizer->setActive(QWidgetResizeHandler::Resize, !unplug && floating && !nativeDeco);
-
1067}
executed: }
Execution Count:22
22
1068 -
1069/*! -
1070 \class QDockWidget -
1071 -
1072 \brief The QDockWidget class provides a widget that can be docked -
1073 inside a QMainWindow or floated as a top-level window on the -
1074 desktop. -
1075 -
1076 \ingroup mainwindow-classes -
1077 \inmodule QtWidgets -
1078 -
1079 QDockWidget provides the concept of dock widgets, also know as -
1080 tool palettes or utility windows. Dock windows are secondary -
1081 windows placed in the \e {dock widget area} around the -
1082 \l{QMainWindow::centralWidget()}{central widget} in a -
1083 QMainWindow. -
1084 -
1085 \image mainwindow-docks.png -
1086 -
1087 Dock windows can be moved inside their current area, moved into -
1088 new areas and floated (e.g., undocked) by the end-user. The -
1089 QDockWidget API allows the programmer to restrict the dock widgets -
1090 ability to move, float and close, as well as the areas in which -
1091 they can be placed. -
1092 -
1093 \section1 Appearance -
1094 -
1095 A QDockWidget consists of a title bar and the content area. The -
1096 title bar displays the dock widgets -
1097 \l{QWidget::windowTitle()}{window title}, -
1098 a \e float button and a \e close button. -
1099 Depending on the state of the QDockWidget, the \e float and \e -
1100 close buttons may be either disabled or not shown at all. -
1101 -
1102 The visual appearance of the title bar and buttons is dependent -
1103 on the \l{QStyle}{style} in use. -
1104 -
1105 A QDockWidget acts as a wrapper for its child widget, set with setWidget(). -
1106 Custom size hints, minimum and maximum sizes and size policies should be -
1107 implemented in the child widget. QDockWidget will respect them, adjusting -
1108 its own constraints to include the frame and title. Size constraints -
1109 should not be set on the QDockWidget itself, because they change depending -
1110 on whether it is docked; a docked QDockWidget has no frame and a smaller title -
1111 bar. -
1112 -
1113 \sa QMainWindow, {Dock Widgets Example} -
1114*/ -
1115 -
1116/*! -
1117 \enum QDockWidget::DockWidgetFeature -
1118 -
1119 \value DockWidgetClosable The dock widget can be closed. On some systems the dock -
1120 widget always has a close button when it's floating -
1121 (for example on MacOS 10.5). -
1122 \value DockWidgetMovable The dock widget can be moved between docks -
1123 by the user. -
1124 \value DockWidgetFloatable The dock widget can be detached from the -
1125 main window, and floated as an independent -
1126 window. -
1127 \value DockWidgetVerticalTitleBar The dock widget displays a vertical title -
1128 bar on its left side. This can be used to -
1129 increase the amount of vertical space in -
1130 a QMainWindow. -
1131 \value AllDockWidgetFeatures (Deprecated) The dock widget can be closed, moved, -
1132 and floated. Since new features might be added in future -
1133 releases, the look and behavior of dock widgets might -
1134 change if you use this flag. Please specify individual -
1135 flags instead. -
1136 \value NoDockWidgetFeatures The dock widget cannot be closed, moved, -
1137 or floated. -
1138 -
1139 \omitvalue DockWidgetFeatureMask -
1140 \omitvalue Reserved -
1141*/ -
1142 -
1143/*! -
1144 \property QDockWidget::windowTitle -
1145 \brief the dock widget title (caption) -
1146 -
1147 By default, this property contains an empty string. -
1148*/ -
1149 -
1150/*! -
1151 Constructs a QDockWidget with parent \a parent and window flags \a -
1152 flags. The dock widget will be placed in the left dock widget -
1153 area. -
1154*/ -
1155QDockWidget::QDockWidget(QWidget *parent, Qt::WindowFlags flags) -
1156 : QWidget(*new QDockWidgetPrivate, parent, flags) -
1157{ -
1158 Q_D(QDockWidget); -
1159 d->init(); -
1160} -
1161 -
1162/*! -
1163 Constructs a QDockWidget with parent \a parent and window flags \a -
1164 flags. The dock widget will be placed in the left dock widget -
1165 area. -
1166 -
1167 The window title is set to \a title. This title is used when the -
1168 QDockWidget is docked and undocked. It is also used in the context -
1169 menu provided by QMainWindow. -
1170 -
1171 \sa setWindowTitle() -
1172*/ -
1173QDockWidget::QDockWidget(const QString &title, QWidget *parent, Qt::WindowFlags flags) -
1174 : QWidget(*new QDockWidgetPrivate, parent, flags) -
1175{ -
1176 Q_D(QDockWidget); -
1177 d->init(); -
1178 setWindowTitle(title); -
1179} -
1180 -
1181/*! -
1182 Destroys the dock widget. -
1183*/ -
1184QDockWidget::~QDockWidget() -
1185{ } -
1186 -
1187/*! -
1188 Returns the widget for the dock widget. This function returns zero -
1189 if the widget has not been set. -
1190 -
1191 \sa setWidget() -
1192*/ -
1193QWidget *QDockWidget::widget() const -
1194{ -
1195 QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(this->layout()); -
1196 return layout->widgetForRole(QDockWidgetLayout::Content); -
1197} -
1198 -
1199/*! -
1200 Sets the widget for the dock widget to \a widget. -
1201 -
1202 If the dock widget is visible when \a widget is added, you must -
1203 \l{QWidget::}{show()} it explicitly. -
1204 -
1205 Note that you must add the layout of the \a widget before you call -
1206 this function; if not, the \a widget will not be visible. -
1207 -
1208 \sa widget() -
1209*/ -
1210void QDockWidget::setWidget(QWidget *widget) -
1211{ -
1212 QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(this->layout()); -
1213 layout->setWidgetForRole(QDockWidgetLayout::Content, widget); -
1214} -
1215 -
1216/*! -
1217 \property QDockWidget::features -
1218 \brief whether the dock widget is movable, closable, and floatable -
1219 -
1220 By default, this property is set to a combination of DockWidgetClosable, -
1221 DockWidgetMovable and DockWidgetFloatable. -
1222 -
1223 \sa DockWidgetFeature -
1224*/ -
1225 -
1226void QDockWidget::setFeatures(QDockWidget::DockWidgetFeatures features) -
1227{ -
1228 Q_D(QDockWidget); -
1229 features &= DockWidgetFeatureMask; -
1230 if (d->features == features) -
1231 return; -
1232 const bool closableChanged = (d->features ^ features) & DockWidgetClosable; -
1233 d->features = features; -
1234 QDockWidgetLayout *layout -
1235 = qobject_cast<QDockWidgetLayout*>(this->layout()); -
1236 layout->setVerticalTitleBar(features & DockWidgetVerticalTitleBar); -
1237 d->updateButtons(); -
1238 d->toggleViewAction->setEnabled((d->features & DockWidgetClosable) == DockWidgetClosable); -
1239 emit featuresChanged(d->features); -
1240 update(); -
1241 if (closableChanged && layout->nativeWindowDeco()) { -
1242 //this ensures the native decoration is drawn -
1243 d->setWindowState(true /*floating*/, true /*unplug*/); -
1244 } -
1245} -
1246 -
1247QDockWidget::DockWidgetFeatures QDockWidget::features() const -
1248{ -
1249 Q_D(const QDockWidget); -
1250 return d->features; -
1251} -
1252 -
1253/*! -
1254 \property QDockWidget::floating -
1255 \brief whether the dock widget is floating -
1256 -
1257 A floating dock widget is presented to the user as an independent -
1258 window "on top" of its parent QMainWindow, instead of being -
1259 docked in the QMainWindow. -
1260 -
1261 By default, this property is true. -
1262 -
1263 \sa isWindow() -
1264*/ -
1265void QDockWidget::setFloating(bool floating) -
1266{ -
1267 Q_D(QDockWidget); -
1268 -
1269 // the initial click of a double-click may have started a drag... -
1270 if (d->state != 0) -
1271 d->endDrag(true); -
1272 -
1273 QRect r = d->undockedGeometry; -
1274 -
1275 d->setWindowState(floating, false, floating ? r : QRect()); -
1276 -
1277 if (floating && r.isNull()) { -
1278 if (x() < 0 || y() < 0) //may happen if we have been hidden -
1279 move(QPoint()); -
1280 setAttribute(Qt::WA_Moved, false); //we want it at the default position -
1281 } -
1282} -
1283 -
1284/*! -
1285 \property QDockWidget::allowedAreas -
1286 \brief areas where the dock widget may be placed -
1287 -
1288 The default is Qt::AllDockWidgetAreas. -
1289 -
1290 \sa Qt::DockWidgetArea -
1291*/ -
1292 -
1293void QDockWidget::setAllowedAreas(Qt::DockWidgetAreas areas) -
1294{ -
1295 Q_D(QDockWidget); -
1296 areas &= Qt::DockWidgetArea_Mask; -
1297 if (areas == d->allowedAreas) -
1298 return; -
1299 d->allowedAreas = areas; -
1300 emit allowedAreasChanged(d->allowedAreas); -
1301} -
1302 -
1303Qt::DockWidgetAreas QDockWidget::allowedAreas() const -
1304{ -
1305 Q_D(const QDockWidget); -
1306 return d->allowedAreas; -
1307} -
1308 -
1309/*! -
1310 \fn bool QDockWidget::isAreaAllowed(Qt::DockWidgetArea area) const -
1311 -
1312 Returns true if this dock widget can be placed in the given \a area; -
1313 otherwise returns false. -
1314*/ -
1315 -
1316/*! \reimp */ -
1317void QDockWidget::changeEvent(QEvent *event) -
1318{ -
1319 Q_D(QDockWidget); -
1320 QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(this->layout()); -
1321 -
1322 switch (event->type()) { -
1323 case QEvent::ModifiedChange: -
1324 case QEvent::WindowTitleChange: -
1325 update(layout->titleArea()); -
1326#ifndef QT_NO_ACTION -
1327 d->fixedWindowTitle = qt_setWindowTitle_helperHelper(windowTitle(), this); -
1328 d->toggleViewAction->setText(d->fixedWindowTitle); -
1329#endif -
1330#ifndef QT_NO_TABBAR -
1331 { -
1332 QMainWindow *win = qobject_cast<QMainWindow*>(parentWidget()); -
1333 if (QMainWindowLayout *winLayout = qt_mainwindow_layout(win)) { -
1334 if (QDockAreaLayoutInfo *info = winLayout->layoutState.dockAreaLayout.info(this)) -
1335 info->updateTabBar(); -
1336 } -
1337 } -
1338#endif // QT_NO_TABBAR -
1339 break; -
1340 default: -
1341 break; -
1342 } -
1343 QWidget::changeEvent(event); -
1344} -
1345 -
1346/*! \reimp */ -
1347void QDockWidget::closeEvent(QCloseEvent *event) -
1348{ -
1349 Q_D(QDockWidget); -
1350 if (d->state) -
1351 d->endDrag(true); -
1352 QWidget::closeEvent(event); -
1353} -
1354 -
1355/*! \reimp */ -
1356void QDockWidget::paintEvent(QPaintEvent *event) -
1357{ -
1358 Q_UNUSED(event) -
1359 -
1360 QDockWidgetLayout *layout -
1361 = qobject_cast<QDockWidgetLayout*>(this->layout()); -
1362 bool customTitleBar = layout->widgetForRole(QDockWidgetLayout::TitleBar) != 0; -
1363 bool nativeDeco = layout->nativeWindowDeco(); -
1364 -
1365 if (!nativeDeco && !customTitleBar) { -
1366 QStylePainter p(this); -
1367 // ### Add PixelMetric to change spacers, so style may show border -
1368 // when not floating. -
1369 if (isFloating()) { -
1370 QStyleOptionFrame framOpt; -
1371 framOpt.init(this); -
1372 p.drawPrimitive(QStyle::PE_FrameDockWidget, framOpt); -
1373 } -
1374 -
1375 // Title must be painted after the frame, since the areas overlap, and -
1376 // the title may wish to extend out to all sides (eg. XP style) -
1377 QStyleOptionDockWidgetV2 titleOpt; -
1378 initStyleOption(&titleOpt); -
1379 p.drawControl(QStyle::CE_DockWidgetTitle, titleOpt); -
1380 } -
1381} -
1382 -
1383/*! \reimp */ -
1384bool QDockWidget::event(QEvent *event) -
1385{ -
1386 Q_D(QDockWidget);
executed (the execution status of this line is deduced): QDockWidgetPrivate * const d = d_func();
-
1387 -
1388 QMainWindow *win = qobject_cast<QMainWindow*>(parentWidget());
executed (the execution status of this line is deduced): QMainWindow *win = qobject_cast<QMainWindow*>(parentWidget());
-
1389 QMainWindowLayout *layout = qt_mainwindow_layout(win);
executed (the execution status of this line is deduced): QMainWindowLayout *layout = qt_mainwindow_layout(win);
-
1390 -
1391 switch (event->type()) { -
1392#ifndef QT_NO_ACTION -
1393 case QEvent::Hide: -
1394 if (layout != 0)
evaluated: layout != 0
TRUEFALSE
yes
Evaluation Count:15
yes
Evaluation Count:4
4-15
1395 layout->keepSize(this);
executed: layout->keepSize(this);
Execution Count:15
15
1396 d->toggleViewAction->setChecked(false);
executed (the execution status of this line is deduced): d->toggleViewAction->setChecked(false);
-
1397 emit visibilityChanged(false);
executed (the execution status of this line is deduced): visibilityChanged(false);
-
1398 break;
executed: break;
Execution Count:19
19
1399 case QEvent::Show: -
1400 if (static_cast<QDockWidgetLayout *>(QDockWidget::layout())->nativeWindowDeco(isFloating()))
partially evaluated: static_cast<QDockWidgetLayout *>(QDockWidget::layout())->nativeWindowDeco(isFloating())
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:34
0-34
1401 setFrameStrutEventsEnabled(this, true);
never executed: setFrameStrutEventsEnabled(this, true);
0
1402 d->toggleViewAction->setChecked(true);
executed (the execution status of this line is deduced): d->toggleViewAction->setChecked(true);
-
1403 emit visibilityChanged(geometry().right() >= 0 && geometry().bottom() >= 0);
executed (the execution status of this line is deduced): visibilityChanged(geometry().right() >= 0 && geometry().bottom() >= 0);
-
1404 break;
executed: break;
Execution Count:34
34
1405#endif -
1406 case QEvent::ApplicationLayoutDirectionChange: -
1407 case QEvent::LayoutDirectionChange: -
1408 case QEvent::StyleChange: -
1409 case QEvent::ParentChange: -
1410 d->updateButtons();
executed (the execution status of this line is deduced): d->updateButtons();
-
1411 break;
executed: break;
Execution Count:15
15
1412 case QEvent::ZOrderChange: { -
1413 bool onTop = false;
executed (the execution status of this line is deduced): bool onTop = false;
-
1414 if (win != 0) {
evaluated: win != 0
TRUEFALSE
yes
Evaluation Count:18
yes
Evaluation Count:3
3-18
1415 const QObjectList &siblings = win->children();
executed (the execution status of this line is deduced): const QObjectList &siblings = win->children();
-
1416 onTop = siblings.count() > 0 && siblings.last() == (QObject*)this;
partially evaluated: siblings.count() > 0
TRUEFALSE
yes
Evaluation Count:18
no
Evaluation Count:0
evaluated: siblings.last() == (QObject*)this
TRUEFALSE
yes
Evaluation Count:11
yes
Evaluation Count:7
0-18
1417 }
executed: }
Execution Count:18
18
1418 if (!isFloating() && layout != 0 && onTop)
evaluated: !isFloating()
TRUEFALSE
yes
Evaluation Count:9
yes
Evaluation Count:12
partially evaluated: layout != 0
TRUEFALSE
yes
Evaluation Count:9
no
Evaluation Count:0
evaluated: onTop
TRUEFALSE
yes
Evaluation Count:4
yes
Evaluation Count:5
0-12
1419 layout->raise(this);
executed: layout->raise(this);
Execution Count:4
4
1420 break;
executed: break;
Execution Count:21
21
1421 } -
1422 case QEvent::WindowActivate: -
1423 case QEvent::WindowDeactivate: -
1424 update(qobject_cast<QDockWidgetLayout *>(this->layout())->titleArea());
executed (the execution status of this line is deduced): update(qobject_cast<QDockWidgetLayout *>(this->layout())->titleArea());
-
1425 break;
executed: break;
Execution Count:18
18
1426 case QEvent::ContextMenu: -
1427 if (d->state) {
never evaluated: d->state
0
1428 event->accept();
never executed (the execution status of this line is deduced): event->accept();
-
1429 return true;
never executed: return true;
0
1430 } -
1431 break;
never executed: break;
0
1432 // return true after calling the handler since we don't want -
1433 // them to be passed onto the default handlers -
1434 case QEvent::MouseButtonPress: -
1435 if (d->mousePressEvent(static_cast<QMouseEvent *>(event)))
never evaluated: d->mousePressEvent(static_cast<QMouseEvent *>(event))
0
1436 return true;
never executed: return true;
0
1437 break;
never executed: break;
0
1438 case QEvent::MouseButtonDblClick: -
1439 if (d->mouseDoubleClickEvent(static_cast<QMouseEvent *>(event)))
never evaluated: d->mouseDoubleClickEvent(static_cast<QMouseEvent *>(event))
0
1440 return true;
never executed: return true;
0
1441 break;
never executed: break;
0
1442 case QEvent::MouseMove: -
1443 if (d->mouseMoveEvent(static_cast<QMouseEvent *>(event)))
never evaluated: d->mouseMoveEvent(static_cast<QMouseEvent *>(event))
0
1444 return true;
never executed: return true;
0
1445 break;
never executed: break;
0
1446#ifdef Q_WS_WIN -
1447 case QEvent::Leave: -
1448 if (d->state != 0 && d->state->dragging && !d->state->nca) { -
1449 // This is a workaround for loosing the mouse on Vista. -
1450 QPoint pos = QCursor::pos(); -
1451 QMouseEvent fake(QEvent::MouseMove, mapFromGlobal(pos), pos, Qt::NoButton, -
1452 QApplication::mouseButtons(), QApplication::keyboardModifiers()); -
1453 d->mouseMoveEvent(&fake); -
1454 } -
1455 break; -
1456#endif -
1457 case QEvent::MouseButtonRelease: -
1458 if (d->mouseReleaseEvent(static_cast<QMouseEvent *>(event)))
never evaluated: d->mouseReleaseEvent(static_cast<QMouseEvent *>(event))
0
1459 return true;
never executed: return true;
0
1460 break;
never executed: break;
0
1461 case QEvent::NonClientAreaMouseMove: -
1462 case QEvent::NonClientAreaMouseButtonPress: -
1463 case QEvent::NonClientAreaMouseButtonRelease: -
1464 case QEvent::NonClientAreaMouseButtonDblClick: -
1465 d->nonClientAreaMouseEvent(static_cast<QMouseEvent*>(event));
executed (the execution status of this line is deduced): d->nonClientAreaMouseEvent(static_cast<QMouseEvent*>(event));
-
1466 return true;
executed: return true;
Execution Count:2
2
1467 case QEvent::Move: -
1468 d->moveEvent(static_cast<QMoveEvent*>(event));
executed (the execution status of this line is deduced): d->moveEvent(static_cast<QMoveEvent*>(event));
-
1469 break;
executed: break;
Execution Count:37
37
1470 case QEvent::Resize: -
1471 // if the mainwindow is plugging us, we don't want to update undocked geometry -
1472 if (isFloating() && layout != 0 && layout->pluggingWidget != this)
evaluated: isFloating()
TRUEFALSE
yes
Evaluation Count:15
yes
Evaluation Count:20
evaluated: layout != 0
TRUEFALSE
yes
Evaluation Count:8
yes
Evaluation Count:7
partially evaluated: layout->pluggingWidget != this
TRUEFALSE
yes
Evaluation Count:8
no
Evaluation Count:0
0-20
1473 d->undockedGeometry = geometry();
executed: d->undockedGeometry = geometry();
Execution Count:8
8
1474 break;
executed: break;
Execution Count:35
35
1475 default: -
1476 break;
executed: break;
Execution Count:671
671
1477 } -
1478 return QWidget::event(event);
executed: return QWidget::event(event);
Execution Count:850
850
1479} -
1480 -
1481#ifndef QT_NO_ACTION -
1482/*! -
1483 Returns a checkable action that can be used to show or close this -
1484 dock widget. -
1485 -
1486 The action's text is set to the dock widget's window title. -
1487 -
1488 \sa QAction::text, QWidget::windowTitle -
1489 */ -
1490QAction * QDockWidget::toggleViewAction() const -
1491{ -
1492 Q_D(const QDockWidget); -
1493 return d->toggleViewAction; -
1494} -
1495#endif // QT_NO_ACTION -
1496 -
1497/*! -
1498 \fn void QDockWidget::featuresChanged(QDockWidget::DockWidgetFeatures features) -
1499 -
1500 This signal is emitted when the \l features property changes. The -
1501 \a features parameter gives the new value of the property. -
1502*/ -
1503 -
1504/*! -
1505 \fn void QDockWidget::topLevelChanged(bool topLevel) -
1506 -
1507 This signal is emitted when the \l floating property changes. -
1508 The \a topLevel parameter is true if the dock widget is now floating; -
1509 otherwise it is false. -
1510 -
1511 \sa isWindow() -
1512*/ -
1513 -
1514/*! -
1515 \fn void QDockWidget::allowedAreasChanged(Qt::DockWidgetAreas allowedAreas) -
1516 -
1517 This signal is emitted when the \l allowedAreas property changes. The -
1518 \a allowedAreas parameter gives the new value of the property. -
1519*/ -
1520 -
1521/*! -
1522 \fn void QDockWidget::visibilityChanged(bool visible) -
1523 \since 4.3 -
1524 -
1525 This signal is emitted when the dock widget becomes \a visible (or -
1526 invisible). This happens when the widget is hidden or shown, as -
1527 well as when it is docked in a tabbed dock area and its tab -
1528 becomes selected or unselected. -
1529*/ -
1530 -
1531/*! -
1532 \fn void QDockWidget::dockLocationChanged(Qt::DockWidgetArea area) -
1533 \since 4.3 -
1534 -
1535 This signal is emitted when the dock widget is moved to another -
1536 dock \a area, or is moved to a different location in its current -
1537 dock area. This happens when the dock widget is moved -
1538 programmatically or is dragged to a new location by the user. -
1539*/ -
1540 -
1541/*! -
1542 \since 4.3 -
1543 -
1544 Sets an arbitrary \a widget as the dock widget's title bar. If \a widget -
1545 is 0, any custom title bar widget previously set on the dock widget is -
1546 removed, but not deleted, and the default title bar will be used -
1547 instead. -
1548 -
1549 If a title bar widget is set, QDockWidget will not use native window -
1550 decorations when it is floated. -
1551 -
1552 Here are some tips for implementing custom title bars: -
1553 -
1554 \list -
1555 \li Mouse events that are not explicitly handled by the title bar widget -
1556 must be ignored by calling QMouseEvent::ignore(). These events then -
1557 propagate to the QDockWidget parent, which handles them in the usual -
1558 manner, moving when the title bar is dragged, docking and undocking -
1559 when it is double-clicked, etc. -
1560 -
1561 \li When DockWidgetVerticalTitleBar is set on QDockWidget, the title -
1562 bar widget is repositioned accordingly. In resizeEvent(), the title -
1563 bar should check what orientation it should assume: -
1564 \snippet code/src_gui_widgets_qdockwidget.cpp 0 -
1565 -
1566 \li The title bar widget must have a valid QWidget::sizeHint() and -
1567 QWidget::minimumSizeHint(). These functions should take into account -
1568 the current orientation of the title bar. -
1569 -
1570 \li It is not possible to remove a title bar from a dock widget. However, -
1571 a similar effect can be achieved by setting a default constructed -
1572 QWidget as the title bar widget. -
1573 \endlist -
1574 -
1575 Using qobject_cast() as shown above, the title bar widget has full access -
1576 to its parent QDockWidget. Hence it can perform such operations as docking -
1577 and hiding in response to user actions. -
1578 -
1579 \sa titleBarWidget(), DockWidgetVerticalTitleBar -
1580*/ -
1581 -
1582void QDockWidget::setTitleBarWidget(QWidget *widget) -
1583{ -
1584 Q_D(QDockWidget); -
1585 QDockWidgetLayout *layout -
1586 = qobject_cast<QDockWidgetLayout*>(this->layout()); -
1587 layout->setWidgetForRole(QDockWidgetLayout::TitleBar, widget); -
1588 d->updateButtons(); -
1589 if (isWindow()) { -
1590 //this ensures the native decoration is drawn -
1591 d->setWindowState(true /*floating*/, true /*unplug*/); -
1592 } -
1593} -
1594 -
1595/*! -
1596 \since 4.3 -
1597 Returns the custom title bar widget set on the QDockWidget, or 0 if no -
1598 custom title bar has been set. -
1599 -
1600 \sa setTitleBarWidget() -
1601*/ -
1602 -
1603QWidget *QDockWidget::titleBarWidget() const -
1604{ -
1605 QDockWidgetLayout *layout -
1606 = qobject_cast<QDockWidgetLayout*>(this->layout()); -
1607 return layout->widgetForRole(QDockWidgetLayout::TitleBar); -
1608} -
1609 -
1610QT_END_NAMESPACE -
1611 -
1612#include "qdockwidget.moc" -
1613#include "moc_qdockwidget.cpp" -
1614 -
1615#endif // QT_NO_DOCKWIDGET -
1616 -
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial