22#include "core/LayoutSaver_p.h"
23#include "core/Logging_p.h"
24#include "core/Position_p.h"
25#include "core/Utils_p.h"
26#include "core/View_p.h"
34#include "core/DockWidget_p.h"
36#include "core/nlohmann_helpers_p.h"
37#include "core/layouting/Item_p.h"
67std::map<QString, LayoutSaver::DockWidget::Ptr> LayoutSaver::DockWidget::s_dockWidgets;
68LayoutSaver::Layout *LayoutSaver::Layout::s_currentLayoutBeingRestored =
nullptr;
73 InternalRestoreOptions ret = {};
75 ret.setFlag(InternalRestoreOption::SkipMainWindowGeometry);
76 ret.setFlag(InternalRestoreOption::RelativeFloatingWindowGeometry);
80 ret.setFlag(InternalRestoreOption::RelativeFloatingWindowGeometry,
false);
85 KDDW_ERROR(
"Unknown options={}",
int(options));
91bool LayoutSaver::Private::s_restoreInProgress =
false;
96T
jsonValue(
const nlohmann::json &json,
const char *name,
const T &defaultValue)
100 return json.value(name, defaultValue);
106template<
typename Type>
107void to_json(nlohmann::json &json,
const typename Type::List &list)
109 for (
const auto &l : list) {
114void to_json(nlohmann::json &json,
const LayoutSaver::Group &f)
117 json[
"isNull"] = f.isNull;
118 json[
"objectName"] = f.objectName;
119 json[
"geometry"] = f.geometry;
120 json[
"options"] = f.options;
121 json[
"currentTabIndex"] = f.currentTabIndex;
122 json[
"mainWindowUniqueName"] = f.mainWindowUniqueName;
123 json[
"dockWidgets"] = dockWidgetNames(f.dockWidgets);
125void from_json(
const nlohmann::json &json, LayoutSaver::Group &f)
128 f.isNull =
jsonValue(json,
"isNull",
true);
130 f.geometry =
jsonValue(json,
"geometry", Rect());
132 f.currentTabIndex =
jsonValue(json,
"currentTabIndex", 0);
133 f.mainWindowUniqueName =
jsonValue(json,
"mainWindowUniqueName",
QString());
135 auto it = json.find(
"dockWidgets");
136 if (it == json.end())
139 auto &dockWidgets = *it;
140 f.dockWidgets.reserve((
int )dockWidgets.size());
141 for (
const auto &d : dockWidgets) {
142 LayoutSaver::DockWidget::Ptr dw =
143 LayoutSaver::DockWidget::dockWidgetForName(d.get<
QString>());
144 f.dockWidgets.push_back(dw);
148void to_json(nlohmann::json &json,
const LayoutSaver::MultiSplitter &s)
150 json[
"layout"] = s.layout;
151 auto &groups = json[
"frames"];
152 for (
const auto &it : s.groups) {
153 const auto &group = it.second;
154 groups[group.id.toStdString()] = group;
158void from_json(
const nlohmann::json &json, LayoutSaver::MultiSplitter &s)
161 s.layout =
jsonValue(json,
"layout", nlohmann::json::object());
162 auto it = json.find(
"frames");
163 if (it == json.end())
169 if (!frms.is_object())
170 KDDW_ERROR(
"Unexpected not object");
172 for (
const auto &kv : frms.items()) {
174 auto group = kv.value().get<LayoutSaver::Group>();
175 s.groups[key] = group;
179void to_json(nlohmann::json &json,
const LayoutSaver::MainWindow &mw)
181 json[
"options"] = int(mw.options);
182 json[
"multiSplitterLayout"] = mw.multiSplitterLayout;
183 json[
"uniqueName"] = mw.uniqueName;
184 json[
"geometry"] = mw.geometry;
185 json[
"normalGeometry"] = mw.normalGeometry;
186 json[
"screenIndex"] = mw.screenIndex;
187 json[
"screenSize"] = mw.screenSize;
188 json[
"isVisible"] = mw.isVisible;
189 json[
"affinities"] = mw.affinities;
190 json[
"windowState"] = mw.windowState;
196 std::string key = std::string(
"sidebar-") + std::to_string((
int )loc);
197 json[key] = dockWidgets;
202void from_json(
const nlohmann::json &json, LayoutSaver::MainWindow &mw)
204 mw.options =
static_cast<decltype(mw.options)
>(
jsonValue(json,
"options", 0));
205 mw.multiSplitterLayout =
jsonValue(json,
"multiSplitterLayout", LayoutSaver::MultiSplitter());
207 mw.geometry =
jsonValue(json,
"geometry", Rect());
208 mw.normalGeometry =
jsonValue(json,
"normalGeometry", Rect());
209 mw.screenIndex =
jsonValue(json,
"screenIndex", 0);
210 mw.screenSize =
jsonValue(json,
"screenSize", Size(800, 600));
211 mw.isVisible =
jsonValue(json,
"isVisible",
false);
217 if (json.find(
"affinityName") != json.end()) {
219 if (!mw.affinities.contains(affinityName)) {
226 std::string key = std::string(
"sidebar-") + std::to_string((
int )loc);
227 auto it = json.find(key);
228 if (it == json.end())
231 if (val.is_array() && !val.empty()) {
237void to_json(nlohmann::json &json,
const LayoutSaver::FloatingWindow &window)
239 json[
"multiSplitterLayout"] = window.multiSplitterLayout;
240 json[
"parentIndex"] = window.parentIndex;
241 json[
"geometry"] = window.geometry;
242 json[
"normalGeometry"] = window.normalGeometry;
243 json[
"screenIndex"] = window.screenIndex;
244 json[
"screenSize"] = window.screenSize;
245 json[
"flags"] = window.flags;
246 json[
"isVisible"] = window.isVisible;
247 json[
"windowState"] = window.windowState;
249 if (!window.affinities.isEmpty()) {
250 json[
"affinities"] = window.affinities;
254void from_json(
const nlohmann::json &json, LayoutSaver::FloatingWindow &window)
256 window.multiSplitterLayout =
jsonValue(json,
"multiSplitterLayout", LayoutSaver::MultiSplitter());
257 window.parentIndex =
jsonValue(json,
"parentIndex", -1);
258 window.geometry =
jsonValue(json,
"geometry", Rect());
259 window.normalGeometry =
jsonValue(json,
"normalGeometry", Rect());
260 window.screenIndex =
jsonValue(json,
"screenIndex", 0);
261 window.screenSize =
jsonValue(json,
"screenSize", Size(800, 600));
262 window.isVisible =
jsonValue(json,
"isVisible",
false);
270 if (!affinityName.
isEmpty() && !window.affinities.contains(affinityName)) {
271 window.affinities.push_back(affinityName);
275void to_json(nlohmann::json &json,
const LayoutSaver::ScreenInfo &screenInfo)
277 json[
"index"] = screenInfo.index;
278 json[
"geometry"] = screenInfo.geometry;
279 json[
"name"] = screenInfo.name;
280 json[
"devicePixelRatio"] = screenInfo.devicePixelRatio;
282void from_json(
const nlohmann::json &j, LayoutSaver::ScreenInfo &screenInfo)
284 screenInfo.index = j.value(
"index", 0);
285 screenInfo.geometry = j.value(
"geometry", Rect());
286 screenInfo.name = j.value(
"name",
QString());
287 screenInfo.devicePixelRatio = j.value(
"devicePixelRatio", 1.0);
290void to_json(nlohmann::json &json,
const LayoutSaver::Placeholder &placeHolder)
292 json[
"isFloatingWindow"] = placeHolder.isFloatingWindow;
293 json[
"itemIndex"] = placeHolder.itemIndex;
294 if (placeHolder.isFloatingWindow)
295 json[
"indexOfFloatingWindow"] = placeHolder.indexOfFloatingWindow;
297 json[
"mainWindowUniqueName"] = placeHolder.mainWindowUniqueName;
300void from_json(
const nlohmann::json &json, LayoutSaver::Placeholder &placeHolder)
302 placeHolder.isFloatingWindow =
jsonValue(json,
"isFloatingWindow",
false);
303 placeHolder.itemIndex =
jsonValue(json,
"itemIndex", 0);
304 placeHolder.indexOfFloatingWindow =
jsonValue(json,
"indexOfFloatingWindow", -1);
305 placeHolder.mainWindowUniqueName =
jsonValue(json,
"mainWindowUniqueName",
QString());
308void to_json(nlohmann::json &json,
const LayoutSaver::Position &pos)
310 json[
"lastFloatingGeometry"] = pos.lastFloatingGeometry;
311 json[
"lastOverlayedGeometries"] = pos.lastOverlayedGeometries;
312 json[
"tabIndex"] = pos.tabIndex;
313 json[
"wasFloating"] = pos.wasFloating;
314 json[
"placeholders"] = pos.placeholders;
317void from_json(
const nlohmann::json &json, LayoutSaver::Position &pos)
319 pos.lastFloatingGeometry =
jsonValue(json,
"lastFloatingGeometry", Rect());
320 pos.lastOverlayedGeometries =
jsonValue(json,
"lastOverlayedGeometries", std::unordered_map<KDDockWidgets::SideBarLocation, Rect>());
321 pos.tabIndex =
jsonValue(json,
"tabIndex", 0);
322 pos.wasFloating =
jsonValue(json,
"wasFloating",
false);
323 pos.placeholders =
jsonValue(json,
"placeholders", LayoutSaver::Placeholder::List());
326void to_json(nlohmann::json &json,
const LayoutSaver::DockWidget &dw)
328 if (!dw.affinities.isEmpty())
329 json[
"affinities"] = dw.affinities;
330 json[
"uniqueName"] = dw.uniqueName;
331 json[
"lastPosition"] = dw.lastPosition;
333void from_json(
const nlohmann::json &json, LayoutSaver::DockWidget &dw)
335 auto it = json.find(
"affinities");
336 if (it != json.end())
340 if (dw.uniqueName.isEmpty())
341 KDDW_ERROR(
"Unexpected no uniqueName for dockWidget");
343 dw.lastPosition =
jsonValue(json,
"lastPosition", LayoutSaver::Position());
346void to_json(nlohmann::json &json,
const typename LayoutSaver::DockWidget::List &list)
348 for (
const auto &mw : list) {
353void from_json(
const nlohmann::json &json,
typename LayoutSaver::DockWidget::List &list)
356 for (
const auto &v : json) {
357 auto it = v.find(
"uniqueName");
359 KDDW_ERROR(
"Unexpected no uniqueName");
363 auto dw = LayoutSaver::DockWidget::dockWidgetForName(uniqueName);
372 : d(new Private(options))
374 d->m_dockRegistry->registerLayoutSaver();
379 d->m_dockRegistry->unregisterLayoutSaver();
387 std::ofstream file(jsonFilename.
toStdString(), std::ios::binary);
388 if (!file.is_open()) {
389 KDDW_ERROR(
"Failed to open {}", jsonFilename);
411 if (!d->m_dockRegistry->isSane()) {
412 KDDW_ERROR(
"Refusing to serialize this layout. Check previous warnings.");
416 LayoutSaver::Layout layout;
419 d->m_dockRegistry->ensureAllFloatingWidgetsAreMorphed();
421 const auto mainWindows = d->m_dockRegistry->mainwindows();
422 layout.mainWindows.reserve(mainWindows.size());
423 for (
auto mainWindow : mainWindows) {
424 if (d->matchesAffinity(mainWindow->affinities()))
425 layout.mainWindows.push_back(mainWindow->serialize());
429 d->m_dockRegistry->floatingWindows(
false,
true);
430 layout.floatingWindows.reserve(floatingWindows.
size());
432 if (d->matchesAffinity(floatingWindow->affinities()))
433 layout.floatingWindows.push_back(floatingWindow->serialize());
438 layout.closedDockWidgets.reserve(closedDockWidgets.
size());
440 if (d->matchesAffinity(dockWidget->affinities()))
441 layout.closedDockWidgets.push_back(dockWidget->d->serialize());
448 layout.allDockWidgets.reserve(dockWidgets.
size());
452 if (!skipsRestore && d->matchesAffinity(dockWidget->affinities())) {
453 auto dw = dockWidget->d->serialize();
454 dw->lastPosition = dockWidget->d->lastPosition()->serialize();
455 layout.allDockWidgets.push_back(dw);
459 return layout.toJson();
464 LayoutSaver::DockWidget::s_dockWidgets.clear();
465 d->clearRestoredProperty();
478 m_saver->d->deleteEmptyGroups();
481 FrameCleanup(
const FrameCleanup &) =
delete;
482 FrameCleanup &operator=(
const FrameCleanup) =
delete;
487 FrameCleanup cleanup(
this);
488 LayoutSaver::Layout layout;
489 if (!layout.fromJson(data)) {
490 KDDW_ERROR(
"Failed to parse json data");
494 if (!layout.isValid()) {
498 layout.scaleSizes(d->m_restoreOptions);
500 d->floatWidgetsWhichSkipRestore(layout.mainWindowNames());
501 d->floatUnknownWidgets(layout);
503 Private::RAIIIsRestoring isRestoring;
508 d->m_dockRegistry->clear(d->m_dockRegistry->dockWidgets(layout.dockWidgetsToClose()),
509 d->m_dockRegistry->mainWindows(layout.mainWindowNames()),
513 for (
const LayoutSaver::MainWindow &mw : std::as_const(layout.mainWindows)) {
514 auto mainWindow = d->m_dockRegistry->mainWindowByName(mw.uniqueName);
517 mainWindow = mwFunc(mw.uniqueName, mw.options);
519 KDDW_ERROR(
"Failed to restore layout create MainWindow with name {} first");
524 if (!d->matchesAffinity(mainWindow->affinities()))
527 if (!(d->m_restoreOptions & InternalRestoreOption::SkipMainWindowGeometry)) {
528 Window::Ptr window = mainWindow->view()->window();
529 d->deserializeWindowGeometry(mw, window);
531 if (
auto w = mainWindow->view()->window()) {
532 w->setWindowState(mw.windowState);
537 if (!mainWindow->deserialize(mw))
542 for (LayoutSaver::FloatingWindow &fw : layout.floatingWindows) {
543 if (!d->matchesAffinity(fw.affinities) || fw.skipsRestore())
549 auto floatingWindow =
551 fw.floatingWindowInstance = floatingWindow;
552 d->deserializeWindowGeometry(fw, floatingWindow->view()->window());
553 if (!floatingWindow->deserialize(fw)) {
554 KDDW_ERROR(
"Failed to deserialize floating window");
561 for (
const auto &dw : std::as_const(layout.closedDockWidgets)) {
562 if (d->matchesAffinity(dw->affinities)) {
568 for (
const auto &dw : std::as_const(layout.allDockWidgets)) {
569 if (!d->matchesAffinity(dw->affinities))
574 dockWidget->d->lastPosition()->deserialize(dw->lastPosition);
576 KDDW_ERROR(
"Couldn't find dock widget {}", dw->uniqueName);
585 d->m_affinityNames = affinityNames;
588 d->m_affinityNames.push_back(
QString());
603 if (dw->d->m_wasRestored)
604 result.push_back(dw);
610void LayoutSaver::Private::clearRestoredProperty()
614 dw->d->m_wasRestored =
false;
619void LayoutSaver::Private::deserializeWindowGeometry(
const T &saved, Window::Ptr window)
624 Rect geometry = saved.geometry;
625 if (!isNormalWindowState(saved.windowState)) {
628 geometry = saved.normalGeometry;
633 window->setGeometry(geometry);
634 window->setVisible(saved.isVisible);
637LayoutSaver::Private::Private(RestoreOptions options)
643bool LayoutSaver::Private::matchesAffinity(
const Vector<QString> &affinities)
const
645 return m_affinityNames.isEmpty() || affinities.
isEmpty()
649void LayoutSaver::Private::floatWidgetsWhichSkipRestore(
const Vector<QString> &mainWindowNames)
657 for (
auto mw : mainWindows) {
659 for (
auto dw : docks) {
660 if (dw->skipsRestore()) {
661 dw->setFloating(
true);
667void LayoutSaver::Private::floatUnknownWidgets(
const LayoutSaver::Layout &layout)
674 for (
auto mw : mainWindows) {
677 if (!layout.containsDockWidget(dw->uniqueName())) {
678 dw->setFloating(
true);
684void LayoutSaver::Private::deleteEmptyGroups()
const
689 const auto groups = m_dockRegistry->groups();
690 for (
auto group : groups) {
691 if (!group->beingDeletedLater() && group->isEmpty() && !group->isCentralFrame()) {
692 if (
auto item = group->layoutItem()) {
693 item->turnIntoPlaceholder();
696 KDDW_ERROR(
"Expected item for frame");
705 return Private::s_restoreInProgress;
708bool LayoutSaver::Layout::isValid()
const
710 if (serializationVersion != KDDOCKWIDGETS_SERIALIZATION_VERSION) {
711 KDDW_ERROR(
"Serialization format is too old {}, current={}", serializationVersion, KDDOCKWIDGETS_SERIALIZATION_VERSION);
715 for (
auto &m : mainWindows) {
720 for (
auto &m : floatingWindows) {
725 for (
auto &m : allDockWidgets) {
734void to_json(nlohmann::json &j,
const LayoutSaver::Layout &layout)
736 j[
"serializationVersion"] = layout.serializationVersion;
737 j[
"mainWindows"] = layout.mainWindows;
738 j[
"floatingWindows"] = layout.floatingWindows;
739 j[
"closedDockWidgets"] = ::dockWidgetNames(layout.closedDockWidgets);
740 j[
"allDockWidgets"] = layout.allDockWidgets;
741 j[
"screenInfo"] = layout.screenInfo;
744void from_json(
const nlohmann::json &j, LayoutSaver::Layout &layout)
746 layout.serializationVersion = j.value(
"serializationVersion", 0);
747 layout.mainWindows = j.value(
"mainWindows", LayoutSaver::MainWindow::List {});
748 layout.allDockWidgets = j.value(
"allDockWidgets", LayoutSaver::DockWidget::List {});
750 layout.closedDockWidgets.clear();
752 const auto closedDockWidgets = j.value(
"closedDockWidgets",
Vector<QString>());
753 for (
const QString &name : closedDockWidgets) {
754 layout.closedDockWidgets.push_back(
755 LayoutSaver::DockWidget::dockWidgetForName(name));
758 layout.floatingWindows = j.value(
"floatingWindows", LayoutSaver::FloatingWindow::List {});
759 layout.screenInfo = j.value(
"screenInfo", LayoutSaver::ScreenInfo::List {});
765 nlohmann::json json = *
this;
769bool LayoutSaver::Layout::fromJson(
const QByteArray &jsonData)
771 nlohmann::json json = nlohmann::json::parse(jsonData,
nullptr,
false);
772 if (json.is_discarded()) {
778 }
catch (
const std::exception &e) {
779 KDDW_ERROR(
"LayoutSaver::Layout::fromJson: Caught exception: {}", e.what());
782 KDDW_ERROR(
"LayoutSaver::Layout::fromJson: Caught exception.");
789void LayoutSaver::Layout::scaleSizes(InternalRestoreOptions options)
791 if (mainWindows.isEmpty())
794 const bool skipsMainWindowGeometry = options & InternalRestoreOption::SkipMainWindowGeometry;
795 if (!skipsMainWindowGeometry) {
804 for (
auto &mw : mainWindows)
810 const bool useRelativeSizesForFloatingWidgets =
811 options & InternalRestoreOption::RelativeFloatingWindowGeometry;
813 if (useRelativeSizesForFloatingWidgets) {
814 for (
auto &fw : floatingWindows) {
815 LayoutSaver::MainWindow mw = mainWindowForIndex(fw.parentIndex);
816 if (mw.scalingInfo.isValid())
817 fw.scaleSizes(mw.scalingInfo);
821 const ScalingInfo firstScalingInfo = mainWindows.constFirst().scalingInfo;
822 if (firstScalingInfo.isValid()) {
823 for (
auto &dw : allDockWidgets) {
827 dw->scaleSizes(firstScalingInfo);
832LayoutSaver::MainWindow LayoutSaver::Layout::mainWindowForIndex(
int index)
const
834 if (index < 0 || index >= mainWindows.size())
837 return mainWindows.at(index);
840LayoutSaver::FloatingWindow LayoutSaver::Layout::floatingWindowForIndex(
int index)
const
842 if (index < 0 || index >= floatingWindows.size())
845 return floatingWindows.at(index);
851 names.
reserve(mainWindows.size());
852 for (
const auto &mw : mainWindows) {
853 names.push_back(mw.uniqueName);
863 for (
const auto &dw : allDockWidgets) {
864 names.push_back(dw->uniqueName);
878 for (
const auto &dw : allDockWidgets) {
883 if (dockWidget->skipsRestore()) {
884 if (
auto fw = dockWidget->floatingWindow()) {
894 names.push_back(dw->uniqueName);
901bool LayoutSaver::Layout::containsDockWidget(
const QString &uniqueName)
const
903 return std::find_if(allDockWidgets.cbegin(), allDockWidgets.cend(),
904 [uniqueName](
const std::shared_ptr<LayoutSaver::DockWidget> &dock) {
905 return dock->uniqueName == uniqueName;
907 != allDockWidgets.cend();
910bool LayoutSaver::Group::isValid()
const
915 if (!geometry.isValid()) {
916 KDDW_ERROR(
"Invalid geometry");
921 KDDW_ERROR(
"Invalid id");
925 if (!dockWidgets.isEmpty()) {
926 if (currentTabIndex >= dockWidgets.size() || currentTabIndex < 0) {
929 KDDW_ERROR(
"Invalid tab index = {}, size = {}", currentTabIndex, dockWidgets.size());
934 KDDW_WARN(
"Invalid tab index = {}, size = {}", currentTabIndex, dockWidgets.size());
935 const_cast<LayoutSaver::Group *
>(
this)->currentTabIndex = 0;
939 for (
auto &dw : dockWidgets) {
947bool LayoutSaver::Group::hasSingleDockWidget()
const
949 return dockWidgets.size() == 1;
952bool LayoutSaver::Group::skipsRestore()
const
954 return std::all_of(dockWidgets.cbegin(), dockWidgets.cend(),
955 [](LayoutSaver::DockWidget::Ptr dw) { return dw->skipsRestore(); });
958LayoutSaver::DockWidget::Ptr LayoutSaver::Group::singleDockWidget()
const
960 if (!hasSingleDockWidget())
963 return dockWidgets.first();
966bool LayoutSaver::DockWidget::isValid()
const
971void LayoutSaver::DockWidget::scaleSizes(
const ScalingInfo &scalingInfo)
973 lastPosition.scaleSizes(scalingInfo);
976bool LayoutSaver::DockWidget::skipsRestore()
const
979 return dw->skipsRestore();
984bool LayoutSaver::FloatingWindow::isValid()
const
986 if (!multiSplitterLayout.isValid())
989 if (!geometry.isValid()) {
990 KDDW_ERROR(
"Invalid geometry");
997bool LayoutSaver::FloatingWindow::hasSingleDockWidget()
const
999 return multiSplitterLayout.hasSingleDockWidget();
1002LayoutSaver::DockWidget::Ptr LayoutSaver::FloatingWindow::singleDockWidget()
const
1004 return multiSplitterLayout.singleDockWidget();
1007bool LayoutSaver::FloatingWindow::skipsRestore()
const
1009 return multiSplitterLayout.skipsRestore();
1012void LayoutSaver::FloatingWindow::scaleSizes(
const ScalingInfo &scalingInfo)
1014 scalingInfo.applyFactorsTo( geometry);
1017bool LayoutSaver::MainWindow::isValid()
const
1019 return multiSplitterLayout.isValid();
1024 auto it = dockWidgetsPerSideBar.find(loc);
1025 return it == dockWidgetsPerSideBar.cend() ?
Vector<QString>() : it->second;
1028void LayoutSaver::MainWindow::scaleSizes()
1030 if (scalingInfo.isValid()) {
1036 scalingInfo = ScalingInfo(uniqueName, geometry, screenIndex);
1039bool LayoutSaver::MultiSplitter::isValid()
const
1041 return layout.is_object() && !layout.empty();
1044bool LayoutSaver::MultiSplitter::hasSingleDockWidget()
const
1046 return groups.size() == 1 && groups.cbegin()->second.hasSingleDockWidget();
1049LayoutSaver::DockWidget::Ptr LayoutSaver::MultiSplitter::singleDockWidget()
const
1051 if (!hasSingleDockWidget())
1054 auto group = groups.begin()->second;
1055 return group.singleDockWidget();
1058bool LayoutSaver::MultiSplitter::skipsRestore()
const
1060 return std::all_of(groups.cbegin(), groups.cend(),
1061 [](
auto it) { return it.second.skipsRestore(); });
1064void LayoutSaver::Position::scaleSizes(
const ScalingInfo &scalingInfo)
1066 scalingInfo.applyFactorsTo( lastFloatingGeometry);
1073 return mw->
view()->
d->screen();
1078LayoutSaver::ScalingInfo::ScalingInfo(
const QString &mainWindowId, Rect savedMainWindowGeo,
1083 KDDW_ERROR(
"Failed to find main window with name {}", mainWindowId);
1087 if (!savedMainWindowGeo.isValid() || savedMainWindowGeo.isNull()) {
1088 KDDW_ERROR(
"Invalid saved main window geometry {}", savedMainWindowGeo);
1092 if (!mainWindow->geometry().isValid() || mainWindow->geometry().isNull()) {
1093 KDDW_ERROR(
"Invalid main window geometry {}", mainWindow->geometry());
1097 const int currentScreenIndex =
1100 this->mainWindowName = mainWindowId;
1101 this->savedMainWindowGeometry = savedMainWindowGeo;
1102 realMainWindowGeometry =
1103 mainWindow->window()->d->windowGeometry();
1104 widthFactor = double(realMainWindowGeometry.width()) / savedMainWindowGeo.width();
1105 heightFactor = double(realMainWindowGeometry.height()) / savedMainWindowGeo.height();
1106 mainWindowChangedScreen = currentScreenIndex != screenIndex;
1109void LayoutSaver::ScalingInfo::translatePos(Point &pt)
const
1111 const int deltaX = pt.x() - savedMainWindowGeometry.x();
1112 const int deltaY = pt.y() - savedMainWindowGeometry.y();
1114 const double newDeltaX = deltaX * widthFactor;
1115 const double newDeltaY = deltaY * heightFactor;
1117 pt.setX(
int(std::ceil(savedMainWindowGeometry.x() + newDeltaX)));
1118 pt.setY(
int(std::ceil(savedMainWindowGeometry.y() + newDeltaY)));
1121void LayoutSaver::ScalingInfo::applyFactorsTo(Point &pt)
const
1126void LayoutSaver::ScalingInfo::applyFactorsTo(Size &sz)
const
1128 sz.setWidth(
int(widthFactor * sz.width()));
1129 sz.setHeight(
int(heightFactor * sz.height()));
1132void LayoutSaver::ScalingInfo::applyFactorsTo(Rect &rect)
const
1137 Point pos = rect.topLeft();
1138 Size size = rect.size();
1140 applyFactorsTo( size);
1143 if (!mainWindowChangedScreen) {
1148 applyFactorsTo( pos);
1151 rect.moveTopLeft(pos);
1155LayoutSaver::Private::RAIIIsRestoring::RAIIIsRestoring()
1157 LayoutSaver::Private::s_restoreInProgress =
true;
1160LayoutSaver::Private::RAIIIsRestoring::~RAIIIsRestoring()
1162 LayoutSaver::Private::s_restoreInProgress =
false;
Application-wide config to tune certain behaviours of the framework.
InternalRestoreOptions internalRestoreOptions(RestoreOptions options)
Class to save and restore dockwidget layouts.
A widget that supports an arbitrary number of splitters (called Separators) in any combination of ver...
The MainWindow base-class. MainWindow and MainWindowBase are only split in two so we can share some c...
The MainWindow base-class that's shared between QtWidgets and QtQuick stack.
const char * constData() const const
QByteArray fromStdString(const std::string &str)
bool isEmpty() const const
QString fromStdString(const std::string &str)
bool isEmpty() const const
std::string toStdString() const const