26#include "private/multisplitter/Item_p.h"
27#include "private/LayoutSaver_p.h"
28#include "private/DockRegistry_p.h"
29#include "private/DockWidgetBase_p.h"
30#include "private/FloatingWindow_p.h"
31#include "private/Frame_p.h"
32#include "private/LayoutWidget_p.h"
33#include "private/Logging_p.h"
34#include "private/Position_p.h"
35#include "private/Utils_p.h"
64LayoutSaver::Layout *LayoutSaver::Layout::s_currentLayoutBeingRestored =
nullptr;
69 InternalRestoreOptions ret = {};
71 ret.setFlag(InternalRestoreOption::SkipMainWindowGeometry);
72 ret.setFlag(InternalRestoreOption::RelativeFloatingWindowGeometry);
76 ret.setFlag(InternalRestoreOption::RelativeFloatingWindowGeometry,
false);
81 qWarning() << Q_FUNC_INFO <<
"Unknown options" << options;
87bool LayoutSaver::Private::s_restoreInProgress =
false;
91 QVariantList variantList;
94 variantList.push_back(str);
102 stringList.
reserve(variantList.size());
103 for (
const QVariant &variant : variantList)
104 stringList.
push_back(variant.toString());
110 : d(new Private(options))
123 QFile f(jsonFilename);
125 qWarning() << Q_FUNC_INFO <<
"Failed to open" << jsonFilename << f.
errorString();
135 QFile f(jsonFilename);
137 qWarning() << Q_FUNC_INFO <<
"Failed to open" << jsonFilename << f.
errorString();
149 if (!d->m_dockRegistry->isSane()) {
150 qWarning() << Q_FUNC_INFO <<
"Refusing to serialize this layout. Check previous warnings.";
154 LayoutSaver::Layout layout;
157 d->m_dockRegistry->ensureAllFloatingWidgetsAreMorphed();
160 layout.mainWindows.reserve(mainWindows.
size());
162 if (d->matchesAffinity(mainWindow->affinities()))
163 layout.mainWindows.push_back(mainWindow->serialize());
167 layout.floatingWindows.reserve(floatingWindows.
size());
168 for (KDDockWidgets::FloatingWindow *floatingWindow : floatingWindows) {
169 if (d->matchesAffinity(floatingWindow->affinities()))
170 layout.floatingWindows.push_back(floatingWindow->serialize());
175 layout.closedDockWidgets.reserve(closedDockWidgets.
size());
177 if (d->matchesAffinity(dockWidget->affinities()))
178 layout.closedDockWidgets.push_back(dockWidget->d->serialize());
185 layout.allDockWidgets.reserve(dockWidgets.
size());
188 if (!skipsRestore && d->matchesAffinity(dockWidget->affinities())) {
189 auto dw = dockWidget->d->serialize();
190 dw->lastPosition = dockWidget->d->lastPosition()->serialize();
191 layout.allDockWidgets.push_back(dw);
195 return layout.toJson();
200 d->clearRestoredProperty();
213 m_saver->d->deleteEmptyFrames();
219 FrameCleanup cleanup(
this);
220 LayoutSaver::Layout layout;
221 if (!layout.fromJson(data)) {
222 qWarning() << Q_FUNC_INFO <<
"Failed to parse json data";
226 if (!layout.isValid()) {
230 layout.scaleSizes(d->m_restoreOptions);
232 d->floatWidgetsWhichSkipRestore(layout.mainWindowNames());
233 d->floatUnknownWidgets(layout);
235 Private::RAIIIsRestoring isRestoring;
240 d->m_dockRegistry->clear(d->m_dockRegistry->dockWidgets(layout.dockWidgetsToClose()),
241 d->m_dockRegistry->mainWindows(layout.mainWindowNames()),
245 for (
const LayoutSaver::MainWindow &mw : qAsConst(layout.mainWindows)) {
246 MainWindowBase *mainWindow = d->m_dockRegistry->mainWindowByName(mw.uniqueName);
249 mainWindow = mwFunc(mw.uniqueName);
251 qWarning() <<
"Failed to restore layout create MainWindow with name" << mw.uniqueName <<
"first";
256 if (!d->matchesAffinity(mainWindow->
affinities()))
259 if (!(d->m_restoreOptions & InternalRestoreOption::SkipMainWindowGeometry)) {
260 d->deserializeWindowGeometry(mw, mainWindow->
window());
263 w->setWindowState(mw.windowState);
268 if (!mainWindow->deserialize(mw))
273 for (LayoutSaver::FloatingWindow &fw : layout.floatingWindows) {
274 if (!d->matchesAffinity(fw.affinities) || fw.skipsRestore())
278 : DockRegistry::self()->mainwindows().at(fw.parentIndex);
281 fw.floatingWindowInstance = floatingWindow;
282 d->deserializeWindowGeometry(fw, floatingWindow);
283 if (!floatingWindow->deserialize(fw)) {
284 qWarning() << Q_FUNC_INFO <<
"Failed to deserialize floating window";
290 for (
const auto &dw : qAsConst(layout.closedDockWidgets)) {
291 if (d->matchesAffinity(dw->affinities)) {
292 DockWidgetBase::deserialize(dw);
297 for (
const auto &dw : qAsConst(layout.allDockWidgets)) {
298 if (!d->matchesAffinity(dw->affinities))
302 d->m_dockRegistry->dockByName(dw->uniqueName, DockRegistry::DockByNameFlag::ConsultRemapping)) {
303 dockWidget->d->lastPosition()->deserialize(dw->lastPosition);
305 qWarning() << Q_FUNC_INFO <<
"Couldn't find dock widget" << dw->uniqueName;
314 d->m_affinityNames = affinityNames;
317 d->m_affinityNames <<
QString();
332 if (dw->property(
"kddockwidget_was_restored").toBool())
339void LayoutSaver::Private::clearRestoredProperty()
343 dw->setProperty(
"kddockwidget_was_restored",
QVariant());
348void LayoutSaver::Private::deserializeWindowGeometry(
const T &saved,
QWidgetOrQuick *topLevel)
353 QRect geometry = saved.geometry;
354 if (!isNormalWindowState(saved.windowState)) {
357 geometry = saved.normalGeometry;
360 ::FloatingWindow::ensureRectIsOnScreen(geometry);
365 KDDockWidgets::Private::setTopLevelGeometry(geometry, topLevel);
371LayoutSaver::Private::Private(RestoreOptions options)
372 : m_dockRegistry(DockRegistry::self())
377bool LayoutSaver::Private::matchesAffinity(
const QStringList &affinities)
const
379 return m_affinityNames.isEmpty() || affinities.
isEmpty()
380 || DockRegistry::self()->affinitiesMatch(m_affinityNames, affinities);
383void LayoutSaver::Private::floatWidgetsWhichSkipRestore(
const QStringList &mainWindowNames)
390 for (
MainWindowBase *mw : DockRegistry::self()->mainWindows(mainWindowNames)) {
392 for (
auto dw : docks) {
393 if (dw->skipsRestore()) {
394 dw->setFloating(
true);
400void LayoutSaver::Private::floatUnknownWidgets(
const LayoutSaver::Layout &layout)
406 for (
MainWindowBase *mw : DockRegistry::self()->mainWindows(layout.mainWindowNames())) {
409 if (!layout.containsDockWidget(dw->uniqueName())) {
410 dw->setFloating(
true);
416void LayoutSaver::Private::deleteEmptyFrames()
421 for (
auto frame : m_dockRegistry->frames()) {
422 if (!frame->beingDeletedLater() && frame->isEmpty() && !frame->isCentralFrame()) {
423 if (
auto item = frame->layoutItem()) {
424 item->turnIntoPlaceholder();
427 qWarning() << Q_FUNC_INFO <<
"Expected item for frame";
435std::unique_ptr<QSettings> LayoutSaver::Private::settings()
const
437 auto settings = std::unique_ptr<QSettings>(
new QSettings(qApp->organizationName(),
438 qApp->applicationName()));
439 settings->beginGroup(QStringLiteral(
"KDDockWidgets::LayoutSaver"));
446 return Private::s_restoreInProgress;
449bool LayoutSaver::Layout::isValid()
const
451 if (serializationVersion != KDDOCKWIDGETS_SERIALIZATION_VERSION) {
452 qWarning() << Q_FUNC_INFO <<
"Serialization format is too old"
453 << serializationVersion <<
"current=" << KDDOCKWIDGETS_SERIALIZATION_VERSION;
457 for (
auto &m : mainWindows) {
462 for (
auto &m : floatingWindows) {
467 for (
auto &m : allDockWidgets) {
481bool LayoutSaver::Layout::fromJson(
const QByteArray &jsonData)
493QVariantMap LayoutSaver::Layout::toVariantMap()
const
496 map.insert(QStringLiteral(
"serializationVersion"), serializationVersion);
497 map.insert(QStringLiteral(
"mainWindows"), toVariantList<LayoutSaver::MainWindow>(mainWindows));
498 map.insert(QStringLiteral(
"floatingWindows"), toVariantList<LayoutSaver::FloatingWindow>(floatingWindows));
499 map.insert(QStringLiteral(
"closedDockWidgets"), ::dockWidgetNames(closedDockWidgets));
500 map.insert(QStringLiteral(
"allDockWidgets"), toVariantList(allDockWidgets));
501 map.insert(QStringLiteral(
"screenInfo"), toVariantList<LayoutSaver::ScreenInfo>(screenInfo));
506void LayoutSaver::Layout::fromVariantMap(
const QVariantMap &map)
508 allDockWidgets.
clear();
509 const QVariantList dockWidgetsV = map.value(QStringLiteral(
"allDockWidgets")).toList();
510 for (
const QVariant &v : dockWidgetsV) {
511 const QVariantMap dwV = v.toMap();
512 const QString name = dwV.value(QStringLiteral(
"uniqueName")).toString();
513 auto dw = LayoutSaver::DockWidget::dockWidgetForName(name);
514 dw->fromVariantMap(dwV);
518 closedDockWidgets.clear();
519 const QVariantList closedDockWidgetsV = map.value(QStringLiteral(
"closedDockWidgets")).toList();
520 closedDockWidgets.reserve(closedDockWidgetsV.size());
521 for (
const QVariant &v : closedDockWidgetsV) {
522 closedDockWidgets.push_back(LayoutSaver::DockWidget::dockWidgetForName(v.toString()));
525 serializationVersion = map.value(QStringLiteral(
"serializationVersion")).toInt();
526 mainWindows = fromVariantList<LayoutSaver::MainWindow>(map.value(QStringLiteral(
"mainWindows")).toList());
527 floatingWindows = fromVariantList<LayoutSaver::FloatingWindow>(map.value(QStringLiteral(
"floatingWindows")).toList());
528 screenInfo = fromVariantList<LayoutSaver::ScreenInfo>(map.value(QStringLiteral(
"screenInfo")).toList());
531void LayoutSaver::Layout::scaleSizes(InternalRestoreOptions options)
533 if (mainWindows.isEmpty())
536 const bool skipsMainWindowGeometry = options & InternalRestoreOption::SkipMainWindowGeometry;
537 if (!skipsMainWindowGeometry) {
546 for (
auto &mw : mainWindows)
552 const bool useRelativeSizesForFloatingWidgets =
553 options & InternalRestoreOption::RelativeFloatingWindowGeometry;
555 if (useRelativeSizesForFloatingWidgets) {
556 for (
auto &fw : floatingWindows) {
557 LayoutSaver::MainWindow mw = mainWindowForIndex(fw.parentIndex);
558 if (mw.scalingInfo.isValid())
559 fw.scaleSizes(mw.scalingInfo);
563 const ScalingInfo firstScalingInfo = mainWindows.constFirst().scalingInfo;
564 if (firstScalingInfo.isValid()) {
565 for (
auto &dw : allDockWidgets) {
569 dw->scaleSizes(firstScalingInfo);
574LayoutSaver::MainWindow LayoutSaver::Layout::mainWindowForIndex(
int index)
const
576 if (index < 0 || index >= mainWindows.size())
579 return mainWindows.at(index);
582LayoutSaver::FloatingWindow LayoutSaver::Layout::floatingWindowForIndex(
int index)
const
584 if (index < 0 || index >= floatingWindows.size())
587 return floatingWindows.at(index);
590QStringList LayoutSaver::Layout::mainWindowNames()
const
593 names.
reserve(mainWindows.size());
594 for (
const auto &mw : mainWindows) {
595 names << mw.uniqueName;
601QStringList LayoutSaver::Layout::dockWidgetNames()
const
605 for (
const auto &dw : allDockWidgets) {
606 names << dw->uniqueName;
612QStringList LayoutSaver::Layout::dockWidgetsToClose()
const
618 auto registry = DockRegistry::self();
619 for (
const auto &dw : allDockWidgets) {
620 if (
DockWidgetBase *dockWidget = registry->dockByName(dw->uniqueName)) {
624 if (dockWidget->skipsRestore()) {
625 if (
auto fw = dockWidget->floatingWindow()) {
634 names << dw->uniqueName;
641bool LayoutSaver::Layout::containsDockWidget(
const QString &uniqueName)
const
643 return std::find_if(allDockWidgets.
cbegin(), allDockWidgets.
cend(), [uniqueName](
const std::shared_ptr<LayoutSaver::DockWidget> &dock) {
644 return dock->uniqueName == uniqueName;
646 != allDockWidgets.
cend();
649bool LayoutSaver::Frame::isValid()
const
655 qWarning() << Q_FUNC_INFO <<
"Invalid geometry";
660 qWarning() << Q_FUNC_INFO <<
"Invalid id";
664 if (!dockWidgets.isEmpty()) {
665 if (currentTabIndex >= dockWidgets.size() || currentTabIndex < 0) {
666 qWarning() << Q_FUNC_INFO <<
"Invalid tab index" << currentTabIndex << dockWidgets.size();
671 for (
auto &dw : dockWidgets) {
679bool LayoutSaver::Frame::hasSingleDockWidget()
const
681 return dockWidgets.size() == 1;
684bool LayoutSaver::Frame::skipsRestore()
const
686 return std::all_of(dockWidgets.cbegin(), dockWidgets.cend(), [](LayoutSaver::DockWidget::Ptr dw) {
687 return dw->skipsRestore();
691LayoutSaver::DockWidget::Ptr LayoutSaver::Frame::singleDockWidget()
const
693 if (!hasSingleDockWidget())
696 return dockWidgets.first();
699QVariantMap LayoutSaver::Frame::toVariantMap()
const
702 map.insert(QStringLiteral(
"id"),
id);
703 map.insert(QStringLiteral(
"isNull"), isNull);
704 map.insert(QStringLiteral(
"objectName"), objectName);
705 map.insert(QStringLiteral(
"geometry"), Layouting::rectToMap(geometry));
706 map.insert(QStringLiteral(
"options"), options);
707 map.insert(QStringLiteral(
"currentTabIndex"), currentTabIndex);
708 map.insert(QStringLiteral(
"mainWindowUniqueName"), mainWindowUniqueName);
709 map.insert(QStringLiteral(
"dockWidgets"), dockWidgetNames(dockWidgets));
714void LayoutSaver::Frame::fromVariantMap(
const QVariantMap &map)
722 id = map.value(QStringLiteral(
"id")).toString();
723 isNull = map.value(QStringLiteral(
"isNull")).toBool();
724 objectName = map.value(QStringLiteral(
"objectName")).toString();
725 mainWindowUniqueName = map.value(QStringLiteral(
"mainWindowUniqueName")).toString();
726 geometry = Layouting::mapToRect(map.value(QStringLiteral(
"geometry")).toMap());
728 currentTabIndex = map.value(QStringLiteral(
"currentTabIndex")).toInt();
730 const QVariantList dockWidgetsV = map.value(QStringLiteral(
"dockWidgets")).toList();
733 dockWidgets.reserve(dockWidgetsV.size());
734 for (
const auto &variant : dockWidgetsV) {
735 DockWidget::Ptr dw = DockWidget::dockWidgetForName(variant.toString());
736 dockWidgets.push_back(dw);
740bool LayoutSaver::DockWidget::isValid()
const
745void LayoutSaver::DockWidget::scaleSizes(
const ScalingInfo &scalingInfo)
747 lastPosition.scaleSizes(scalingInfo);
750bool LayoutSaver::DockWidget::skipsRestore()
const
752 if (
DockWidgetBase *dw = DockRegistry::self()->dockByName(uniqueName))
753 return dw->skipsRestore();
758QVariantMap LayoutSaver::DockWidget::toVariantMap()
const
763 map.insert(QStringLiteral(
"uniqueName"), uniqueName);
764 map.insert(QStringLiteral(
"lastPosition"), lastPosition.toVariantMap());
769void LayoutSaver::DockWidget::fromVariantMap(
const QVariantMap &map)
774 const QString affinityName = map.value(QStringLiteral(
"affinityName")).toString();
779 uniqueName = map.value(QStringLiteral(
"uniqueName")).toString();
780 lastPosition.fromVariantMap(map.value(QStringLiteral(
"lastPosition")).toMap());
783bool LayoutSaver::FloatingWindow::isValid()
const
785 if (!multiSplitterLayout.isValid())
789 qWarning() << Q_FUNC_INFO <<
"Invalid geometry";
796bool LayoutSaver::FloatingWindow::hasSingleDockWidget()
const
798 return multiSplitterLayout.hasSingleDockWidget();
801LayoutSaver::DockWidget::Ptr LayoutSaver::FloatingWindow::singleDockWidget()
const
803 return multiSplitterLayout.singleDockWidget();
806bool LayoutSaver::FloatingWindow::skipsRestore()
const
808 return multiSplitterLayout.skipsRestore();
811void LayoutSaver::FloatingWindow::scaleSizes(
const ScalingInfo &scalingInfo)
813 scalingInfo.applyFactorsTo( geometry);
816QVariantMap LayoutSaver::FloatingWindow::toVariantMap()
const
819 map.
insert(QStringLiteral(
"multiSplitterLayout"), multiSplitterLayout.toVariantMap());
820 map.
insert(QStringLiteral(
"parentIndex"), parentIndex);
821 map.
insert(QStringLiteral(
"geometry"), Layouting::rectToMap(geometry));
822 map.
insert(QStringLiteral(
"normalGeometry"), Layouting::rectToMap(normalGeometry));
823 map.
insert(QStringLiteral(
"screenIndex"), screenIndex);
824 map.
insert(QStringLiteral(
"screenSize"), Layouting::sizeToMap(screenSize));
825 map.
insert(QStringLiteral(
"isVisible"), isVisible);
826 map.
insert(QStringLiteral(
"windowState"), windowState);
827 map.
insert(QStringLiteral(
"flags"), flags);
835void LayoutSaver::FloatingWindow::fromVariantMap(
const QVariantMap &map)
837 multiSplitterLayout.fromVariantMap(map.value(QStringLiteral(
"multiSplitterLayout")).toMap());
838 parentIndex = map.value(QStringLiteral(
"parentIndex")).
toInt();
839 geometry = Layouting::mapToRect(map.value(QStringLiteral(
"geometry")).toMap());
840 normalGeometry = Layouting::mapToRect(map.value(QStringLiteral(
"normalGeometry")).toMap());
841 screenIndex = map.value(QStringLiteral(
"screenIndex")).toInt();
843 screenSize = Layouting::mapToSize(map.value(QStringLiteral(
"screenSize")).toMap());
844 isVisible = map.value(QStringLiteral(
"isVisible")).toBool();
849 const QString affinityName = map.value(QStringLiteral(
"affinityName")).toString();
855bool LayoutSaver::MainWindow::isValid()
const
857 if (!multiSplitterLayout.isValid())
863void LayoutSaver::MainWindow::scaleSizes()
865 if (scalingInfo.isValid()) {
871 scalingInfo = ScalingInfo(uniqueName, geometry, screenIndex);
874QVariantMap LayoutSaver::MainWindow::toVariantMap()
const
877 map.insert(QStringLiteral(
"options"),
int(options));
878 map.insert(QStringLiteral(
"multiSplitterLayout"), multiSplitterLayout.toVariantMap());
879 map.insert(QStringLiteral(
"uniqueName"), uniqueName);
880 map.insert(QStringLiteral(
"geometry"), Layouting::rectToMap(geometry));
881 map.insert(QStringLiteral(
"normalGeometry"), Layouting::rectToMap(normalGeometry));
882 map.insert(QStringLiteral(
"screenIndex"), screenIndex);
883 map.insert(QStringLiteral(
"screenSize"), Layouting::sizeToMap(screenSize));
884 map.insert(QStringLiteral(
"isVisible"), isVisible);
886 map.insert(QStringLiteral(
"windowState"), windowState);
897void LayoutSaver::MainWindow::fromVariantMap(
const QVariantMap &map)
899 options = KDDockWidgets::MainWindowOptions(map.value(QStringLiteral(
"options")).toInt());
900 multiSplitterLayout.fromVariantMap(map.value(QStringLiteral(
"multiSplitterLayout")).toMap());
901 uniqueName = map.value(QStringLiteral(
"uniqueName")).toString();
902 geometry = Layouting::mapToRect(map.value(QStringLiteral(
"geometry")).toMap());
903 normalGeometry = Layouting::mapToRect(map.value(QStringLiteral(
"normalGeometry")).toMap());
904 screenIndex = map.value(QStringLiteral(
"screenIndex")).toInt();
905 screenSize = Layouting::mapToSize(map.value(QStringLiteral(
"screenSize")).toMap());
906 isVisible = map.value(QStringLiteral(
"isVisible")).toBool();
911 const QString affinityName = map.value(QStringLiteral(
"affinityName")).toString();
917 dockWidgetsPerSideBar.clear();
919 const QVariantList dockWidgets = map.
value(QStringLiteral(
"sidebar-%1").arg(
int(loc))).toList();
920 if (!dockWidgets.isEmpty())
925bool LayoutSaver::MultiSplitter::isValid()
const
927 if (layout.isEmpty())
938bool LayoutSaver::MultiSplitter::hasSingleDockWidget()
const
940 return frames.size() == 1 && frames.cbegin()->hasSingleDockWidget();
943LayoutSaver::DockWidget::Ptr LayoutSaver::MultiSplitter::singleDockWidget()
const
945 if (!hasSingleDockWidget())
948 return frames.cbegin()->singleDockWidget();
951bool LayoutSaver::MultiSplitter::skipsRestore()
const
953 return std::all_of(frames.cbegin(), frames.cend(), [](
const LayoutSaver::Frame &frame) {
954 return frame.skipsRestore();
958QVariantMap LayoutSaver::MultiSplitter::toVariantMap()
const
961 result.insert(QStringLiteral(
"layout"), layout);
964 for (
auto &frame : frames)
965 framesV.insert(frame.id, frame.toVariantMap());
967 result.insert(QStringLiteral(
"frames"), framesV);
971void LayoutSaver::MultiSplitter::fromVariantMap(
const QVariantMap &map)
973 layout = map.value(QStringLiteral(
"layout")).toMap();
974 const QVariantMap framesV = map.value(QStringLiteral(
"frames")).toMap();
976 for (
const QVariant &frameV : framesV) {
977 LayoutSaver::Frame frame;
978 frame.fromVariantMap(frameV.toMap());
979 frames.insert(frame.id, frame);
983void LayoutSaver::Position::scaleSizes(
const ScalingInfo &scalingInfo)
985 scalingInfo.applyFactorsTo( lastFloatingGeometry);
991 result.reserve(geometries.
size());
992 for (
auto it = geometries.
cbegin(), end = geometries.
cend(); it != end; ++it) {
994 map.insert(QStringLiteral(
"location"),
static_cast<int>(it.key()));
995 map.insert(QStringLiteral(
"rect"), Layouting::rectToMap(it.value()));
996 result.push_back(map);
1001QVariantMap LayoutSaver::Position::toVariantMap()
const
1004 map.insert(QStringLiteral(
"lastFloatingGeometry"), Layouting::rectToMap(lastFloatingGeometry));
1006 map.insert(QStringLiteral(
"tabIndex"), tabIndex);
1007 map.insert(QStringLiteral(
"wasFloating"), wasFloating);
1008 map.insert(QStringLiteral(
"placeholders"), toVariantList<LayoutSaver::Placeholder>(placeholders));
1017 const auto map = v.toMap();
1019 const auto rect = Layouting::mapToRect(map.value(QStringLiteral(
"rect")).toMap());
1020 result.
insert(location, rect);
1025void LayoutSaver::Position::fromVariantMap(
const QVariantMap &map)
1027 lastFloatingGeometry = Layouting::mapToRect(map.value(QStringLiteral(
"lastFloatingGeometry")).toMap());
1029 tabIndex = map.value(QStringLiteral(
"tabIndex")).toInt();
1030 wasFloating = map.value(QStringLiteral(
"wasFloating")).toBool();
1031 placeholders = fromVariantList<LayoutSaver::Placeholder>(map.value(QStringLiteral(
"placeholders")).toList());
1034QVariantMap LayoutSaver::ScreenInfo::toVariantMap()
const
1037 map.insert(QStringLiteral(
"index"), index);
1038 map.insert(QStringLiteral(
"geometry"), Layouting::rectToMap(geometry));
1039 map.insert(QStringLiteral(
"name"), name);
1040 map.insert(QStringLiteral(
"devicePixelRatio"), devicePixelRatio);
1045void LayoutSaver::ScreenInfo::fromVariantMap(
const QVariantMap &map)
1047 index = map.value(QStringLiteral(
"index")).toInt();
1048 geometry = Layouting::mapToRect(map.value(QStringLiteral(
"geometry")).toMap());
1049 name = map.value(QStringLiteral(
"name")).toString();
1050 devicePixelRatio = map.value(QStringLiteral(
"devicePixelRatio")).
toDouble();
1053QVariantMap LayoutSaver::Placeholder::toVariantMap()
const
1056 map.insert(QStringLiteral(
"isFloatingWindow"), isFloatingWindow);
1057 map.insert(QStringLiteral(
"itemIndex"), itemIndex);
1059 if (isFloatingWindow)
1060 map.insert(QStringLiteral(
"indexOfFloatingWindow"), indexOfFloatingWindow);
1062 map.insert(QStringLiteral(
"mainWindowUniqueName"), mainWindowUniqueName);
1067void LayoutSaver::Placeholder::fromVariantMap(
const QVariantMap &map)
1069 isFloatingWindow = map.value(QStringLiteral(
"isFloatingWindow")).toBool();
1070 indexOfFloatingWindow = map.value(QStringLiteral(
"indexOfFloatingWindow"), -1).toInt();
1071 itemIndex = map.value(QStringLiteral(
"itemIndex")).toInt();
1072 mainWindowUniqueName = map.value(QStringLiteral(
"mainWindowUniqueName")).toString();
1079#ifdef KDDOCKWIDGETS_QTQUICK
1083#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
1085 return window->screen();
1092LayoutSaver::ScalingInfo::ScalingInfo(
const QString &mainWindowId,
QRect savedMainWindowGeo,
int screenIndex)
1094 auto mainWindow = DockRegistry::self()->mainWindowByName(mainWindowId);
1096 qWarning() << Q_FUNC_INFO <<
"Failed to find main window with name" << mainWindowName;
1100 if (!savedMainWindowGeo.
isValid() || savedMainWindowGeo.
isNull()) {
1101 qWarning() << Q_FUNC_INFO <<
"Invalid saved main window geometry" << savedMainWindowGeo;
1105 if (!mainWindow->geometry().isValid() || mainWindow->geometry().isNull()) {
1106 qWarning() << Q_FUNC_INFO <<
"Invalid main window geometry" << mainWindow->geometry();
1112 this->mainWindowName = mainWindowId;
1113 this->savedMainWindowGeometry = savedMainWindowGeo;
1114 realMainWindowGeometry = mainWindow->windowGeometry();
1115 widthFactor = double(realMainWindowGeometry.width()) / savedMainWindowGeo.
width();
1116 heightFactor = double(realMainWindowGeometry.height()) / savedMainWindowGeo.
height();
1117 mainWindowChangedScreen = currentScreenIndex != screenIndex;
1120void LayoutSaver::ScalingInfo::translatePos(
QPoint &pt)
const
1122 const int deltaX = pt.
x() - savedMainWindowGeometry.x();
1123 const int deltaY = pt.
y() - savedMainWindowGeometry.y();
1125 const double newDeltaX = deltaX * widthFactor;
1126 const double newDeltaY = deltaY * heightFactor;
1128 pt.
setX(qCeil(savedMainWindowGeometry.x() + newDeltaX));
1129 pt.
setY(qCeil(savedMainWindowGeometry.y() + newDeltaY));
1132void LayoutSaver::ScalingInfo::applyFactorsTo(
QPoint &pt)
const
1137void LayoutSaver::ScalingInfo::applyFactorsTo(
QSize &sz)
const
1143void LayoutSaver::ScalingInfo::applyFactorsTo(
QRect &rect)
const
1151 applyFactorsTo( size);
1154 if (!mainWindowChangedScreen) {
1159 applyFactorsTo( pos);
1166LayoutSaver::Private::RAIIIsRestoring::RAIIIsRestoring()
1168 LayoutSaver::Private::s_restoreInProgress =
true;
1171LayoutSaver::Private::RAIIIsRestoring::~RAIIIsRestoring()
1173 LayoutSaver::Private::s_restoreInProgress =
false;
Application-wide config to tune certain behaviours of the framework.
static QStringList variantToStringList(const QVariantList &variantList)
InternalRestoreOptions internalRestoreOptions(RestoreOptions options)
static QHash< KDDockWidgets::SideBarLocation, QRect > listToOverlayedGeometries(const QVariantList &list)
static QScreen * screenForMainWindow(MainWindowBase *mw)
static QVariantList stringListToVariant(const QStringList &strs)
static QVariantList overlayedGeometriesToList(const QHash< KDDockWidgets::SideBarLocation, QRect > &geometries)
Class to save and restore dockwidget layouts.
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...
bool isEmpty() const const
virtual bool open(QIODevice::OpenMode mode) override
QHash::const_iterator cbegin() const const
QHash::const_iterator cend() const const
QHash::iterator insert(const Key &key, const T &value)
QString errorString() const const
qint64 write(const char *data, qint64 maxSize)
QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error)
QJsonDocument fromVariant(const QVariant &variant)
QByteArray toJson() const const
QVariant toVariant() const const
bool isEmpty() const const
void push_back(const T &value)
T value(int i) const const
bool isEmpty() const const
bool isNull() const const
bool isValid() const const
void moveTopLeft(const QPoint &position)
void setSize(const QSize &size)
QPoint topLeft() const const
void setHeight(int height)
QString & insert(int position, QChar ch)
bool isEmpty() const const
double toDouble(bool *ok) const const
int toInt(bool *ok, int base) const const
bool contains(const QString &str, Qt::CaseSensitivity cs) const const
QMap< QString, QVariant > toMap() const const
QVector::const_iterator cbegin() const const
QVector::const_iterator cend() const const
void push_back(const T &value)