KDDockWidgets API Documentation  1.5
MultiSplitter.cpp
Go to the documentation of this file.
1 /*
2  This file is part of KDDockWidgets.
3 
4  SPDX-FileCopyrightText: 2020-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
5  Author: SĂ©rgio Martins <sergio.martins@kdab.com>
6 
7  SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
8 
9  Contact KDAB at <info@kdab.com> for commercial licensing options.
10 */
11 
20 #include "MultiSplitter_p.h"
21 #include "LayoutSaver_p.h"
22 #include "Config.h"
23 #include "DockRegistry_p.h"
24 #include "DockWidgetBase.h"
25 #include "DockWidgetBase_p.h"
26 #include "FloatingWindow_p.h"
27 #include "Frame_p.h"
28 #include "FrameworkWidgetFactory.h"
29 #include "LayoutSaver.h"
30 #include "Logging_p.h"
31 #include "MainWindowBase.h"
32 #include "Position_p.h"
33 #include "WindowBeingDragged_p.h"
34 #include "multisplitter/Widget.h"
35 
36 #include <QScopedValueRollback>
37 
38 using namespace KDDockWidgets;
39 
40 MultiSplitter::MultiSplitter(QWidgetOrQuick *parent)
41  : LayoutWidget(parent)
42 {
43  Q_ASSERT(parent);
44  setRootItem(new Layouting::ItemBoxContainer(this));
45  DockRegistry::self()->registerLayout(this);
46 
47  setLayoutSize(parent->size());
48 
49  // Initialize min size
50  updateSizeConstraints();
51 
53 }
54 
55 MultiSplitter::~MultiSplitter()
56 {
57 }
58 
59 bool MultiSplitter::validateInputs(QWidgetOrQuick *widget, Location location,
60  const Frame *relativeToFrame, InitialOption option) const
61 {
62  if (!widget) {
63  qWarning() << Q_FUNC_INFO << "Widget is null";
64  return false;
65  }
66 
67  const bool isDockWidget = qobject_cast<DockWidgetBase *>(widget);
68  const bool isStartHidden = option.startsHidden();
69 
70  if (!qobject_cast<Frame *>(widget) && !qobject_cast<MultiSplitter *>(widget) && !isDockWidget) {
71  qWarning() << "Unknown widget type" << widget;
72  return false;
73  }
74 
75  if (isDockWidget != isStartHidden) {
76  qWarning() << "Wrong parameters" << isDockWidget << isStartHidden;
77  return false;
78  }
79 
80  if (relativeToFrame && relativeToFrame == widget) {
81  qWarning() << "widget can't be relative to itself";
82  return false;
83  }
84 
85  Layouting::Item *item = itemForFrame(qobject_cast<Frame *>(widget));
86 
87  if (containsItem(item)) {
88  qWarning() << "MultiSplitter::addWidget: Already contains" << widget;
89  return false;
90  }
91 
92  if (location == Location_None) {
93  qWarning() << "MultiSplitter::addWidget: not adding to location None";
94  return false;
95  }
96 
97  const bool relativeToThis = relativeToFrame == nullptr;
98 
99  Layouting::Item *relativeToItem = itemForFrame(relativeToFrame);
100  if (!relativeToThis && !containsItem(relativeToItem)) {
101  qWarning() << "MultiSplitter::addWidget: Doesn't contain relativeTo:"
102  << "; relativeToFrame=" << relativeToFrame
103  << "; relativeToItem=" << relativeToItem
104  << "; options=" << option;
105  return false;
106  }
107 
108  return true;
109 }
110 
111 void MultiSplitter::addWidget(QWidgetOrQuick *w, Location location,
112  Frame *relativeToWidget,
113  InitialOption option)
114 {
115  auto frame = qobject_cast<Frame *>(w);
116  if (itemForFrame(frame) != nullptr) {
117  // Item already exists, remove it.
118  // Changing the frame parent will make the item clean itself up. It turns into a placeholder and is removed by unrefOldPlaceholders
119  frame->QWidgetAdapter::setParent(nullptr); // so ~Item doesn't delete it
120  frame->setLayoutItem(nullptr); // so Item is destroyed, as there's no refs to it
121  }
122 
123  // Make some sanity checks:
124  if (!validateInputs(w, location, relativeToWidget, option))
125  return;
126 
127  Layouting::Item *relativeTo = itemForFrame(relativeToWidget);
128  if (!relativeTo)
129  relativeTo = m_rootItem;
130 
131  Layouting::Item *newItem = nullptr;
132 
133  Frame::List frames = framesFrom(w);
134  unrefOldPlaceholders(frames);
135  auto dw = qobject_cast<DockWidgetBase *>(w);
136 
137  if (frame) {
138  newItem = new Layouting::Item(this);
139  newItem->setGuestWidget(frame);
140  } else if (dw) {
141  newItem = new Layouting::Item(this);
143  newItem->setGuestWidget(frame);
144  frame->addWidget(dw, option);
145  } else if (auto ms = qobject_cast<MultiSplitter *>(w)) {
146  newItem = ms->m_rootItem;
147  newItem->setHostWidget(this);
148 
149  if (FloatingWindow *fw = ms->floatingWindow()) {
150  newItem->setSize_recursive(fw->size());
151  }
152 
153  delete ms;
154  } else {
155  // This doesn't happen but let's make coverity happy.
156  // Tests will fail if this is ever printed.
157  qWarning() << Q_FUNC_INFO << "Unknown widget added" << w;
158  return;
159  }
160 
161  Q_ASSERT(!newItem->geometry().isEmpty());
162  Layouting::ItemBoxContainer::insertItemRelativeTo(newItem, relativeTo, location, option);
163 
164  if (dw && option.startsHidden())
165  delete frame;
166 }
167 
168 void MultiSplitter::addMultiSplitter(MultiSplitter *sourceMultiSplitter, Location location,
169  Frame *relativeTo,
170  InitialOption option)
171 {
172  qCDebug(addwidget) << Q_FUNC_INFO << sourceMultiSplitter << location << relativeTo;
173  addWidget(sourceMultiSplitter, location, relativeTo, option);
174 }
175 
176 QVector<Layouting::Separator *> MultiSplitter::separators() const
177 {
178  return m_rootItem->separators_recursive();
179 }
180 
181 int MultiSplitter::availableLengthForOrientation(Qt::Orientation orientation) const
182 {
183  if (orientation == Qt::Vertical)
184  return availableSize().height();
185  else
186  return availableSize().width();
187 }
188 
189 QSize MultiSplitter::availableSize() const
190 {
191  return m_rootItem->availableSize();
192 }
193 
194 void MultiSplitter::layoutEqually()
195 {
196  if (!checkSanity())
197  return;
198 
199  layoutEqually(m_rootItem);
200 }
201 
202 void MultiSplitter::layoutEqually(Layouting::ItemBoxContainer *container)
203 {
204  if (container) {
205  container->layoutEqually_recursive();
206  } else {
207  qWarning() << Q_FUNC_INFO << "null container";
208  }
209 }
210 
211 void MultiSplitter::setRootItem(Layouting::ItemBoxContainer *root)
212 {
213  LayoutWidget::setRootItem(root);
214  m_rootItem = root;
215 }
216 
217 Layouting::ItemBoxContainer *MultiSplitter::rootItem() const
218 {
219  return m_rootItem;
220 }
221 
222 QRect MultiSplitter::rectForDrop(const WindowBeingDragged *wbd, Location location,
223  const Layouting::Item *relativeTo) const
224 {
225  Layouting::Item item(nullptr);
226  if (!wbd)
227  return {};
228 
229  item.setSize(wbd->size().boundedTo(wbd->maxSize()));
230  item.setMinSize(wbd->minSize());
231  item.setMaxSizeHint(wbd->maxSize());
232 
233  Layouting::ItemBoxContainer *container = relativeTo ? relativeTo->parentBoxContainer()
234  : m_rootItem;
235 
236  return container->suggestedDropRect(&item, relativeTo, location);
237 }
238 
239 bool MultiSplitter::deserialize(const LayoutSaver::MultiSplitter &l)
240 {
241  setRootItem(new Layouting::ItemBoxContainer(this));
242  return LayoutWidget::deserialize(l);
243 }
DockWidgetBase.h
The DockWidget base-class that's shared between QtWidgets and QtQuick stack.
LayoutSaver.h
Class to save and restore dockwidget layouts.
QRect
KDDockWidgets::InitialOption
Struct describing the preferred dock widget size and visibility when adding it to a layout.
Definition: KDDockWidgets.h:105
Widget.h
An abstraction/wrapper around QWidget, QtQuickItem or anything else.
QWidget
KDDockWidgets::Location
Location
Definition: KDDockWidgets.h:45
QSize
QWidget::setMinimumSize
void setMinimumSize(const QSize &)
MainWindowBase.h
The MainWindow base-class that's shared between QtWidgets and QtQuick stack.
Qt::Orientation
Orientation
KDDockWidgets::Config::frameworkWidgetFactory
FrameworkWidgetFactory * frameworkWidgetFactory() const
getter for the framework widget factory
Definition: Config.cpp:143
KDDockWidgets::FrameworkWidgetFactory::createFrame
virtual Frame * createFrame(QWidgetOrQuick *parent=nullptr, FrameOptions options=FrameOption_None) const =0
Called internally by the framework to create a Frame class Override to provide your own Frame sub-cla...
Config.h
Application-wide config to tune certain behaviours of the framework.
KDDockWidgets::InitialOption::startsHidden
bool startsHidden() const
Definition: KDDockWidgets.h:133
KDDockWidgets
Definition: Config.cpp:36
KDDockWidgets::Location_None
@ Location_None
Definition: KDDockWidgets.h:46
QVector< Layouting::Separator * >
QObject::parent
QObject * parent() const const
KDDockWidgets::Config::self
static Config & self()
returns the singleton Config instance
Definition: Config.cpp:82
FrameworkWidgetFactory.h
A factory class for allowing the user to customize some internal widgets.

© 2019-2022 Klarälvdalens Datakonsult AB (KDAB)
"The Qt, C++ and OpenGL Experts"
https://www.kdab.com/
KDDockWidgets
Advanced Dock Widget Framework for Qt
https://www.kdab.com/development-resources/qt-tools/kddockwidgets/
Generated on Mon Mar 7 2022 02:01:20 for KDDockWidgets API Documentation by doxygen 1.8.20