diff --git a/common/control.h b/common/control.h --- a/common/control.h +++ b/common/control.h @@ -49,6 +49,7 @@ OutputRetention getOutputRetention(const KScreen::OutputPtr &output) const; OutputRetention getOutputRetention(const QString &outputId, const QString &outputName) const; + void setOutputRetention(const KScreen::OutputPtr &output, OutputRetention value); void setOutputRetention(const QString &outputId, const QString &outputName, OutputRetention value); bool writeFile(); diff --git a/common/control.cpp b/common/control.cpp --- a/common/control.cpp +++ b/common/control.cpp @@ -147,6 +147,11 @@ return metadata; } +void ControlConfig::setOutputRetention(const KScreen::OutputPtr &output, OutputRetention value) +{ + setOutputRetention(output->hash(), output->name(), value); +} + void ControlConfig::setOutputRetention(const QString &outputId, const QString &outputName, OutputRetention value) { QList::iterator it; diff --git a/kcm/src/CMakeLists.txt b/kcm/src/CMakeLists.txt --- a/kcm/src/CMakeLists.txt +++ b/kcm/src/CMakeLists.txt @@ -16,6 +16,8 @@ widget.cpp previewwidget.cpp scalingconfig.cpp + ../../common/globals.cpp + ../../common/control.cpp ) ecm_qt_declare_logging_category(kcm_kscreen_SRCS HEADER kcm_screen_debug.h IDENTIFIER KSCREEN_KCM CATEGORY_NAME kscreen.kcm) diff --git a/kcm/src/controlpanel.h b/kcm/src/controlpanel.h --- a/kcm/src/controlpanel.h +++ b/kcm/src/controlpanel.h @@ -22,6 +22,8 @@ #ifndef CONTROLPANEL_H #define CONTROLPANEL_H +#include "../../common/control.h" + #include #include @@ -31,6 +33,8 @@ class UnifiedOutputConfig; +#include + class ControlPanel : public QFrame { Q_OBJECT @@ -43,6 +47,8 @@ void setUnifiedOutput(const KScreen::OutputPtr &output); + void save(); + public Q_SLOTS: void activateOutput(const KScreen::OutputPtr &output); @@ -59,6 +65,8 @@ QVBoxLayout *mLayout; UnifiedOutputConfig *mUnifiedOutputCfg; + + std::unique_ptr mControlConfig = nullptr; }; #endif // CONTROLPANEL_H diff --git a/kcm/src/controlpanel.cpp b/kcm/src/controlpanel.cpp --- a/kcm/src/controlpanel.cpp +++ b/kcm/src/controlpanel.cpp @@ -53,6 +53,7 @@ } mConfig = config; + mControlConfig = std::unique_ptr(new ControlConfig(config)); connect(mConfig.data(), &KScreen::Config::outputAdded, this, &ControlPanel::addOutput); connect(mConfig.data(), &KScreen::Config::outputRemoved, @@ -68,10 +69,9 @@ OutputConfig *outputCfg = new OutputConfig(this); outputCfg->setVisible(false); outputCfg->setShowScaleOption(mConfig->supportedFeatures().testFlag(KScreen::Config::Feature::PerOutputScaling)); - outputCfg->setOutput(output); + outputCfg->setOutput(output, mControlConfig->getOutputRetention(output)); connect(outputCfg, &OutputConfig::changed, this, &ControlPanel::changed); - mLayout->addWidget(outputCfg); mOutputConfigs << outputCfg; } @@ -123,3 +123,21 @@ this, &ControlPanel::changed); } } + +void ControlPanel::save() +{ + if (!mControlConfig) { + return; + } + for (const auto outputConfig : mOutputConfigs) { + if (!outputConfig->hasChange()) { + continue; + } + mControlConfig->setOutputRetention(outputConfig->output(), outputConfig->applyRetention()); + } + + if (!mControlConfig->writeFile()) { + // TODO: error handling + } + // TODO: write output controls in the future +} diff --git a/kcm/src/kcm_kscreen.cpp b/kcm/src/kcm_kscreen.cpp --- a/kcm/src/kcm_kscreen.cpp +++ b/kcm/src/kcm_kscreen.cpp @@ -118,6 +118,7 @@ return; } + mKScreenWidget->saveControls(); const KScreen::ConfigPtr &config = mKScreenWidget->currentConfig(); bool atLeastOneEnabledOutput = false; diff --git a/kcm/src/outputconfig.h b/kcm/src/outputconfig.h --- a/kcm/src/outputconfig.h +++ b/kcm/src/outputconfig.h @@ -22,13 +22,16 @@ #ifndef OUTPUTCONFIG_H #define OUTPUTCONFIG_H -#include +#include "../../common/control.h" + #include #include +#include #include class QCheckBox; +class QGroupBox; class ResolutionSlider; class QLabel; @@ -42,13 +45,17 @@ explicit OutputConfig(const KScreen::OutputPtr &output, QWidget *parent = nullptr); ~OutputConfig() override; - virtual void setOutput(const KScreen::OutputPtr &output); + virtual void setOutput(const KScreen::OutputPtr &output, Control::OutputRetention retention = Control::OutputRetention::Undefined); KScreen::OutputPtr output() const; void setTitle(const QString &title); void setShowScaleOption(bool showScaleOption); bool showScaleOption() const; + bool hasChange() const; + + Control::OutputRetention applyRetention(); + protected Q_SLOTS: void slotResolutionChanged(const QSize &size); void slotRotationChanged(int index); @@ -70,6 +77,15 @@ QComboBox *mScale = nullptr; QComboBox *mRefreshRate = nullptr; bool mShowScaleOption = false; + + QGroupBox *mRetentionGroupBox = nullptr; + QRadioButton *mGlobalRetentionButton = nullptr; + QRadioButton *mIndividualRetentionButton = nullptr; + + Control::OutputRetention mRetention = Control::OutputRetention::Undefined; + + // TODO: we should do this instead with a separate config being watched + bool mChanged = false; }; #endif // OUTPUTCONFIG_H diff --git a/kcm/src/outputconfig.cpp b/kcm/src/outputconfig.cpp --- a/kcm/src/outputconfig.cpp +++ b/kcm/src/outputconfig.cpp @@ -105,6 +105,7 @@ this, [=](bool checked) { mOutput->setEnabled(checked); qCDebug(KSCREEN_KCM) << mOutput.data() << mOutput->name() << mOutput->isEnabled(); + mChanged = true; Q_EMIT changed(); }); formLayout->addRow(i18n("Display:"), mEnabled); @@ -149,11 +150,27 @@ slotResolutionChanged(mResolution->currentResolution()); connect(mRefreshRate, static_cast(&QComboBox::activated), this, &OutputConfig::slotRefreshRateChanged); + + + mRetentionGroupBox = new QGroupBox(i18n("Retention of values"), this); + mGlobalRetentionButton = new QRadioButton(i18n("Save as new global values for this display."), this); + mIndividualRetentionButton = new QRadioButton(i18n("Save values only for display in this specific configuration."), this); + mIndividualRetentionButton->setChecked(mRetention == Control::OutputRetention::Individual); + mGlobalRetentionButton->setChecked(!mIndividualRetentionButton->isChecked()); + + QVBoxLayout *vbox2 = new QVBoxLayout(mRetentionGroupBox); + vbox2->addWidget(mGlobalRetentionButton); + vbox2->addWidget(mIndividualRetentionButton); + mRetentionGroupBox->setLayout(vbox2); + + vbox->addWidget(mRetentionGroupBox); } -void OutputConfig::setOutput(const KScreen::OutputPtr &output) +void OutputConfig::setOutput(const KScreen::OutputPtr &output, Control::OutputRetention retention) { mOutput = output; + mRetention = retention; + initUi(); } @@ -201,7 +218,7 @@ mRefreshRate->setCurrentIndex(i + 1); } } - + mChanged = true; Q_EMIT changed(); } @@ -211,6 +228,7 @@ static_cast(mRotation->itemData(index).toInt()); mOutput->setRotation(rotation); + mChanged = true; Q_EMIT changed(); } @@ -227,13 +245,15 @@ } mOutput->setCurrentModeId(modeId); + mChanged = true; Q_EMIT changed(); } void OutputConfig::slotScaleChanged(int index) { auto scale = mScale->itemData(index).toInt(); mOutput->setScale(scale); + mChanged = true; Q_EMIT changed(); } @@ -249,3 +269,18 @@ { return mShowScaleOption; } + +Control::OutputRetention OutputConfig::applyRetention() +{ + if (mIndividualRetentionButton->isChecked()) { + mRetention = Control::OutputRetention::Individual; + } else { + mRetention = Control::OutputRetention::Global; + } + return mRetention; +} + +bool OutputConfig::hasChange() const +{ + return mChanged; +} diff --git a/kcm/src/unifiedoutputconfig.h b/kcm/src/unifiedoutputconfig.h --- a/kcm/src/unifiedoutputconfig.h +++ b/kcm/src/unifiedoutputconfig.h @@ -37,7 +37,7 @@ explicit UnifiedOutputConfig(const KScreen::ConfigPtr &config, QWidget *parent); ~UnifiedOutputConfig() override; - void setOutput(const KScreen::OutputPtr &output) override; + void setOutput(const KScreen::OutputPtr &output, Control::OutputRetention retention = Control::OutputRetention::Undefined) override; private Q_SLOTS: void slotResolutionChanged(const QSize &size); diff --git a/kcm/src/unifiedoutputconfig.cpp b/kcm/src/unifiedoutputconfig.cpp --- a/kcm/src/unifiedoutputconfig.cpp +++ b/kcm/src/unifiedoutputconfig.cpp @@ -61,8 +61,10 @@ { } -void UnifiedOutputConfig::setOutput(const KScreen::OutputPtr &output) +void UnifiedOutputConfig::setOutput(const KScreen::OutputPtr &output, Control::OutputRetention retention) { + Q_UNUSED(retention); // TODO: use? + mOutput = output; mClones.clear(); diff --git a/kcm/src/widget.h b/kcm/src/widget.h --- a/kcm/src/widget.h +++ b/kcm/src/widget.h @@ -28,7 +28,7 @@ class QMLOutput; class QMLScreen; class ControlPanel; - +class ControlConfig; class QQuickView; @@ -58,6 +58,7 @@ Q_SIGNALS: void changed(); + void saveControls(); private Q_SLOTS: void slotFocusedOutputChanged(QMLOutput *output); diff --git a/kcm/src/widget.cpp b/kcm/src/widget.cpp --- a/kcm/src/widget.cpp +++ b/kcm/src/widget.cpp @@ -30,6 +30,7 @@ #include "declarative/qmlscreen.h" #include "utils.h" #include "scalingconfig.h" +#include "../../common/control.h" #include #include @@ -77,6 +78,7 @@ dialog->exec(); delete dialog; }); + connect(this, &Widget::saveControls, mControlPanel, &ControlPanel::save); mOutputTimer = new QTimer(this); connect(mOutputTimer, &QTimer::timeout,