13#include "private/DockWidgetBase_p.h" 
   14#include "private/DockRegistry_p.h" 
   15#include "private/FloatingWindow_p.h" 
   16#include "private/Frame_p.h" 
   17#include "private/LayoutSaver_p.h" 
   18#include "private/Logging_p.h" 
   19#include "private/MDILayoutWidget_p.h" 
   20#include "private/SideBar_p.h" 
   21#include "private/TitleBar_p.h" 
   22#include "private/Utils_p.h" 
   23#include "private/WindowBeingDragged_p.h" 
   24#include "private/Position_p.h" 
   32#include <QScopedValueRollback> 
   44                               LayoutSaverOptions layoutSaverOptions)
 
   45    : QWidgetAdapter(nullptr, 
Qt::Tool)
 
   46    , d(new Private(name, options, layoutSaverOptions, this))
 
   49    DockRegistry::self()->registerDockWidget(
this);
 
   52        qWarning() << Q_FUNC_INFO << 
"Name can't be null";
 
 
   59    DockRegistry::self()->unregisterDockWidget(
this);
 
 
   66        qWarning() << Q_FUNC_INFO << 
"Refusing to add dock widget into itself" << other;
 
   71        qWarning() << Q_FUNC_INFO << 
"dock widget is null";
 
   75    if (!DockRegistry::self()->affinitiesMatch(other->
affinities(), d->affinities)) {
 
   76        qWarning() << Q_FUNC_INFO << 
"Refusing to dock widget with incompatible affinity." 
   82        qWarning() << Q_FUNC_INFO << 
"Refusing to dock non-dockable widget" << other;
 
   87        qWarning() << Q_FUNC_INFO << 
"Not supported with MainWindowOption_HasCentralWidget." 
   88                   << 
"MainWindowOption_HasCentralWidget can only have 1 widget in the center." 
   89                   << 
"Use MainWindowOption_HasCentralFrame instead, which is similar but supports tabbing.";
 
   93    Frame *frame = d->frame();
 
   96        if (frame->containsDockWidget(other)) {
 
   97            qWarning() << Q_FUNC_INFO << 
"Already contains" << other;
 
  103            d->morphIntoFloatingWindow();
 
  107            qWarning() << Q_FUNC_INFO << 
"null frame";
 
  112    other->setParent(
nullptr);
 
  113    frame->addWidget(other, option);
 
 
  121    if (
auto mainWindow = qobject_cast<MainWindowBase *>(window())) {
 
  127    if (!DockRegistry::self()->affinitiesMatch(other->
affinities(), d->affinities)) {
 
  128        qWarning() << Q_FUNC_INFO << 
"Refusing to dock widget with incompatible affinity." 
  134        qWarning() << Q_FUNC_INFO << 
"Refusing to dock non-dockable widget" << other;
 
  139        d->morphIntoFloatingWindow();
 
  141    if (
auto fw = floatingWindow()) {
 
  142        fw->addDockWidget(other, location, relativeTo, initialOption);
 
  144        qWarning() << Q_FUNC_INFO << 
"Couldn't find floating nested window";
 
 
  155        d->widget->setParent(
nullptr);
 
 
  175    auto fw = floatingWindow();
 
  176    return fw && fw->hasSingleDockWidget();
 
 
  183    if (floats == alreadyFloating)
 
  198            auto frame = d->frame();
 
  200                qWarning() << 
"DockWidget::setFloating: Tabbed but no frame exists" 
  206            frame->detachTab(
this);
 
  211        auto lastGeo = d->lastPosition()->lastFloatingGeometry();
 
  212        if (lastGeo.isValid()) {
 
  213            if (
auto fw = floatingWindow())
 
  218        d->saveLastFloatingGeometry();
 
  219        return d->restoreToPreviousPosition();
 
 
  225    return d->toggleAction;
 
 
  230    return d->floatAction;
 
 
  240    if (d->isMDIWrapper()) {
 
  242        auto dropAreaGuest = qobject_cast<DropArea *>(
widget());
 
  243        Q_ASSERT(dropAreaGuest);
 
  244        if (dropAreaGuest->hasSingleFrame()) {
 
  245            return dropAreaGuest->frames().constFirst()->title();
 
  247            return qApp->applicationName();
 
 
  256    if (
title != d->title) {
 
 
  265    if (
Frame *f = d->frame())
 
  266        return f->QWidgetAdapter::geometry();
 
  269    return QWidgetAdapter::geometry();
 
 
  279    return d->layoutSaverOptions;
 
 
  285        qWarning() << Q_FUNC_INFO << 
"Option_NotDockable not allowed to change. Pass via ctor only.";
 
 
  299    if (
Frame *frame = d->frame()) {
 
  300        return frame->alwaysShowsTabs() || frame->dockWidgetCount() > 1;
 
  303            qWarning() << 
"DockWidget::isTabbed() Couldn't find any tab widget.";
 
 
  310    if (
Frame *frame = d->frame()) {
 
  311        return frame->currentIndex() == frame->indexOfDockWidget(
const_cast<DockWidgetBase *
>(
this));
 
 
  319    if (
Frame *frame = d->frame())
 
  320        frame->setCurrentDockWidget(
this);
 
 
  325    if (
Frame *frame = d->frame())
 
  326        return frame->indexOfDockWidget(
this);
 
 
  333    if (
Frame *frame = d->frame())
 
  334        return frame->currentTabIndex();
 
 
  342        d->titleBarIcon = 
icon;
 
  345        d->tabBarIcon = 
icon;
 
  348        d->toggleAction->setIcon(
icon);
 
 
  356        return d->titleBarIcon;
 
  359        return d->tabBarIcon;
 
  362        return d->toggleAction->icon();
 
 
  374    if (
Frame *f = d->frame())
 
  375        return f->actualTitleBar();
 
 
  382    return d->toggleAction->isChecked();
 
 
  387    return d->affinities;
 
 
  392    if (isWindow() && (d->m_lastPosition->wasFloating() || !d->m_lastPosition->isValid())) {
 
  395        d->morphIntoFloatingWindow();
 
 
  408    if (
auto fw = floatingWindow()) {
 
  410        fw->activateWindow();
 
  411    } 
else if (
Frame *frame = d->frame()) {
 
 
  419    return qobject_cast<MainWindowBase *>(
widget());
 
 
  424    return d->mainWindow() != 
nullptr;
 
 
  429    return d->mainWindow();
 
 
  451    if (!d->affinities.isEmpty()) {
 
  452        qWarning() << Q_FUNC_INFO
 
  453                   << 
"Affinity is already set, refusing to change." 
  454                   << 
"Submit a feature request with a good justification.";
 
 
  464        m->moveToSideBar(
this);
 
 
  470        return m->overlayedDockWidget() == 
this;
 
 
  477    return DockRegistry::self()->sideBarLocationForDockWidget(
this);
 
 
  487    return d->m_lastPosition->isValid();
 
 
  492    return d->m_lastOverlayedSize;
 
 
  497    return DockRegistry::self()->dockByName(
uniqueName);
 
 
  508        window()->setGeometry(geometry);
 
  510        d->m_lastPosition->setLastFloatingGeometry(geometry);
 
 
  514FloatingWindow *DockWidgetBase::Private::morphIntoFloatingWindow()
 
  516    if (
auto fw = floatingWindow())
 
  520        QRect geo = m_lastPosition->lastFloatingGeometry();
 
  526                const QPoint center = defaultCenterPosForFloating();
 
  527                if (!center.isNull())
 
  535        FloatingWindow::ensureRectIsOnScreen(geo);
 
  536        auto floatingWindow =
 
  538        floatingWindow->show();
 
  540        return floatingWindow;
 
  546void DockWidgetBase::Private::maybeMorphIntoFloatingWindow()
 
  548    if (q->isWindow() && q->isVisible())
 
  549        morphIntoFloatingWindow();
 
  552MDILayoutWidget *DockWidgetBase::Private::mdiLayout()
 const 
  554    auto p = 
const_cast<QObject *
>(q->parent());
 
  556        if (qobject_cast<const QWindow *>(p)) {
 
  561        if (qobject_cast<LayoutWidget *>(p)) {
 
  563            if (
auto mdiLayout = qobject_cast<MDILayoutWidget *>(p)) {
 
  566            } 
else if (
auto dropArea = qobject_cast<DropArea *>(p)) {
 
  569                if (!dropArea->isMDIWrapper())
 
  582bool DockWidgetBase::Private::isMDIWrapper()
 const 
  584    return mdiDropAreaWrapper() != 
nullptr;
 
  587DropArea *DockWidgetBase::Private::mdiDropAreaWrapper()
 const 
  589    if (
auto dropAreaGuest = qobject_cast<DropArea *>(q->widget())) {
 
  590        if (dropAreaGuest->isMDIWrapper())
 
  591            return dropAreaGuest;
 
  597DockWidgetBase *DockWidgetBase::Private::mdiDockWidgetWrapper()
 const 
  599    if (isMDIWrapper()) {
 
  604    auto p = 
const_cast<QObject *
>(q->parent());
 
  606        if (qobject_cast<const QWindow *>(p)) {
 
  611        if (qobject_cast<LayoutWidget *>(p)) {
 
  612            if (
auto dropArea = qobject_cast<DropArea *>(p)) {
 
  613                if (dropArea->isMDIWrapper())
 
  614                    return dropArea->mdiDockWidgetWrapper();
 
  626DockWidgetBase::Private *DockWidgetBase::dptr()
 const 
  631QPoint DockWidgetBase::Private::defaultCenterPosForFloating()
 
  636    if (!mw || !q->isFloating())
 
  642bool DockWidgetBase::Private::eventFilter(
QObject *watched, 
QEvent *event)
 
  646    if ((isWindowActivate || isWindowDeactivate) && watched == q->window())
 
  647        Q_EMIT q->windowActiveAboutToChange(isWindowActivate);
 
  652void DockWidgetBase::Private::updateTitle()
 
  655        q->window()->setWindowTitle(title);
 
  657    toggleAction->setText(title);
 
  660void DockWidgetBase::Private::toggle(
bool enabled)
 
  662    if (SideBar *sb = sideBar()) {
 
  664        sb->toggleOverlay(q);
 
  675void DockWidgetBase::Private::updateToggleAction()
 
  678    m_updatingToggleAction = 
true;
 
  679    if ((q->isVisible() || frame()) && !toggleAction->isChecked()) {
 
  680        toggleAction->setChecked(
true);
 
  681    } 
else if ((!q->isVisible() && !frame()) && toggleAction->isChecked()) {
 
  682        toggleAction->setChecked(
false);
 
  686void DockWidgetBase::Private::updateFloatAction()
 
  690    if (q->isFloating()) {
 
  691        floatAction->setEnabled(m_lastPosition->isValid());
 
  692        floatAction->setChecked(
true);
 
  693        floatAction->setToolTip(tr(
"Dock"));
 
  695        floatAction->setEnabled(
true);
 
  696        floatAction->setChecked(
false);
 
  697        floatAction->setToolTip(tr(
"Detach"));
 
  701void DockWidgetBase::Private::onDockWidgetShown()
 
  703    updateToggleAction();
 
  707void DockWidgetBase::Private::onDockWidgetHidden()
 
  709    updateToggleAction();
 
  713void DockWidgetBase::Private::close()
 
  715    if (!m_processingToggleAction && !q->isOpen()) {
 
  719    if (m_isPersistentCentralDockWidget)
 
  723    if (SideBar *sb = DockRegistry::self()->sideBarForDockWidget(q)) {
 
  724        auto mainWindow = sb->mainWindow();
 
  725        if (mainWindow->overlayedDockWidget() == q) {
 
  726            mainWindow->clearSideBarOverlay(
false);
 
  730    if (!m_isForceClosing && q->isFloating()
 
  734        m_lastPosition->setLastFloatingGeometry(q->window()->geometry());
 
  740    if (Frame *frame = this->frame()) {
 
  741        q->setParent(
nullptr);
 
  742        frame->removeWidget(q);
 
  744        if (SideBar *sb = DockRegistry::self()->sideBarForDockWidget(q)) {
 
  745            sb->removeDockWidget(q);
 
  750        Q_EMIT q->aboutToDeleteOnClose();
 
  755bool DockWidgetBase::Private::restoreToPreviousPosition()
 
  757    if (!m_lastPosition->isValid())
 
  760    Layouting::Item *item = m_lastPosition->lastItem();
 
  762    LayoutWidget *layout = DockRegistry::self()->layoutForItem(item);
 
  764    layout->restorePlaceholder(q, item, m_lastPosition->lastTabIndex());
 
  768void DockWidgetBase::Private::maybeRestoreToPreviousPosition()
 
  772    if (!m_lastPosition->isValid())
 
  775    Layouting::Item *layoutItem = m_lastPosition->lastItem();
 
  779    if (m_lastPosition->wasFloating())
 
  782    Frame *frame = this->frame();
 
  784    if (frame && frame->QWidgetAdapter::parentWidget() == DockRegistry::self()->layoutForItem(layoutItem)) {
 
  792    if (q->parentWidget()) {
 
  798    restoreToPreviousPosition();
 
  801int DockWidgetBase::Private::currentTabIndex()
 const 
  803    Frame *frame = this->frame();
 
  804    return frame ? frame->indexOfDockWidget(q) : 0;
 
  807void DockWidgetBase::Private::saveTabIndex()
 
  809    m_lastPosition->saveTabIndex(currentTabIndex(), q->isFloating());
 
  812void DockWidgetBase::Private::show()
 
  820#ifdef KDDOCKWIDGETS_QTWIDGETS 
  823    Q_EMIT QQuickItem::parentChanged(parentItem());
 
  825    d->updateToggleAction();
 
  826    d->updateFloatAction();
 
 
  833    d->onDockWidgetShown();
 
  836    if (
Frame *f = d->frame()) {
 
  838            f->onDockWidgetShown(
this);
 
  842    d->maybeRestoreToPreviousPosition();
 
 
  850    d->onDockWidgetHidden();
 
  853    if (
Frame *f = d->frame()) {
 
  855            f->onDockWidgetHidden(
this);
 
 
  863        if (
auto frame = d->frame()) {
 
  864            d->m_lastOverlayedSize = frame->QWidgetAdapter::size();
 
  866            qWarning() << Q_FUNC_INFO << 
"Overlayed dock widget without frame shouldn't happen";
 
  870    return QWidgetAdapter::onResize(newSize);
 
 
  877        qApp->sendEvent(d->widget, e); 
 
 
  883DockWidgetBase *DockWidgetBase::deserialize(
const LayoutSaver::DockWidget::Ptr &saved)
 
  885    auto dr = DockRegistry::self();
 
  886    DockWidgetBase *dw = dr->dockByName(saved->uniqueName, DockRegistry::DockByNameFlag::CreateIfNotFound);
 
  890        dw->setProperty(
"kddockwidget_was_restored", 
true);
 
  893            qWarning() << Q_FUNC_INFO << 
"Affinity name changed from" << dw->
affinities()
 
  894                       << 
"; to" << saved->affinities;
 
  895            dw->d->affinities = saved->affinities;
 
  909    return d->m_userType;
 
 
  915        if (
auto wrapperDW = d->mdiDockWidgetWrapper()) {
 
  917            layout->moveDockWidget(wrapperDW, pos);
 
  919            layout->moveDockWidget(
this, pos);
 
 
  927        if (
auto wrapperDW = d->mdiDockWidgetWrapper()) {
 
  929            layout->resizeDockWidget(wrapperDW, size);
 
  931            layout->resizeDockWidget(
this, size);
 
 
  938#ifdef KDDOCKWIDGETS_QTQUICK 
  939    if (
Frame *frame = d->frame()) {
 
  946    qWarning() << Q_FUNC_INFO << 
"Not implemented for QtQuick";
 
 
  952    return d->m_isPersistentCentralDockWidget;
 
 
  955LayoutSaver::DockWidget::Ptr DockWidgetBase::Private::serialize()
 const 
  957    auto ptr = LayoutSaver::DockWidget::dockWidgetForName(q->uniqueName());
 
  958    ptr->affinities = q->affinities();
 
  963void DockWidgetBase::Private::forceClose()
 
  969DockWidgetBase::Private::Private(
const QString &dockName, DockWidgetBase::Options options_,
 
  976    , layoutSaverOptions(layoutSaverOptions_)
 
  981        if (!m_updatingToggleAction) { 
 
  985            m_processingToggleAction = 
true;
 
  988            m_processingToggleAction = 
false;
 
  993        if (!m_updatingFloatAction) { 
 
  994            q->setFloating(checked);
 
  997        Q_EMIT q->isFloatingChanged(checked);
 
 1000        if (checked && q->isOpen()) {
 
 1001            if (SideBar *sb = DockRegistry::self()->sideBarForDockWidget(q)) {
 
 1002                sb->mainWindow()->clearSideBarOverlay(
false);
 
 1003                sb->removeDockWidget(q);
 
 1011    qApp->installEventFilter(
this);
 
 1014void DockWidgetBase::Private::addPlaceholderItem(Layouting::Item *item)
 
 1017    m_lastPosition->addPlaceholderItem(item);
 
 1020Position::Ptr &DockWidgetBase::Private::lastPosition()
 
 1022    return m_lastPosition;
 
 1025Frame *DockWidgetBase::Private::frame()
 const 
 1029        if (
auto frame = qobject_cast<Frame *>(p))
 
 1036void DockWidgetBase::Private::saveLastFloatingGeometry()
 
 1038    if (q->isFloating() && q->isVisible()) {
 
 1040        lastPosition()->setLastFloatingGeometry(q->window()->geometry());
 
 1046    if (floatingWindow()) {
 
 1047        qWarning() << Q_FUNC_INFO << 
"Call this function only before having a floating window";
 
 
Application-wide config to tune certain behaviours of the framework.
The MainWindow base-class. MainWindow and MainWindowBase are only split in two so we can share some c...
Q_INVOKABLE void addDockWidget(KDDockWidgets::DockWidgetBase *dockWidget, KDDockWidgets::Location location, KDDockWidgets::DockWidgetBase *relativeTo=nullptr, KDDockWidgets::InitialOption initialOption={})
Docks a DockWidget into this main window.
void toggled(bool checked)
bool isAccepted() const const
int removeAll(const T &value)
bool blockSignals(bool block)
virtual bool eventFilter(QObject *watched, QEvent *event)
QObject * parent() const const
bool isNull() const const
void moveCenter(const QPoint &position)
void setSize(const QSize &size)
QSize boundedTo(const QSize &otherSize) const const
bool isEmpty() const const
const T & constFirst() const const
bool isEmpty() const const