21#include "private/DockRegistry_p.h" 
   22#include "private/MDILayoutWidget_p.h" 
   23#include "private/DropArea_p.h" 
   24#include "private/Frame_p.h" 
   25#include "private/Utils_p.h" 
   26#include "private/SideBar_p.h" 
   27#include "private/Logging_p.h" 
   28#include "private/WidgetResizeHandler_p.h" 
   30#include "private/DropAreaWithCentralFrame_p.h" 
   31#include "private/LayoutSaver_p.h" 
   32#include "private/DockWidgetBase_p.h" 
   33#include "private/multisplitter/Item_p.h" 
   36#ifdef KDDOCKWIDGETS_QTQUICK 
   49        return new MDILayoutWidget(mainWindow);
 
   51    return new DropAreaWithCentralFrame(mainWindow, options);
 
 
   54class MainWindowBase::Private
 
   61        , m_persistentCentralDockWidget(createPersistentCentralDockWidget(
uniqueName))
 
   65    bool supportsCentralFrame()
 const 
   70    bool supportsPersistentCentralWidget()
 const 
   82        if (!supportsPersistentCentralWidget())
 
   86        dw->dptr()->m_isPersistentCentralDockWidget = 
true;
 
   87        Frame *frame = dropArea()->m_centralFrame;
 
  107    void clearSideBars();
 
  114    LayoutWidget *
const m_layoutWidget;
 
  116    int m_overlayMargin = 1;
 
  122    , d(new Private(this, uniqueName, options))
 
  126    connect(d->m_layoutWidget, &LayoutWidget::visibleWidgetCountChanged, 
this,
 
 
  132    DockRegistry::self()->unregisterMainWindow(
this);
 
 
  157    if (d->supportsPersistentCentralWidget()) {
 
  159                   << 
"MainWindowOption_HasCentralWidget can only have 1 widget in the center." 
  160                   << 
"Use MainWindowOption_HasCentralFrame instead, which is similar but supports tabbing";
 
  161    } 
else if (d->supportsCentralFrame()) {
 
  162        dropArea()->m_centralFrame->addWidget(widget);
 
 
  207    return d->m_layoutWidget;
 
 
  223    if (!d->affinities.isEmpty()) {
 
  225                   << 
"Affinity is already set, refusing to change." 
  226                   << 
"Submit a feature request with a good justification.";
 
 
  235    return d->affinities;
 
 
  248CursorPositions MainWindowBase::Private::allowedResizeSides(
SideBarLocation loc)
 const 
  271    SideBar *sb = q->sideBar(location);
 
  275    const QRect centralAreaGeo = q->centralAreaGeometry();
 
  276    const QMargins centerWidgetMargins = q->centerWidgetMargins();
 
  279    const int margin = m_overlayMargin;
 
  286        const int leftSideBarWidth = (leftSideBar && leftSideBar->isVisible()) ? leftSideBar->
width()
 
  288        const int rightSideBarWidth = (rightSideBar && rightSideBar->isVisible()) ? rightSideBar->width()
 
  290        rect.
setHeight(qMax(300, frame->minSize().height()));
 
  291        rect.
setWidth(centralAreaGeo.
width() - margin * 2 - leftSideBarWidth - rightSideBarWidth);
 
  292        rect.
moveLeft(margin + leftSideBarWidth);
 
  296            rect.
moveTop(centralAreaGeo.
y() + sb->height() + centerWidgetMargins.
top());
 
  304        const int topSideBarHeight = (topSideBar && topSideBar->isVisible()) ? topSideBar->height()
 
  306        const int bottomSideBarHeight = (bottomSideBar && bottomSideBar->isVisible()) ? bottomSideBar->height()
 
  308        rect.
setWidth(qMax(300, frame->minSize().width()));
 
  309        rect.
setHeight(centralAreaGeo.
height() - topSideBarHeight - bottomSideBarHeight - centerWidgetMargins.
top() - centerWidgetMargins.
bottom());
 
  310        rect.
moveTop(sb->mapTo(q, 
QPoint(0, 0)).y() + topSideBarHeight - 1);
 
  312            rect.
moveLeft(centralAreaGeo.
x() + centralAreaGeo.
width() - rect.
width() - sb->width() - centerWidgetMargins.
right() - margin);
 
  314            rect.
moveLeft(margin + centralAreaGeo.
x() + centerWidgetMargins.
left() + sb->width());
 
  329    case Layouting::LayoutBorderLocation_North:
 
  331    case Layouting::LayoutBorderLocation_East:
 
  333    case Layouting::LayoutBorderLocation_West:
 
  335    case Layouting::LayoutBorderLocation_South:
 
  337    case Layouting::LayoutBorderLocation_All:
 
  338    case Layouting::LayoutBorderLocation_Verticals:
 
  339    case Layouting::LayoutBorderLocation_Horizontals:
 
  340    case Layouting::LayoutBorderLocation_None:
 
  344    qWarning() << Q_FUNC_INFO << 
"Unknown loc" << loc;
 
 
  351    case Layouting::LayoutBorderLocation_North:
 
  353    case Layouting::LayoutBorderLocation_East:
 
  355    case Layouting::LayoutBorderLocation_West:
 
  357    case Layouting::LayoutBorderLocation_South:
 
  359    case Layouting::LayoutBorderLocation_All:
 
  360    case Layouting::LayoutBorderLocation_Verticals:
 
  361    case Layouting::LayoutBorderLocation_Horizontals:
 
  362    case Layouting::LayoutBorderLocation_None:
 
 
  373    Layouting::Item *item = q->layoutWidget()->itemForFrame(dw->d->frame());
 
  375        qWarning() << Q_FUNC_INFO << 
"No item for dock widget";
 
  379    const Layouting::LayoutBorderLocations borders = item->adjacentLayoutBorders();
 
  380    const qreal aspectRatio = dw->width() / (std::max(1, dw->height()) * 1.0);
 
  383    if (borders == Layouting::LayoutBorderLocation_All) {
 
  389    for (
auto borderLoc : { Layouting::LayoutBorderLocation_North, Layouting::LayoutBorderLocation_East,
 
  390                            Layouting::LayoutBorderLocation_West, Layouting::LayoutBorderLocation_South }) {
 
  391        if (borders == (Layouting::LayoutBorderLocation_All & ~borderLoc))
 
  396    if ((borders & Layouting::LayoutBorderLocation_Verticals) == Layouting::LayoutBorderLocation_Verticals) {
 
  402    if ((borders & Layouting::LayoutBorderLocation_Horizontals) == Layouting::LayoutBorderLocation_Horizontals) {
 
  408    if (borders == (Layouting::LayoutBorderLocation_West | Layouting::LayoutBorderLocation_South)) {
 
  411    } 
else if (borders == (Layouting::LayoutBorderLocation_East | Layouting::LayoutBorderLocation_South)) {
 
  414    } 
else if (borders == (Layouting::LayoutBorderLocation_West | Layouting::LayoutBorderLocation_North)) {
 
  417    } 
else if (borders == (Layouting::LayoutBorderLocation_East | Layouting::LayoutBorderLocation_North)) {
 
  435void MainWindowBase::Private::updateOverlayGeometry(
QSize suggestedSize)
 
  437    if (!m_overlayedDockWidget)
 
  440    SideBar *sb = q->sideBarForDockWidget(m_overlayedDockWidget);
 
  442        qWarning() << Q_FUNC_INFO << 
"Expected a sidebar";
 
  446    const QRect defaultGeometry = rectForOverlay(m_overlayedDockWidget->d->frame(), sb->location());
 
  447    QRect newGeometry = defaultGeometry;
 
  449    Frame *frame = m_overlayedDockWidget->d->frame();
 
  453        switch (sb->location()) {
 
  455            const int maxHeight = q->
height() - frame->pos().y() - 10; 
 
  460            const int maxHeight = sb->pos().y() - m_layoutWidget->pos().y() - 10; 
 
  461            const int bottom = newGeometry.
bottom();
 
  467            const int maxWidth = sb->pos().x() - m_layoutWidget->pos().x() - 10; 
 
  474            const int maxWidth = q->width() - frame->pos().x() - 10; 
 
  479            qWarning() << Q_FUNC_INFO << 
"Unexpected sidebar value";
 
  484    m_overlayedDockWidget->d->frame()->QWidgetAdapter::setGeometry(newGeometry);
 
  487void MainWindowBase::Private::clearSideBars()
 
  491        if (SideBar *sb = q->sideBar(loc))
 
  503    if (
dw->isPersistentCentralDockWidget())
 
  509        sb->addDockWidget(
dw);
 
  512        qWarning() << 
Q_FUNC_INFO << 
"Minimization supported, probably disabled in Config::self().flags()";
 
 
  519    if (
dw == d->m_overlayedDockWidget)
 
  529    sb->removeDockWidget(
dw);
 
  530    dw->setFloating(
false); 
 
 
  535    if (!
dw || 
dw->isPersistentCentralDockWidget())
 
  540        qWarning() << 
Q_FUNC_INFO << 
"You need to add the dock widget to the sidebar before you can overlay it";
 
  544    if (d->m_overlayedDockWidget == 
dw) {
 
  553    d->m_overlayedDockWidget = 
dw;
 
  554    frame->addWidget(
dw);
 
  555    d->updateOverlayGeometry(
dw->d->lastPosition()->lastOverlayedGeometry(
sb->location()).size());
 
  556    connect(frame, &QWidgetAdapter::widgetGeometryChanged, 
this, [
dw, 
sb, frame] {
 
  560    frame->setAllowedResizeSides(d->allowedResizeSides(
sb->location()));
 
  561    frame->QWidgetAdapter::show();
 
  563    Q_EMIT dw->isOverlayedChanged(
true);
 
 
  577    if (!d->m_overlayedDockWidget)
 
  580    Frame *frame = d->m_overlayedDockWidget->d->frame();
 
  582        d->m_overlayedDockWidget = 
nullptr;
 
  586    frame->disconnect(
this);
 
  590        d->m_overlayedDockWidget->setParent(
nullptr);
 
  591        Q_EMIT d->m_overlayedDockWidget->isOverlayedChanged(
false);
 
  592        d->m_overlayedDockWidget = 
nullptr;
 
  597        Q_EMIT d->m_overlayedDockWidget->isOverlayedChanged(
false);
 
  598        d->m_overlayedDockWidget = 
nullptr;
 
 
  618    return d->m_overlayedDockWidget;
 
 
  624        return !
sb->isEmpty(); 
 
 
  650    const auto dockWidgets = d->m_layoutWidget->dockWidgets();
 
  652        Frame *frame = 
dw->d->frame();
 
  661        if (frame->beingDeletedLater()) {
 
 
  681    if (d->name.isEmpty()) {
 
  684        DockRegistry::self()->registerMainWindow(
this);
 
 
  692    if (d->m_overlayedDockWidget)
 
  693        d->updateOverlayGeometry(d->m_overlayedDockWidget->d->frame()->QWidgetAdapter::size());
 
 
  696bool MainWindowBase::deserialize(
const LayoutSaver::MainWindow &mw)
 
  700                   << 
"; expected=" << 
mw.options << 
"; has=" << 
options();
 
  704    if (d->affinities != 
mw.affinities) {
 
  706                   << 
"; to" << 
mw.affinities;
 
  708        d->affinities = 
mw.affinities;
 
  726                           << 
". Won't restore it to sidebar";
 
  730            sb->addDockWidget(
dw);
 
  741LayoutSaver::MainWindow MainWindowBase::serialize()
 const 
  743    LayoutSaver::MainWindow 
m;
 
  753    m.affinities = d->affinities;
 
  778    return d->m_overlayMargin;
 
 
  783    if (margin == d->m_overlayMargin) {
 
  787    d->m_overlayMargin = margin;
 
 
  793    if (!d->supportsPersistentCentralWidget()) {
 
  794        qWarning() << 
"MainWindow::setPersistentCentralWidget() requires MainWindowOption_HasCentralWidget";
 
  798    auto dw = d->m_persistentCentralDockWidget;
 
  800        dw->setWidget(widget);
 
 
  808    if (
auto dw = d->m_persistentCentralDockWidget)
 
 
  816    d->m_layoutWidget->onCloseEvent(
e);
 
 
static LayoutWidget * createLayoutWidget(MainWindowBase *mainWindow, MainWindowOptions options)
static SideBarLocation sideBarLocationForBorder(Layouting::LayoutBorderLocations loc)
static SideBarLocation opposedSideBarLocationForBorder(Layouting::LayoutBorderLocation loc)
The MainWindow base-class that's shared between QtWidgets and QtQuick stack.
The MainWindow base-class. MainWindow and MainWindowBase are only split in two so we can share some c...
Q_INVOKABLE void toggleOverlayOnSideBar(KDDockWidgets::DockWidgetBase *)
Shows or hides an overlay. It's assumed the dock widget is already in a side-bar.
Q_INVOKABLE void moveToSideBar(KDDockWidgets::DockWidgetBase *)
Moves the dock widget into one of the MainWindow's sidebar. Means the dock widget is removed from the...
MainWindowBase(const QString &uniqueName, MainWindowOptions options=MainWindowOption_HasCentralFrame, WidgetType *parent=nullptr, Qt::WindowFlags flags=Qt::WindowFlags())
virtual SideBar * sideBar(SideBarLocation) const =0
void overlayMarginChanged(int)
Q_INVOKABLE void overlayOnSideBar(KDDockWidgets::DockWidgetBase *)
Shows the dock widget overlayed on top of the main window, placed next to the sidebar.
DockWidgetBase * overlayedDockWidget() const
returns the dock widget which is currently overlayed. nullptr if none. This is only relevant when usi...
void onResized(QResizeEvent *)
MDILayoutWidget * mdiLayoutWidget() const
Q_INVOKABLE void setPersistentCentralWidget(KDDockWidgets::QWidgetOrQuick *widget)
Sets a persistent central widget. It can't be detached.
Q_INVOKABLE void restoreFromSideBar(KDDockWidgets::DockWidgetBase *)
Removes the dock widget from the sidebar and docks it into the main window again.
void setAffinities(const QStringList &names)
Sets the affinities names. Dock widgets can only dock into main windows of the same affinity.
QRect windowGeometry() const
Returns the window geometry This is usually the same as MainWindowBase::geometry() But fixes the foll...
void setUniqueName(const QString &uniqueName)
Q_INVOKABLE void layoutParentContainerEqually(KDDockWidgets::DockWidgetBase *dockWidget)
like layoutEqually() but starts with the container that has dockWidget. While layoutEqually() starts ...
LayoutWidget * layoutWidget() const
Q_INVOKABLE KDDockWidgets::SideBar * sideBarForDockWidget(const KDDockWidgets::DockWidgetBase *) const
Returns the sidebar this dockwidget is in. nullptr if not in any.
DropAreaWithCentralFrame * dropArea() const
Q_INVOKABLE void clearSideBarOverlay(bool deleteFrame=true)
closes any overlayed dock widget. The sidebar still displays them as button.
void frameCountChanged(int)
emitted when the number of docked frames changes Note that we're using the "Frame" nomenculature inst...
~MainWindowBase() override
void setOverlayMargin(int margin)
Sets the margin used by overlay docks. Does not modify currently overlayed docks.
Q_INVOKABLE bool sideBarIsVisible(KDDockWidgets::SideBarLocation) const
Returns whether the specified sidebar is visible.
Q_INVOKABLE void addDockWidgetAsTab(KDDockWidgets::DockWidgetBase *dockwidget)
Docks a DockWidget into the central frame, tabbed.
Q_INVOKABLE void layoutEqually()
layouts all the widgets so they have an equal size within their parent container
Q_INVOKABLE void addDockWidget(KDDockWidgets::DockWidgetBase *dockWidget, KDDockWidgets::Location location, KDDockWidgets::DockWidgetBase *relativeTo=nullptr, KDDockWidgets::InitialOption initialOption={})
Docks a DockWidget into this main window.
bool anySideBarIsVisible() const
Returns whether any side bar is visible.
QWidgetOrQuick * persistentCentralWidget() const
KDDockWidgets::MainWindowOptions options
void onCloseEvent(QCloseEvent *)
Q_INVOKABLE bool closeDockWidgets(bool force=false)
Closes all dock widgets which are docked into this main window This is convenience to calling DockWid...
MultiSplitter * multiSplitter() const
void insert(int i, const T &value)
int removeAll(const T &value)
T value(int i) const const
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
T qobject_cast(QObject *object)
void setHeight(int height)
bool isEmpty() const const
bool isValid() const const
bool isEmpty() const const
QTextStream & right(QTextStream &stream)
Qt::WindowState windowState() const const