From 1175705bfc8934909db3c74385a17c8d0daba4b3 Mon Sep 17 00:00:00 2001 From: Leandro Melo <leandro.melo@nokia.com> Date: Thu, 2 Dec 2010 17:02:23 +0100 Subject: [PATCH] Snippets: Make it easier for plugins to add snippets groups Groups are no longer enum values but identified from snippet providers. --- src/plugins/cppeditor/cppeditor.pro | 4 +- src/plugins/cppeditor/cppeditorconstants.h | 2 + src/plugins/cppeditor/cppplugin.cpp | 4 +- ...ordecorator.cpp => cppsnippetprovider.cpp} | 24 ++- ...editordecorator.h => cppsnippetprovider.h} | 13 +- src/plugins/cpptools/cppcodecompletion.cpp | 4 +- src/plugins/cpptools/cppcodecompletion.h | 4 +- .../qmljseditor/qmljscodecompletion.cpp | 3 +- src/plugins/qmljseditor/qmljscodecompletion.h | 4 +- src/plugins/qmljseditor/qmljseditor.pro | 4 +- .../qmljseditor/qmljseditorconstants.h | 1 + src/plugins/qmljseditor/qmljseditorplugin.cpp | 4 +- ...decorator.cpp => qmljssnippetprovider.cpp} | 24 ++- ...itordecorator.h => qmljssnippetprovider.h} | 13 +- ...itordecorator.cpp => isnippetprovider.cpp} | 6 +- ...eteditordecorator.h => isnippetprovider.h} | 11 +- .../snippets/plaintextsnippetprovider.cpp | 56 +++++++ .../snippets/plaintextsnippetprovider.h | 53 ++++++ src/plugins/texteditor/snippets/reuse.h | 26 --- src/plugins/texteditor/snippets/snippet.cpp | 18 +- src/plugins/texteditor/snippets/snippet.h | 22 +-- ...ippetprovider.cpp => snippetcollector.cpp} | 22 +-- .../{snippetprovider.h => snippetcollector.h} | 11 +- src/plugins/texteditor/snippets/snippets.xml | 1 + .../snippets/snippetscollection.cpp | 154 +++++++++++------- .../texteditor/snippets/snippetscollection.h | 67 +++++--- .../texteditor/snippets/snippetsmanager.h | 3 + .../texteditor/snippets/snippetssettings.cpp | 3 +- .../snippets/snippetssettingspage.cpp | 105 ++++++------ src/plugins/texteditor/texteditor.pro | 10 +- src/plugins/texteditor/texteditorconstants.h | 1 + src/plugins/texteditor/texteditorplugin.cpp | 4 + 32 files changed, 410 insertions(+), 271 deletions(-) rename src/plugins/cppeditor/{cppsnippeteditordecorator.cpp => cppsnippetprovider.cpp} (81%) rename src/plugins/cppeditor/{cppsnippeteditordecorator.h => cppsnippetprovider.h} (80%) rename src/plugins/qmljseditor/{qmljssnippeteditordecorator.cpp => qmljssnippetprovider.cpp} (79%) rename src/plugins/qmljseditor/{qmljssnippeteditordecorator.h => qmljssnippetprovider.h} (80%) rename src/plugins/texteditor/snippets/{isnippeteditordecorator.cpp => isnippetprovider.cpp} (89%) rename src/plugins/texteditor/snippets/{isnippeteditordecorator.h => isnippetprovider.h} (85%) create mode 100644 src/plugins/texteditor/snippets/plaintextsnippetprovider.cpp create mode 100644 src/plugins/texteditor/snippets/plaintextsnippetprovider.h rename src/plugins/texteditor/snippets/{snippetprovider.cpp => snippetcollector.cpp} (75%) rename src/plugins/texteditor/snippets/{snippetprovider.h => snippetcollector.h} (89%) diff --git a/src/plugins/cppeditor/cppeditor.pro b/src/plugins/cppeditor/cppeditor.pro index a9bd9296ff4..9f38859a880 100644 --- a/src/plugins/cppeditor/cppeditor.pro +++ b/src/plugins/cppeditor/cppeditor.pro @@ -26,7 +26,7 @@ HEADERS += cppplugin.h \ cppqtstyleindenter.h \ cppautocompleter.h \ cppcompleteswitch.h \ - cppsnippeteditordecorator.h + cppsnippetprovider.h SOURCES += cppplugin.cpp \ cppeditor.cpp \ @@ -47,7 +47,7 @@ SOURCES += cppplugin.cpp \ cppqtstyleindenter.cpp \ cppautocompleter.cpp \ cppcompleteswitch.cpp \ - cppsnippeteditordecorator.cpp + cppsnippetprovider.cpp RESOURCES += cppeditor.qrc OTHER_FILES += CppEditor.mimetypes.xml diff --git a/src/plugins/cppeditor/cppeditorconstants.h b/src/plugins/cppeditor/cppeditorconstants.h index 17c13d1186d..c90b46abbdf 100644 --- a/src/plugins/cppeditor/cppeditorconstants.h +++ b/src/plugins/cppeditor/cppeditorconstants.h @@ -68,6 +68,8 @@ const char * const CPP_HEADER_MIMETYPE = "text/x-c++hdr"; const char * const WIZARD_CATEGORY = "O.C++"; const char * const WIZARD_TR_CATEGORY = QT_TRANSLATE_NOOP("CppEditor", "C++"); +const char * const CPP_SNIPPETS_GROUP_ID = "C++"; + } // namespace Constants } // namespace CppEditor diff --git a/src/plugins/cppeditor/cppplugin.cpp b/src/plugins/cppeditor/cppplugin.cpp index a33a151aee7..21d0c8a6dbe 100644 --- a/src/plugins/cppeditor/cppplugin.cpp +++ b/src/plugins/cppeditor/cppplugin.cpp @@ -38,7 +38,7 @@ #include "cppoutline.h" #include "cppquickfixcollector.h" #include "cpptypehierarchy.h" -#include "cppsnippeteditordecorator.h" +#include "cppsnippetprovider.h" #include <coreplugin/icore.h> #include <coreplugin/coreconstants.h> @@ -212,7 +212,7 @@ bool CppPlugin::initialize(const QStringList & /*arguments*/, QString *errorMess addAutoReleasedObject(new CppHoverHandler); addAutoReleasedObject(new CppOutlineWidgetFactory); addAutoReleasedObject(new CppTypeHierarchyFactory); - addAutoReleasedObject(new CppSnippetEditorDecorator); + addAutoReleasedObject(new CppSnippetProvider); m_quickFixCollector = new CppQuickFixCollector; addAutoReleasedObject(m_quickFixCollector); diff --git a/src/plugins/cppeditor/cppsnippeteditordecorator.cpp b/src/plugins/cppeditor/cppsnippetprovider.cpp similarity index 81% rename from src/plugins/cppeditor/cppsnippeteditordecorator.cpp rename to src/plugins/cppeditor/cppsnippetprovider.cpp index 159a6c38229..b7273f8c97a 100644 --- a/src/plugins/cppeditor/cppsnippeteditordecorator.cpp +++ b/src/plugins/cppeditor/cppsnippetprovider.cpp @@ -27,35 +27,41 @@ ** **************************************************************************/ -#include "cppsnippeteditordecorator.h" +#include "cppsnippetprovider.h" #include "cpphighlighter.h" #include "cppeditor.h" #include "cppqtstyleindenter.h" #include "cppautocompleter.h" +#include "cppeditorconstants.h" #include <texteditor/texteditorsettings.h> #include <texteditor/fontsettings.h> #include <texteditor/texteditorconstants.h> #include <texteditor/snippets/snippeteditor.h> +#include <QtCore/QLatin1String> + using namespace CppEditor; using namespace Internal; -CppSnippetEditorDecorator::CppSnippetEditorDecorator() : - TextEditor::ISnippetEditorDecorator() +CppSnippetProvider::CppSnippetProvider() : + TextEditor::ISnippetProvider() {} -CppSnippetEditorDecorator::~CppSnippetEditorDecorator() +CppSnippetProvider::~CppSnippetProvider() {} -bool CppSnippetEditorDecorator::supports(TextEditor::Snippet::Group group) const +QString CppSnippetProvider::groupId() const +{ + return QLatin1String(Constants::CPP_SNIPPETS_GROUP_ID); +} + +QString CppSnippetProvider::displayName() const { - if (group == TextEditor::Snippet::Cpp) - return true; - return false; + return tr("C++"); } -void CppSnippetEditorDecorator::apply(TextEditor::SnippetEditor *editor) const +void CppSnippetProvider::decorateEditor(TextEditor::SnippetEditor *editor) const { CppHighlighter *highlighter = new CppHighlighter; const TextEditor::FontSettings &fs = TextEditor::TextEditorSettings::instance()->fontSettings(); diff --git a/src/plugins/cppeditor/cppsnippeteditordecorator.h b/src/plugins/cppeditor/cppsnippetprovider.h similarity index 80% rename from src/plugins/cppeditor/cppsnippeteditordecorator.h rename to src/plugins/cppeditor/cppsnippetprovider.h index 605099e19c0..ba3f172be0b 100644 --- a/src/plugins/cppeditor/cppsnippeteditordecorator.h +++ b/src/plugins/cppeditor/cppsnippetprovider.h @@ -30,20 +30,21 @@ #ifndef CPPSNIPPETEDITORDECORATOR_H #define CPPSNIPPETEDITORDECORATOR_H -#include <texteditor/snippets/isnippeteditordecorator.h> +#include <texteditor/snippets/isnippetprovider.h> namespace CppEditor { namespace Internal { -class CppSnippetEditorDecorator : public TextEditor::ISnippetEditorDecorator +class CppSnippetProvider : public TextEditor::ISnippetProvider { public: - CppSnippetEditorDecorator(); - virtual ~CppSnippetEditorDecorator(); + CppSnippetProvider(); + virtual ~CppSnippetProvider(); public: - virtual bool supports(TextEditor::Snippet::Group group) const; - virtual void apply(TextEditor::SnippetEditor *editor) const; + virtual QString groupId() const; + virtual QString displayName() const; + virtual void decorateEditor(TextEditor::SnippetEditor *editor) const; }; } // Internal diff --git a/src/plugins/cpptools/cppcodecompletion.cpp b/src/plugins/cpptools/cppcodecompletion.cpp index 479de433d10..e73e5451420 100644 --- a/src/plugins/cpptools/cppcodecompletion.cpp +++ b/src/plugins/cpptools/cppcodecompletion.cpp @@ -52,6 +52,8 @@ #include <cplusplus/BackwardsScanner.h> #include <cplusplus/LookupContext.h> +#include <cppeditor/cppeditorconstants.h> + #include <coreplugin/icore.h> #include <coreplugin/mimedatabase.h> #include <coreplugin/editormanager/editormanager.h> @@ -463,7 +465,7 @@ CppCodeCompletion::CppCodeCompletion(CppModelManager *manager) m_automaticCompletion(false), m_completionOperator(T_EOF_SYMBOL), m_objcEnabled(true), - m_snippetProvider(TextEditor::Snippet::Cpp, + m_snippetProvider(CppEditor::Constants::CPP_SNIPPETS_GROUP_ID, QIcon(QLatin1String(":/texteditor/images/snippet.png"))) { } diff --git a/src/plugins/cpptools/cppcodecompletion.h b/src/plugins/cpptools/cppcodecompletion.h index 483bf3358b2..28239823560 100644 --- a/src/plugins/cpptools/cppcodecompletion.h +++ b/src/plugins/cpptools/cppcodecompletion.h @@ -37,7 +37,7 @@ #include <cplusplus/TypeOfExpression.h> #include <texteditor/icompletioncollector.h> -#include <texteditor/snippets/snippetprovider.h> +#include <texteditor/snippets/snippetcollector.h> #include <QtCore/QObject> #include <QtCore/QPointer> @@ -153,7 +153,7 @@ private: unsigned m_completionOperator; bool m_objcEnabled; - TextEditor::SnippetProvider m_snippetProvider; + TextEditor::SnippetCollector m_snippetProvider; CPlusPlus::Icons m_icons; CPlusPlus::Overview overview; diff --git a/src/plugins/qmljseditor/qmljscodecompletion.cpp b/src/plugins/qmljseditor/qmljscodecompletion.cpp index 8dc714dc80e..c9c21c658e8 100644 --- a/src/plugins/qmljseditor/qmljscodecompletion.cpp +++ b/src/plugins/qmljseditor/qmljscodecompletion.cpp @@ -30,6 +30,7 @@ #include "qmljscodecompletion.h" #include "qmlexpressionundercursor.h" #include "qmljseditor.h" +#include "qmljseditorconstants.h" #include <qmljs/qmljsmodelmanagerinterface.h> #include <qmljs/parser/qmljsast_p.h> @@ -487,7 +488,7 @@ CodeCompletion::CodeCompletion(ModelManagerInterface *modelManager, QObject *par m_editor(0), m_startPosition(0), m_restartCompletion(false), - m_snippetProvider(TextEditor::Snippet::Qml, iconForColor(Qt::red), SnippetOrder) + m_snippetProvider(Constants::QML_SNIPPETS_GROUP_ID, iconForColor(Qt::red), SnippetOrder) { Q_ASSERT(modelManager); } diff --git a/src/plugins/qmljseditor/qmljscodecompletion.h b/src/plugins/qmljseditor/qmljscodecompletion.h index d3448c4c72f..ae8c8589a43 100644 --- a/src/plugins/qmljseditor/qmljscodecompletion.h +++ b/src/plugins/qmljseditor/qmljscodecompletion.h @@ -32,7 +32,7 @@ #include <qmljs/qmljsdocument.h> #include <texteditor/icompletioncollector.h> -#include <texteditor/snippets/snippetprovider.h> +#include <texteditor/snippets/snippetcollector.h> #include <QtCore/QDateTime> #include <QtCore/QPointer> @@ -97,7 +97,7 @@ private: TextEditor::ITextEditable *m_editor; int m_startPosition; bool m_restartCompletion; - TextEditor::SnippetProvider m_snippetProvider; + TextEditor::SnippetCollector m_snippetProvider; QList<TextEditor::CompletionItem> m_completions; QPointer<FunctionArgumentWidget> m_functionArgumentWidget; }; diff --git a/src/plugins/qmljseditor/qmljseditor.pro b/src/plugins/qmljseditor/qmljseditor.pro index 24e6caf03db..6d08513810a 100644 --- a/src/plugins/qmljseditor/qmljseditor.pro +++ b/src/plugins/qmljseditor/qmljseditor.pro @@ -35,7 +35,7 @@ HEADERS += \ qmljsindenter.h \ qmljsautocompleter.h \ jsfilewizard.h \ - qmljssnippeteditordecorator.h + qmljssnippetprovider.h SOURCES += \ qmljscodecompletion.cpp \ @@ -64,7 +64,7 @@ SOURCES += \ qmljsindenter.cpp \ qmljsautocompleter.cpp \ jsfilewizard.cpp \ - qmljssnippeteditordecorator.cpp + qmljssnippetprovider.cpp RESOURCES += qmljseditor.qrc OTHER_FILES += QmlJSEditor.mimetypes.xml diff --git a/src/plugins/qmljseditor/qmljseditorconstants.h b/src/plugins/qmljseditor/qmljseditorconstants.h index 63de1bb73ba..496facce501 100644 --- a/src/plugins/qmljseditor/qmljseditorconstants.h +++ b/src/plugins/qmljseditor/qmljseditorconstants.h @@ -60,6 +60,7 @@ const char *const TASK_CATEGORY_QML = "Task.Category.Qml"; const char * const WIZARD_CATEGORY_QML = "S.Qml"; const char * const WIZARD_TR_CATEGORY_QML = QT_TRANSLATE_NOOP("QmlJsEditor", "QML"); +const char * const QML_SNIPPETS_GROUP_ID = "QML"; } // namespace Constants } // namespace QmlJSEditor diff --git a/src/plugins/qmljseditor/qmljseditorplugin.cpp b/src/plugins/qmljseditor/qmljseditorplugin.cpp index 1d394e62015..ef362840621 100644 --- a/src/plugins/qmljseditor/qmljseditorplugin.cpp +++ b/src/plugins/qmljseditor/qmljseditorplugin.cpp @@ -39,7 +39,7 @@ #include "qmljsoutline.h" #include "qmljspreviewrunner.h" #include "qmljsquickfix.h" -#include "qmljssnippeteditordecorator.h" +#include "qmljssnippetprovider.h" #include "qmltaskmanager.h" #include "quicktoolbar.h" #include "quicktoolbarsettingspage.h" @@ -129,7 +129,7 @@ bool QmlJSEditorPlugin::initialize(const QStringList & /*arguments*/, QString *e return false; m_modelManager = QmlJS::ModelManagerInterface::instance(); - addAutoReleasedObject(new QmlJSSnippetEditorDecorator); + addAutoReleasedObject(new QmlJSSnippetProvider); Core::Context context(QmlJSEditor::Constants::C_QMLJSEDITOR_ID); diff --git a/src/plugins/qmljseditor/qmljssnippeteditordecorator.cpp b/src/plugins/qmljseditor/qmljssnippetprovider.cpp similarity index 79% rename from src/plugins/qmljseditor/qmljssnippeteditordecorator.cpp rename to src/plugins/qmljseditor/qmljssnippetprovider.cpp index 0413bdf3800..9c24e197308 100644 --- a/src/plugins/qmljseditor/qmljssnippeteditordecorator.cpp +++ b/src/plugins/qmljseditor/qmljssnippetprovider.cpp @@ -27,35 +27,41 @@ ** **************************************************************************/ -#include "qmljssnippeteditordecorator.h" +#include "qmljssnippetprovider.h" #include "qmljshighlighter.h" #include "qmljseditor.h" #include "qmljsindenter.h" #include "qmljsautocompleter.h" +#include "qmljseditorconstants.h" #include <texteditor/texteditorsettings.h> #include <texteditor/fontsettings.h> #include <texteditor/texteditorconstants.h> #include <texteditor/snippets/snippeteditor.h> +#include <QtCore/QLatin1String> + using namespace QmlJSEditor; using namespace Internal; -QmlJSSnippetEditorDecorator::QmlJSSnippetEditorDecorator() : - TextEditor::ISnippetEditorDecorator() +QmlJSSnippetProvider::QmlJSSnippetProvider() : + TextEditor::ISnippetProvider() {} -QmlJSSnippetEditorDecorator::~QmlJSSnippetEditorDecorator() +QmlJSSnippetProvider::~QmlJSSnippetProvider() {} -bool QmlJSSnippetEditorDecorator::supports(TextEditor::Snippet::Group group) const +QString QmlJSSnippetProvider::groupId() const +{ + return QLatin1String(Constants::QML_SNIPPETS_GROUP_ID); +} + +QString QmlJSSnippetProvider::displayName() const { - if (group == TextEditor::Snippet::Qml) - return true; - return false; + return tr("QML"); } -void QmlJSSnippetEditorDecorator::apply(TextEditor::SnippetEditor *editor) const +void QmlJSSnippetProvider::decorateEditor(TextEditor::SnippetEditor *editor) const { Highlighter *highlighter = new Highlighter; const TextEditor::FontSettings &fs = TextEditor::TextEditorSettings::instance()->fontSettings(); diff --git a/src/plugins/qmljseditor/qmljssnippeteditordecorator.h b/src/plugins/qmljseditor/qmljssnippetprovider.h similarity index 80% rename from src/plugins/qmljseditor/qmljssnippeteditordecorator.h rename to src/plugins/qmljseditor/qmljssnippetprovider.h index d22a4785642..f3b7b18550b 100644 --- a/src/plugins/qmljseditor/qmljssnippeteditordecorator.h +++ b/src/plugins/qmljseditor/qmljssnippetprovider.h @@ -30,20 +30,21 @@ #ifndef QMLJSSNIPPETEDITORDECORATOR_H #define QMLJSSNIPPETEDITORDECORATOR_H -#include <texteditor/snippets/isnippeteditordecorator.h> +#include <texteditor/snippets/isnippetprovider.h> namespace QmlJSEditor { namespace Internal { -class QmlJSSnippetEditorDecorator : public TextEditor::ISnippetEditorDecorator +class QmlJSSnippetProvider : public TextEditor::ISnippetProvider { public: - QmlJSSnippetEditorDecorator(); - virtual ~QmlJSSnippetEditorDecorator(); + QmlJSSnippetProvider(); + virtual ~QmlJSSnippetProvider(); public: - virtual bool supports(TextEditor::Snippet::Group group) const; - virtual void apply(TextEditor::SnippetEditor *editor) const; + virtual QString groupId() const; + virtual QString displayName() const; + virtual void decorateEditor(TextEditor::SnippetEditor *editor) const; }; } // Internal diff --git a/src/plugins/texteditor/snippets/isnippeteditordecorator.cpp b/src/plugins/texteditor/snippets/isnippetprovider.cpp similarity index 89% rename from src/plugins/texteditor/snippets/isnippeteditordecorator.cpp rename to src/plugins/texteditor/snippets/isnippetprovider.cpp index 5c94c6ec656..f438ad0b007 100644 --- a/src/plugins/texteditor/snippets/isnippeteditordecorator.cpp +++ b/src/plugins/texteditor/snippets/isnippetprovider.cpp @@ -27,12 +27,12 @@ ** **************************************************************************/ -#include "isnippeteditordecorator.h" +#include "isnippetprovider.h" using namespace TextEditor; -ISnippetEditorDecorator::ISnippetEditorDecorator() : QObject() +ISnippetProvider::ISnippetProvider() : QObject() {} -ISnippetEditorDecorator::~ISnippetEditorDecorator() +ISnippetProvider::~ISnippetProvider() {} diff --git a/src/plugins/texteditor/snippets/isnippeteditordecorator.h b/src/plugins/texteditor/snippets/isnippetprovider.h similarity index 85% rename from src/plugins/texteditor/snippets/isnippeteditordecorator.h rename to src/plugins/texteditor/snippets/isnippetprovider.h index 945461f308b..8f3a881e5f6 100644 --- a/src/plugins/texteditor/snippets/isnippeteditordecorator.h +++ b/src/plugins/texteditor/snippets/isnippetprovider.h @@ -40,17 +40,18 @@ namespace TextEditor { class SnippetEditor; -class TEXTEDITOR_EXPORT ISnippetEditorDecorator : public QObject +class TEXTEDITOR_EXPORT ISnippetProvider : public QObject { Q_OBJECT public: - virtual ~ISnippetEditorDecorator(); + virtual ~ISnippetProvider(); - virtual bool supports(Snippet::Group group) const = 0; - virtual void apply(SnippetEditor *editor) const = 0; + virtual QString groupId() const = 0; + virtual QString displayName() const = 0; + virtual void decorateEditor(SnippetEditor *editor) const = 0; protected: - ISnippetEditorDecorator(); + ISnippetProvider(); }; } // TextEditor diff --git a/src/plugins/texteditor/snippets/plaintextsnippetprovider.cpp b/src/plugins/texteditor/snippets/plaintextsnippetprovider.cpp new file mode 100644 index 00000000000..a333e201db9 --- /dev/null +++ b/src/plugins/texteditor/snippets/plaintextsnippetprovider.cpp @@ -0,0 +1,56 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "plaintextsnippetprovider.h" + +#include <texteditor/texteditorconstants.h> + +#include <QtCore/QLatin1String> + +using namespace TextEditor; +using namespace Internal; + +PlainTextSnippetProvider::PlainTextSnippetProvider() +{} + +PlainTextSnippetProvider::~PlainTextSnippetProvider() +{} + +QString PlainTextSnippetProvider::groupId() const +{ + return QLatin1String(Constants::TEXT_SNIPPET_GROUP_ID); +} + +QString PlainTextSnippetProvider::displayName() const +{ + return tr("Text"); +} + +void PlainTextSnippetProvider::decorateEditor(TextEditor::SnippetEditor *) const +{} diff --git a/src/plugins/texteditor/snippets/plaintextsnippetprovider.h b/src/plugins/texteditor/snippets/plaintextsnippetprovider.h new file mode 100644 index 00000000000..4d7a608d21b --- /dev/null +++ b/src/plugins/texteditor/snippets/plaintextsnippetprovider.h @@ -0,0 +1,53 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef PLAINTEXTSNIPPETPROVIDER_H +#define PLAINTEXTSNIPPETPROVIDER_H + +#include "isnippetprovider.h" + +namespace TextEditor { +namespace Internal { + +class PlainTextSnippetProvider : public ISnippetProvider +{ +public: + PlainTextSnippetProvider(); + virtual ~PlainTextSnippetProvider(); + +public: + virtual QString groupId() const; + virtual QString displayName() const; + virtual void decorateEditor(TextEditor::SnippetEditor *editor) const; +}; + +} // Internal +} // TextEditor + +#endif // PLAINTEXTSNIPPETPROVIDER_H diff --git a/src/plugins/texteditor/snippets/reuse.h b/src/plugins/texteditor/snippets/reuse.h index 5ab7b403ec6..17c4a34888f 100644 --- a/src/plugins/texteditor/snippets/reuse.h +++ b/src/plugins/texteditor/snippets/reuse.h @@ -30,41 +30,15 @@ #ifndef REUSE_H #define REUSE_H -#include "snippet.h" - #include <QtCore/QString> #include <QtCore/QLatin1String> namespace TextEditor { namespace Internal { -const QLatin1String kCpp("C++"); -const QLatin1String kQml("QML"); -const QLatin1String kText("Text"); const QLatin1String kTrue("true"); const QLatin1String kFalse("false"); -inline Snippet::Group toSnippetGroup(const QString &s) -{ - const QString &upper = s.toUpper(); - if (upper == kCpp) - return Snippet::Cpp; - else if (upper == kQml) - return Snippet::Qml; - else - return Snippet::PlainText; -} - -inline QString fromSnippetGroup(Snippet::Group group) -{ - if (group == Snippet::Cpp) - return kCpp; - else if (group == Snippet::Qml) - return kQml; - else - return kText; -} - inline bool toBool(const QString &s) { if (s == kTrue) diff --git a/src/plugins/texteditor/snippets/snippet.cpp b/src/plugins/texteditor/snippets/snippet.cpp index b00056110ce..7291e8084b5 100644 --- a/src/plugins/texteditor/snippets/snippet.cpp +++ b/src/plugins/texteditor/snippets/snippet.cpp @@ -37,7 +37,8 @@ using namespace TextEditor; const QChar Snippet::kVariableDelimiter(QLatin1Char('$')); -Snippet::Snippet(const QString &id) : m_isRemoved(false), m_isModified(false), m_id(id) +Snippet::Snippet(const QString &groupId, const QString &id) : + m_isRemoved(false), m_isModified(false), m_groupId(groupId), m_id(id) {} Snippet::~Snippet() @@ -48,6 +49,11 @@ const QString &Snippet::id() const return m_id; } +const QString &Snippet::groupId() const +{ + return m_groupId; +} + bool Snippet::isBuiltIn() const { return !m_id.isEmpty(); @@ -103,16 +109,6 @@ bool Snippet::isModified() const return m_isModified; } -void Snippet::setGroup(Group group) -{ - m_group = group; -} - -Snippet::Group Snippet::group() const -{ - return m_group; -} - QString Snippet::generateTip() const { static const QLatin1Char kNewLine('\n'); diff --git a/src/plugins/texteditor/snippets/snippet.h b/src/plugins/texteditor/snippets/snippet.h index 984da3e7f9c..2ec985408b3 100644 --- a/src/plugins/texteditor/snippets/snippet.h +++ b/src/plugins/texteditor/snippets/snippet.h @@ -40,18 +40,11 @@ namespace TextEditor { class TEXTEDITOR_EXPORT Snippet { public: - Snippet(const QString &id = QString()); + Snippet(const QString &groupId = QString(), const QString &id = QString()); ~Snippet(); - // Values from this enumeration need to be contiguous (they are used as indexes). - enum Group { - Cpp = 0, - Qml, - PlainText, - GroupSize - }; - const QString &id() const; + const QString &groupId() const; bool isBuiltIn() const; @@ -70,9 +63,6 @@ public: void setIsModified(bool modified); bool isModified() const; - void setGroup(Group group); - Group group() const; - QString generateTip() const; static const QChar kVariableDelimiter; @@ -80,19 +70,13 @@ public: private: bool m_isRemoved; bool m_isModified; + QString m_groupId; QString m_id; // Only built-in snippets have an id. QString m_trigger; QString m_content; QString m_complement; - Group m_group; }; -inline Snippet::Group& operator++(Snippet::Group& group) -{ - group = Snippet::Group(group + 1); - return group; -} - } // TextEditor #endif // SNIPPET_H diff --git a/src/plugins/texteditor/snippets/snippetprovider.cpp b/src/plugins/texteditor/snippets/snippetcollector.cpp similarity index 75% rename from src/plugins/texteditor/snippets/snippetprovider.cpp rename to src/plugins/texteditor/snippets/snippetcollector.cpp index 37c94380d00..0a875ca4f47 100644 --- a/src/plugins/texteditor/snippets/snippetprovider.cpp +++ b/src/plugins/texteditor/snippets/snippetcollector.cpp @@ -27,10 +27,12 @@ ** **************************************************************************/ -#include "snippetprovider.h" +#include "snippetcollector.h" #include "snippetsmanager.h" #include "snippetscollection.h" +#include <texteditor/texteditorconstants.h> + using namespace TextEditor; using namespace Internal; @@ -38,15 +40,15 @@ namespace { void appendSnippets(ICompletionCollector *collector, QList<CompletionItem> *completionItems, - Snippet::Group group, + const QString &groupId, const QIcon &icon, int order) { QSharedPointer<SnippetsCollection> collection = SnippetsManager::instance()->snippetsCollection(); - const int size = collection->totalActiveSnippets(group); + const int size = collection->totalActiveSnippets(groupId); for (int i = 0; i < size; ++i) { - const Snippet &snippet = collection->snippet(i, group); + const Snippet &snippet = collection->snippet(i, groupId); CompletionItem item(collector); item.text = snippet.trigger() + QLatin1Char(' ') + snippet.complement(); item.data = snippet.content(); @@ -60,17 +62,17 @@ void appendSnippets(ICompletionCollector *collector, } // anonymous -SnippetProvider::SnippetProvider(Snippet::Group group, const QIcon &icon, int order) : - m_group(group), m_icon(icon), m_order(order) +SnippetCollector::SnippetCollector(const QString &groupId, const QIcon &icon, int order) : + m_groupId(groupId), m_icon(icon), m_order(order) {} -SnippetProvider::~SnippetProvider() +SnippetCollector::~SnippetCollector() {} -QList<CompletionItem> SnippetProvider::getSnippets(ICompletionCollector *collector) const +QList<CompletionItem> SnippetCollector::getSnippets(ICompletionCollector *collector) const { QList<CompletionItem> completionItems; - appendSnippets(collector, &completionItems, m_group, m_icon, m_order); - appendSnippets(collector, &completionItems, Snippet::PlainText, m_icon, m_order); + appendSnippets(collector, &completionItems, m_groupId, m_icon, m_order); + appendSnippets(collector, &completionItems, Constants::TEXT_SNIPPET_GROUP_ID, m_icon, m_order); return completionItems; } diff --git a/src/plugins/texteditor/snippets/snippetprovider.h b/src/plugins/texteditor/snippets/snippetcollector.h similarity index 89% rename from src/plugins/texteditor/snippets/snippetprovider.h rename to src/plugins/texteditor/snippets/snippetcollector.h index 486ebcf165c..8b44b74edfc 100644 --- a/src/plugins/texteditor/snippets/snippetprovider.h +++ b/src/plugins/texteditor/snippets/snippetcollector.h @@ -30,26 +30,25 @@ #ifndef SNIPPETPROVIDER_H #define SNIPPETPROVIDER_H -#include "snippet.h" - #include <texteditor/texteditor_global.h> #include <texteditor/icompletioncollector.h> +#include <QtCore/QString> #include <QtCore/QList> #include <QtGui/QIcon> namespace TextEditor { -class TEXTEDITOR_EXPORT SnippetProvider +class TEXTEDITOR_EXPORT SnippetCollector { public: - SnippetProvider(Snippet::Group group, const QIcon &icon, int order = 0); - ~SnippetProvider(); + SnippetCollector(const QString &groupId, const QIcon &icon, int order = 0); + ~SnippetCollector(); QList<CompletionItem> getSnippets(ICompletionCollector *collector) const; private: - Snippet::Group m_group; + QString m_groupId; QIcon m_icon; int m_order; }; diff --git a/src/plugins/texteditor/snippets/snippets.xml b/src/plugins/texteditor/snippets/snippets.xml index 0d511a8d41c..0febaac0a49 100644 --- a/src/plugins/texteditor/snippets/snippets.xml +++ b/src/plugins/texteditor/snippets/snippets.xml @@ -117,4 +117,5 @@ public: <snippet group="QML" trigger="PropertyAction" id="propertyactionwithtarget" complement="with target">PropertyAction { target: $name$; property: "$name$"; value: $value$ }</snippet> <snippet group="QML" trigger="PauseAnimation" id="pauseanimation">PauseAnimation { duration: $200$ }</snippet> <snippet group="QML" trigger="ColorAnimation" id="coloranimation">ColorAnimation { from: $"white"$; to: $"black"$; duration: $200$ }</snippet> +<snippet group="Text" trigger="global" id="global" complement="example">// This is available in all editors.</snippet> </snippets> diff --git a/src/plugins/texteditor/snippets/snippetscollection.cpp b/src/plugins/texteditor/snippets/snippetscollection.cpp index 731f0626031..dd2531e7cce 100644 --- a/src/plugins/texteditor/snippets/snippetscollection.cpp +++ b/src/plugins/texteditor/snippets/snippetscollection.cpp @@ -28,15 +28,16 @@ **************************************************************************/ #include "snippetscollection.h" +#include "isnippetprovider.h" #include "reuse.h" #include <coreplugin/icore.h> +#include <extensionsystem/pluginmanager.h> #include <QtCore/QLatin1String> #include <QtCore/QFile> #include <QtCore/QFileInfo> #include <QtCore/QDir> -#include <QtCore/QHash> #include <QtCore/QDebug> #include <QtCore/QXmlStreamReader> #include <QtCore/QXmlStreamWriter> @@ -99,28 +100,24 @@ int SnippetsCollection::Hint::index() const // SnippetsCollection SnippetsCollection::SnippetsCollection() : - m_snippets(Snippet::GroupSize), - m_activeSnippetsEnd(Snippet::GroupSize), m_builtInSnippetsPath(QLatin1String(":/texteditor/snippets/")), m_userSnippetsPath(Core::ICore::instance()->userResourcePath() + QLatin1String("/snippets/")), m_snippetsFileName(QLatin1String("snippets.xml")) { - for (Snippet::Group group = Snippet::Cpp; group < Snippet::GroupSize; ++group) - m_activeSnippetsEnd[group] = m_snippets[group].end(); + connect(Core::ICore::instance(), SIGNAL(coreOpened()), this, SLOT(identifyGroups())); } SnippetsCollection::~SnippetsCollection() {} -void SnippetsCollection::insertSnippet(const Snippet &snippet, Snippet::Group group) +void SnippetsCollection::insertSnippet(const Snippet &snippet) { - insertSnippet(snippet, group, computeInsertionHint(snippet, group)); + insertSnippet(snippet, computeInsertionHint(snippet)); } -void SnippetsCollection::insertSnippet(const Snippet &snippet, - Snippet::Group group, - const Hint &hint) +void SnippetsCollection::insertSnippet(const Snippet &snippet, const Hint &hint) { + const int group = groupIndex(snippet.groupId()); if (snippet.isBuiltIn() && snippet.isRemoved()) { m_activeSnippetsEnd[group] = m_snippets[group].insert(m_activeSnippetsEnd[group], snippet); } else { @@ -129,25 +126,23 @@ void SnippetsCollection::insertSnippet(const Snippet &snippet, } } -SnippetsCollection::Hint SnippetsCollection::computeInsertionHint(const Snippet &snippet, - Snippet::Group group) +SnippetsCollection::Hint SnippetsCollection::computeInsertionHint(const Snippet &snippet) { + const int group = groupIndex(snippet.groupId()); QList<Snippet> &snippets = m_snippets[group]; QList<Snippet>::iterator it = qUpperBound( snippets.begin(), m_activeSnippetsEnd.at(group), snippet, snippetComp); return Hint(static_cast<int>(std::distance(snippets.begin(), it)), it); } -void SnippetsCollection::replaceSnippet(int index, const Snippet &snippet, Snippet::Group group) +void SnippetsCollection::replaceSnippet(int index, const Snippet &snippet) { - replaceSnippet(index, snippet, group, computeReplacementHint(index, snippet, group)); + replaceSnippet(index, snippet, computeReplacementHint(index, snippet)); } -void SnippetsCollection::replaceSnippet(int index, - const Snippet &snippet, - Snippet::Group group, - const Hint &hint) +void SnippetsCollection::replaceSnippet(int index, const Snippet &snippet, const Hint &hint) { + const int group = groupIndex(snippet.groupId()); Snippet replacement(snippet); if (replacement.isBuiltIn() && !replacement.isModified()) replacement.setIsModified(true); @@ -155,7 +150,7 @@ void SnippetsCollection::replaceSnippet(int index, if (index == hint.index()) { m_snippets[group][index] = replacement; } else { - insertSnippet(replacement, group, hint); + insertSnippet(replacement, hint); // Consider whether the row moved up towards the beginning or down towards the end. if (index < hint.index()) m_snippets[group].removeAt(index); @@ -166,9 +161,9 @@ void SnippetsCollection::replaceSnippet(int index, } SnippetsCollection::Hint SnippetsCollection::computeReplacementHint(int index, - const Snippet &snippet, - Snippet::Group group) + const Snippet &snippet) { + const int group = groupIndex(snippet.groupId()); QList<Snippet> &snippets = m_snippets[group]; QList<Snippet>::iterator it = qLowerBound( snippets.begin(), m_activeSnippetsEnd.at(group), snippet, snippetComp); @@ -183,8 +178,9 @@ SnippetsCollection::Hint SnippetsCollection::computeReplacementHint(int index, return Hint(index); } -void SnippetsCollection::removeSnippet(int index, Snippet::Group group) +void SnippetsCollection::removeSnippet(int index, const QString &groupId) { + const int group = groupIndex(groupId); Snippet snippet(m_snippets.at(group).at(index)); m_snippets[group].removeAt(index); if (snippet.isBuiltIn()) { @@ -195,90 +191,99 @@ void SnippetsCollection::removeSnippet(int index, Snippet::Group group) } } -const Snippet &SnippetsCollection::snippet(int index, Snippet::Group group) const +const Snippet &SnippetsCollection::snippet(int index, const QString &groupId) const { - return m_snippets.at(group).at(index); + return m_snippets.at(groupIndex(groupId)).at(index); } -void SnippetsCollection::setSnippetContent(int index, Snippet::Group group, const QString &content) +void SnippetsCollection::setSnippetContent(int index, + const QString &groupId, + const QString &content) { - Snippet &snippet = m_snippets[group][index]; + Snippet &snippet = m_snippets[groupIndex(groupId)][index]; snippet.setContent(content); if (snippet.isBuiltIn() && !snippet.isModified()) snippet.setIsModified(true); } -int SnippetsCollection::totalActiveSnippets(Snippet::Group group) const +int SnippetsCollection::totalActiveSnippets(const QString &groupId) const { + const int group = groupIndex(groupId); return std::distance<QList<Snippet>::const_iterator>(m_snippets.at(group).begin(), m_activeSnippetsEnd.at(group)); } -int SnippetsCollection::totalSnippets(Snippet::Group group) const +int SnippetsCollection::totalSnippets(const QString &groupId) const { - return m_snippets.at(group).size(); + return m_snippets.at(groupIndex(groupId)).size(); } -void SnippetsCollection::clear() +QList<QString> SnippetsCollection::groupIds() const { - for (Snippet::Group group = Snippet::Cpp; group < Snippet::GroupSize; ++group) - clear(group); + return m_groupIndexById.keys(); } -void SnippetsCollection::clear(Snippet::Group group) +void SnippetsCollection::clearSnippets() { - m_snippets[group].clear(); - m_activeSnippetsEnd[group] = m_snippets[group].end(); + for (int group = 0; group < m_groupIndexById.size(); ++group) + clearSnippets(group); } -void SnippetsCollection::updateActiveSnippetsEnd(Snippet::Group group) +void SnippetsCollection::clearSnippets(int groupIndex) { - m_activeSnippetsEnd[group] = std::find_if(m_snippets[group].begin(), - m_snippets[group].end(), - removedSnippetPred); + m_snippets[groupIndex].clear(); + m_activeSnippetsEnd[groupIndex] = m_snippets[groupIndex].end(); } -void SnippetsCollection::restoreRemovedSnippets(Snippet::Group group) +void SnippetsCollection::updateActiveSnippetsEnd(int groupIndex) +{ + m_activeSnippetsEnd[groupIndex] = std::find_if(m_snippets[groupIndex].begin(), + m_snippets[groupIndex].end(), + removedSnippetPred); +} + +void SnippetsCollection::restoreRemovedSnippets(const QString &groupId) { // The version restored contains the last modifications (if any) by the user. - // Reverting the snippet can still bring it to the original version. + // Reverting the snippet can still bring it to the original version + const int group = groupIndex(groupId); 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); + insertSnippet(snippet); } } -Snippet SnippetsCollection::revertedSnippet(int index, Snippet::Group group) const +Snippet SnippetsCollection::revertedSnippet(int index, const QString &groupId) const { - const Snippet &candidate = snippet(index, group); + const Snippet &candidate = snippet(index, groupId); 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(); + return Snippet(groupId); } -void SnippetsCollection::reset(Snippet::Group group) +void SnippetsCollection::reset(const QString &groupId) { - clear(group); + clearSnippets(groupIndex(groupId)); const QList<Snippet> &builtInSnippets = readXML(m_builtInSnippetsPath + m_snippetsFileName); foreach (const Snippet &snippet, builtInSnippets) - if (group == snippet.group()) - insertSnippet(snippet, snippet.group()); + if (groupId == snippet.groupId()) + insertSnippet(snippet); } void SnippetsCollection::reload() { - clear(); + clearSnippets(); - QHash<QString, Snippet> activeBuiltInSnippets; const QList<Snippet> &builtInSnippets = readXML(m_builtInSnippetsPath + m_snippetsFileName); + QHash<QString, Snippet> activeBuiltInSnippets; foreach (const Snippet &snippet, builtInSnippets) activeBuiltInSnippets.insert(snippet.id(), snippet); @@ -287,11 +292,11 @@ void SnippetsCollection::reload() if (snippet.isBuiltIn()) // This user snippet overrides the corresponding built-in snippet. activeBuiltInSnippets.remove(snippet.id()); - insertSnippet(snippet, snippet.group()); + insertSnippet(snippet); } foreach (const Snippet &snippet, activeBuiltInSnippets) - insertSnippet(snippet, snippet.group()); + insertSnippet(snippet); } void SnippetsCollection::synchronize() @@ -303,10 +308,10 @@ void SnippetsCollection::synchronize() writer.setAutoFormatting(true); writer.writeStartDocument(); writer.writeStartElement(kSnippets); - for (Snippet::Group group = Snippet::Cpp; group < Snippet::GroupSize; ++group) { - const int size = totalSnippets(group); + foreach (const QString &groupId, m_groupIndexById.keys()) { + const int size = m_snippets.at(groupIndex(groupId)).size(); for (int i = 0; i < size; ++i) { - const Snippet ¤t = snippet(i, group); + const Snippet ¤t = snippet(i, groupId); if (!current.isBuiltIn() || current.isRemoved() || current.isModified()) writeSnippetXML(current, &writer); } @@ -320,10 +325,10 @@ void SnippetsCollection::synchronize() reload(); } -void SnippetsCollection::writeSnippetXML(const Snippet &snippet, QXmlStreamWriter *writer) +void SnippetsCollection::writeSnippetXML(const Snippet &snippet, QXmlStreamWriter *writer) const { writer->writeStartElement(kSnippet); - writer->writeAttribute(kGroup, fromSnippetGroup(snippet.group())); + writer->writeAttribute(kGroup, snippet.groupId()); writer->writeAttribute(kTrigger, snippet.trigger()); writer->writeAttribute(kId, snippet.id()); writer->writeAttribute(kComplement, snippet.complement()); @@ -333,7 +338,7 @@ void SnippetsCollection::writeSnippetXML(const Snippet &snippet, QXmlStreamWrite writer->writeEndElement(); } -QList<Snippet> SnippetsCollection::readXML(const QString &fileName, const QString &snippetId) +QList<Snippet> SnippetsCollection::readXML(const QString &fileName, const QString &snippetId) const { QList<Snippet> snippets; QFile file(fileName); @@ -345,11 +350,11 @@ QList<Snippet> SnippetsCollection::readXML(const QString &fileName, const QStrin if (xml.name() == kSnippet) { const QXmlStreamAttributes &atts = xml.attributes(); const QString &id = atts.value(kId).toString(); - if (snippetId.isEmpty() || snippetId == id) { - Snippet snippet(id); + const QString &groupId = atts.value(kGroup).toString(); + if (isGroupKnown(groupId) && (snippetId.isEmpty() || snippetId == id)) { + Snippet snippet(groupId, 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())); @@ -383,3 +388,28 @@ QList<Snippet> SnippetsCollection::readXML(const QString &fileName, const QStrin return snippets; } + +int SnippetsCollection::groupIndex(const QString &groupId) const +{ + return m_groupIndexById.value(groupId); +} + +void SnippetsCollection::identifyGroups() +{ + const QList<ISnippetProvider *> &providers = + ExtensionSystem::PluginManager::instance()->getObjects<ISnippetProvider>(); + foreach (ISnippetProvider *provider, providers) { + const int groupIndex = m_groupIndexById.size(); + m_groupIndexById.insert(provider->groupId(), groupIndex); + m_snippets.resize(groupIndex + 1); + m_activeSnippetsEnd.resize(groupIndex + 1); + m_activeSnippetsEnd[groupIndex] = m_snippets[groupIndex].end(); + } + + reload(); +} + +bool SnippetsCollection::isGroupKnown(const QString &groupId) const +{ + return m_groupIndexById.value(groupId, -1) != -1; +} diff --git a/src/plugins/texteditor/snippets/snippetscollection.h b/src/plugins/texteditor/snippets/snippetscollection.h index 4282ea7af63..0926a33c5a2 100644 --- a/src/plugins/texteditor/snippets/snippetscollection.h +++ b/src/plugins/texteditor/snippets/snippetscollection.h @@ -34,6 +34,7 @@ #include <QtCore/QVector> #include <QtCore/QList> +#include <QtCore/QHash> QT_FORWARD_DECLARE_CLASS(QXmlStreamWriter) @@ -49,8 +50,9 @@ namespace Internal { // - Provide fast index access. // - Not thread-safe. -class SnippetsCollection +class SnippetsCollection : public QObject { + Q_OBJECT public: SnippetsCollection(); ~SnippetsCollection(); @@ -61,43 +63,52 @@ public: public: int index() const; private: - Hint(int index); + explicit Hint(int index); Hint(int index, QList<Snippet>::iterator it); int m_index; QList<Snippet>::iterator m_it; }; - void insertSnippet(const Snippet &snippet, Snippet::Group group); - void insertSnippet(const Snippet &snippet, Snippet::Group group, const Hint &hint); - Hint computeInsertionHint(const Snippet &snippet, Snippet::Group group); + void insertSnippet(const Snippet &snippet); + void insertSnippet(const Snippet &snippet, const Hint &hint); + Hint computeInsertionHint(const Snippet &snippet); - void replaceSnippet(int index, const Snippet &snippet, Snippet::Group group); - void replaceSnippet(int index, const Snippet &snippet, Snippet::Group group, const Hint &hint); - Hint computeReplacementHint(int index, const Snippet &snippet, Snippet::Group group); + // Replace snippets only within the same group. + void replaceSnippet(int index, const Snippet &snippet); + void replaceSnippet(int index, const Snippet &snippet, const Hint &hint); + Hint computeReplacementHint(int index, const Snippet &snippet); - void removeSnippet(int index, Snippet::Group group); - void restoreRemovedSnippets(Snippet::Group group); + void removeSnippet(int index, const QString &groupId); + void restoreRemovedSnippets(const QString &groupId); - void setSnippetContent(int index, Snippet::Group group, const QString &content); + void setSnippetContent(int index, const QString &groupId, const QString &content); - const Snippet &snippet(int index, Snippet::Group group) const; - Snippet revertedSnippet(int index, Snippet::Group group) const; + const Snippet &snippet(int index, const QString &groupId) const; + Snippet revertedSnippet(int index, const QString &groupId) const; - void reset(Snippet::Group group); + void reset(const QString &groupId); - int totalActiveSnippets(Snippet::Group group) const; - int totalSnippets(Snippet::Group group) const; + int totalActiveSnippets(const QString &groupId) const; + int totalSnippets(const QString &groupId) const; + + QList<QString> groupIds() const; void reload(); void synchronize(); +private slots: + void identifyGroups(); + private: - void clear(); - void clear(Snippet::Group group); - void updateActiveSnippetsEnd(Snippet::Group group); + int groupIndex(const QString &groupId) const; + + void clearSnippets(); + void clearSnippets(int groupIndex); + + void updateActiveSnippetsEnd(int groupIndex); - static QList<Snippet> readXML(const QString &fileName, const QString &snippetId = QString()); - static void writeSnippetXML(const Snippet &snippet, QXmlStreamWriter *writer); + QList<Snippet> readXML(const QString &fileName, const QString &snippetId = QString()) const; + void writeSnippetXML(const Snippet &snippet, QXmlStreamWriter *writer) const; static const QLatin1String kSnippet; static const QLatin1String kSnippets; @@ -108,11 +119,7 @@ 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; + bool isGroupKnown(const QString &groupId) const; // 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 @@ -120,6 +127,14 @@ private: QString m_builtInSnippetsPath; QString m_userSnippetsPath; QString m_snippetsFileName; + + // 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; + + QHash<QString, int> m_groupIndexById; }; } // Internal diff --git a/src/plugins/texteditor/snippets/snippetsmanager.h b/src/plugins/texteditor/snippets/snippetsmanager.h index 6a527815f78..131377948f2 100644 --- a/src/plugins/texteditor/snippets/snippetsmanager.h +++ b/src/plugins/texteditor/snippets/snippetsmanager.h @@ -33,6 +33,9 @@ #include <QtCore/QSharedPointer> namespace TextEditor { + +class ISnippetProvider; + namespace Internal { class SnippetsCollection; diff --git a/src/plugins/texteditor/snippets/snippetssettings.cpp b/src/plugins/texteditor/snippets/snippetssettings.cpp index e99cbaf59e8..f6ea3a64534 100644 --- a/src/plugins/texteditor/snippets/snippetssettings.cpp +++ b/src/plugins/texteditor/snippets/snippetssettings.cpp @@ -57,8 +57,7 @@ void SnippetsSettings::fromSettings(const QString &category, QSettings *s) { const QString &group = category + kGroupPostfix; s->beginGroup(group); - m_lastUsedSnippetGroup = - s->value(kLastUsedSnippetGroup, fromSnippetGroup(Snippet::Cpp)).toString(); + m_lastUsedSnippetGroup = s->value(kLastUsedSnippetGroup, QString()).toString(); s->endGroup(); } diff --git a/src/plugins/texteditor/snippets/snippetssettingspage.cpp b/src/plugins/texteditor/snippets/snippetssettingspage.cpp index f73fe64673f..b9beef03839 100644 --- a/src/plugins/texteditor/snippets/snippetssettingspage.cpp +++ b/src/plugins/texteditor/snippets/snippetssettingspage.cpp @@ -30,7 +30,7 @@ #include "snippetssettingspage.h" #include "snippetsmanager.h" #include "snippeteditor.h" -#include "isnippeteditordecorator.h" +#include "isnippetprovider.h" #include "snippet.h" #include "snippetscollection.h" #include "snippetssettings.h" @@ -46,6 +46,7 @@ #include <QtCore/QList> #include <QtCore/QSettings> #include <QtCore/QTextStream> +#include <QtCore/QHash> #include <QtGui/QMessageBox> namespace TextEditor { @@ -68,7 +69,8 @@ public: virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - void load(Snippet::Group group); + QList<QString> groupIds() const; + void load(const QString &groupId); QModelIndex createSnippet(); QModelIndex insertSnippet(const Snippet &snippet); @@ -83,13 +85,12 @@ private: void replaceSnippet(const Snippet &snippet, const QModelIndex &modelIndex); static bool isValidTrigger(const QString &s); - Snippet::Group m_activeGroup; QSharedPointer<SnippetsCollection> m_collection; + QString m_activeGroupId; }; SnippetsTableModel::SnippetsTableModel(QObject *parent) : QAbstractTableModel(parent), - m_activeGroup(Snippet::Cpp), m_collection(SnippetsManager::instance()->snippetsCollection()) {} @@ -97,7 +98,7 @@ int SnippetsTableModel::rowCount(const QModelIndex &) const { if (m_collection.isNull()) return 0; - return m_collection->totalActiveSnippets(m_activeGroup); + return m_collection->totalActiveSnippets(m_activeGroupId); } int SnippetsTableModel::columnCount(const QModelIndex &) const @@ -121,7 +122,7 @@ QVariant SnippetsTableModel::data(const QModelIndex &modelIndex, int role) const return QVariant(); if (role == Qt::DisplayRole || role == Qt::EditRole) { - const Snippet &snippet = m_collection->snippet(modelIndex.row(), m_activeGroup); + const Snippet &snippet = m_collection->snippet(modelIndex.row(), m_activeGroupId); if (modelIndex.column() == 0) return snippet.trigger(); else @@ -134,7 +135,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) { - Snippet snippet(m_collection->snippet(modelIndex.row(), m_activeGroup)); + Snippet snippet(m_collection->snippet(modelIndex.row(), m_activeGroupId)); if (modelIndex.column() == 0) { const QString &s = value.toString(); if (!isValidTrigger(s)) { @@ -165,25 +166,28 @@ QVariant SnippetsTableModel::headerData(int section, Qt::Orientation orientation return tr("Complement"); } -void SnippetsTableModel::load(Snippet::Group group) +void SnippetsTableModel::load(const QString &groupId) { - m_activeGroup = group; + m_activeGroupId = groupId; reset(); } +QList<QString> SnippetsTableModel::groupIds() const +{ + return m_collection->groupIds(); +} + QModelIndex SnippetsTableModel::createSnippet() { - Snippet snippet; - snippet.setGroup(m_activeGroup); + Snippet snippet(m_activeGroupId); return insertSnippet(snippet); } QModelIndex SnippetsTableModel::insertSnippet(const Snippet &snippet) { - const SnippetsCollection::Hint &hint = - m_collection->computeInsertionHint(snippet, m_activeGroup); + const SnippetsCollection::Hint &hint = m_collection->computeInsertionHint(snippet); beginInsertRows(QModelIndex(), hint.index(), hint.index()); - m_collection->insertSnippet(snippet, m_activeGroup, hint); + m_collection->insertSnippet(snippet, hint); endInsertRows(); return index(hint.index(), 0); @@ -192,23 +196,23 @@ QModelIndex SnippetsTableModel::insertSnippet(const Snippet &snippet) void SnippetsTableModel::removeSnippet(const QModelIndex &modelIndex) { beginRemoveRows(QModelIndex(), modelIndex.row(), modelIndex.row()); - m_collection->removeSnippet(modelIndex.row(), m_activeGroup); + m_collection->removeSnippet(modelIndex.row(), m_activeGroupId); endRemoveRows(); } const Snippet &SnippetsTableModel::snippetAt(const QModelIndex &modelIndex) const { - return m_collection->snippet(modelIndex.row(), m_activeGroup); + return m_collection->snippet(modelIndex.row(), m_activeGroupId); } void SnippetsTableModel::setSnippetContent(const QModelIndex &modelIndex, const QString &content) { - m_collection->setSnippetContent(modelIndex.row(), m_activeGroup, content); + m_collection->setSnippetContent(modelIndex.row(), m_activeGroupId, content); } void SnippetsTableModel::revertBuitInSnippet(const QModelIndex &modelIndex) { - const Snippet &snippet = m_collection->revertedSnippet(modelIndex.row(), m_activeGroup); + const Snippet &snippet = m_collection->revertedSnippet(modelIndex.row(), m_activeGroupId); if (snippet.id().isEmpty()) { QMessageBox::critical(0, tr("Error"), tr("Error reverting snippet.")); return; @@ -218,13 +222,13 @@ void SnippetsTableModel::revertBuitInSnippet(const QModelIndex &modelIndex) void SnippetsTableModel::restoreRemovedBuiltInSnippets() { - m_collection->restoreRemovedSnippets(m_activeGroup); + m_collection->restoreRemovedSnippets(m_activeGroupId); reset(); } void SnippetsTableModel::resetSnippets() { - m_collection->reset(m_activeGroup); + m_collection->reset(m_activeGroupId); reset(); } @@ -232,9 +236,9 @@ void SnippetsTableModel::replaceSnippet(const Snippet &snippet, const QModelInde { const int row = modelIndex.row(); const SnippetsCollection::Hint &hint = - m_collection->computeReplacementHint(row, snippet, m_activeGroup); + m_collection->computeReplacementHint(row, snippet); if (modelIndex.row() == hint.index()) { - m_collection->replaceSnippet(row, snippet, m_activeGroup, hint); + m_collection->replaceSnippet(row, snippet, hint); emit dataChanged(modelIndex, modelIndex); } else { if (row < hint.index()) @@ -242,7 +246,7 @@ void SnippetsTableModel::replaceSnippet(const Snippet &snippet, const QModelInde beginMoveRows(QModelIndex(), row, row, QModelIndex(), hint.index() + 1); else beginMoveRows(QModelIndex(), row, row, QModelIndex(), hint.index()); - m_collection->replaceSnippet(row, snippet, m_activeGroup, hint); + m_collection->replaceSnippet(row, snippet, hint); endMoveRows(); } } @@ -290,8 +294,6 @@ private: SnippetEditor *currentEditor() const; SnippetEditor *editorAt(int i) const; - static void decorateEditor(SnippetEditor *editor, Snippet::Group group); - void loadSettings(); bool settingsChanged() const; void writeSettings(); @@ -328,9 +330,15 @@ void SnippetsSettingsPagePrivate::configureUi(QWidget *w) { m_ui.setupUi(w); - m_ui.groupCombo->insertItem(Snippet::Cpp, fromSnippetGroup(Snippet::Cpp)); - m_ui.groupCombo->insertItem(Snippet::Qml, fromSnippetGroup(Snippet::Qml)); - m_ui.groupCombo->insertItem(Snippet::PlainText, fromSnippetGroup(Snippet::PlainText)); + const QList<ISnippetProvider *> &providers = + ExtensionSystem::PluginManager::instance()->getObjects<ISnippetProvider>(); + foreach (ISnippetProvider *provider, providers) { + m_ui.groupCombo->addItem(provider->displayName(), provider->groupId()); + SnippetEditor *snippetEditor = new SnippetEditor(w); + provider->decorateEditor(snippetEditor); + m_ui.snippetsEditorStack->insertWidget(m_ui.groupCombo->count() - 1, snippetEditor); + connect(snippetEditor, SIGNAL(snippetContentChanged()), this, SLOT(setSnippetContent())); + } m_ui.snippetsTable->setSelectionBehavior(QAbstractItemView::SelectRows); m_ui.snippetsTable->setSelectionMode(QAbstractItemView::SingleSelection); @@ -340,13 +348,6 @@ void SnippetsSettingsPagePrivate::configureUi(QWidget *w) m_ui.snippetsTable->verticalHeader()->setDefaultSectionSize(20); m_ui.snippetsTable->setModel(m_model); - m_ui.snippetsEditorStack->insertWidget(Snippet::Cpp, new SnippetEditor(w)); - m_ui.snippetsEditorStack->insertWidget(Snippet::Qml, new SnippetEditor(w)); - m_ui.snippetsEditorStack->insertWidget(Snippet::PlainText, new SnippetEditor(w)); - decorateEditor(editorAt(Snippet::Cpp), Snippet::Cpp); - decorateEditor(editorAt(Snippet::Qml), Snippet::Qml); - decorateEditor(editorAt(Snippet::PlainText), Snippet::PlainText); - m_ui.revertButton->setEnabled(false); QTextStream(&m_keywords) << m_displayName; @@ -354,13 +355,6 @@ void SnippetsSettingsPagePrivate::configureUi(QWidget *w) loadSettings(); loadSnippetGroup(m_ui.groupCombo->currentIndex()); - connect(editorAt(Snippet::Cpp), SIGNAL(snippetContentChanged()), - this, SLOT(setSnippetContent())); - connect(editorAt(Snippet::Qml), SIGNAL(snippetContentChanged()), - this, SLOT(setSnippetContent())); - connect(editorAt(Snippet::PlainText), SIGNAL(snippetContentChanged()), - this, SLOT(setSnippetContent())); - connect(m_model, SIGNAL(rowsInserted(QModelIndex, int, int)), this, SLOT(selectSnippet(QModelIndex,int))); connect(m_model, SIGNAL(rowsInserted(QModelIndex, int, int)), @@ -387,15 +381,6 @@ void SnippetsSettingsPagePrivate::configureUi(QWidget *w) this, SLOT(updateCurrentSnippetDependent(QModelIndex))); } -void SnippetsSettingsPagePrivate::decorateEditor(SnippetEditor *editor, Snippet::Group group) -{ - const QList<ISnippetEditorDecorator *> &decorators = - ExtensionSystem::PluginManager::instance()->getObjects<ISnippetEditorDecorator>(); - foreach (ISnippetEditorDecorator *decorator, decorators) - if (decorator->supports(group)) - decorator->apply(editor); -} - void SnippetsSettingsPagePrivate::apply() { if (settingsChanged()) @@ -417,14 +402,25 @@ void SnippetsSettingsPagePrivate::finish() void SnippetsSettingsPagePrivate::loadSettings() { + if (m_ui.groupCombo->count() == 0) + return; + if (QSettings *s = Core::ICore::instance()->settings()) { m_settings.fromSettings(m_settingsPrefix, s); - m_ui.groupCombo->setCurrentIndex(toSnippetGroup(m_settings.lastUsedSnippetGroup())); + const QString &lastGroupName = m_settings.lastUsedSnippetGroup(); + const int index = m_ui.groupCombo->findText(lastGroupName); + if (index != -1) + m_ui.groupCombo->setCurrentIndex(index); + else + m_ui.groupCombo->setCurrentIndex(0); } } void SnippetsSettingsPagePrivate::writeSettings() { + if (m_ui.groupCombo->count() == 0) + return; + if (QSettings *s = Core::ICore::instance()->settings()) { m_settings.setLastUsedSnippetGroup(m_ui.groupCombo->currentText()); m_settings.toSettings(m_settingsPrefix, s); @@ -440,9 +436,12 @@ bool SnippetsSettingsPagePrivate::settingsChanged() const void SnippetsSettingsPagePrivate::loadSnippetGroup(int index) { + if (index == -1) + return; + m_ui.snippetsEditorStack->setCurrentIndex(index); currentEditor()->clear(); - m_model->load(Snippet::Group(index)); + m_model->load(m_ui.groupCombo->itemData(index).toString()); } void SnippetsSettingsPagePrivate::markSnippetsCollection() diff --git a/src/plugins/texteditor/texteditor.pro b/src/plugins/texteditor/texteditor.pro index fbc8b67cd4c..bbf384a767e 100644 --- a/src/plugins/texteditor/texteditor.pro +++ b/src/plugins/texteditor/texteditor.pro @@ -77,10 +77,11 @@ SOURCES += texteditorplugin.cpp \ snippets/snippet.cpp \ snippets/snippetsmanager.cpp \ snippets/snippeteditor.cpp \ - snippets/isnippeteditordecorator.cpp \ snippets/snippetscollection.cpp \ snippets/snippetssettings.cpp \ - snippets/snippetprovider.cpp + snippets/isnippetprovider.cpp \ + snippets/snippetcollector.cpp \ + snippets/plaintextsnippetprovider.cpp HEADERS += texteditorplugin.h \ textfilewizard.h \ @@ -159,11 +160,12 @@ HEADERS += texteditorplugin.h \ snippets/snippet.h \ snippets/snippetsmanager.h \ snippets/snippeteditor.h \ - snippets/isnippeteditordecorator.h \ snippets/snippetscollection.h \ snippets/reuse.h \ snippets/snippetssettings.h \ - snippets/snippetprovider.h + snippets/isnippetprovider.h \ + snippets/snippetcollector.h \ + snippets/plaintextsnippetprovider.h FORMS += behaviorsettingspage.ui \ displaysettingspage.ui \ diff --git a/src/plugins/texteditor/texteditorconstants.h b/src/plugins/texteditor/texteditorconstants.h index a22917d2cd6..0cb27722c07 100644 --- a/src/plugins/texteditor/texteditorconstants.h +++ b/src/plugins/texteditor/texteditorconstants.h @@ -143,6 +143,7 @@ const char * const TEXT_EDITOR_HIGHLIGHTER_SETTINGS = "E.HighlighterSettings"; const char * const TEXT_EDITOR_SNIPPETS_SETTINGS = "F.SnippetsSettings"; const char * const SNIPPET_EDITOR_ID = "TextEditor.SnippetEditor"; +const char * const TEXT_SNIPPET_GROUP_ID = "Text"; } // namespace Constants } // namespace TextEditor diff --git a/src/plugins/texteditor/texteditorplugin.cpp b/src/plugins/texteditor/texteditorplugin.cpp index 142145c9064..b547f49e822 100644 --- a/src/plugins/texteditor/texteditorplugin.cpp +++ b/src/plugins/texteditor/texteditorplugin.cpp @@ -41,6 +41,7 @@ #include "storagesettings.h" #include "manager.h" #include "outlinefactory.h" +#include "snippets/plaintextsnippetprovider.h" #include <coreplugin/icore.h> #include <coreplugin/coreconstants.h> @@ -144,6 +145,9 @@ bool TextEditorPlugin::initialize(const QStringList &arguments, QString *errorMe connect(Core::ICore::instance(), SIGNAL(coreOpened()), Manager::instance(), SLOT(registerMimeTypes())); + // Add text snippet provider. + addAutoReleasedObject(new PlainTextSnippetProvider); + m_outlineFactory = new OutlineFactory; addAutoReleasedObject(m_outlineFactory); -- GitLab