KDDockWidgets API Documentation  1.6
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 #include "multisplitter/Item_p.h"
36 
37 #include <QScopedValueRollback>
38 
39 using namespace KDDockWidgets;
40 
41 MultiSplitter::MultiSplitter(QWidgetOrQuick *parent)
42  : LayoutWidget(parent)
43 {
44  Q_ASSERT(parent);
45  setRootItem(new Layouting::ItemBoxContainer(this));
46  DockRegistry::self()->registerLayout(this);
47 
48  setLayoutSize(parent->size());
49 
50  // Initialize min size
51  updateSizeConstraints();
52 
53  setMinimumSize(minimumSize());
54 }
55 
56 MultiSplitter::~MultiSplitter()
57 {
58 }
59 
60 bool MultiSplitter::validateInputs(QWidgetOrQuick *widget, Location location,
61  const Frame *relativeToFrame, InitialOption option) const
62 {
63  if (!widget) {
64  qWarning() << Q_FUNC_INFO << "Widget is null";
65  return false;
66  }
67 
68  const bool isDockWidget = qobject_cast<DockWidgetBase *>(widget);
69  const bool isStartHidden = option.startsHidden();
70 
71  if (!qobject_cast<Frame *>(widget) && !qobject_cast<MultiSplitter *>(widget) && !isDockWidget) {
72  qWarning() << "Unknown widget type" << widget;
73  return false;
74  }
75 
76  if (isDockWidget != isStartHidden) {
77  qWarning() << "Wrong parameters" << isDockWidget << isStartHidden;
78  return false;
79  }
80 
81  if (relativeToFrame && relativeToFrame == widget) {
82  qWarning() << "widget can't be relative to itself";
83  return false;
84  }
85 
86  Layouting::Item *item = itemForFrame(qobject_cast<Frame *>(widget));
87 
88  if (containsItem(item)) {
89  qWarning() << "MultiSplitter::addWidget: Already contains" << widget;
90  return false;
91  }
92 
93  if (location == Location_None) {
94  qWarning() << "MultiSplitter::addWidget: not adding to location None";
95  return false;
96  }
97 
98  const bool relativeToThis = relativeToFrame == nullptr;
99 
100  Layouting::Item *relativeToItem = itemForFrame(relativeToFrame);
101  if (!relativeToThis && !containsItem(relativeToItem)) {
102  qWarning() << "MultiSplitter::addWidget: Doesn't contain relativeTo:"
103  << "; relativeToFrame=" << relativeToFrame
104  << "; relativeToItem=" << relativeToItem
105  << "; options=" << option;
106  return false;
107  }
108 
109  return true;
110 }
111 
112 void MultiSplitter::addWidget(QWidgetOrQuick *w, Location location,
113  Frame *relativeToWidget,
114  InitialOption option)
115 {
116  auto frame = qobject_cast<Frame *>(w);
117  if (itemForFrame(frame) != nullptr) {
118  // Item already exists, remove it.
119  // Changing the frame parent will make the item clean itself up. It turns into a placeholder and is removed by unrefOldPlaceholders
120  frame->QWidgetAdapter::setParent(nullptr); // so ~Item doesn't delete it
121  frame->setLayoutItem(nullptr); // so Item is destroyed, as there's no refs to it
122  }
123 
124  // Make some sanity checks:
125  if (!validateInputs(w, location, relativeToWidget, option))
126  return;
127 
128  Layouting::Item *relativeTo = itemForFrame(relativeToWidget);
129  if (!relativeTo)
130  relativeTo = m_rootItem;
131 
132  Layouting::Item *newItem = nullptr;
133 
134  Frame::List frames = framesFrom(w);
135  unrefOldPlaceholders(frames);
136  auto dw = qobject_cast<DockWidgetBase *>(w);
137 
138  if (frame) {
139  newItem = new Layouting::Item(this);
140  newItem->setGuestWidget(frame);
141  } else if (dw) {
142  newItem = new Layouting::Item(this);
144  newItem->setGuestWidget(frame);
145  frame->addWidget(dw, option);
146  } else if (auto ms = qobject_cast<MultiSplitter *>(w)) {
147  newItem = ms->m_rootItem;
148  newItem->setHostWidget(this);
149 
150  if (FloatingWindow *fw = ms->floatingWindow()) {
151  newItem->setSize_recursive(fw->size());
152  }
153 
154  delete ms;
155  } else {
156  // This doesn't happen but let's make coverity happy.
157  // Tests will fail if this is ever printed.
158  qWarning() << Q_FUNC_INFO << "Unknown widget added" << w;
159  return;
160  }
161 
162  Q_ASSERT(!newItem->geometry().isEmpty());
163  Layouting::ItemBoxContainer::insertItemRelativeTo(newItem, relativeTo, location, option);
164 
165  if (dw && option.startsHidden())
166  delete frame;
167 }
168 
169 void MultiSplitter::addMultiSplitter(MultiSplitter *sourceMultiSplitter, Location location,
170  Frame *relativeTo,
171  InitialOption option)
172 {
173  qCDebug(addwidget) << Q_FUNC_INFO << sourceMultiSplitter << location << relativeTo;
174  addWidget(sourceMultiSplitter, location, relativeTo, option);
175 }
176 
177 QVector<Layouting::Separator *> MultiSplitter::separators() const
178 {
179  return m_rootItem->separators_recursive();
180 }
181 
182 int MultiSplitter::availableLengthForOrientation(Qt::Orientation orientation) const
183 {
184  if (orientation == Qt::Vertical)
185  return availableSize().height();
186  else
187  return availableSize().width();
188 }
189 
190 QSize MultiSplitter::availableSize() const
191 {
192  return m_rootItem->availableSize();
193 }
194 
195 void MultiSplitter::layoutEqually()
196 {
197  if (!checkSanity())
198  return;
199 
200  layoutEqually(m_rootItem);
201 }
202 
203 void MultiSplitter::layoutEqually(Layouting::ItemBoxContainer *container)
204 {
205  if (container) {
206  container->layoutEqually_recursive();
207  } else {
208  qWarning() << Q_FUNC_INFO << "null container";
209  }
210 }
211 
212 void MultiSplitter::setRootItem(Layouting::ItemBoxContainer *root)
213 {
214  LayoutWidget::setRootItem(root);
215  m_rootItem = root;
216 }
217 
218 Layouting::ItemBoxContainer *MultiSplitter::rootItem() const
219 {
220  return m_rootItem;
221 }
222 
223 QRect MultiSplitter::rectForDrop(const WindowBeingDragged *wbd, Location location,
224  const Layouting::Item *relativeTo) const
225 {
226  Layouting::Item item(nullptr);
227  if (!wbd)
228  return {};
229 
230  item.setSize(wbd->size().boundedTo(wbd->maxSize()));
231  item.setMinSize(wbd->minSize());
232  item.setMaxSizeHint(wbd->maxSize());
233 
234  Layouting::ItemBoxContainer *container = relativeTo ? relativeTo->parentBoxContainer()
235  : m_rootItem;
236 
237  return container->suggestedDropRect(&item, relativeTo, location);
238 }
239 
240 bool MultiSplitter::deserialize(const LayoutSaver::MultiSplitter &l)
241 {
242  setRootItem(new Layouting::ItemBoxContainer(this));
243  return LayoutWidget::deserialize(l);
244 }
245 
246 int MultiSplitter::numSideBySide_recursive(Qt::Orientation o) const
247 {
248  return m_rootItem->numSideBySide_recursive(o);
249 }
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:101
Widget.h
An abstraction/wrapper around QWidget, QtQuickItem or anything else.
QWidget
KDDockWidgets::Location
Location
Definition: KDDockWidgets.h:44
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:145
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:129
KDDockWidgets
Definition: Config.cpp:37
KDDockWidgets::Location_None
@ Location_None
Definition: KDDockWidgets.h:45
QVector< Layouting::Separator * >
QWidget::size
size
KDDockWidgets::Config::self
static Config & self()
returns the singleton Config instance
Definition: Config.cpp:84
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 Thu Sep 15 2022 00:16:29 for KDDockWidgets API Documentation by doxygen 1.8.20