diff --git a/lookandfeelexplorer/package/contents/ui/FormField.qml b/lookandfeelexplorer/package/contents/ui/FormField.qml --- a/lookandfeelexplorer/package/contents/ui/FormField.qml +++ b/lookandfeelexplorer/package/contents/ui/FormField.qml @@ -18,12 +18,15 @@ */ import QtQuick 2.3 +import QtQuick.Layouts 1.1 import QtQuick.Controls 1.2 +import org.kde.kirigami 1.0 as Kirigami TextField { id: field property string key text: lnfLogic[key] + Layout.minimumWidth: Kirigami.Units.gridUnit * 15 onAccepted: { lnfLogic.name = text; timer.running = false; diff --git a/lookandfeelexplorer/package/contents/ui/main.qml b/lookandfeelexplorer/package/contents/ui/main.qml --- a/lookandfeelexplorer/package/contents/ui/main.qml +++ b/lookandfeelexplorer/package/contents/ui/main.qml @@ -157,13 +157,13 @@ } Button { text: i18n("Layout from current Plasma setup") - onClicked: lnfLogic.dumpCurrentPlasmaLayout(); + onClicked: lnfLogic.performLayoutDump = true Layout.columnSpan: 2 Layout.alignment: Qt.AlignRight } Button { text: i18n("Defaults from current setup") - onClicked: lnfLogic.dumpDefaultsConfigFile(lnfLogic.theme); + onClicked: lnfLogic.performDefaultsDump = true Layout.columnSpan: 2 Layout.alignment: Qt.AlignRight } @@ -213,4 +213,13 @@ } } } + Button { + anchors { + right: parent.right + bottom: parent.bottom + } + text: i18n("Save") + enabled: lnfLogic.needsSave + onClicked: lnfLogic.save() + } } diff --git a/lookandfeelexplorer/src/lnflogic.h b/lookandfeelexplorer/src/lnflogic.h --- a/lookandfeelexplorer/src/lnflogic.h +++ b/lookandfeelexplorer/src/lnflogic.h @@ -35,15 +35,21 @@ Q_PROPERTY(QString theme READ theme WRITE setTheme NOTIFY themeChanged) Q_PROPERTY(bool isWritable READ isWritable NOTIFY themeChanged) Q_PROPERTY(QString themeFolder READ themeFolder NOTIFY themeChanged) - Q_PROPERTY(QString name READ name WRITE setName NOTIFY themeChanged) - Q_PROPERTY(QString comment READ comment WRITE setComment NOTIFY themeChanged) - Q_PROPERTY(QString author READ author WRITE setAuthor NOTIFY themeChanged) - Q_PROPERTY(QString email READ email WRITE setEmail NOTIFY themeChanged) - Q_PROPERTY(QString version READ version WRITE setVersion NOTIFY themeChanged) - Q_PROPERTY(QString website READ website WRITE setWebsite NOTIFY themeChanged) - Q_PROPERTY(QString license READ license WRITE setLicense NOTIFY themeChanged) + + Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) + Q_PROPERTY(QString comment READ comment WRITE setComment NOTIFY commentChanged) + Q_PROPERTY(QString author READ author WRITE setAuthor NOTIFY authorChanged) + Q_PROPERTY(QString email READ email WRITE setEmail NOTIFY emailChanged) + Q_PROPERTY(QString version READ version WRITE setVersion NOTIFY versionChanged) + Q_PROPERTY(QString website READ website WRITE setWebsite NOTIFY websiteChanged) + Q_PROPERTY(QString license READ license WRITE setLicense NOTIFY licenseChanged) Q_PROPERTY(QString thumbnailPath READ thumbnailPath NOTIFY themeChanged) + Q_PROPERTY(bool performLayoutDump READ performLayoutDump WRITE setPerformLayoutDump NOTIFY performLayoutDumpChanged) + Q_PROPERTY(bool performDefaultsDump READ performDefaultsDump WRITE setPerformDefaultsDump NOTIFY performDefaultsDumpChanged) + + Q_PROPERTY(bool needsSave READ needsSave NOTIFY needsSaveChanged) + public: enum ErrorLevel { Info, @@ -54,8 +60,6 @@ explicit LnfLogic(QObject *parent = 0); ~LnfLogic(); - void writeMetadata(const QString &key, const QString &value); - LnfListModel *lnfList(); void setTheme(const QString &theme); @@ -85,25 +89,48 @@ QString license() const; void setLicense(const QString &license); + bool performLayoutDump() const; + void setPerformLayoutDump(bool dump); + + bool performDefaultsDump() const; + void setPerformDefaultsDump(bool dump); + QString thumbnailPath() const; void dumpPlasmaLayout(const QString &pluginName); + bool needsSave(); + + Q_INVOKABLE void save(); Q_INVOKABLE void createNewTheme(const QString &pluginName, const QString &name, const QString &comment, const QString &author, const QString &email, const QString &license, const QString &website); Q_INVOKABLE void processThumbnail(const QString &path); Q_INVOKABLE QString openFile(); - Q_INVOKABLE void dumpCurrentPlasmaLayout(); - Q_INVOKABLE void dumpDefaultsConfigFile(const QString &pluginName); + void dumpCurrentPlasmaLayout(); + void dumpDefaultsConfigFile(const QString &pluginName); Q_SIGNALS: void themeChanged(); void messageRequested(ErrorLevel level, const QString &message); + void needsSaveChanged(); + void nameChanged(); + void commentChanged(); + void authorChanged(); + void emailChanged(); + void versionChanged(); + void websiteChanged(); + void licenseChanged(); + void performLayoutDumpChanged(); + void performDefaultsDumpChanged(); private: QString m_themeName; KPackage::Package m_package; LnfListModel *m_lnfListModel; + QHash m_tempMetadata; + bool m_performLayoutDump : 1; + bool m_performDefaultsDump : 1; + bool m_needsSave; }; #endif // LNFLOGIC_H diff --git a/lookandfeelexplorer/src/lnflogic.cpp b/lookandfeelexplorer/src/lnflogic.cpp --- a/lookandfeelexplorer/src/lnflogic.cpp +++ b/lookandfeelexplorer/src/lnflogic.cpp @@ -42,7 +42,8 @@ LnfLogic::LnfLogic(QObject *parent) : QObject(parent), m_themeName(QStringLiteral("org.kde.breeze.desktop")), - m_lnfListModel(new LnfListModel(this)) + m_lnfListModel(new LnfListModel(this)), + m_needsSave(false) { m_package = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("Plasma/LookAndFeel")); } @@ -77,7 +78,6 @@ void LnfLogic::dumpPlasmaLayout(const QString &pluginName) { - //TODO: async and error management QDBusMessage message = QDBusMessage::createMethodCall("org.kde.plasmashell", "/PlasmaShell", "org.kde.PlasmaShell", "dumpCurrentLayoutJS"); QDBusPendingCall pcall = QDBusConnection::sessionBus().asyncCall(message); @@ -94,7 +94,6 @@ } const QString layout = msg.arguments().first().toString(); - //TODO: error checking QDir themeDir(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) % QLatin1Literal("/plasma/look-and-feel/") % pluginName); if (!themeDir.mkpath("contents/layouts")) { qWarning() << "Impossible to create the layouts directory in the look and feel package"; @@ -161,12 +160,27 @@ dumpPlasmaLayout(m_themeName); } -void LnfLogic::writeMetadata(const QString &key, const QString &value) +void LnfLogic::save() { KConfig c(m_package.filePath("metadata")); KConfigGroup cg(&c, "Desktop Entry"); - cg.writeEntry(key, value); + QHash::const_iterator i; + for (i = m_tempMetadata.constBegin(); i != m_tempMetadata.constEnd(); ++i) { + cg.writeEntry(i.key(), i.value()); + } + m_tempMetadata.clear(); + m_needsSave = false; + if (m_performLayoutDump) { + dumpCurrentPlasmaLayout(); + m_performLayoutDump = false; + } + if (m_performDefaultsDump) { + dumpDefaultsConfigFile(m_themeName); + m_performDefaultsDump = false; + } + + emit needsSaveChanged(); //HACK m_package.setPath(QString()); @@ -199,92 +213,204 @@ return; } + m_tempMetadata.clear(); m_themeName = theme; m_package.setPath(theme); + m_needsSave = false; + emit needsSaveChanged(); emit themeChanged(); + emit nameChanged(); + emit commentChanged(); + emit authorChanged(); + emit emailChanged(); + emit versionChanged(); + emit websiteChanged(); + emit licenseChanged(); } QString LnfLogic::name() const { + if (m_tempMetadata.contains(QStringLiteral("Name"))) { + return m_tempMetadata.value(QStringLiteral("Name")); + } return m_package.metadata().name(); } void LnfLogic::setName(const QString &name) { - writeMetadata("Name", name); - emit themeChanged(); + if (LnfLogic::name() == name) { + return; + } + + m_tempMetadata[QStringLiteral("Name")] = name; + m_needsSave = true; + emit needsSaveChanged(); + emit nameChanged(); } QString LnfLogic::comment() const { + if (m_tempMetadata.contains(QStringLiteral("Comment"))) { + return m_tempMetadata.value(QStringLiteral("Comment")); + } return m_package.metadata().description(); } void LnfLogic::setComment(const QString &comment) { - writeMetadata("Comment", comment); - emit themeChanged(); + if (LnfLogic::comment() == comment) { + return; + } + + m_tempMetadata[QStringLiteral("Comment")] = comment; + m_needsSave = true; + emit needsSaveChanged(); + emit commentChanged(); } QString LnfLogic::author() const { + if (m_tempMetadata.contains(QStringLiteral("X-KDE-PluginInfo-Author"))) { + return m_tempMetadata.value(QStringLiteral("X-KDE-PluginInfo-Author")); + } if (m_package.metadata().authors().isEmpty()) { return QString(); } return m_package.metadata().authors().first().name(); } void LnfLogic::setAuthor(const QString &author) { - writeMetadata("X-KDE-PluginInfo-Author", author); - emit themeChanged(); + if (LnfLogic::author() == author) { + return; + } + + m_tempMetadata[QStringLiteral("X-KDE-PluginInfo-Author")] = author; + m_needsSave = true; + emit needsSaveChanged(); + emit authorChanged(); } QString LnfLogic::email() const { + if (m_tempMetadata.contains(QStringLiteral("X-KDE-PluginInfo-Email"))) { + return m_tempMetadata.value(QStringLiteral("X-KDE-PluginInfo-Email")); + } if (m_package.metadata().authors().isEmpty()) { return QString(); } return m_package.metadata().authors().first().emailAddress(); } void LnfLogic::setEmail(const QString &email) { - writeMetadata("X-KDE-PluginInfo-Email", email); - emit themeChanged(); + if (LnfLogic::email() == email) { + return; + } + + m_tempMetadata[QStringLiteral("X-KDE-PluginInfo-Email")] = email; + m_needsSave = true; + emit needsSaveChanged(); + emit emailChanged(); } QString LnfLogic::version() const { + if (m_tempMetadata.contains(QStringLiteral("X-KDE-PluginInfo-Version"))) { + return m_tempMetadata.value(QStringLiteral("X-KDE-PluginInfo-Version")); + } return m_package.metadata().version(); } void LnfLogic::setVersion(const QString &version) { - writeMetadata("X-KDE-PluginInfo-Version", version); - emit themeChanged(); + if (LnfLogic::version() == version) { + return; + } + + m_tempMetadata[QStringLiteral("X-KDE-PluginInfo-Version")] = version; + m_needsSave = true; + emit needsSaveChanged(); + emit versionChanged(); } QString LnfLogic::website() const { + if (m_tempMetadata.contains(QStringLiteral("X-KDE-PluginInfo-Website"))) { + return m_tempMetadata.value(QStringLiteral("X-KDE-PluginInfo-Website")); + } return m_package.metadata().website(); } void LnfLogic::setWebsite(const QString &website) { - writeMetadata("X-KDE-PluginInfo-Website", website); - emit themeChanged(); + if (LnfLogic::website() == website) { + return; + } + + m_tempMetadata[QStringLiteral("X-KDE-PluginInfo-Website")] = website; + m_needsSave = true; + emit needsSaveChanged(); + emit websiteChanged(); } QString LnfLogic::license() const { + if (m_tempMetadata.contains(QStringLiteral("X-KDE-PluginInfo-License"))) { + return m_tempMetadata.value(QStringLiteral("X-KDE-PluginInfo-License")); + } return m_package.metadata().license(); } void LnfLogic::setLicense(const QString &license) { - writeMetadata("X-KDE-PluginInfo-License", license); - emit themeChanged(); + if (LnfLogic::license() == license) { + return; + } + + m_tempMetadata[QStringLiteral("X-KDE-PluginInfo-License")] = license; + m_needsSave = true; + emit needsSaveChanged(); + emit licenseChanged(); +} + +bool LnfLogic::performLayoutDump() const +{ + return m_performLayoutDump; +} + +void LnfLogic::setPerformLayoutDump(bool dump) +{ + if (m_performLayoutDump == dump) { + return; + } + + m_needsSave = true; + emit needsSaveChanged(); + m_performLayoutDump = dump; + emit performLayoutDumpChanged(); +} + +bool LnfLogic::performDefaultsDump() const +{ + return m_performDefaultsDump; +} + +void LnfLogic::setPerformDefaultsDump(bool dump) +{ + if (m_performDefaultsDump == dump) { + return; + } + + m_needsSave = true; + emit needsSaveChanged(); + m_performDefaultsDump = dump; + emit performDefaultsDumpChanged(); +} + +bool LnfLogic::needsSave() +{ + return m_needsSave; } QString LnfLogic::thumbnailPath() const