From ecf67a2a9d46fbe9fefd7bce84e662e0480fee52 Mon Sep 17 00:00:00 2001 From: Michail Vourlakos Date: Sun, 23 Jul 2017 21:05:34 +0300 Subject: [PATCH] dynamic changing to layouts based on activities --- app/dockcorona.cpp | 10 +++- app/layoutmanager.cpp | 100 +++++++++++++++++++++++++++++++++++++- app/layoutmanager.h | 12 +++++ app/universalsettings.cpp | 18 +++++++ app/universalsettings.h | 5 ++ 5 files changed, 141 insertions(+), 4 deletions(-) diff --git a/app/dockcorona.cpp b/app/dockcorona.cpp index 7e6d66476..dbdc1f7bb 100644 --- a/app/dockcorona.cpp +++ b/app/dockcorona.cpp @@ -81,7 +81,6 @@ DockCorona::DockCorona(QObject *parent) setKPackage(package); //! universal settings must be loaded after the package has been set m_universalSettings->load(); - m_layoutManager->load(); qmlRegisterTypes(); QFontDatabase::addApplicationFont(kPackage().filePath("tangerineFont")); @@ -146,6 +145,7 @@ void DockCorona::load() { if (m_activityConsumer && (m_activityConsumer->serviceStatus() == KActivities::Consumer::Running) && m_activitiesStarting) { disconnect(m_activityConsumer, &KActivities::Consumer::serviceStatusChanged, this, &DockCorona::load); + m_layoutManager->load(); m_activitiesStarting = false; m_tasksWillBeLoaded = heuresticForLoadingDockWithTasks(); @@ -157,7 +157,13 @@ void DockCorona::load() connect(QApplication::desktop(), &QDesktopWidget::screenCountChanged, this, &DockCorona::screenCountChanged); connect(m_screenPool, &ScreenPool::primaryPoolChanged, this, &DockCorona::screenCountChanged); - m_layoutManager->switchToLayout(m_universalSettings->currentLayoutName()); + QString assignedLayout = m_layoutManager->shouldSwitchToLayout(m_activityConsumer->currentActivity()); + + if (!assignedLayout.isEmpty() && assignedLayout != m_universalSettings->currentLayoutName()) { + m_layoutManager->switchToLayout(assignedLayout); + } else { + m_layoutManager->switchToLayout(m_universalSettings->currentLayoutName()); + } foreach (auto containment, containments()) addDock(containment); diff --git a/app/layoutmanager.cpp b/app/layoutmanager.cpp index 112fe1b96..2b7bf72a2 100644 --- a/app/layoutmanager.cpp +++ b/app/layoutmanager.cpp @@ -24,8 +24,9 @@ #include #include -#include #include +#include +#include namespace Latte { @@ -50,6 +51,10 @@ LayoutManager::LayoutManager(QObject *parent) connect(m_addWidgetsAction, &QAction::triggered, this, &LayoutManager::showWidgetsExplorer); connect(m_corona->universalSettings(), &UniversalSettings::currentLayoutNameChanged, this, &LayoutManager::currentLayoutNameChanged); + + m_dynamicSwitchTimer.setSingleShot(true); + m_dynamicSwitchTimer.setInterval(3000); + connect(&m_dynamicSwitchTimer, &QTimer::timeout, this, &LayoutManager::confirmDynamicSwitch); } } @@ -88,6 +93,9 @@ void LayoutManager::load() qDebug() << "Latte is loading its layouts..."; + connect(m_corona->m_activityConsumer, &KActivities::Consumer::currentActivityChanged, + this, &LayoutManager::currentActivityChanged); + loadLayouts(); } @@ -132,7 +140,15 @@ QStringList LayoutManager::layouts() const QStringList LayoutManager::menuLayouts() const { - return m_menuLayouts; + QStringList fixedMenuLayouts = m_menuLayouts; + + //! in case the current layout isnt checked to be shown in the menus + //! we must add it on top + if (!fixedMenuLayouts.contains(currentLayoutName())) { + fixedMenuLayouts.prepend(currentLayoutName()); + } + + return fixedMenuLayouts; } void LayoutManager::setMenuLayouts(QStringList layouts) @@ -166,6 +182,45 @@ QString LayoutManager::layoutPath(QString layoutName) return path; } +void LayoutManager::currentActivityChanged(const QString &id) +{ + qDebug() << "activity changed :: " << id; + + m_shouldSwitchToLayout = shouldSwitchToLayout(id); + + m_dynamicSwitchTimer.start(); +} + +QString LayoutManager::shouldSwitchToLayout(QString activityId) +{ + if (m_assignedLayouts.contains(activityId) && m_assignedLayouts[activityId] != currentLayoutName()) { + return m_assignedLayouts[activityId]; + } else if (!m_assignedLayouts.contains(activityId) && !m_corona->universalSettings()->lastNonAssignedLayoutName().isEmpty() + && m_corona->universalSettings()->lastNonAssignedLayoutName() != currentLayoutName()) { + return m_corona->universalSettings()->lastNonAssignedLayoutName(); + } + + return QString(); +} + +void LayoutManager::confirmDynamicSwitch() +{ + QString tempShouldSwitch = shouldSwitchToLayout(m_corona->m_activityConsumer->currentActivity()); + + if (m_shouldSwitchToLayout == tempShouldSwitch) { + qDebug() << "dynamic switch to layout :: " << m_shouldSwitchToLayout; + //NOTE: The pointer is automatically deleted when the event is closed + auto notification = new KNotification("dynamic-switch", KNotification::CloseOnTimeout); + notification->setText(i18nc("dynamic-switch-layout", "Changing to layout %0...").arg(m_shouldSwitchToLayout)); + notification->sendEvent(); + + switchToLayout(m_shouldSwitchToLayout); + } else { + m_shouldSwitchToLayout = tempShouldSwitch; + m_dynamicSwitchTimer.start(); + } +} + void LayoutManager::toggleLayout() { if (m_corona->universalSettings()->currentLayoutName() == i18n("Alternative")) { @@ -180,6 +235,7 @@ void LayoutManager::loadLayouts() m_layouts.clear(); m_menuLayouts.clear(); m_presetsPaths.clear(); + m_assignedLayouts.clear(); QDir layoutDir(QDir::homePath() + "/.config/latte"); QStringList filter; @@ -189,6 +245,13 @@ void LayoutManager::loadLayouts() foreach (auto layout, files) { LayoutSettings layoutSets(this, layoutDir.absolutePath() + "/" + layout); + QStringList validActivityIds = validActivities(layoutSets.activities()); + layoutSets.setActivities(validActivityIds); + + foreach (auto activity, validActivityIds) { + m_assignedLayouts[activity] = layoutSets.name(); + } + m_layouts.append(layoutSets.name()); if (layoutSets.showInMenu()) { @@ -225,9 +288,14 @@ bool LayoutManager::switchToLayout(QString layoutName) //! sessions QTimer::singleShot(0, [this, layoutName, lPath]() { qDebug() << layoutName << " - " << lPath; + m_corona->loadLatteLayout(lPath); m_corona->universalSettings()->setCurrentLayoutName(layoutName); + if (!layoutIsAssigned(layoutName)) { + m_corona->universalSettings()->setLastNonAssignedLayoutName(layoutName); + } + if (m_currentLayout) { m_currentLayout->deleteLater(); } @@ -295,6 +363,34 @@ void LayoutManager::importPresets(bool includeDefault) } } +QStringList LayoutManager::validActivities(QStringList currentList) +{ + QStringList validIds; + + foreach (auto activity, currentList) { + if (activities().contains(activity)) { + validIds.append(activity); + } + } + + return validIds; +} + +bool LayoutManager::layoutIsAssigned(QString layoutName) +{ + QHashIterator i(m_assignedLayouts); + + while (i.hasNext()) { + i.next(); + + if (i.value() == layoutName) { + return true; + } + } + + return false; +} + void LayoutManager::showLayoutConfigDialog() { if (!m_layoutConfigDialog) diff --git a/app/layoutmanager.h b/app/layoutmanager.h index 971e22bb5..f935e347b 100644 --- a/app/layoutmanager.h +++ b/app/layoutmanager.h @@ -61,6 +61,8 @@ public: void load(); + QString shouldSwitchToLayout(QString activityId); + QString currentLayoutName() const; QStringList layouts() const; @@ -94,9 +96,11 @@ signals: void toggleLayoutActionChanged(); private slots: + void currentActivityChanged(const QString &id); void showWidgetsExplorer(); private: + void confirmDynamicSwitch(); void setMenuLayouts(QStringList layouts); QString layoutPath(QString layoutName); @@ -111,6 +115,10 @@ private: LayoutSettings *m_currentLayout{nullptr}; QString m_lastNonAlternativeLayout{QString(i18n("My Layout"))}; + QString m_shouldSwitchToLayout; + + bool layoutIsAssigned(QString layoutName); + QStringList validActivities(QStringList currentList); QStringList m_layouts; QStringList m_menuLayouts; @@ -121,6 +129,10 @@ private: QPointer m_layoutConfigDialog; + QHash m_assignedLayouts; + + QTimer m_dynamicSwitchTimer; + friend class LayoutConfigDialog; }; diff --git a/app/universalsettings.cpp b/app/universalsettings.cpp index 0d91e270e..46814757e 100644 --- a/app/universalsettings.cpp +++ b/app/universalsettings.cpp @@ -30,6 +30,7 @@ UniversalSettings::UniversalSettings(KSharedConfig::Ptr config, QObject *parent) m_universalGroup(KConfigGroup(config, QStringLiteral("UniversalSettings"))) { connect(this, &UniversalSettings::currentLayoutNameChanged, this, &UniversalSettings::saveConfig); + connect(this, &UniversalSettings::lastNonAssignedLayoutNameChanged, this, &UniversalSettings::saveConfig); connect(this, &UniversalSettings::versionChanged, this, &UniversalSettings::saveConfig); } @@ -83,6 +84,21 @@ void UniversalSettings::setCurrentLayoutName(QString layoutName) emit currentLayoutNameChanged(); } +QString UniversalSettings::lastNonAssignedLayoutName() const +{ + return m_lastNonAssignedLayoutName; +} + +void UniversalSettings::setLastNonAssignedLayoutName(QString layoutName) +{ + if (m_lastNonAssignedLayoutName == layoutName) { + return; + } + + m_lastNonAssignedLayoutName = layoutName; + emit lastNonAssignedLayoutNameChanged(); +} + QSize UniversalSettings::layoutsWindowSize() const { return m_layoutsWindowSize; @@ -140,6 +156,7 @@ void UniversalSettings::loadConfig() { m_version = m_universalGroup.readEntry("version", 1); m_currentLayoutName = m_universalGroup.readEntry("currentLayout", QString()); + m_lastNonAssignedLayoutName = m_universalGroup.readEntry("lastNonAssignedLayout", QString()); m_layoutsWindowSize = m_universalGroup.readEntry("layoutsWindowSize", QSize(700, 450)); } @@ -147,6 +164,7 @@ void UniversalSettings::saveConfig() { m_universalGroup.writeEntry("version", m_version); m_universalGroup.writeEntry("currentLayout", m_currentLayoutName); + m_universalGroup.writeEntry("lastNonAssignedLayout", m_lastNonAssignedLayoutName); m_universalGroup.writeEntry("layoutsWindowSize", m_layoutsWindowSize); m_universalGroup.sync(); diff --git a/app/universalsettings.h b/app/universalsettings.h index 9fc7dc448..8ea487274 100644 --- a/app/universalsettings.h +++ b/app/universalsettings.h @@ -53,12 +53,16 @@ public: QString currentLayoutName() const; void setCurrentLayoutName(QString layoutName); + QString lastNonAssignedLayoutName() const; + void setLastNonAssignedLayoutName(QString layoutName); + QSize layoutsWindowSize() const; void setLayoutsWindowSize(QSize); signals: void autostartChanged(); void currentLayoutNameChanged(); + void lastNonAssignedLayoutNameChanged(); void layoutsWindowSizeChanged(); void versionChanged(); @@ -74,6 +78,7 @@ private: int m_version{1}; QString m_currentLayoutName; + QString m_lastNonAssignedLayoutName; QSize m_layoutsWindowSize{700, 450}; KConfigGroup m_universalGroup;