File indexing completed on 2024-06-02 05:43:39

0001 /* ColorEdit widget for KDE Display color scheme setup module
0002     SPDX-FileCopyrightText: 2016 Olivier Churlaud <olivier@churlaud.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "scmeditordialog.h"
0008 #include "scmeditorcolors.h"
0009 #include "scmeditoreffects.h"
0010 #include "scmeditoroptions.h"
0011 
0012 #include <QDebug>
0013 #include <QDir>
0014 #include <QInputDialog>
0015 #include <QLineEdit>
0016 #include <QUrl>
0017 
0018 #include <KConfigGroup>
0019 #include <KMessageBox>
0020 #include <KStandardGuiItem>
0021 #include <KWindowSystem>
0022 
0023 using namespace Qt::StringLiterals;
0024 
0025 SchemeEditorDialog::SchemeEditorDialog(KSharedConfigPtr config, QWidget *parent)
0026     : QDialog(parent)
0027     , m_config(config)
0028 {
0029     init();
0030 }
0031 
0032 SchemeEditorDialog::SchemeEditorDialog(const QString &path, QWidget *parent)
0033     : QDialog(parent)
0034     , m_filePath(path)
0035     , m_config(KSharedConfig::openConfig(path, KSharedConfig::SimpleConfig))
0036 {
0037     m_schemeName = KConfigGroup(m_config, u"General"_s).readEntry("Name");
0038     this->setWindowTitle(m_schemeName);
0039     init();
0040 }
0041 
0042 bool SchemeEditorDialog::showApplyOverwriteButton() const
0043 {
0044     return m_showApplyOverwriteButton;
0045 }
0046 
0047 void SchemeEditorDialog::setShowApplyOverwriteButton(bool show)
0048 {
0049     m_showApplyOverwriteButton = show;
0050 
0051     buttonBox->button(QDialogButtonBox::Apply)->setVisible(show);
0052 }
0053 
0054 void SchemeEditorDialog::init()
0055 {
0056     setupUi(this);
0057 
0058     m_optionTab = new SchemeEditorOptions(m_config);
0059     m_colorTab = new SchemeEditorColors(m_config);
0060     m_disabledTab = new SchemeEditorEffects(m_config, QPalette::Disabled);
0061     m_inactiveTab = new SchemeEditorEffects(m_config, QPalette::Inactive);
0062     tabWidget->addTab(m_optionTab, i18n("Options"));
0063     tabWidget->addTab(m_colorTab, i18n("Colors"));
0064     tabWidget->addTab(m_disabledTab, i18n("Disabled"));
0065     tabWidget->setCurrentWidget(m_colorTab);
0066 
0067     connect(m_optionTab, &SchemeEditorOptions::changed, this, &SchemeEditorDialog::updateTabs);
0068     connect(m_colorTab, &SchemeEditorColors::changed, this, &SchemeEditorDialog::updateTabs);
0069     connect(m_disabledTab, &SchemeEditorEffects::changed, this, &SchemeEditorDialog::updateTabs);
0070     connect(m_inactiveTab, &SchemeEditorEffects::changed, this, &SchemeEditorDialog::updateTabs);
0071 
0072     // "Save" is only shown in overwrite mode
0073     KGuiItem::assign(buttonBox->button(QDialogButtonBox::Apply), KStandardGuiItem::save());
0074     buttonBox->button(QDialogButtonBox::Apply)->setVisible(false);
0075     buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
0076 
0077     KGuiItem::assign(buttonBox->button(QDialogButtonBox::Save), KStandardGuiItem::saveAs());
0078     buttonBox->button(QDialogButtonBox::Reset)->setEnabled(false);
0079     updateTabs();
0080 }
0081 
0082 void SchemeEditorDialog::on_buttonBox_clicked(QAbstractButton *button)
0083 {
0084     if (buttonBox->standardButton(button) == QDialogButtonBox::Reset) {
0085         m_config->markAsClean();
0086         m_config->reparseConfiguration();
0087         updateTabs();
0088         setUnsavedChanges(false);
0089     } else if (buttonBox->standardButton(button) == QDialogButtonBox::Save) {
0090         saveScheme(false /*overwrite*/);
0091     } else if (buttonBox->standardButton(button) == QDialogButtonBox::Apply) {
0092         saveScheme(true /*overwrite*/);
0093     } else if (buttonBox->standardButton(button) == QDialogButtonBox::Close) {
0094         if (m_unsavedChanges) {
0095             KMessageBox::ButtonCode ans = KMessageBox::questionTwoActions(this,
0096                                                                           i18n("You have unsaved changes. Do you really want to quit?"),
0097                                                                           i18n("Unsaved changes"),
0098                                                                           KStandardGuiItem::quit(),
0099                                                                           KStandardGuiItem::cancel());
0100             if (ans == KMessageBox::SecondaryAction) {
0101                 return;
0102             }
0103         }
0104         m_config->markAsClean();
0105         m_config->reparseConfiguration();
0106         this->accept();
0107     }
0108 }
0109 
0110 void SchemeEditorDialog::saveScheme(bool overwrite)
0111 {
0112     QString name = m_schemeName;
0113 
0114     // prompt for the name to save as
0115     if (!overwrite) {
0116         bool ok;
0117         name = QInputDialog::getText(this, i18n("Save Color Scheme"), i18n("&Enter a name for the color scheme:"), QLineEdit::Normal, m_schemeName, &ok);
0118         if (!ok) {
0119             return;
0120         }
0121     }
0122 
0123     QString filename = name;
0124     filename.remove(QLatin1Char('\'')); // So Foo's does not become FooS
0125     QRegularExpression fixer(QStringLiteral("[\\W,.-]+(.?)"));
0126     for (auto match = fixer.match(filename); match.hasMatch(); match = fixer.match(filename)) {
0127         filename.replace(match.capturedStart(), match.capturedLength(), match.captured(1).toUpper());
0128     }
0129     filename.replace(0, 1, filename.at(0).toUpper());
0130 
0131     // check if that name is already in the list
0132     const QString path = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("color-schemes/") + filename + QStringLiteral(".colors"));
0133 
0134     QFile file(path);
0135     const int permissions = file.permissions();
0136     const bool canWrite = (permissions & QFile::WriteUser);
0137     // or if we can overwrite it if it exists
0138     if (path.isEmpty() || !file.exists() || canWrite) {
0139         if (canWrite && !overwrite) {
0140             int ret = KMessageBox::questionTwoActions(this,
0141                                                       i18n("A color scheme with that name already exists.\nDo you want to overwrite it?"),
0142                                                       i18n("Save Color Scheme"),
0143                                                       KStandardGuiItem::overwrite(),
0144                                                       KStandardGuiItem::cancel());
0145 
0146             // on don't overwrite, call again the function
0147             if (ret == KMessageBox::SecondaryAction) {
0148                 this->saveScheme(overwrite);
0149                 return;
0150             }
0151         }
0152 
0153         // go ahead and save it
0154         QString newpath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/color-schemes/";
0155         QDir dir;
0156         dir.mkpath(newpath);
0157         newpath += filename + ".colors";
0158 
0159         KConfig *config = m_config->copyTo(newpath);
0160         m_config->markAsClean();
0161         m_config->reparseConfiguration();
0162         KConfigGroup group(config, u"General"_s);
0163         group.writeEntry("Name", name);
0164 
0165         // sync it and delete pointer
0166         config->sync();
0167         delete config;
0168         // reopen and update window
0169         m_config = KSharedConfig::openConfig(newpath);
0170         m_schemeName = name;
0171         setWindowTitle(name);
0172 
0173         setUnsavedChanges(false);
0174 
0175         QTextStream out(stdout);
0176         out << filename << Qt::endl;
0177     } else if (!canWrite && file.exists()) {
0178         KMessageBox::error(this, i18n("You do not have permission to overwrite that scheme"), i18n("Error"));
0179     }
0180 }
0181 
0182 void SchemeEditorDialog::updateTabs(bool madeByUser)
0183 {
0184     if (madeByUser) {
0185         setUnsavedChanges(true);
0186     }
0187     KConfigGroup group(m_config, u"ColorEffects:Inactive"_s);
0188     bool showInactiveTab = group.readEntry("Enable", QVariant(true)).toBool();
0189 
0190     const int idx = tabWidget->indexOf(m_inactiveTab);
0191 
0192     if (showInactiveTab && idx == -1) {
0193         tabWidget->addTab(m_inactiveTab, i18n("Inactive"));
0194     } else if (!showInactiveTab && idx > -1) {
0195         tabWidget->removeTab(idx);
0196     }
0197 
0198     m_optionTab->updateValues();
0199     m_colorTab->updateValues();
0200     m_inactiveTab->updateValues();
0201     m_disabledTab->updateValues();
0202 }
0203 
0204 void SchemeEditorDialog::setUnsavedChanges(bool changes)
0205 {
0206     m_unsavedChanges = changes;
0207     if (changes) {
0208         buttonBox->button(QDialogButtonBox::Apply)->setEnabled(true);
0209         buttonBox->button(QDialogButtonBox::Reset)->setEnabled(true);
0210     } else {
0211         buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
0212         buttonBox->button(QDialogButtonBox::Reset)->setEnabled(false);
0213     }
0214 }