OSDN Git Service

Snippets: Add more use-cases
authorLeandro Melo <leandro.melo@nokia.com>
Wed, 24 Nov 2010 10:04:24 +0000 (11:04 +0100)
committerLeandro Melo <leandro.melo@nokia.com>
Wed, 8 Dec 2010 16:22:11 +0000 (17:22 +0100)
- Restored removed built-in snippets.
- Revert a built-in snippet.
- Reset the snippets collection.

src/plugins/texteditor/snippets/snippet.h
src/plugins/texteditor/snippets/snippetscollection.cpp
src/plugins/texteditor/snippets/snippetscollection.h
src/plugins/texteditor/snippets/snippetssettingspage.cpp
src/plugins/texteditor/snippets/snippetssettingspage.ui

index d9d6c42..984da3e 100644 (file)
@@ -80,7 +80,7 @@ public:
 private:
     bool m_isRemoved;
     bool m_isModified;
-    QString m_id;
+    QString m_id; // Only built-in snippets have an id.
     QString m_trigger;
     QString m_content;
     QString m_complement;
index 1aad276..731f062 100644 (file)
@@ -221,10 +221,14 @@ int SnippetsCollection::totalSnippets(Snippet::Group group) const
 
 void SnippetsCollection::clear()
 {
-    for (Snippet::Group group = Snippet::Cpp; group < Snippet::GroupSize; ++group) {
-        m_snippets[group].clear();
-        m_activeSnippetsEnd[group] = m_snippets[group].end();
-    }
+    for (Snippet::Group group = Snippet::Cpp; group < Snippet::GroupSize; ++group)
+        clear(group);
+}
+
+void SnippetsCollection::clear(Snippet::Group group)
+{
+    m_snippets[group].clear();
+    m_activeSnippetsEnd[group] = m_snippets[group].end();
 }
 
 void SnippetsCollection::updateActiveSnippetsEnd(Snippet::Group group)
@@ -234,6 +238,41 @@ void SnippetsCollection::updateActiveSnippetsEnd(Snippet::Group group)
                                               removedSnippetPred);
 }
 
+void SnippetsCollection::restoreRemovedSnippets(Snippet::Group group)
+{
+    // The version restored contains the last modifications (if any) by the user.
+    // Reverting the snippet can still bring it to the original version.
+    QVector<Snippet> toRestore(std::distance(m_activeSnippetsEnd[group], m_snippets[group].end()));
+    qCopy(m_activeSnippetsEnd[group], m_snippets[group].end(), toRestore.begin());
+    m_snippets[group].erase(m_activeSnippetsEnd[group], m_snippets[group].end());
+    foreach (Snippet snippet, toRestore) {
+        snippet.setIsRemoved(false);
+        insertSnippet(snippet, group);
+    }
+}
+
+Snippet SnippetsCollection::revertedSnippet(int index, Snippet::Group group) const
+{
+    const Snippet &candidate = snippet(index, group);
+    Q_ASSERT(candidate.isBuiltIn());
+
+    const QList<Snippet> &builtIn =
+        readXML(m_builtInSnippetsPath + m_snippetsFileName, candidate.id());
+    if (builtIn.size() == 1)
+        return builtIn.at(0);
+    return Snippet();
+}
+
+void SnippetsCollection::reset(Snippet::Group group)
+{
+    clear(group);
+
+    const QList<Snippet> &builtInSnippets = readXML(m_builtInSnippetsPath + m_snippetsFileName);
+    foreach (const Snippet &snippet, builtInSnippets)
+        if (group == snippet.group())
+            insertSnippet(snippet, snippet.group());
+}
+
 void SnippetsCollection::reload()
 {
     clear();
@@ -268,10 +307,8 @@ void SnippetsCollection::synchronize()
                 const int size = totalSnippets(group);
                 for (int i = 0; i < size; ++i) {
                     const Snippet &current = snippet(i, group);
-                    if (!current.isBuiltIn() ||
-                       (current.isBuiltIn() && (current.isRemoved() || current.isModified()))) {
+                    if (!current.isBuiltIn() || current.isRemoved() || current.isModified())
                         writeSnippetXML(current, &writer);
-                    }
                 }
             }
             writer.writeEndElement();
@@ -296,7 +333,7 @@ void SnippetsCollection::writeSnippetXML(const Snippet &snippet, QXmlStreamWrite
     writer->writeEndElement();
 }
 
-QList<Snippet> SnippetsCollection::readXML(const QString &fileName)
+QList<Snippet> SnippetsCollection::readXML(const QString &fileName, const QString &snippetId)
 {
     QList<Snippet> snippets;
     QFile file(fileName);
@@ -307,31 +344,36 @@ QList<Snippet> SnippetsCollection::readXML(const QString &fileName)
                 while (xml.readNextStartElement()) {
                     if (xml.name() == kSnippet) {
                         const QXmlStreamAttributes &atts = xml.attributes();
+                        const QString &id = atts.value(kId).toString();
+                        if (snippetId.isEmpty() || snippetId == id) {
+                            Snippet snippet(id);
+                            snippet.setTrigger(atts.value(kTrigger).toString());
+                            snippet.setComplement(atts.value(kComplement).toString());
+                            snippet.setGroup(toSnippetGroup(atts.value(kGroup).toString()));
+                            snippet.setIsRemoved(toBool(atts.value(kRemoved).toString()));
+                            snippet.setIsModified(toBool(atts.value(kModified).toString()));
+
+                            QString content;
+                            while (!xml.atEnd()) {
+                                xml.readNext();
+                                if (xml.isCharacters()) {
+                                    content += xml.text();
+                                } else if (xml.isEndElement()) {
+                                    snippet.setContent(content);
+                                    snippets.append(snippet);
+                                    break;
+                                }
+                            }
 
-                        Snippet snippet(atts.value(kId).toString());
-                        snippet.setTrigger(atts.value(kTrigger).toString());
-                        snippet.setComplement(atts.value(kComplement).toString());
-                        snippet.setGroup(toSnippetGroup(atts.value(kGroup).toString()));
-                        snippet.setIsRemoved(toBool(atts.value(kRemoved).toString()));
-                        snippet.setIsModified(toBool(atts.value(kModified).toString()));
-
-                        QString content;
-                        while (!xml.atEnd()) {
-                            xml.readNext();
-                            if (xml.isCharacters()) {
-                                content += xml.text();
-                            } else if (xml.isEndElement()) {
-                                snippet.setContent(content);
-                                snippets.append(snippet);
+                            if (!snippetId.isEmpty())
                                 break;
-                            }
+                        } else {
+                            xml.skipCurrentElement();
                         }
                     } else {
                         xml.skipCurrentElement();
                     }
                 }
-            } else {
-                xml.skipCurrentElement();
             }
         }
         if (xml.hasError())
index 64fd300..4282ea7 100644 (file)
@@ -76,10 +76,14 @@ public:
     Hint computeReplacementHint(int index, const Snippet &snippet, Snippet::Group group);
 
     void removeSnippet(int index, Snippet::Group group);
+    void restoreRemovedSnippets(Snippet::Group group);
 
     void setSnippetContent(int index, Snippet::Group group, const QString &content);
 
     const Snippet &snippet(int index, Snippet::Group group) const;
+    Snippet revertedSnippet(int index, Snippet::Group group) const;
+
+    void reset(Snippet::Group group);
 
     int totalActiveSnippets(Snippet::Group group) const;
     int totalSnippets(Snippet::Group group) const;
@@ -89,9 +93,10 @@ public:
 
 private:
     void clear();
+    void clear(Snippet::Group group);
     void updateActiveSnippetsEnd(Snippet::Group group);
 
-    static QList<Snippet> readXML(const QString &fileName);
+    static QList<Snippet> readXML(const QString &fileName, const QString &snippetId = QString());
     static void writeSnippetXML(const Snippet &snippet, QXmlStreamWriter *writer);
 
     static const QLatin1String kSnippet;
@@ -103,9 +108,15 @@ private:
     static const QLatin1String kRemoved;
     static const QLatin1String kModified;
 
+    // Snippets for each group are kept in a list. However, not all of them are necessarily
+    // active. Specifically, removed built-in snippets are kept as the last ones (for each
+    // group there is a iterator that marks the logical end).
     QVector<QList<Snippet> > m_snippets;
     QVector<QList<Snippet>::iterator> m_activeSnippetsEnd;
 
+    // Built-in snippets are specified in an XML embedded as a resource. Snippets created/
+    // modified/removed by the user are stored in another XML created dynamically in the
+    // user's folder.
     QString m_builtInSnippetsPath;
     QString m_userSnippetsPath;
     QString m_snippetsFileName;
index 156b42a..f73fe64 100644 (file)
@@ -75,8 +75,12 @@ public:
     void removeSnippet(const QModelIndex &modelIndex);
     const Snippet &snippetAt(const QModelIndex &modelIndex) const;
     void setSnippetContent(const QModelIndex &modelIndex, const QString &content);
+    void revertBuitInSnippet(const QModelIndex &modelIndex);
+    void restoreRemovedBuiltInSnippets();
+    void resetSnippets();
 
 private:
+    void replaceSnippet(const Snippet &snippet, const QModelIndex &modelIndex);
     static bool isValidTrigger(const QString &s);
 
     Snippet::Group m_activeGroup;
@@ -130,8 +134,7 @@ QVariant SnippetsTableModel::data(const QModelIndex &modelIndex, int role) const
 bool SnippetsTableModel::setData(const QModelIndex &modelIndex, const QVariant &value, int role)
 {
     if (modelIndex.isValid() && role == Qt::EditRole) {
-        const int row = modelIndex.row();
-        Snippet snippet(m_collection->snippet(row, m_activeGroup));
+        Snippet snippet(m_collection->snippet(modelIndex.row(), m_activeGroup));
         if (modelIndex.column() == 0) {
             const QString &s = value.toString();
             if (!isValidTrigger(s)) {
@@ -145,21 +148,7 @@ bool SnippetsTableModel::setData(const QModelIndex &modelIndex, const QVariant &
             snippet.setComplement(value.toString());
         }
 
-        const SnippetsCollection::Hint &hint =
-            m_collection->computeReplacementHint(row, snippet, m_activeGroup);
-        if (modelIndex.row() == hint.index()) {
-            m_collection->replaceSnippet(row, snippet, m_activeGroup, hint);
-            emit dataChanged(modelIndex, modelIndex);
-        } else {
-            if (row < hint.index())
-                // Rows will be moved down.
-                beginMoveRows(QModelIndex(), row, row, QModelIndex(), hint.index() + 1);
-            else
-                beginMoveRows(QModelIndex(), row, row, QModelIndex(), hint.index());
-            m_collection->replaceSnippet(row, snippet, m_activeGroup, hint);
-            endMoveRows();
-        }
-
+        replaceSnippet(snippet, modelIndex);
         return true;
     }
     return false;
@@ -217,6 +206,47 @@ void SnippetsTableModel::setSnippetContent(const QModelIndex &modelIndex, const
     m_collection->setSnippetContent(modelIndex.row(), m_activeGroup, content);
 }
 
+void SnippetsTableModel::revertBuitInSnippet(const QModelIndex &modelIndex)
+{
+    const Snippet &snippet = m_collection->revertedSnippet(modelIndex.row(), m_activeGroup);
+    if (snippet.id().isEmpty()) {
+        QMessageBox::critical(0, tr("Error"), tr("Error reverting snippet."));
+        return;
+    }
+    replaceSnippet(snippet, modelIndex);
+}
+
+void SnippetsTableModel::restoreRemovedBuiltInSnippets()
+{
+    m_collection->restoreRemovedSnippets(m_activeGroup);
+    reset();
+}
+
+void SnippetsTableModel::resetSnippets()
+{
+    m_collection->reset(m_activeGroup);
+    reset();
+}
+
+void SnippetsTableModel::replaceSnippet(const Snippet &snippet, const QModelIndex &modelIndex)
+{
+    const int row = modelIndex.row();
+    const SnippetsCollection::Hint &hint =
+        m_collection->computeReplacementHint(row, snippet, m_activeGroup);
+    if (modelIndex.row() == hint.index()) {
+        m_collection->replaceSnippet(row, snippet, m_activeGroup, hint);
+        emit dataChanged(modelIndex, modelIndex);
+    } else {
+        if (row < hint.index())
+            // Rows will be moved down.
+            beginMoveRows(QModelIndex(), row, row, QModelIndex(), hint.index() + 1);
+        else
+            beginMoveRows(QModelIndex(), row, row, QModelIndex(), hint.index());
+        m_collection->replaceSnippet(row, snippet, m_activeGroup, hint);
+        endMoveRows();
+    }
+}
+
 bool SnippetsTableModel::isValidTrigger(const QString &s)
 {
     if (s.isEmpty())
@@ -248,10 +278,13 @@ private slots:
     void markSnippetsCollection();
     void addSnippet();
     void removeSnippet();
+    void revertBuiltInSnippet();
+    void restoreRemovedBuiltInSnippets();
+    void resetAllSnippets();
     void selectSnippet(const QModelIndex &parent, int row);
     void selectMovedSnippet(const QModelIndex &, int, int, const QModelIndex &, int row);
-    void previewSnippet(const QModelIndex &modelIndex);
-    void updateSnippetContent();
+    void setSnippetContent();
+    void updateCurrentSnippetDependent(const QModelIndex &modelIndex = QModelIndex());
 
 private:
     SnippetEditor *currentEditor() const;
@@ -314,17 +347,19 @@ void SnippetsSettingsPagePrivate::configureUi(QWidget *w)
     decorateEditor(editorAt(Snippet::Qml), Snippet::Qml);
     decorateEditor(editorAt(Snippet::PlainText), Snippet::PlainText);
 
+    m_ui.revertButton->setEnabled(false);
+
     QTextStream(&m_keywords) << m_displayName;
 
     loadSettings();
     loadSnippetGroup(m_ui.groupCombo->currentIndex());
 
     connect(editorAt(Snippet::Cpp), SIGNAL(snippetContentChanged()),
-            this, SLOT(updateSnippetContent()));
+            this, SLOT(setSnippetContent()));
     connect(editorAt(Snippet::Qml), SIGNAL(snippetContentChanged()),
-            this, SLOT(updateSnippetContent()));
+            this, SLOT(setSnippetContent()));
     connect(editorAt(Snippet::PlainText), SIGNAL(snippetContentChanged()),
-            this, SLOT(updateSnippetContent()));
+            this, SLOT(setSnippetContent()));
 
     connect(m_model, SIGNAL(rowsInserted(QModelIndex, int, int)),
             this, SLOT(selectSnippet(QModelIndex,int)));
@@ -338,12 +373,18 @@ void SnippetsSettingsPagePrivate::configureUi(QWidget *w)
             this, SLOT(markSnippetsCollection()));
     connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
             this, SLOT(markSnippetsCollection()));
+    connect(m_model, SIGNAL(modelReset()), this, SLOT(updateCurrentSnippetDependent()));
+    connect(m_model, SIGNAL(modelReset()), this, SLOT(markSnippetsCollection()));
 
     connect(m_ui.groupCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(loadSnippetGroup(int)));
     connect(m_ui.addButton, SIGNAL(clicked()), this, SLOT(addSnippet()));
     connect(m_ui.removeButton, SIGNAL(clicked()), this, SLOT(removeSnippet()));
+    connect(m_ui.resetAllButton, SIGNAL(clicked()), this, SLOT(resetAllSnippets()));
+    connect(m_ui.restoreRemovedButton, SIGNAL(clicked()),
+            this, SLOT(restoreRemovedBuiltInSnippets()));
+    connect(m_ui.revertButton, SIGNAL(clicked()), this, SLOT(revertBuiltInSnippet()));
     connect(m_ui.snippetsTable->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
-            this, SLOT(previewSnippet(QModelIndex)));
+            this, SLOT(updateCurrentSnippetDependent(QModelIndex)));
 }
 
 void SnippetsSettingsPagePrivate::decorateEditor(SnippetEditor *editor, Snippet::Group group)
@@ -427,6 +468,21 @@ void SnippetsSettingsPagePrivate::removeSnippet()
     m_model->removeSnippet(modelIndex);
 }
 
+void SnippetsSettingsPagePrivate::restoreRemovedBuiltInSnippets()
+{
+    m_model->restoreRemovedBuiltInSnippets();
+}
+
+void SnippetsSettingsPagePrivate::revertBuiltInSnippet()
+{
+    m_model->revertBuitInSnippet(m_ui.snippetsTable->selectionModel()->currentIndex());
+}
+
+void SnippetsSettingsPagePrivate::resetAllSnippets()
+{
+    m_model->resetSnippets();
+}
+
 void SnippetsSettingsPagePrivate::selectSnippet(const QModelIndex &parent, int row)
 {
     QModelIndex topLeft = m_model->index(row, 0, parent);
@@ -449,14 +505,22 @@ void SnippetsSettingsPagePrivate::selectMovedSnippet(const QModelIndex &,
     else
         modelIndex = m_model->index(destinationRow, 0, destinationParent);
     m_ui.snippetsTable->scrollTo(modelIndex);
+    currentEditor()->setPlainText(m_model->snippetAt(modelIndex).content());
 }
 
-void SnippetsSettingsPagePrivate::previewSnippet(const QModelIndex &modelIndex)
+void SnippetsSettingsPagePrivate::updateCurrentSnippetDependent(const QModelIndex &modelIndex)
 {
-    currentEditor()->setPlainText(m_model->snippetAt(modelIndex).content());
+    if (modelIndex.isValid()) {
+        const Snippet &snippet = m_model->snippetAt(modelIndex);
+        currentEditor()->setPlainText(snippet.content());
+        m_ui.revertButton->setEnabled(snippet.isBuiltIn());
+    } else {
+        currentEditor()->clear();
+        m_ui.revertButton->setEnabled(false);
+    }
 }
 
-void SnippetsSettingsPagePrivate::updateSnippetContent()
+void SnippetsSettingsPagePrivate::setSnippetContent()
 {
     const QModelIndex &modelIndex = m_ui.snippetsTable->selectionModel()->currentIndex();
     if (modelIndex.isValid()) {
index df9917d..e95fa7a 100644 (file)
         </widget>
        </item>
        <item>
+        <widget class="QPushButton" name="revertButton">
+         <property name="text">
+          <string>Revert Built-in</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QPushButton" name="restoreRemovedButton">
+         <property name="text">
+          <string>Restore Removed Built-ins</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QPushButton" name="resetAllButton">
+         <property name="text">
+          <string>Reset All</string>
+         </property>
+        </widget>
+       </item>
+       <item>
         <spacer name="verticalSpacer">
          <property name="orientation">
           <enum>Qt::Vertical</enum>