/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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, Nokia gives you certain additional
** rights. These rights are described in the Nokia 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.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qdockwidget.h"

#ifndef QT_NO_DOCKWIDGET
#include <qaction.h>
#include <qapplication.h>
#include <qdesktopwidget.h>
#include <qdrawutil.h>
#include <qevent.h>
#include <qfontmetrics.h>
#include <qmainwindow.h>
#include <qrubberband.h>
#include <qstylepainter.h>
#include <qtoolbutton.h>
#include <qdebug.h>

#include <private/qwidgetresizehandler_p.h>

#include "qdockwidget_p.h"
#include "qmainwindowlayout_p.h"
#ifdef Q_WS_MAC
#include <private/qapplication_p.h>
#include <private/qt_mac_p.h>
#include <qmacstyle_mac.h>
#endif

QT_BEGIN_NAMESPACE

extern QString qt_setWindowTitle_helperHelper(const QString&, const QWidget*); // qwidget.cpp

// qmainwindow.cpp
extern QMainWindowLayout *qt_mainwindow_layout(const QMainWindow *window);

static inline bool hasFeature(const QDockWidgetPrivate *priv, QDockWidget::DockWidgetFeature feature)
{ return (priv->features & feature) == feature; }

static inline bool hasFeature(const QDockWidget *dockwidget, QDockWidget::DockWidgetFeature feature)
{ return (dockwidget->features() & feature) == feature; }


/*
    A Dock Window:

    [+] is the float button
    [X] is the close button

    +-------------------------------+
    | Dock Window Title       [+][X]|
    +-------------------------------+
    |                               |
    | place to put the single       |
    | QDockWidget child (this space |
    | does not yet have a name)     |
    |                               |
    |                               |
    |                               |
    |                               |
    |                               |
    |                               |
    |                               |
    |                               |
    |                               |
    +-------------------------------+

*/

/******************************************************************************
** QDockWidgetTitleButton
*/

class QDockWidgetTitleButton : public QAbstractButton
{
    Q_OBJECT

public:
    QDockWidgetTitleButton(QDockWidget *dockWidget);

    QSize sizeHint() const;
    inline QSize minimumSizeHint() const
    { return sizeHint(); }

    void enterEvent(QEvent *event);
    void leaveEvent(QEvent *event);
    void paintEvent(QPaintEvent *event);
};


QDockWidgetTitleButton::QDockWidgetTitleButton(QDockWidget *dockWidget)
    : QAbstractButton(dockWidget)
{
    setFocusPolicy(Qt::NoFocus);
}

QSize QDockWidgetTitleButton::sizeHint() const
{
    ensurePolished();

    int size = 2*style()->pixelMetric(QStyle::PM_DockWidgetTitleBarButtonMargin, 0, this);
    if (!icon().isNull()) {
        int iconSize = style()->pixelMetric(QStyle::PM_SmallIconSize, 0, this);
        QSize sz = icon().actualSize(QSize(iconSize, iconSize));
        size += qMax(sz.width(), sz.height());
    }

    return QSize(size, size);
}

void QDockWidgetTitleButton::enterEvent(QEvent *event)
{
    if (isEnabled()) update();
    QAbstractButton::enterEvent(event);
}

void QDockWidgetTitleButton::leaveEvent(QEvent *event)
{
    if (isEnabled()) update();
    QAbstractButton::leaveEvent(event);
}

void QDockWidgetTitleButton::paintEvent(QPaintEvent *)
{
    QPainter p(this);

    QRect r = rect();
    QStyleOptionToolButton opt;
    opt.init(this);
    opt.state |= QStyle::State_AutoRaise;

    if (style()->styleHint(QStyle::SH_DockWidget_ButtonsHaveFrame, 0, this))
    {
        if (isEnabled() && underMouse() && !isChecked() && !isDown())
            opt.state |= QStyle::State_Raised;
        if (isChecked())
            opt.state |= QStyle::State_On;
        if (isDown())
            opt.state |= QStyle::State_Sunken;
        style()->drawPrimitive(QStyle::PE_PanelButtonTool, &opt, &p, this);
    }

    opt.icon = icon();
    opt.subControls = 0;
    opt.activeSubControls = 0;
    opt.features = QStyleOptionToolButton::None;
    opt.arrowType = Qt::NoArrow;
    int size = style()->pixelMetric(QStyle::PM_SmallIconSize, 0, this);
    opt.iconSize = QSize(size, size);
    style()->drawComplexControl(QStyle::CC_ToolButton, &opt, &p, this);
}

/******************************************************************************
** QDockWidgetLayout
*/

QDockWidgetLayout::QDockWidgetLayout(QWidget *parent)
    : QLayout(parent), verticalTitleBar(false), item_list(RoleCount, 0)
{
}

QDockWidgetLayout::~QDockWidgetLayout()
{
    qDeleteAll(item_list);
}

bool QDockWidgetLayout::nativeWindowDeco() const
{
    return nativeWindowDeco(parentWidget()->isWindow());
}

bool QDockWidgetLayout::nativeWindowDeco(bool floating) const
{
#if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_WS_WINCE)
    Q_UNUSED(floating);
    return false;
#else
    return floating && item_list[QDockWidgetLayout::TitleBar] == 0;
#endif
}


void QDockWidgetLayout::addItem(QLayoutItem*)
{
    qWarning() << "QDockWidgetLayout::addItem(): please use QDockWidgetLayout::setWidget()";
    return;
}

QLayoutItem *QDockWidgetLayout::itemAt(int index) const
{
    int cnt = 0;
    for (int i = 0; i < item_list.count(); ++i) {
        QLayoutItem *item = item_list.at(i);
        if (item == 0)
            continue;
        if (index == cnt++)
            return item;
    }
    return 0;
}

QLayoutItem *QDockWidgetLayout::takeAt(int index)
{
    int j = 0;
    for (int i = 0; i < item_list.count(); ++i) {
        QLayoutItem *item = item_list.at(i);
        if (item == 0)
            continue;
        if (index == j) {
            item_list[i] = 0;
            invalidate();
            return item;
        }
        ++j;
    }
    return 0;
}

int QDockWidgetLayout::count() const
{
    int result = 0;
    for (int i = 0; i < item_list.count(); ++i) {
        if (item_list.at(i))
            ++result;
    }
    return result;
}

QSize QDockWidgetLayout::sizeFromContent(const QSize &content, bool floating) const
{
    QSize result = content;

    if (verticalTitleBar) {
        result.setHeight(qMax(result.height(), minimumTitleWidth()));
        result.setWidth(qMax(content.width(), 0));
    } else {
        result.setHeight(qMax(result.height(), 0));
        result.setWidth(qMax(content.width(), minimumTitleWidth()));
    }

    QDockWidget *w = qobject_cast<QDockWidget*>(parentWidget());
    const bool nativeDeco = nativeWindowDeco(floating);

    int fw = floating && !nativeDeco
            ? w->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, w)
            : 0;

    const int th = titleHeight();
    if (!nativeDeco) {
        if (verticalTitleBar)
            result += QSize(th + 2*fw, 2*fw);
        else
            result += QSize(2*fw, th + 2*fw);
    }

    result.setHeight(qMin(result.height(), (int) QWIDGETSIZE_MAX));
    result.setWidth(qMin(result.width(), (int) QWIDGETSIZE_MAX));

    if (content.width() < 0)
        result.setWidth(-1);
    if (content.height() < 0)
        result.setHeight(-1);

    int left, top, right, bottom;
    w->getContentsMargins(&left, &top, &right, &bottom);
    //we need to substract the contents margin (it will be added by the caller)
    QSize min = w->minimumSize() - QSize(left + right, top + bottom);
    QSize max = w->maximumSize() - QSize(left + right, top + bottom);

    /* A floating dockwidget will automatically get its minimumSize set to the layout's
       minimum size + deco. We're *not* interested in this, we only take minimumSize()
       into account if the user set it herself. Otherwise we end up expanding the result
       of a calculation for a non-floating dock widget to a floating dock widget's
       minimum size + window decorations. */

    uint explicitMin = 0;
    uint explicitMax = 0;
    if (w->d_func()->extra != 0) {
        explicitMin = w->d_func()->extra->explicitMinSize;
        explicitMax = w->d_func()->extra->explicitMaxSize;
    }

    if (!(explicitMin & Qt::Horizontal) || min.width() == 0)
        min.setWidth(-1);
    if (!(explicitMin & Qt::Vertical) || min.height() == 0)
        min.setHeight(-1);

    if (!(explicitMax & Qt::Horizontal))
        max.setWidth(QWIDGETSIZE_MAX);
    if (!(explicitMax & Qt::Vertical))
        max.setHeight(QWIDGETSIZE_MAX);

    return result.boundedTo(max).expandedTo(min);
}

QSize QDockWidgetLayout::sizeHint() const
{
    QDockWidget *w = qobject_cast<QDockWidget*>(parentWidget());

    QSize content(-1, -1);
    if (item_list[Content] != 0)
        content = item_list[Content]->sizeHint();

    return sizeFromContent(content, w->isFloating());
}

QSize QDockWidgetLayout::maximumSize() const
{
    if (item_list[Content] != 0) {
        const QSize content = item_list[Content]->maximumSize();
        return sizeFromContent(content, parentWidget()->isWindow());
    } else {
        return parentWidget()->maximumSize();
    }

}

QSize QDockWidgetLayout::minimumSize() const
{
    QDockWidget *w = qobject_cast<QDockWidget*>(parentWidget());

    QSize content(0, 0);
    if (item_list[Content] != 0)
        content = item_list[Content]->minimumSize();

    return sizeFromContent(content, w->isFloating());
}

QWidget *QDockWidgetLayout::widgetForRole(Role r) const
{
    QLayoutItem *item = item_list.at(r);
    return item == 0 ? 0 : item->widget();
}

QLayoutItem *QDockWidgetLayout::itemForRole(Role r) const
{
    return item_list.at(r);
}

void QDockWidgetLayout::setWidgetForRole(Role r, QWidget *w)
{
    QWidget *old = widgetForRole(r);
    if (old != 0) {
        old->hide();
        removeWidget(old);
    }

    if (w != 0) {
        addChildWidget(w);
        item_list[r] = new QWidgetItemV2(w);
        w->show();
    } else {
        item_list[r] = 0;
    }

    invalidate();
}

static inline int pick(bool vertical, const QSize &size)
{
    return vertical ? size.height() : size.width();
}

static inline int perp(bool vertical, const QSize &size)
{
    return vertical ? size.width() : size.height();
}

int QDockWidgetLayout::minimumTitleWidth() const
{
    QDockWidget *q = qobject_cast<QDockWidget*>(parentWidget());

    if (QWidget *title = widgetForRole(TitleBar))
        return pick(verticalTitleBar, title->minimumSizeHint());

    QSize closeSize(0, 0);
    QSize floatSize(0, 0);
    if (hasFeature(q, QDockWidget::DockWidgetClosable)) {
        if (QLayoutItem *item = item_list[CloseButton])
            closeSize = item->widget()->sizeHint();
    }
    if (hasFeature(q, QDockWidget::DockWidgetFloatable)) {
        if (QLayoutItem *item = item_list[FloatButton])
            floatSize = item->widget()->sizeHint();
    }

    int titleHeight = this->titleHeight();

    int mw = q->style()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, 0, q);
    int fw = q->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, q);

    return pick(verticalTitleBar, closeSize)
            + pick(verticalTitleBar, floatSize)
            + titleHeight + 2*fw + 3*mw;
}

int QDockWidgetLayout::titleHeight() const
{
    QDockWidget *q = qobject_cast<QDockWidget*>(parentWidget());

    if (QWidget *title = widgetForRole(TitleBar))
        return perp(verticalTitleBar, title->sizeHint());

    QSize closeSize(0, 0);
    QSize floatSize(0, 0);
    if (QLayoutItem *item = item_list[CloseButton])
        closeSize = item->widget()->sizeHint();
    if (QLayoutItem *item = item_list[FloatButton])
        floatSize = item->widget()->sizeHint();

    int buttonHeight = qMax(perp(verticalTitleBar, closeSize),
                            perp(verticalTitleBar, floatSize));

    QFontMetrics titleFontMetrics = q->fontMetrics();
#ifdef Q_WS_MAC
    if (qobject_cast<QMacStyle *>(q->style())) {
        //### this breaks on proxy styles.  (But is this code still called?)
        QFont font = qt_app_fonts_hash()->value("QToolButton", q->font());
        titleFontMetrics = QFontMetrics(font);
    }
#endif

    int mw = q->style()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, 0, q);

    return qMax(buttonHeight + 2, titleFontMetrics.height() + 2*mw);
}

void QDockWidgetLayout::setGeometry(const QRect &geometry)
{
    QDockWidget *q = qobject_cast<QDockWidget*>(parentWidget());

    bool nativeDeco = nativeWindowDeco();

    int fw = q->isFloating() && !nativeDeco
            ? q->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, q)
            : 0;

    if (nativeDeco) {
        if (QLayoutItem *item = item_list[Content])
            item->setGeometry(geometry);
    } else {
        int titleHeight = this->titleHeight();

        if (verticalTitleBar) {
            _titleArea = QRect(QPoint(fw, fw),
                                QSize(titleHeight, geometry.height() - (fw * 2)));
        } else {
            _titleArea = QRect(QPoint(fw, fw),
                                QSize(geometry.width() - (fw * 2), titleHeight));
        }

        if (QLayoutItem *item = item_list[TitleBar]) {
            item->setGeometry(_titleArea);
        } else {
            QStyleOptionDockWidgetV2 opt;
            q->initStyleOption(&opt);

            if (QLayoutItem *item = item_list[CloseButton]) {
                if (!item->isEmpty()) {
                    QRect r = q->style()
                        ->subElementRect(QStyle::SE_DockWidgetCloseButton,
                                            &opt, q);
                    if (!r.isNull())
                        item->setGeometry(r);
                }
            }

            if (QLayoutItem *item = item_list[FloatButton]) {
                if (!item->isEmpty()) {
                    QRect r = q->style()
                        ->subElementRect(QStyle::SE_DockWidgetFloatButton,
                                            &opt, q);
                    if (!r.isNull())
                        item->setGeometry(r);
                }
            }
        }

        if (QLayoutItem *item = item_list[Content]) {
            QRect r = geometry;
            if (verticalTitleBar) {
                r.setLeft(_titleArea.right() + 1);
                r.adjust(0, fw, -fw, -fw);
            } else {
                r.setTop(_titleArea.bottom() + 1);
                r.adjust(fw, 0, -fw, -fw);
            }
            item->setGeometry(r);
        }
    }
}

void QDockWidgetLayout::setVerticalTitleBar(bool b)
{
    if (b == verticalTitleBar)
        return;
    verticalTitleBar = b;
    invalidate();
    parentWidget()->update();
}

/******************************************************************************
** QDockWidgetItem
*/

QDockWidgetItem::QDockWidgetItem(QDockWidget *dockWidget)
    : QWidgetItem(dockWidget)
{
}

QSize QDockWidgetItem::minimumSize() const
{
    QSize widgetMin(0, 0);
    if (QLayoutItem *item = dockWidgetChildItem())
        widgetMin = item->minimumSize();
    return dockWidgetLayout()->sizeFromContent(widgetMin, false);
}

QSize QDockWidgetItem::maximumSize() const
{
    if (QLayoutItem *item = dockWidgetChildItem()) {
        return dockWidgetLayout()->sizeFromContent(item->maximumSize(), false);
    } else {
        return QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
    }
}


QSize QDockWidgetItem::sizeHint() const
{
    if (QLayoutItem *item = dockWidgetChildItem()) {
         return dockWidgetLayout()->sizeFromContent(item->sizeHint(), false);
    } else {
        return QWidgetItem::sizeHint();
    }
}

/******************************************************************************
** QDockWidgetPrivate
*/

void QDockWidgetPrivate::init()
{
    Q_Q(QDockWidget);

    QDockWidgetLayout *layout = new QDockWidgetLayout(q);
    layout->setSizeConstraint(QLayout::SetMinAndMaxSize);

    QAbstractButton *button = new QDockWidgetTitleButton(q);
    button->setObjectName(QLatin1String("qt_dockwidget_floatbutton"));
    QObject::connect(button, SIGNAL(clicked()), q, SLOT(_q_toggleTopLevel()));
    layout->setWidgetForRole(QDockWidgetLayout::FloatButton, button);

    button = new QDockWidgetTitleButton(q);
    button->setObjectName(QLatin1String("qt_dockwidget_closebutton"));
    QObject::connect(button, SIGNAL(clicked()), q, SLOT(close()));
    layout->setWidgetForRole(QDockWidgetLayout::CloseButton, button);

    resizer = new QWidgetResizeHandler(q);
    resizer->setMovingEnabled(false);
    resizer->setActive(false);

#ifndef QT_NO_ACTION
    toggleViewAction = new QAction(q);
    toggleViewAction->setCheckable(true);
    fixedWindowTitle = qt_setWindowTitle_helperHelper(q->windowTitle(), q);
    toggleViewAction->setText(fixedWindowTitle);
    QObject::connect(toggleViewAction, SIGNAL(triggered(bool)),
                        q, SLOT(_q_toggleView(bool)));
#endif

    updateButtons();
}

/*!
    Initialize \a option with the values from this QDockWidget. This method
    is useful for subclasses when they need a QStyleOptionDockWidget, but don't want
    to fill in all the information themselves.

    \sa QStyleOption::initFrom()
*/
void QDockWidget::initStyleOption(QStyleOptionDockWidget *option) const
{
    Q_D(const QDockWidget);

    if (!option)
        return;
    QDockWidgetLayout *dwlayout = qobject_cast<QDockWidgetLayout*>(layout());

    option->initFrom(this);
    option->rect = dwlayout->titleArea();
    option->title = d->fixedWindowTitle;
    option->closable = hasFeature(this, QDockWidget::DockWidgetClosable);
    option->movable = hasFeature(this, QDockWidget::DockWidgetMovable);
    option->floatable = hasFeature(this, QDockWidget::DockWidgetFloatable);

    QDockWidgetLayout *l = qobject_cast<QDockWidgetLayout*>(layout());
    QStyleOptionDockWidgetV2 *v2
        = qstyleoption_cast<QStyleOptionDockWidgetV2*>(option);
    if (v2 != 0)
        v2->verticalTitleBar = l->verticalTitleBar;
}

void QDockWidgetPrivate::_q_toggleView(bool b)
{
    Q_Q(QDockWidget);
    if (b == q->isHidden()) {
        if (b)
            q->show();
        else
            q->close();
    }
}

void QDockWidgetPrivate::updateButtons()
{
    Q_Q(QDockWidget);
    QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout);

    QStyleOptionDockWidget opt;
    q->initStyleOption(&opt);

    bool customTitleBar = dwLayout->widgetForRole(QDockWidgetLayout::TitleBar) != 0;
    bool nativeDeco = dwLayout->nativeWindowDeco();
    bool hideButtons = nativeDeco || customTitleBar;

    bool canClose = hasFeature(this, QDockWidget::DockWidgetClosable);
    bool canFloat = hasFeature(this, QDockWidget::DockWidgetFloatable);

    QAbstractButton *button
        = qobject_cast<QAbstractButton*>(dwLayout->widgetForRole(QDockWidgetLayout::FloatButton));
    button->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarNormalButton, &opt, q));
    button->setVisible(canFloat && !hideButtons);

    button
        = qobject_cast <QAbstractButton*>(dwLayout->widgetForRole(QDockWidgetLayout::CloseButton));
    button->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarCloseButton, &opt, q));
    button->setVisible(canClose && !hideButtons);

    q->setAttribute(Qt::WA_ContentsPropagated,
                    (canFloat || canClose) && !hideButtons);

    layout->invalidate();
}

void QDockWidgetPrivate::_q_toggleTopLevel()
{
    Q_Q(QDockWidget);
    q->setFloating(!q->isFloating());
}

void QDockWidgetPrivate::initDrag(const QPoint &pos, bool nca)
{
    if (state != 0)
        return;

    QMainWindow *win = qobject_cast<QMainWindow*>(parent);
    Q_ASSERT(win != 0);
    QMainWindowLayout *layout = qt_mainwindow_layout(win);
    Q_ASSERT(layout != 0);
    if (layout->pluggingWidget != 0) // the main window is animating a docking operation
        return;

    state = new QDockWidgetPrivate::DragState;
    state->pressPos = pos;
    state->dragging = false;
    state->widgetItem = 0;
    state->ownWidgetItem = false;
    state->nca = nca;
    state->ctrlDrag = false;
}

void QDockWidgetPrivate::startDrag()
{
    Q_Q(QDockWidget);

    if (state == 0 || state->dragging)
        return;

    QMainWindowLayout *layout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget()));
    Q_ASSERT(layout != 0);

    state->widgetItem = layout->unplug(q);
    if (state->widgetItem == 0) {
        /* I have a QMainWindow parent, but I was never inserted with
            QMainWindow::addDockWidget, so the QMainWindowLayout has no
            widget item for me. :( I have to create it myself, and then
            delete it if I don't get dropped into a dock area. */
        state->widgetItem = new QDockWidgetItem(q);
        state->ownWidgetItem = true;
    }

    if (state->ctrlDrag)
        layout->restore();

    state->dragging = true;
}

void QDockWidgetPrivate::endDrag(bool abort)
{
    Q_Q(QDockWidget);
    Q_ASSERT(state != 0);

    q->releaseMouse();

    if (state->dragging) {
        QMainWindowLayout *mwLayout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget()));
        Q_ASSERT(mwLayout != 0);

        if (abort || !mwLayout->plug(state->widgetItem)) {
            if (hasFeature(this, QDockWidget::DockWidgetFloatable)) {
                if (state->ownWidgetItem)
                    delete state->widgetItem;
                mwLayout->restore();
#ifdef Q_WS_X11
                // get rid of the X11BypassWindowManager window flag and activate the resizer
                Qt::WindowFlags flags = q->windowFlags();
                flags &= ~Qt::X11BypassWindowManagerHint;
                q->setWindowFlags(flags);
                resizer->setActive(QWidgetResizeHandler::Resize, true);
                q->show();
#else
                QDockWidgetLayout *myLayout
                    = qobject_cast<QDockWidgetLayout*>(layout);
                resizer->setActive(QWidgetResizeHandler::Resize,
                                    myLayout->widgetForRole(QDockWidgetLayout::TitleBar) != 0);
#endif
                undockedGeometry = q->geometry();
                q->activateWindow();
            } else {
                mwLayout->revert(state->widgetItem);
            }
        }
    }
    delete state;
    state = 0;
}

bool QDockWidgetPrivate::isAnimating() const
{
    Q_Q(const QDockWidget);

    QMainWindow *mainWin = qobject_cast<QMainWindow*>(parent);
    if (mainWin == 0)
        return false;

    QMainWindowLayout *mainWinLayout = qt_mainwindow_layout(mainWin);
    if (mainWinLayout == 0)
        return false;

    return (void*)mainWinLayout->pluggingWidget == (void*)q;
}

bool QDockWidgetPrivate::mousePressEvent(QMouseEvent *event)
{
#if !defined(QT_NO_MAINWINDOW)
    Q_Q(QDockWidget);

    QDockWidgetLayout *dwLayout
        = qobject_cast<QDockWidgetLayout*>(layout);

    if (!dwLayout->nativeWindowDeco()) {
        QRect titleArea = dwLayout->titleArea();

        if (event->button() != Qt::LeftButton ||
            !titleArea.contains(event->pos()) ||
            // check if the tool window is movable... do nothing if it
            // is not (but allow moving if the window is floating)
            (!hasFeature(this, QDockWidget::DockWidgetMovable) && !q->isFloating()) ||
            qobject_cast<QMainWindow*>(parent) == 0 ||
            isAnimating() || state != 0) {
            return false;
        }

        initDrag(event->pos(), false);

        if (state)
            state->ctrlDrag = hasFeature(this, QDockWidget::DockWidgetFloatable) && event->modifiers() & Qt::ControlModifier;

        return true;
    }

#endif // !defined(QT_NO_MAINWINDOW)
    return false;
}

bool QDockWidgetPrivate::mouseDoubleClickEvent(QMouseEvent *event)
{
    QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout);

    if (!dwLayout->nativeWindowDeco()) {
        QRect titleArea = dwLayout->titleArea();

        if (event->button() == Qt::LeftButton && titleArea.contains(event->pos()) &&
            hasFeature(this, QDockWidget::DockWidgetFloatable)) {
            _q_toggleTopLevel();
            return true;
        }
    }
    return false;
}

bool QDockWidgetPrivate::mouseMoveEvent(QMouseEvent *event)
{
    bool ret = false;
#if !defined(QT_NO_MAINWINDOW)
    Q_Q(QDockWidget);

    if (!state)
        return ret;

    QDockWidgetLayout *dwlayout
        = qobject_cast<QDockWidgetLayout *>(layout);
    QMainWindowLayout *mwlayout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget()));
    if (!dwlayout->nativeWindowDeco()) {
        if (!state->dragging
            && mwlayout->pluggingWidget == 0
            && (event->pos() - state->pressPos).manhattanLength()
                > QApplication::startDragDistance()) {
            startDrag();
#ifdef Q_OS_WIN
            grabMouseWhileInWindow();
#else
            q->grabMouse();
#endif
            ret = true;
        }
    }

    if (state->dragging && !state->nca) {
        QPoint pos = event->globalPos() - state->pressPos;
        q->move(pos);

        if (!state->ctrlDrag)
            mwlayout->hover(state->widgetItem, event->globalPos());

        ret = true;
    }

#endif // !defined(QT_NO_MAINWINDOW)
    return ret;
}

bool QDockWidgetPrivate::mouseReleaseEvent(QMouseEvent *event)
{
#if !defined(QT_NO_MAINWINDOW)

    if (event->button() == Qt::LeftButton && state && !state->nca) {
        endDrag();
        return true; //filter out the event
    }

#endif // !defined(QT_NO_MAINWINDOW)
    return false;
}

void QDockWidgetPrivate::nonClientAreaMouseEvent(QMouseEvent *event)
{
    Q_Q(QDockWidget);

    int fw = q->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, q);

    QRect geo = q->geometry();
    QRect titleRect = q->frameGeometry();
#ifdef Q_WS_MAC
    if ((features & QDockWidget::DockWidgetVerticalTitleBar)) {
        titleRect.setTop(geo.top());
        titleRect.setBottom(geo.bottom());
        titleRect.setRight(geo.left() - 1);
    } else
#endif
    {
        titleRect.setLeft(geo.left());
        titleRect.setRight(geo.right());
        titleRect.setBottom(geo.top() - 1);
        titleRect.adjust(0, fw, 0, 0);
    }

    switch (event->type()) {
        case QEvent::NonClientAreaMouseButtonPress:
            if (!titleRect.contains(event->globalPos()))
                break;
            if (state != 0)
                break;
            if (qobject_cast<QMainWindow*>(parent) == 0)
                break;
            if (isAnimating())
                break;
            initDrag(event->pos(), true);
            if (state == 0)
                break;
#ifdef Q_OS_WIN
            // On Windows, NCA mouse events don't contain modifier info
            state->ctrlDrag = GetKeyState(VK_CONTROL) & 0x8000;
#else
            state->ctrlDrag = event->modifiers() & Qt::ControlModifier;
#endif
            startDrag();
            break;
        case QEvent::NonClientAreaMouseMove:
            if (state == 0 || !state->dragging)
                break;
            if (state->nca) {
                endDrag();
            }
#ifdef Q_OS_MAC
            else { // workaround for lack of mouse-grab on Mac
                QMainWindowLayout *layout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget()));
                Q_ASSERT(layout != 0);

                q->move(event->globalPos() - state->pressPos);
                if (!state->ctrlDrag)
                    layout->hover(state->widgetItem, event->globalPos());
            }
#endif
            break;
        case QEvent::NonClientAreaMouseButtonRelease:
#ifdef Q_OS_MAC
                        if (state)
                                endDrag();
#endif
                        break;
        case QEvent::NonClientAreaMouseButtonDblClick:
            _q_toggleTopLevel();
            break;
        default:
            break;
    }
}

void QDockWidgetPrivate::moveEvent(QMoveEvent *event)
{
    Q_Q(QDockWidget);

    if (state == 0 || !state->dragging || !state->nca || !q->isWindow())
        return;

    // When the native window frame is being dragged, all we get is these mouse
    // move events.

    if (state->ctrlDrag)
        return;

    QMainWindowLayout *layout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget()));
    Q_ASSERT(layout != 0);

    QPoint globalMousePos = event->pos() + state->pressPos;
    layout->hover(state->widgetItem, globalMousePos);
}

void QDockWidgetPrivate::unplug(const QRect &rect)
{
    Q_Q(QDockWidget);
    QRect r = rect;
    r.moveTopLeft(q->mapToGlobal(QPoint(0, 0)));
    QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout);
    if (dwLayout->nativeWindowDeco(true))
        r.adjust(0, dwLayout->titleHeight(), 0, 0);
    setWindowState(true, true, r);
}

void QDockWidgetPrivate::plug(const QRect &rect)
{
    setWindowState(false, false, rect);
}

void QDockWidgetPrivate::setWindowState(bool floating, bool unplug, const QRect &rect)
{
    Q_Q(QDockWidget);

    if (!floating && parent) {
        QMainWindowLayout *mwlayout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget()));
        if (mwlayout && mwlayout->dockWidgetArea(q) == Qt::NoDockWidgetArea)
            return; // this dockwidget can't be redocked
    }

    bool wasFloating = q->isFloating();
    bool hidden = q->isHidden();

    if (q->isVisible())
        q->hide();

    Qt::WindowFlags flags = floating ? Qt::Tool : Qt::Widget;

    QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout);
    const bool nativeDeco = dwLayout->nativeWindowDeco(floating);

    if (nativeDeco) {
        flags |= Qt::CustomizeWindowHint | Qt::WindowTitleHint;
        if (hasFeature(this, QDockWidget::DockWidgetClosable))
            flags |= Qt::WindowCloseButtonHint;
    } else {
        flags |= Qt::FramelessWindowHint;
    }

    if (unplug)
        flags |= Qt::X11BypassWindowManagerHint;

    q->setWindowFlags(flags);

#if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA)
    if (floating && nativeDeco && (q->features() & QDockWidget::DockWidgetVerticalTitleBar)) {
        ChangeWindowAttributes(HIViewGetWindow(HIViewRef(q->winId())), kWindowSideTitlebarAttribute, 0);
    }
#endif

    if (!rect.isNull())
        q->setGeometry(rect);

    updateButtons();

    if (!hidden)
        q->show();

    if (floating != wasFloating) {
        emit q->topLevelChanged(floating);
        if (!floating && parent) {
            QMainWindowLayout *mwlayout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget()));
            if (mwlayout)
                emit q->dockLocationChanged(mwlayout->dockWidgetArea(q));
        }
    }

    resizer->setActive(QWidgetResizeHandler::Resize, !unplug && floating && !nativeDeco);
}

/*!
    \class QDockWidget

    \brief The QDockWidget class provides a widget that can be docked
    inside a QMainWindow or floated as a top-level window on the
    desktop.

    \ingroup mainwindow-classes

    QDockWidget provides the concept of dock widgets, also know as
    tool palettes or utility windows.  Dock windows are secondary
    windows placed in the \e {dock widget area} around the
    \l{QMainWindow::centralWidget()}{central widget} in a
    QMainWindow.

    \image mainwindow-docks.png

    Dock windows can be moved inside their current area, moved into
    new areas and floated (e.g., undocked) by the end-user.  The
    QDockWidget API allows the programmer to restrict the dock widgets
    ability to move, float and close, as well as the areas in which
    they can be placed.

    \section1 Appearance

    A QDockWidget consists of a title bar and the content area.  The
    title bar displays the dock widgets \link QWidget::windowTitle()
    window title\endlink, a \e float button and a \e close button.
    Depending on the state of the QDockWidget, the \e float and \e
    close buttons may be either disabled or not shown at all.

    The visual appearance of the title bar and buttons is dependent
    on the \l{QStyle}{style} in use.

    A QDockWidget acts as a wrapper for its child widget, set with setWidget().
    Custom size hints, minimum and maximum sizes and size policies should be
    implemented in the child widget. QDockWidget will respect them, adjusting
    its own constraints to include the frame and title. Size constraints
    should not be set on the QDockWidget itself, because they change depending
    on whether it is docked; a docked QDockWidget has no frame and a smaller title
    bar.

    \sa QMainWindow, {Dock Widgets Example}
*/

/*!
    \enum QDockWidget::DockWidgetFeature

    \value DockWidgetClosable   The dock widget can be closed. On some systems the dock
	                            widget always has a close button when it's floating
								(for example on MacOS 10.5).
    \value DockWidgetMovable    The dock widget can be moved between docks
                                by the user.
    \value DockWidgetFloatable  The dock widget can be detached from the
                                main window, and floated as an independent
                                window.
    \value DockWidgetVerticalTitleBar The dock widget displays a vertical title
                                  bar on its left side. This can be used to
                                  increase the amount of vertical space in
                                  a QMainWindow.
    \value AllDockWidgetFeatures  (Deprecated) The dock widget can be closed, moved,
                                  and floated. Since new features might be added in future
                                  releases, the look and behavior of dock widgets might
                                  change if you use this flag. Please specify individual
                                  flags instead.
    \value NoDockWidgetFeatures   The dock widget cannot be closed, moved,
                                  or floated.

    \omitvalue DockWidgetFeatureMask
    \omitvalue Reserved
*/

/*!
    \property QDockWidget::windowTitle
    \brief the dock widget title (caption)

    By default, this property contains an empty string.
*/

/*!
    Constructs a QDockWidget with parent \a parent and window flags \a
    flags. The dock widget will be placed in the left dock widget
    area.
*/
QDockWidget::QDockWidget(QWidget *parent, Qt::WindowFlags flags)
    : QWidget(*new QDockWidgetPrivate, parent, flags)
{
    Q_D(QDockWidget);
    d->init();
}

/*!
    Constructs a QDockWidget with parent \a parent and window flags \a
    flags. The dock widget will be placed in the left dock widget
    area.

    The window title is set to \a title. This title is used when the
    QDockWidget is docked and undocked. It is also used in the context
    menu provided by QMainWindow.

    \sa setWindowTitle()
*/
QDockWidget::QDockWidget(const QString &title, QWidget *parent, Qt::WindowFlags flags)
    : QWidget(*new QDockWidgetPrivate, parent, flags)
{
    Q_D(QDockWidget);
    d->init();
    setWindowTitle(title);
}

/*!
    Destroys the dock widget.
*/
QDockWidget::~QDockWidget()
{ }

/*!
    Returns the widget for the dock widget. This function returns zero
    if the widget has not been set.

    \sa setWidget()
*/
QWidget *QDockWidget::widget() const
{
    QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(this->layout());
    return layout->widgetForRole(QDockWidgetLayout::Content);
}

/*!
    Sets the widget for the dock widget to \a widget.

    If the dock widget is visible when \a widget is added, you must
    \l{QWidget::}{show()} it explicitly.

    Note that you must add the layout of the \a widget before you call
    this function; if not, the \a widget will not be visible.

    \sa widget()
*/
void QDockWidget::setWidget(QWidget *widget)
{
    QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(this->layout());
    layout->setWidgetForRole(QDockWidgetLayout::Content, widget);
}

/*!
    \property QDockWidget::features
    \brief whether the dock widget is movable, closable, and floatable

    By default, this property is set to a combination of DockWidgetClosable,
    DockWidgetMovable and DockWidgetFloatable.

    \sa DockWidgetFeature
*/

void QDockWidget::setFeatures(QDockWidget::DockWidgetFeatures features)
{
    Q_D(QDockWidget);
    features &= DockWidgetFeatureMask;
    if (d->features == features)
        return;
    const bool closableChanged = (d->features ^ features) & DockWidgetClosable;
    d->features = features;
    QDockWidgetLayout *layout
        = qobject_cast<QDockWidgetLayout*>(this->layout());
    layout->setVerticalTitleBar(features & DockWidgetVerticalTitleBar);
    d->updateButtons();
    d->toggleViewAction->setEnabled((d->features & DockWidgetClosable) == DockWidgetClosable);
    emit featuresChanged(d->features);
    update();
    if (closableChanged && layout->nativeWindowDeco()) {
        //this ensures the native decoration is drawn
        d->setWindowState(true /*floating*/, true /*unplug*/);
    }
}

QDockWidget::DockWidgetFeatures QDockWidget::features() const
{
    Q_D(const QDockWidget);
    return d->features;
}

/*!
    \property QDockWidget::floating
    \brief whether the dock widget is floating

    A floating dock widget is presented to the user as an independent
    window "on top" of its parent QMainWindow, instead of being
    docked in the QMainWindow.

    By default, this property is true.

    \sa isWindow()
*/
void QDockWidget::setFloating(bool floating)
{
    Q_D(QDockWidget);

    // the initial click of a double-click may have started a drag...
    if (d->state != 0)
        d->endDrag(true);

    QRect r = d->undockedGeometry;

    d->setWindowState(floating, false, floating ? r : QRect());

    if (floating && r.isNull()) {
        if (x() < 0 || y() < 0) //may happen if we have been hidden
            move(QPoint());
        setAttribute(Qt::WA_Moved, false); //we want it at the default position
    }
}

/*!
    \property QDockWidget::allowedAreas
    \brief areas where the dock widget may be placed

    The default is Qt::AllDockWidgetAreas.

    \sa Qt::DockWidgetArea
*/

void QDockWidget::setAllowedAreas(Qt::DockWidgetAreas areas)
{
    Q_D(QDockWidget);
    areas &= Qt::DockWidgetArea_Mask;
    if (areas == d->allowedAreas)
        return;
    d->allowedAreas = areas;
    emit allowedAreasChanged(d->allowedAreas);
}

Qt::DockWidgetAreas QDockWidget::allowedAreas() const
{
    Q_D(const QDockWidget);
    return d->allowedAreas;
}

/*!
    \fn bool QDockWidget::isAreaAllowed(Qt::DockWidgetArea area) const

    Returns true if this dock widget can be placed in the given \a area;
    otherwise returns false.
*/

/*! \reimp */
void QDockWidget::changeEvent(QEvent *event)
{
    Q_D(QDockWidget);
    QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(this->layout());

    switch (event->type()) {
    case QEvent::ModifiedChange:
    case QEvent::WindowTitleChange:
        update(layout->titleArea());
#ifndef QT_NO_ACTION
        d->fixedWindowTitle = qt_setWindowTitle_helperHelper(windowTitle(), this);
        d->toggleViewAction->setText(d->fixedWindowTitle);
#endif
#ifndef QT_NO_TABBAR
        {
            QMainWindow *win = qobject_cast<QMainWindow*>(parentWidget());
            if (QMainWindowLayout *winLayout = qt_mainwindow_layout(win)) {
                if (QDockAreaLayoutInfo *info = winLayout->layoutState.dockAreaLayout.info(this))
                    info->updateTabBar();
            }
        }
#endif // QT_NO_TABBAR
        break;
    default:
        break;
    }
    QWidget::changeEvent(event);
}

/*! \reimp */
void QDockWidget::closeEvent(QCloseEvent *event)
{
    Q_D(QDockWidget);
    if (d->state)
        d->endDrag(true);
    QWidget::closeEvent(event);
}

/*! \reimp */
void QDockWidget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event)

    QDockWidgetLayout *layout
        = qobject_cast<QDockWidgetLayout*>(this->layout());
    bool customTitleBar = layout->widgetForRole(QDockWidgetLayout::TitleBar) != 0;
    bool nativeDeco = layout->nativeWindowDeco();

    if (!nativeDeco && !customTitleBar) {
        QStylePainter p(this);
        // ### Add PixelMetric to change spacers, so style may show border
        // when not floating.
        if (isFloating()) {
            QStyleOptionFrame framOpt;
            framOpt.init(this);
            p.drawPrimitive(QStyle::PE_FrameDockWidget, framOpt);
        }

        // Title must be painted after the frame, since the areas overlap, and
        // the title may wish to extend out to all sides (eg. XP style)
        QStyleOptionDockWidgetV2 titleOpt;
        initStyleOption(&titleOpt);
        p.drawControl(QStyle::CE_DockWidgetTitle, titleOpt);
    }
}

/*! \reimp */
bool QDockWidget::event(QEvent *event)
{
    Q_D(QDockWidget);

    QMainWindow *win = qobject_cast<QMainWindow*>(parentWidget());
    QMainWindowLayout *layout = qt_mainwindow_layout(win);

    switch (event->type()) {
#ifndef QT_NO_ACTION
    case QEvent::Hide:
        if (layout != 0)
            layout->keepSize(this);
        d->toggleViewAction->setChecked(false);
        emit visibilityChanged(false);
        break;
    case QEvent::Show:
        d->toggleViewAction->setChecked(true);
        emit visibilityChanged(geometry().right() >= 0 && geometry().bottom() >= 0);
        break;
#endif
    case QEvent::ApplicationLayoutDirectionChange:
    case QEvent::LayoutDirectionChange:
    case QEvent::StyleChange:
    case QEvent::ParentChange:
        d->updateButtons();
        break;
    case QEvent::ZOrderChange: {
        bool onTop = false;
        if (win != 0) {
            const QObjectList &siblings = win->children();
            onTop = siblings.count() > 0 && siblings.last() == (QObject*)this;
        }
        if (!isFloating() && layout != 0 && onTop)
            layout->raise(this);
        break;
    }
    case QEvent::WindowActivate:
    case QEvent::WindowDeactivate:
        update(qobject_cast<QDockWidgetLayout *>(this->layout())->titleArea());
        break;
    case QEvent::ContextMenu:
        if (d->state) {
            event->accept();
            return true;
        }
        break;
        // return true after calling the handler since we don't want
        // them to be passed onto the default handlers
    case QEvent::MouseButtonPress:
        if (d->mousePressEvent(static_cast<QMouseEvent *>(event)))
            return true;
        break;
    case QEvent::MouseButtonDblClick:
        if (d->mouseDoubleClickEvent(static_cast<QMouseEvent *>(event)))
            return true;
        break;
    case QEvent::MouseMove:
        if (d->mouseMoveEvent(static_cast<QMouseEvent *>(event)))
            return true;
        break;
#ifdef Q_OS_WIN
    case QEvent::Leave:
        if (d->state != 0 && d->state->dragging && !d->state->nca) {
            // This is a workaround for loosing the mouse on Vista.
            QPoint pos = QCursor::pos();
            QMouseEvent fake(QEvent::MouseMove, mapFromGlobal(pos), pos, Qt::NoButton,
                             QApplication::mouseButtons(), QApplication::keyboardModifiers());
            d->mouseMoveEvent(&fake);
        }
        break;
#endif
    case QEvent::MouseButtonRelease:
        if (d->mouseReleaseEvent(static_cast<QMouseEvent *>(event)))
            return true;
        break;
    case QEvent::NonClientAreaMouseMove:
    case QEvent::NonClientAreaMouseButtonPress:
    case QEvent::NonClientAreaMouseButtonRelease:
    case QEvent::NonClientAreaMouseButtonDblClick:
        d->nonClientAreaMouseEvent(static_cast<QMouseEvent*>(event));
        return true;
    case QEvent::Move:
        d->moveEvent(static_cast<QMoveEvent*>(event));
        break;
    case QEvent::Resize:
        // if the mainwindow is plugging us, we don't want to update undocked geometry
        if (isFloating() && layout != 0 && layout->pluggingWidget != this)
            d->undockedGeometry = geometry();
        break;
    default:
        break;
    }
    return QWidget::event(event);
}

#ifndef QT_NO_ACTION
/*!
  Returns a checkable action that can be used to show or close this
  dock widget.

  The action's text is set to the dock widget's window title.

  \sa QAction::text QWidget::windowTitle
 */
QAction * QDockWidget::toggleViewAction() const
{
    Q_D(const QDockWidget);
    return d->toggleViewAction;
}
#endif // QT_NO_ACTION

/*!
    \fn void QDockWidget::featuresChanged(QDockWidget::DockWidgetFeatures features)

    This signal is emitted when the \l features property changes. The
    \a features parameter gives the new value of the property.
*/

/*!
    \fn void QDockWidget::topLevelChanged(bool topLevel)

    This signal is emitted when the \l floating property changes.
    The \a topLevel parameter is true if the dock widget is now floating;
    otherwise it is false.

    \sa isWindow()
*/

/*!
    \fn void QDockWidget::allowedAreasChanged(Qt::DockWidgetAreas allowedAreas)

    This signal is emitted when the \l allowedAreas property changes. The
    \a allowedAreas parameter gives the new value of the property.
*/

/*!
    \fn void QDockWidget::visibilityChanged(bool visible)
    \since 4.3

    This signal is emitted when the dock widget becomes \a visible (or
    invisible). This happens when the widget is hidden or shown, as
    well as when it is docked in a tabbed dock area and its tab
    becomes selected or unselected.
*/

/*!
    \fn void QDockWidget::dockLocationChanged(Qt::DockWidgetArea area)
    \since 4.3

    This signal is emitted when the dock widget is moved to another
    dock \a area, or is moved to a different location in its current
    dock area. This happens when the dock widget is moved
    programmatically or is dragged to a new location by the user.
*/

/*!
    \since 4.3

    Sets an arbitrary \a widget as the dock widget's title bar. If \a widget
    is 0, any custom title bar widget previously set on the dock widget is
    removed, but not deleted, and the default title bar will be used
    instead.

    If a title bar widget is set, QDockWidget will not use native window
    decorations when it is floated.

    Here are some tips for implementing custom title bars:

    \list
    \o Mouse events that are not explicitly handled by the title bar widget
       must be ignored by calling QMouseEvent::ignore(). These events then
       propagate to the QDockWidget parent, which handles them in the usual
       manner, moving when the title bar is dragged, docking and undocking
       when it is double-clicked, etc.

    \o When DockWidgetVerticalTitleBar is set on QDockWidget, the title
       bar widget is repositioned accordingly. In resizeEvent(), the title
       bar should check what orientation it should assume:
       \snippet doc/src/snippets/code/src_gui_widgets_qdockwidget.cpp 0

    \o The title bar widget must have a valid QWidget::sizeHint() and
       QWidget::minimumSizeHint(). These functions should take into account
       the current orientation of the title bar.

    \o It is not possible to remove a title bar from a dock widget. However,
       a similar effect can be achieved by setting a default constructed
       QWidget as the title bar widget.
    \endlist

    Using qobject_cast() as shown above, the title bar widget has full access
    to its parent QDockWidget. Hence it can perform such operations as docking
    and hiding in response to user actions.

    \sa titleBarWidget() DockWidgetVerticalTitleBar
*/

void QDockWidget::setTitleBarWidget(QWidget *widget)
{
    Q_D(QDockWidget);
    QDockWidgetLayout *layout
        = qobject_cast<QDockWidgetLayout*>(this->layout());
    layout->setWidgetForRole(QDockWidgetLayout::TitleBar, widget);
    d->updateButtons();
    if (isWindow()) {
        //this ensures the native decoration is drawn
        d->setWindowState(true /*floating*/, true /*unplug*/);
    }
}

/*!
    \since 4.3
    Returns the custom title bar widget set on the QDockWidget, or 0 if no
    custom title bar has been set.

    \sa setTitleBarWidget()
*/

QWidget *QDockWidget::titleBarWidget() const
{
    QDockWidgetLayout *layout
        = qobject_cast<QDockWidgetLayout*>(this->layout());
    return layout->widgetForRole(QDockWidgetLayout::TitleBar);
}

QT_END_NAMESPACE

#include "qdockwidget.moc"
#include "moc_qdockwidget.cpp"

#endif // QT_NO_DOCKWIDGET
