From 224d457aaaa576704bc9273bad61ea25d9866b6c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thorbj=C3=B8rn=20Lindeijer?= <thorbjorn.lindeijer@nokia.com>
Date: Mon, 13 Jul 2009 14:08:14 +0200
Subject: [PATCH] Made cloning, deleting and editing of color schemes
 functional

---
 .../texteditor/editcolorschemedialog.cpp      |   5 +-
 .../texteditor/editcolorschemedialog.h        |   1 -
 src/plugins/texteditor/fontsettings.cpp       |  20 ++-
 src/plugins/texteditor/fontsettings.h         |   3 +-
 src/plugins/texteditor/fontsettingspage.cpp   | 163 ++++++++++++++----
 src/plugins/texteditor/fontsettingspage.h     |   6 +-
 src/plugins/texteditor/fontsettingspage.ui    |  35 ++--
 7 files changed, 172 insertions(+), 61 deletions(-)

diff --git a/src/plugins/texteditor/editcolorschemedialog.cpp b/src/plugins/texteditor/editcolorschemedialog.cpp
index f05e09e5421..3d724dea401 100644
--- a/src/plugins/texteditor/editcolorschemedialog.cpp
+++ b/src/plugins/texteditor/editcolorschemedialog.cpp
@@ -47,18 +47,17 @@ static inline QString colorButtonStyleSheet(const QColor &bgColor)
 
 EditColorSchemeDialog::EditColorSchemeDialog(const FormatDescriptions &fd,
                                              const FontSettings &fontSettings,
-                                             const ColorScheme &scheme,
                                              QWidget *parent) :
     QDialog(parent),
     m_descriptions(fd),
     m_fontSettings(fontSettings),
-    m_scheme(scheme),
+    m_scheme(fontSettings.colorScheme()),
     m_curItem(-1),
     m_ui(new Ui::EditColorSchemeDialog)
 {
     m_ui->setupUi(this);
 
-    m_ui->nameEdit->setText(scheme.name());
+    m_ui->nameEdit->setText(m_scheme.name());
 
     foreach (const FormatDescription &d, fd)
         m_ui->itemListWidget->addItem(d.trName());
diff --git a/src/plugins/texteditor/editcolorschemedialog.h b/src/plugins/texteditor/editcolorschemedialog.h
index 386826fd49c..77bc7c69dfe 100644
--- a/src/plugins/texteditor/editcolorschemedialog.h
+++ b/src/plugins/texteditor/editcolorschemedialog.h
@@ -49,7 +49,6 @@ class EditColorSchemeDialog : public QDialog
 public:
     EditColorSchemeDialog(const FormatDescriptions &fd,
                           const FontSettings &fontSettings,
-                          const ColorScheme &scheme,
                           QWidget *parent = 0);
     ~EditColorSchemeDialog();
 
diff --git a/src/plugins/texteditor/fontsettings.cpp b/src/plugins/texteditor/fontsettings.cpp
index 03f61b61c02..ff063080ee7 100644
--- a/src/plugins/texteditor/fontsettings.cpp
+++ b/src/plugins/texteditor/fontsettings.cpp
@@ -220,11 +220,25 @@ QString FontSettings::colorSchemeFileName() const
     return m_schemeFileName;
 }
 
-void FontSettings::loadColorScheme(const QString &fileName,
+/**
+ * Sets the file name of the color scheme. Does not load the scheme from the
+ * given file. If you want to load a scheme, use loadColorScheme() instead.
+ */
+void FontSettings::setColorSchemeFileName(const QString &fileName)
+{
+    m_schemeFileName = fileName;
+}
+
+bool FontSettings::loadColorScheme(const QString &fileName,
                                    const FormatDescriptions &descriptions)
 {
+    bool loaded = true;
     m_schemeFileName = fileName;
-    m_scheme.load(m_schemeFileName);
+
+    if (!m_scheme.load(m_schemeFileName)) {
+        loaded = false;
+        qWarning() << "Failed to load color scheme:" << fileName;
+    }
 
     // Apply default formats to undefined categories
     foreach (const FormatDescription &desc, descriptions) {
@@ -238,6 +252,8 @@ void FontSettings::loadColorScheme(const QString &fileName,
             m_scheme.setFormatFor(name, format);
         }
     }
+
+    return loaded;
 }
 
 /**
diff --git a/src/plugins/texteditor/fontsettings.h b/src/plugins/texteditor/fontsettings.h
index b67e48b3111..0fa93bbe7bb 100644
--- a/src/plugins/texteditor/fontsettings.h
+++ b/src/plugins/texteditor/fontsettings.h
@@ -84,7 +84,8 @@ public:
     Format &formatFor(const QString &category);
 
     QString colorSchemeFileName() const;
-    void loadColorScheme(const QString &fileName, const FormatDescriptions &descriptions);
+    void setColorSchemeFileName(const QString &fileName);
+    bool loadColorScheme(const QString &fileName, const FormatDescriptions &descriptions);
 
     ColorScheme colorScheme() const;
     void setColorScheme(const ColorScheme &scheme);
diff --git a/src/plugins/texteditor/fontsettingspage.cpp b/src/plugins/texteditor/fontsettingspage.cpp
index 5b74300b7d0..e816f1af933 100644
--- a/src/plugins/texteditor/fontsettingspage.cpp
+++ b/src/plugins/texteditor/fontsettingspage.cpp
@@ -37,6 +37,7 @@
 #include <coreplugin/icore.h>
 #include <utils/settingsutils.h>
 
+#include <QtCore/QDebug>
 #include <QtCore/QSettings>
 #include <QtCore/QTimer>
 #include <QtGui/QCheckBox>
@@ -44,6 +45,7 @@
 #include <QtGui/QFileDialog>
 #include <QtGui/QFontDatabase>
 #include <QtGui/QListWidget>
+#include <QtGui/QMessageBox>
 #include <QtGui/QPalette>
 #include <QtGui/QPalette>
 #include <QtGui/QTextCharFormat>
@@ -73,6 +75,23 @@ public:
     Ui::FontSettingsPage ui;
 };
 
+struct ColorSchemeEntry
+{
+    QString fileName;
+    QString name;
+    bool readOnly;
+};
+
+} // namespace Internal
+} // namespace TextEditor
+
+Q_DECLARE_METATYPE(TextEditor::Internal::ColorSchemeEntry)
+
+using namespace TextEditor;
+using namespace TextEditor::Internal;
+
+
+// ------- FontSettingsPagePrivate
 FontSettingsPagePrivate::FontSettingsPagePrivate(const TextEditor::FormatDescriptions &fd,
                                                  const QString &name,
                                                  const QString &category,
@@ -105,11 +124,6 @@ FontSettingsPagePrivate::FontSettingsPagePrivate(const TextEditor::FormatDescrip
     m_lastValue = m_value;
 }
 
-} // namespace Internal
-} // namespace TextEditor
-
-using namespace TextEditor;
-using namespace TextEditor::Internal;
 
 // ------- FormatDescription
 FormatDescription::FormatDescription(const QString &name, const QString &trName, const QColor &color) :
@@ -223,7 +237,6 @@ QWidget *FontSettingsPage::createPage(QWidget *parent)
 
     d_ptr->ui.schemeListWidget->addItem(tr("Default"));
     d_ptr->ui.schemeListWidget->setCurrentIndex(d_ptr->ui.schemeListWidget->model()->index(0, 0));
-    d_ptr->ui.exportButton->setEnabled(true);
     d_ptr->ui.editButton->setEnabled(true);
 
     QFontDatabase db;
@@ -237,8 +250,9 @@ QWidget *FontSettingsPage::createPage(QWidget *parent)
     connect(d_ptr->ui.familyComboBox, SIGNAL(activated(int)), this, SLOT(updatePointSizes()));
     connect(d_ptr->ui.schemeListWidget, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),
             this, SLOT(colorSchemeSelected(QListWidgetItem*)));
-    connect(d_ptr->ui.exportButton, SIGNAL(clicked()), this, SLOT(exportColorScheme()));
+    connect(d_ptr->ui.cloneButton, SIGNAL(clicked()), this, SLOT(cloneColorScheme()));
     connect(d_ptr->ui.editButton, SIGNAL(clicked()), this, SLOT(editColorScheme()));
+    connect(d_ptr->ui.deleteButton, SIGNAL(clicked()), this, SLOT(deleteColorScheme()));
 
     updatePointSizes();
     refreshColorSchemeList();
@@ -272,33 +286,83 @@ void FontSettingsPage::updatePointSizes()
 
 void FontSettingsPage::colorSchemeSelected(QListWidgetItem *item)
 {
-    // TODO: Enable the appropriate actions
+    bool modifiable = false;
+    if (item) {
+        const ColorSchemeEntry entry = item->data(Qt::UserRole).value<ColorSchemeEntry>();
+        modifiable = !entry.readOnly;
+    }
+    d_ptr->ui.cloneButton->setEnabled(item != 0);
+    d_ptr->ui.deleteButton->setEnabled(modifiable);
+    d_ptr->ui.editButton->setEnabled(modifiable);
 }
 
-void FontSettingsPage::importColorScheme()
+void FontSettingsPage::cloneColorScheme()
 {
-    QString fn = QFileDialog::getOpenFileName(d_ptr->ui.importButton->window(),
-                                              tr("Import Color Scheme"),
-                                              QString(),
-                                              tr("Color Schemes (*.xml)"));
-    if (fn.isEmpty())
+    QListWidgetItem *item = d_ptr->ui.schemeListWidget->currentItem();
+    if (!item)
+        return;
+
+    const ColorSchemeEntry entry = item->data(Qt::UserRole).value<ColorSchemeEntry>();
+
+    // Load the currently selected color scheme
+    if (!d_ptr->m_value.loadColorScheme(entry.fileName, d_ptr->m_descriptions))
+        return;
+
+    QString baseDir = customStylesPath();
+    QString baseFileName = baseDir;
+    baseFileName.append(QFileInfo(entry.fileName).completeBaseName());
+
+    // Find an available file name
+    int i = 1;
+    QString fileName;
+    do {
+        fileName = baseFileName;
+        fileName.append(QString("_copy%1.xml").arg((i == 1) ? QString() : QString::number(i)));
+        ++i;
+    } while (QFile::exists(fileName));
+
+    // Create the base directory when it doesn't exist
+    if (!QFile::exists(baseDir) && !QDir().mkpath(baseDir)) {
+        qWarning() << "Failed to create color scheme directory:" << baseDir;
         return;
+    }
+
+    ColorScheme scheme = d_ptr->m_value.colorScheme();
+    scheme.setName(tr("%1 (copy)").arg(scheme.name()));
+    scheme.save(fileName);
+    d_ptr->m_value.setColorSchemeFileName(fileName);
 
-    // Open color scheme and save it in the schemes directory
+    refreshColorSchemeList();
 }
 
-void FontSettingsPage::exportColorScheme()
+void FontSettingsPage::deleteColorScheme()
 {
-    QString fn = QFileDialog::getSaveFileName(d_ptr->ui.exportButton->window(),
-                                              tr("Export Color Scheme"),
-                                              QString(),
-                                              tr("Color Schemes (*.xml)"));
-    if (!fn.isEmpty())
-        d_ptr->m_value.colorScheme().save(fn);
+    QListWidgetItem *item = d_ptr->ui.schemeListWidget->currentItem();
+    if (!item)
+        return;
+
+    const ColorSchemeEntry entry = item->data(Qt::UserRole).value<ColorSchemeEntry>();
+    if (!entry.readOnly) {
+        int ret = QMessageBox::warning(d_ptr->ui.deleteButton->window(),
+                                       tr("Delete Color Scheme"),
+                                       tr("Are you sure you want to delete this color scheme permanently?"),
+                                       QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
+
+        if (ret == QMessageBox::Yes && QFile::remove(entry.fileName))
+            refreshColorSchemeList();
+    }
 }
 
 void FontSettingsPage::editColorScheme()
 {
+    QListWidgetItem *item = d_ptr->ui.schemeListWidget->currentItem();
+    if (!item)
+        return;
+
+    const ColorSchemeEntry entry = item->data(Qt::UserRole).value<ColorSchemeEntry>();
+    if (entry.readOnly)
+        return;
+
     d_ptr->m_value.setFamily(d_ptr->ui.familyComboBox->currentText());
     d_ptr->m_value.setAntialias(d_ptr->ui.antialias->isChecked());
 
@@ -307,13 +371,31 @@ void FontSettingsPage::editColorScheme()
     if (ok)
         d_ptr->m_value.setFontSize(size);
 
+    if (!d_ptr->m_value.loadColorScheme(entry.fileName, d_ptr->m_descriptions))
+        return;
+
     EditColorSchemeDialog dialog(d_ptr->m_descriptions,
                                  d_ptr->m_value,
-                                 d_ptr->m_value.colorScheme(),
                                  d_ptr->ui.editButton->window());
 
-    if (dialog.exec() == QDialog::Accepted)
-        d_ptr->m_value.setColorScheme(dialog.colorScheme());
+    if (dialog.exec() == QDialog::Accepted) {
+        ColorScheme newColorScheme = dialog.colorScheme();
+        newColorScheme.save(entry.fileName);
+        d_ptr->m_value.setColorScheme(newColorScheme);
+        refreshColorSchemeList();
+    }
+}
+
+void FontSettingsPage::addColorSchemeEntry(const QString &fileName, bool readOnly)
+{
+    ColorSchemeEntry entry;
+    entry.fileName = fileName;
+    entry.name = ColorScheme::readNameOfScheme(fileName);
+    entry.readOnly = readOnly;
+
+    QListWidgetItem *item = new QListWidgetItem(entry.name);
+    item->setData(Qt::UserRole, QVariant::fromValue<ColorSchemeEntry>(entry));
+    d_ptr->ui.schemeListWidget->addItem(item);
 }
 
 void FontSettingsPage::refreshColorSchemeList()
@@ -329,11 +411,19 @@ void FontSettingsPage::refreshColorSchemeList()
     int count = 0;
 
     foreach (const QString &file, styleDir.entryList()) {
-        const QString absFileName = styleDir.absoluteFilePath(file);
-        QListWidgetItem *item = new QListWidgetItem(ColorScheme::readNameOfScheme(absFileName));
-        item->setData(Qt::UserRole, absFileName);
-        d_ptr->ui.schemeListWidget->addItem(item);
-        if (d_ptr->m_value.colorSchemeFileName() == absFileName)
+        const QString fileName = styleDir.absoluteFilePath(file);
+        addColorSchemeEntry(fileName, true);
+        if (d_ptr->m_value.colorSchemeFileName() == fileName)
+            selected = count;
+        ++count;
+    }
+
+    styleDir.setPath(customStylesPath());
+
+    foreach (const QString &file, styleDir.entryList()) {
+        const QString fileName = styleDir.absoluteFilePath(file);
+        addColorSchemeEntry(fileName, false);
+        if (d_ptr->m_value.colorSchemeFileName() == fileName)
             selected = count;
         ++count;
     }
@@ -342,6 +432,13 @@ void FontSettingsPage::refreshColorSchemeList()
     d_ptr->ui.schemeListWidget->setCurrentIndex(s);
 }
 
+QString FontSettingsPage::customStylesPath()
+{
+    QString path = QFileInfo(Core::ICore::instance()->settings()->fileName()).path();
+    path.append(QLatin1String("/qtcreator/styles/"));
+    return path;
+}
+
 void FontSettingsPage::delayedChange()
 {
     emit changed(d_ptr->m_value);
@@ -353,9 +450,9 @@ void FontSettingsPage::apply()
     d_ptr->m_value.setAntialias(d_ptr->ui.antialias->isChecked());
 
     if (QListWidgetItem *item = d_ptr->ui.schemeListWidget->currentItem()) {
-        QString file = item->data(Qt::UserRole).toString();
-        if (file != d_ptr->m_value.colorSchemeFileName())
-            d_ptr->m_value.loadColorScheme(file, d_ptr->m_descriptions);
+        const ColorSchemeEntry entry = item->data(Qt::UserRole).value<ColorSchemeEntry>();
+        if (entry.fileName != d_ptr->m_value.colorSchemeFileName())
+            d_ptr->m_value.loadColorScheme(entry.fileName, d_ptr->m_descriptions);
     }
 
     bool ok = true;
diff --git a/src/plugins/texteditor/fontsettingspage.h b/src/plugins/texteditor/fontsettingspage.h
index 748fb48d58c..a57761d2992 100644
--- a/src/plugins/texteditor/fontsettingspage.h
+++ b/src/plugins/texteditor/fontsettingspage.h
@@ -112,12 +112,14 @@ private slots:
     void delayedChange();
     void updatePointSizes();
     void colorSchemeSelected(QListWidgetItem *item);
-    void importColorScheme();
-    void exportColorScheme();
+    void cloneColorScheme();
+    void deleteColorScheme();
     void editColorScheme();
 
 private:
+    void addColorSchemeEntry(const QString &fileName, bool readOnly);
     void refreshColorSchemeList();
+    static QString customStylesPath();
 
     Internal::FontSettingsPagePrivate *d_ptr;
 };
diff --git a/src/plugins/texteditor/fontsettingspage.ui b/src/plugins/texteditor/fontsettingspage.ui
index 799c2c0a8f9..d6e249bd930 100644
--- a/src/plugins/texteditor/fontsettingspage.ui
+++ b/src/plugins/texteditor/fontsettingspage.ui
@@ -109,36 +109,23 @@
      </property>
      <layout class="QGridLayout" name="gridLayout_2">
       <item row="0" column="1">
-       <widget class="QPushButton" name="importButton">
-        <property name="enabled">
-         <bool>false</bool>
-        </property>
-        <property name="text">
-         <string>Import</string>
-        </property>
-       </widget>
-      </item>
-      <item row="1" column="1">
-       <widget class="QPushButton" name="exportButton">
-        <property name="enabled">
-         <bool>false</bool>
-        </property>
+       <widget class="QPushButton" name="cloneButton">
         <property name="text">
-         <string>Export</string>
+         <string>Clone</string>
         </property>
        </widget>
       </item>
       <item row="2" column="1">
-       <widget class="QPushButton" name="editButton">
+       <widget class="QPushButton" name="deleteButton">
         <property name="enabled">
          <bool>false</bool>
         </property>
         <property name="text">
-         <string>Edit</string>
+         <string>Delete</string>
         </property>
        </widget>
       </item>
-      <item row="3" column="1">
+      <item row="4" column="1">
        <spacer name="verticalSpacer">
         <property name="orientation">
          <enum>Qt::Vertical</enum>
@@ -151,9 +138,19 @@
         </property>
        </spacer>
       </item>
-      <item row="0" column="0" rowspan="4">
+      <item row="0" column="0" rowspan="5">
        <widget class="QListWidget" name="schemeListWidget"/>
       </item>
+      <item row="1" column="1">
+       <widget class="QPushButton" name="editButton">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
+        <property name="text">
+         <string>Edit</string>
+        </property>
+       </widget>
+      </item>
      </layout>
     </widget>
    </item>
-- 
GitLab