diff --git a/kcm/config_handler.h b/kcm/config_handler.h --- a/kcm/config_handler.h +++ b/kcm/config_handler.h @@ -44,6 +44,10 @@ return m_config; } + void revert() { + m_config = m_previousConfig->clone(); + } + int retention() const; void setRetention(int retention); @@ -69,6 +73,7 @@ KScreen::ConfigPtr m_config = nullptr; KScreen::ConfigPtr m_initialConfig; + KScreen::ConfigPtr m_previousConfig = nullptr; OutputModel *m_outputs = nullptr; std::unique_ptr m_control; diff --git a/kcm/config_handler.cpp b/kcm/config_handler.cpp --- a/kcm/config_handler.cpp +++ b/kcm/config_handler.cpp @@ -80,6 +80,7 @@ void ConfigHandler::updateInitialConfig() { + m_previousConfig = m_initialConfig->clone(); m_initialRetention = getRetention(); connect(new GetConfigOperation(), &GetConfigOperation::finished, this, [this](ConfigOperation *op) { diff --git a/kcm/kcm.h b/kcm/kcm.h --- a/kcm/kcm.h +++ b/kcm/kcm.h @@ -78,6 +78,8 @@ Q_INVOKABLE void forceSave(); void doSave(bool force); + Q_INVOKABLE void revertSettings(); + Q_INVOKABLE void stopRevertTimer(); Q_SIGNALS: void backendReadyChanged(); @@ -94,6 +96,8 @@ void errorOnSave(); void globalScaleWritten(); void outputConnect(bool connected); + void settingsReverted(); + void showRevertWarning(); private: void setBackendReady(bool error); @@ -109,8 +113,10 @@ std::unique_ptr m_config; bool m_backendReady = false; bool m_screenNormalized = true; + bool m_settingsReverted = false; double m_globalScale = 1.; double m_initialGlobalScale = 1.; QTimer *m_loadCompressor; + QTimer *m_revertTimer; }; diff --git a/kcm/kcm.cpp b/kcm/kcm.cpp --- a/kcm/kcm.cpp +++ b/kcm/kcm.cpp @@ -69,7 +69,11 @@ m_loadCompressor = new QTimer(this); m_loadCompressor->setInterval(1000); m_loadCompressor->setSingleShot(true); + m_revertTimer = new QTimer(this); + m_revertTimer->setSingleShot(true); + m_revertTimer->setInterval(10000); connect (m_loadCompressor, &QTimer::timeout, this, &KCMKScreen::load); + connect (m_revertTimer, &QTimer::timeout, this, &KCMKScreen::revertSettings); } void KCMKScreen::configReady(ConfigOperation *op) @@ -98,6 +102,28 @@ doSave(false); } +void KCMKScreen::revertSettings() +{ + stopRevertTimer(); + if (!m_config) { + setNeedsSave(false); + return; + } + if (!m_settingsReverted) { + m_config->revert(); + m_settingsReverted = true; + doSave(true); + load(); // reload the configuration + Q_EMIT settingsReverted(); + } +} + +void KCMKScreen::stopRevertTimer() { + if (m_revertTimer->isActive()) { + m_revertTimer->stop(); + } +} + void KCMKScreen::doSave(bool force) { if (!m_config) { @@ -160,6 +186,14 @@ return; } m_config->updateInitialConfig(); + if (!m_settingsReverted) { + // start the revert timer + m_revertTimer->start(); + Q_EMIT showRevertWarning(); + } else { + // reset the revert flag + m_settingsReverted = false; + } } ); } diff --git a/kcm/package/contents/ui/main.qml b/kcm/package/contents/ui/main.qml --- a/kcm/package/contents/ui/main.qml +++ b/kcm/package/contents/ui/main.qml @@ -17,6 +17,7 @@ import QtQuick 2.9 import QtQuick.Layouts 1.1 import QtQuick.Controls 2.3 as Controls +import QtQuick.Dialogs 1.3 import org.kde.kirigami 2.4 as Kirigami import org.kde.kcm 1.2 as KCM @@ -28,6 +29,7 @@ implicitHeight: units.gridUnit * 38 property int selectedOutput: 0 + property int revertCountdown: 10 ColumnLayout { Kirigami.InlineMessage { @@ -86,6 +88,27 @@ visible: false showCloseButton: true } + Kirigami.InlineMessage { + id: revertMsg + Layout.fillWidth: true + type: Kirigami.MessageType.Information + text: i18n("Settings are reverted to the previous state.") + visible: false + showCloseButton: true + } + + MessageDialog { + id: confirmDialog + icon: StandardIcon.Question + text: i18n("Is your screen displaying correctly?\nThe settings will be reverted to the previous state in 10 seconds.") + onAccepted: { + kcm.stopRevertTimer(); + } + onRejected: { + kcm.revertSettings(); + } + standardButtons: StandardButton.Save | StandardButton.Cancel + } Connections { target: kcm @@ -101,6 +124,11 @@ connectMsg.visible = true; } onBackendError: errBackendMsg.visible = true; + onSettingsReverted: { + revertMsg.visible = true; + confirmDialog.close(); + } + onShowRevertWarning: confirmDialog.open(); onChanged: { dangerousSaveMsg.visible = false;