summaryrefslogtreecommitdiff
path: root/src/plugins
diff options
context:
space:
mode:
authorLeandro Melo <leandro.melo@nokia.com>2010-10-27 17:38:22 +0200
committerLeandro Melo <leandro.melo@nokia.com>2010-12-08 17:22:07 +0100
commit7528c6d617c60acfdc2d82e2a7f8d1ec2de87a02 (patch)
tree48a2dc39d8653aa8653998f6513fd06d183e7097 /src/plugins
parent27bab4e811bf5a3fd476738c35769573cd7b5ef3 (diff)
downloadqt-creator-7528c6d617c60acfdc2d82e2a7f8d1ec2de87a02.tar.gz
Snippets: Feature enhancement start...
Provide an interface so users can create/edit/remove snippets.
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/cppeditor/cppeditor.cpp36
-rw-r--r--src/plugins/cppeditor/cppeditor.h3
-rw-r--r--src/plugins/cppeditor/cppeditor.pro8
-rw-r--r--src/plugins/cppeditor/cppplugin.cpp2
-rw-r--r--src/plugins/cppeditor/cppsnippeteditordecorator.cpp64
-rw-r--r--src/plugins/cppeditor/cppsnippeteditordecorator.h52
-rw-r--r--src/plugins/cpptools/cppcodecompletion.cpp11
-rw-r--r--src/plugins/cpptools/cppcodecompletion.h4
-rw-r--r--src/plugins/qmljseditor/qmljscodecompletion.cpp4
-rw-r--r--src/plugins/qmljseditor/qmljscodecompletion.h4
-rw-r--r--src/plugins/qmljseditor/qmljseditor.cpp46
-rw-r--r--src/plugins/qmljseditor/qmljseditor.h2
-rw-r--r--src/plugins/qmljseditor/qmljseditor.pro6
-rw-r--r--src/plugins/qmljseditor/qmljseditorplugin.cpp2
-rw-r--r--src/plugins/qmljseditor/qmljssnippeteditordecorator.cpp62
-rw-r--r--src/plugins/qmljseditor/qmljssnippeteditordecorator.h52
-rw-r--r--src/plugins/texteditor/basetexteditor.cpp11
-rw-r--r--src/plugins/texteditor/snippets/isnippeteditordecorator.cpp38
-rw-r--r--src/plugins/texteditor/snippets/isnippeteditordecorator.h58
-rw-r--r--src/plugins/texteditor/snippets/reuse.h85
-rw-r--r--src/plugins/texteditor/snippets/snippet.cpp148
-rw-r--r--src/plugins/texteditor/snippets/snippet.h98
-rw-r--r--src/plugins/texteditor/snippets/snippeteditor.cpp92
-rw-r--r--src/plugins/texteditor/snippets/snippeteditor.h92
-rw-r--r--src/plugins/texteditor/snippets/snippetprovider.cpp62
-rw-r--r--src/plugins/texteditor/snippets/snippetprovider.h (renamed from src/plugins/texteditor/snippetsparser.h)31
-rw-r--r--src/plugins/texteditor/snippets/snippets.xml120
-rw-r--r--src/plugins/texteditor/snippets/snippetscollection.cpp212
-rw-r--r--src/plugins/texteditor/snippets/snippetscollection.h97
-rw-r--r--src/plugins/texteditor/snippets/snippetsmanager.cpp192
-rw-r--r--src/plugins/texteditor/snippets/snippetsmanager.h86
-rw-r--r--src/plugins/texteditor/snippets/snippetssettings.cpp78
-rw-r--r--src/plugins/texteditor/snippets/snippetssettings.h66
-rw-r--r--src/plugins/texteditor/snippets/snippetssettingspage.cpp512
-rw-r--r--src/plugins/texteditor/snippets/snippetssettingspage.h61
-rw-r--r--src/plugins/texteditor/snippets/snippetssettingspage.ui109
-rw-r--r--src/plugins/texteditor/snippetsparser.cpp144
-rw-r--r--src/plugins/texteditor/texteditor.pro32
-rw-r--r--src/plugins/texteditor/texteditor.qrc1
-rw-r--r--src/plugins/texteditor/texteditorconstants.h3
-rw-r--r--src/plugins/texteditor/texteditorsettings.cpp7
41 files changed, 2569 insertions, 224 deletions
diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp
index b132895f06..10672b0e8d 100644
--- a/src/plugins/cppeditor/cppeditor.cpp
+++ b/src/plugins/cppeditor/cppeditor.cpp
@@ -1735,22 +1735,7 @@ void CPPEditor::setFontSettings(const TextEditor::FontSettings &fs)
if (!highlighter)
return;
- static QVector<QString> categories;
- if (categories.isEmpty()) {
- categories << QLatin1String(TextEditor::Constants::C_NUMBER)
- << QLatin1String(TextEditor::Constants::C_STRING)
- << QLatin1String(TextEditor::Constants::C_TYPE)
- << QLatin1String(TextEditor::Constants::C_KEYWORD)
- << QLatin1String(TextEditor::Constants::C_OPERATOR)
- << QLatin1String(TextEditor::Constants::C_PREPROCESSOR)
- << QLatin1String(TextEditor::Constants::C_LABEL)
- << QLatin1String(TextEditor::Constants::C_COMMENT)
- << QLatin1String(TextEditor::Constants::C_DOXYGEN_COMMENT)
- << QLatin1String(TextEditor::Constants::C_DOXYGEN_TAG)
- << QLatin1String(TextEditor::Constants::C_VISUAL_WHITESPACE);
- }
-
- const QVector<QTextCharFormat> formats = fs.toTextCharFormats(categories);
+ const QVector<QTextCharFormat> formats = fs.toTextCharFormats(highlighterFormatCategories());
highlighter->setFormats(formats.constBegin(), formats.constEnd());
m_occurrencesFormat = fs.toTextCharFormat(QLatin1String(TextEditor::Constants::C_OCCURRENCES));
@@ -2175,4 +2160,23 @@ QModelIndex CPPEditor::indexForPosition(int line, int column, const QModelIndex
return lastIndex;
}
+QVector<QString> CPPEditor::highlighterFormatCategories()
+{
+ static QVector<QString> categories;
+ if (categories.isEmpty()) {
+ categories << QLatin1String(TextEditor::Constants::C_NUMBER)
+ << QLatin1String(TextEditor::Constants::C_STRING)
+ << QLatin1String(TextEditor::Constants::C_TYPE)
+ << QLatin1String(TextEditor::Constants::C_KEYWORD)
+ << QLatin1String(TextEditor::Constants::C_OPERATOR)
+ << QLatin1String(TextEditor::Constants::C_PREPROCESSOR)
+ << QLatin1String(TextEditor::Constants::C_LABEL)
+ << QLatin1String(TextEditor::Constants::C_COMMENT)
+ << QLatin1String(TextEditor::Constants::C_DOXYGEN_COMMENT)
+ << QLatin1String(TextEditor::Constants::C_DOXYGEN_TAG)
+ << QLatin1String(TextEditor::Constants::C_VISUAL_WHITESPACE);
+ }
+ return categories;
+}
+
#include "cppeditor.moc"
diff --git a/src/plugins/cppeditor/cppeditor.h b/src/plugins/cppeditor/cppeditor.h
index a781e57362..ed0708132b 100644
--- a/src/plugins/cppeditor/cppeditor.h
+++ b/src/plugins/cppeditor/cppeditor.h
@@ -43,6 +43,7 @@
#include <QtCore/QWaitCondition>
#include <QtCore/QFutureWatcher>
#include <QtCore/QModelIndex>
+#include <QtCore/QVector>
QT_BEGIN_NAMESPACE
class QComboBox;
@@ -184,6 +185,8 @@ public:
static Link linkToSymbol(CPlusPlus::Symbol *symbol);
+ static QVector<QString> highlighterFormatCategories();
+
Q_SIGNALS:
void outlineModelIndexChanged(const QModelIndex &index);
diff --git a/src/plugins/cppeditor/cppeditor.pro b/src/plugins/cppeditor/cppeditor.pro
index 0e6aa03ffd..a9bd9296ff 100644
--- a/src/plugins/cppeditor/cppeditor.pro
+++ b/src/plugins/cppeditor/cppeditor.pro
@@ -25,7 +25,9 @@ HEADERS += cppplugin.h \
cppquickfixcollector.h \
cppqtstyleindenter.h \
cppautocompleter.h \
- cppcompleteswitch.h
+ cppcompleteswitch.h \
+ cppsnippeteditordecorator.h
+
SOURCES += cppplugin.cpp \
cppeditor.cpp \
cpphighlighter.cpp \
@@ -44,6 +46,8 @@ SOURCES += cppplugin.cpp \
cppquickfixcollector.cpp \
cppqtstyleindenter.cpp \
cppautocompleter.cpp \
- cppcompleteswitch.cpp
+ cppcompleteswitch.cpp \
+ cppsnippeteditordecorator.cpp
+
RESOURCES += cppeditor.qrc
OTHER_FILES += CppEditor.mimetypes.xml
diff --git a/src/plugins/cppeditor/cppplugin.cpp b/src/plugins/cppeditor/cppplugin.cpp
index c5923c3b18..a33a151aee 100644
--- a/src/plugins/cppeditor/cppplugin.cpp
+++ b/src/plugins/cppeditor/cppplugin.cpp
@@ -38,6 +38,7 @@
#include "cppoutline.h"
#include "cppquickfixcollector.h"
#include "cpptypehierarchy.h"
+#include "cppsnippeteditordecorator.h"
#include <coreplugin/icore.h>
#include <coreplugin/coreconstants.h>
@@ -211,6 +212,7 @@ bool CppPlugin::initialize(const QStringList & /*arguments*/, QString *errorMess
addAutoReleasedObject(new CppHoverHandler);
addAutoReleasedObject(new CppOutlineWidgetFactory);
addAutoReleasedObject(new CppTypeHierarchyFactory);
+ addAutoReleasedObject(new CppSnippetEditorDecorator);
m_quickFixCollector = new CppQuickFixCollector;
addAutoReleasedObject(m_quickFixCollector);
diff --git a/src/plugins/cppeditor/cppsnippeteditordecorator.cpp b/src/plugins/cppeditor/cppsnippeteditordecorator.cpp
new file mode 100644
index 0000000000..2cf2936a02
--- /dev/null
+++ b/src/plugins/cppeditor/cppsnippeteditordecorator.cpp
@@ -0,0 +1,64 @@
+/**************************************************************************
+**
+** 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 "cppsnippeteditordecorator.h"
+#include "cpphighlighter.h"
+#include "cppeditor.h"
+
+#include <texteditor/texteditorsettings.h>
+#include <texteditor/fontsettings.h>
+#include <texteditor/texteditorconstants.h>
+#include <texteditor/snippets/snippeteditor.h>
+
+using namespace CppEditor;
+using namespace Internal;
+
+CppSnippetEditorDecorator::CppSnippetEditorDecorator() :
+ TextEditor::ISnippetEditorDecorator()
+{}
+
+CppSnippetEditorDecorator::~CppSnippetEditorDecorator()
+{}
+
+bool CppSnippetEditorDecorator::supports(TextEditor::Snippet::Group group) const
+{
+ if (group == TextEditor::Snippet::Cpp)
+ return true;
+ return false;
+}
+
+void CppSnippetEditorDecorator::apply(TextEditor::SnippetEditor *editor) const
+{
+ CppHighlighter *highlighter = new CppHighlighter;
+ const TextEditor::FontSettings &fs = TextEditor::TextEditorSettings::instance()->fontSettings();
+ const QVector<QTextCharFormat> &formats =
+ fs.toTextCharFormats(CPPEditor::highlighterFormatCategories());
+ highlighter->setFormats(formats.constBegin(), formats.constEnd());
+ editor->installSyntaxHighlighter(highlighter);
+}
diff --git a/src/plugins/cppeditor/cppsnippeteditordecorator.h b/src/plugins/cppeditor/cppsnippeteditordecorator.h
new file mode 100644
index 0000000000..605099e19c
--- /dev/null
+++ b/src/plugins/cppeditor/cppsnippeteditordecorator.h
@@ -0,0 +1,52 @@
+/**************************************************************************
+**
+** 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 CPPSNIPPETEDITORDECORATOR_H
+#define CPPSNIPPETEDITORDECORATOR_H
+
+#include <texteditor/snippets/isnippeteditordecorator.h>
+
+namespace CppEditor {
+namespace Internal {
+
+class CppSnippetEditorDecorator : public TextEditor::ISnippetEditorDecorator
+{
+public:
+ CppSnippetEditorDecorator();
+ virtual ~CppSnippetEditorDecorator();
+
+public:
+ virtual bool supports(TextEditor::Snippet::Group group) const;
+ virtual void apply(TextEditor::SnippetEditor *editor) const;
+};
+
+} // Internal
+} // CppEditor
+
+#endif // CPPSNIPPETEDITORDECORATOR_H
diff --git a/src/plugins/cpptools/cppcodecompletion.cpp b/src/plugins/cpptools/cppcodecompletion.cpp
index 81636c71b6..479de433d1 100644
--- a/src/plugins/cpptools/cppcodecompletion.cpp
+++ b/src/plugins/cpptools/cppcodecompletion.cpp
@@ -59,6 +59,7 @@
#include <texteditor/itexteditor.h>
#include <texteditor/itexteditable.h>
#include <texteditor/basetexteditor.h>
+#include <texteditor/snippets/snippet.h>
#include <projectexplorer/projectexplorer.h>
#include <utils/faketooltip.h>
@@ -462,7 +463,8 @@ CppCodeCompletion::CppCodeCompletion(CppModelManager *manager)
m_automaticCompletion(false),
m_completionOperator(T_EOF_SYMBOL),
m_objcEnabled(true),
- m_snippetsParser(Core::ICore::instance()->resourcePath() + QLatin1String("/snippets/cpp.xml"))
+ m_snippetProvider(TextEditor::Snippet::Cpp,
+ QIcon(QLatin1String(":/texteditor/images/snippet.png")))
{
}
@@ -751,12 +753,12 @@ void CppCodeCompletion::completeObjCMsgSend(ClassOrNamespace *binding,
Symbol *arg = method->argumentAt(i);
text += selectorName->nameAt(i)->identifier()->chars();
text += QLatin1Char(':');
- text += QChar::ObjectReplacementCharacter;
+ text += TextEditor::Snippet::kVariableDelimiter;
text += QLatin1Char('(');
text += oo(arg->type());
text += QLatin1Char(')');
text += oo(arg->name());
- text += QChar::ObjectReplacementCharacter;
+ text += TextEditor::Snippet::kVariableDelimiter;
}
} else {
text = selectorName->identifier()->chars();
@@ -2058,8 +2060,7 @@ bool CppCodeCompletion::objcKeywordsWanted() const
void CppCodeCompletion::addSnippets()
{
- static const QIcon icon(QLatin1String(":/texteditor/images/snippet.png"));
- m_completions.append(m_snippetsParser.execute(this, icon));
+ m_completions.append(m_snippetProvider.getSnippets(this));
}
#include "cppcodecompletion.moc"
diff --git a/src/plugins/cpptools/cppcodecompletion.h b/src/plugins/cpptools/cppcodecompletion.h
index 49317eb096..483bf3358b 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/snippetsparser.h>
+#include <texteditor/snippets/snippetprovider.h>
#include <QtCore/QObject>
#include <QtCore/QPointer>
@@ -153,7 +153,7 @@ private:
unsigned m_completionOperator;
bool m_objcEnabled;
- TextEditor::SnippetsParser m_snippetsParser;
+ TextEditor::SnippetProvider m_snippetProvider;
CPlusPlus::Icons m_icons;
CPlusPlus::Overview overview;
diff --git a/src/plugins/qmljseditor/qmljscodecompletion.cpp b/src/plugins/qmljseditor/qmljscodecompletion.cpp
index 68e0ab28f6..8dc714dc80 100644
--- a/src/plugins/qmljseditor/qmljscodecompletion.cpp
+++ b/src/plugins/qmljseditor/qmljscodecompletion.cpp
@@ -487,7 +487,7 @@ CodeCompletion::CodeCompletion(ModelManagerInterface *modelManager, QObject *par
m_editor(0),
m_startPosition(0),
m_restartCompletion(false),
- m_snippetsParser(Core::ICore::instance()->resourcePath() + QLatin1String("/snippets/qml.xml"))
+ m_snippetProvider(TextEditor::Snippet::Qml, iconForColor(Qt::red), SnippetOrder)
{
Q_ASSERT(modelManager);
}
@@ -952,7 +952,7 @@ int CodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
}
if (isQmlFile && (completionOperator.isNull() || completionOperator.isSpace() || isDelimiter(completionOperator))) {
- m_completions.append(m_snippetsParser.execute(this, iconForColor(Qt::red), SnippetOrder));
+ m_completions.append(m_snippetProvider.getSnippets(this));
}
if (! m_completions.isEmpty())
diff --git a/src/plugins/qmljseditor/qmljscodecompletion.h b/src/plugins/qmljseditor/qmljscodecompletion.h
index 6aced15ca6..d3448c4c72 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/snippetsparser.h>
+#include <texteditor/snippets/snippetprovider.h>
#include <QtCore/QDateTime>
#include <QtCore/QPointer>
@@ -97,7 +97,7 @@ private:
TextEditor::ITextEditable *m_editor;
int m_startPosition;
bool m_restartCompletion;
- TextEditor::SnippetsParser m_snippetsParser;
+ TextEditor::SnippetProvider m_snippetProvider;
QList<TextEditor::CompletionItem> m_completions;
QPointer<FunctionArgumentWidget> m_functionArgumentWidget;
};
diff --git a/src/plugins/qmljseditor/qmljseditor.cpp b/src/plugins/qmljseditor/qmljseditor.cpp
index d7e3d2add5..ba9392b336 100644
--- a/src/plugins/qmljseditor/qmljseditor.cpp
+++ b/src/plugins/qmljseditor/qmljseditor.cpp
@@ -1187,27 +1187,7 @@ void QmlJSTextEditor::setFontSettings(const TextEditor::FontSettings &fs)
if (!highlighter)
return;
- /*
- NumberFormat,
- StringFormat,
- TypeFormat,
- KeywordFormat,
- LabelFormat,
- CommentFormat,
- VisualWhitespace,
- */
- static QVector<QString> categories;
- if (categories.isEmpty()) {
- categories << QLatin1String(TextEditor::Constants::C_NUMBER)
- << QLatin1String(TextEditor::Constants::C_STRING)
- << QLatin1String(TextEditor::Constants::C_TYPE)
- << QLatin1String(TextEditor::Constants::C_KEYWORD)
- << QLatin1String(TextEditor::Constants::C_FIELD)
- << QLatin1String(TextEditor::Constants::C_COMMENT)
- << QLatin1String(TextEditor::Constants::C_VISUAL_WHITESPACE);
- }
-
- highlighter->setFormats(fs.toTextCharFormats(categories));
+ highlighter->setFormats(fs.toTextCharFormats(highlighterFormatCategories()));
highlighter->rehighlight();
m_occurrencesFormat = fs.toTextCharFormat(QLatin1String(TextEditor::Constants::C_OCCURRENCES));
@@ -1571,6 +1551,30 @@ bool QmlJSTextEditor::hideContextPane()
return b;
}
+QVector<QString> QmlJSTextEditor::highlighterFormatCategories()
+{
+ /*
+ NumberFormat,
+ StringFormat,
+ TypeFormat,
+ KeywordFormat,
+ LabelFormat,
+ CommentFormat,
+ VisualWhitespace,
+ */
+ static QVector<QString> categories;
+ if (categories.isEmpty()) {
+ categories << QLatin1String(TextEditor::Constants::C_NUMBER)
+ << QLatin1String(TextEditor::Constants::C_STRING)
+ << QLatin1String(TextEditor::Constants::C_TYPE)
+ << QLatin1String(TextEditor::Constants::C_KEYWORD)
+ << QLatin1String(TextEditor::Constants::C_FIELD)
+ << QLatin1String(TextEditor::Constants::C_COMMENT)
+ << QLatin1String(TextEditor::Constants::C_VISUAL_WHITESPACE);
+ }
+ return categories;
+}
+
SemanticHighlighterSource QmlJSTextEditor::currentSource(bool force)
{
int line = 0, column = 0;
diff --git a/src/plugins/qmljseditor/qmljseditor.h b/src/plugins/qmljseditor/qmljseditor.h
index f40ce7e652..d0ac90101a 100644
--- a/src/plugins/qmljseditor/qmljseditor.h
+++ b/src/plugins/qmljseditor/qmljseditor.h
@@ -155,6 +155,8 @@ public:
void renameId(const QString &oldId, const QString &newId);
+ static QVector<QString> highlighterFormatCategories();
+
public slots:
void followSymbolUnderCursor();
void findUsages();
diff --git a/src/plugins/qmljseditor/qmljseditor.pro b/src/plugins/qmljseditor/qmljseditor.pro
index c237d122c6..24e6caf03d 100644
--- a/src/plugins/qmljseditor/qmljseditor.pro
+++ b/src/plugins/qmljseditor/qmljseditor.pro
@@ -34,7 +34,8 @@ HEADERS += \
qmljssemantichighlighter.h \
qmljsindenter.h \
qmljsautocompleter.h \
- jsfilewizard.h
+ jsfilewizard.h \
+ qmljssnippeteditordecorator.h
SOURCES += \
qmljscodecompletion.cpp \
@@ -62,7 +63,8 @@ SOURCES += \
qmljssemantichighlighter.cpp \
qmljsindenter.cpp \
qmljsautocompleter.cpp \
- jsfilewizard.cpp
+ jsfilewizard.cpp \
+ qmljssnippeteditordecorator.cpp
RESOURCES += qmljseditor.qrc
OTHER_FILES += QmlJSEditor.mimetypes.xml
diff --git a/src/plugins/qmljseditor/qmljseditorplugin.cpp b/src/plugins/qmljseditor/qmljseditorplugin.cpp
index e03b1370a5..1d394e6201 100644
--- a/src/plugins/qmljseditor/qmljseditorplugin.cpp
+++ b/src/plugins/qmljseditor/qmljseditorplugin.cpp
@@ -39,6 +39,7 @@
#include "qmljsoutline.h"
#include "qmljspreviewrunner.h"
#include "qmljsquickfix.h"
+#include "qmljssnippeteditordecorator.h"
#include "qmltaskmanager.h"
#include "quicktoolbar.h"
#include "quicktoolbarsettingspage.h"
@@ -128,6 +129,7 @@ bool QmlJSEditorPlugin::initialize(const QStringList & /*arguments*/, QString *e
return false;
m_modelManager = QmlJS::ModelManagerInterface::instance();
+ addAutoReleasedObject(new QmlJSSnippetEditorDecorator);
Core::Context context(QmlJSEditor::Constants::C_QMLJSEDITOR_ID);
diff --git a/src/plugins/qmljseditor/qmljssnippeteditordecorator.cpp b/src/plugins/qmljseditor/qmljssnippeteditordecorator.cpp
new file mode 100644
index 0000000000..f2ca0b07ca
--- /dev/null
+++ b/src/plugins/qmljseditor/qmljssnippeteditordecorator.cpp
@@ -0,0 +1,62 @@
+/**************************************************************************
+**
+** 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 "qmljssnippeteditordecorator.h"
+#include "qmljshighlighter.h"
+#include "qmljseditor.h"
+
+#include <texteditor/texteditorsettings.h>
+#include <texteditor/fontsettings.h>
+#include <texteditor/texteditorconstants.h>
+#include <texteditor/snippets/snippeteditor.h>
+
+using namespace QmlJSEditor;
+using namespace Internal;
+
+QmlJSSnippetEditorDecorator::QmlJSSnippetEditorDecorator() :
+ TextEditor::ISnippetEditorDecorator()
+{}
+
+QmlJSSnippetEditorDecorator::~QmlJSSnippetEditorDecorator()
+{}
+
+bool QmlJSSnippetEditorDecorator::supports(TextEditor::Snippet::Group group) const
+{
+ if (group == TextEditor::Snippet::Qml)
+ return true;
+ return false;
+}
+
+void QmlJSSnippetEditorDecorator::apply(TextEditor::SnippetEditor *editor) const
+{
+ Highlighter *highlighter = new Highlighter;
+ const TextEditor::FontSettings &fs = TextEditor::TextEditorSettings::instance()->fontSettings();
+ highlighter->setFormats(fs.toTextCharFormats(QmlJSTextEditor::highlighterFormatCategories()));
+ editor->installSyntaxHighlighter(highlighter);
+}
diff --git a/src/plugins/qmljseditor/qmljssnippeteditordecorator.h b/src/plugins/qmljseditor/qmljssnippeteditordecorator.h
new file mode 100644
index 0000000000..d22a478564
--- /dev/null
+++ b/src/plugins/qmljseditor/qmljssnippeteditordecorator.h
@@ -0,0 +1,52 @@
+/**************************************************************************
+**
+** 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 QMLJSSNIPPETEDITORDECORATOR_H
+#define QMLJSSNIPPETEDITORDECORATOR_H
+
+#include <texteditor/snippets/isnippeteditordecorator.h>
+
+namespace QmlJSEditor {
+namespace Internal {
+
+class QmlJSSnippetEditorDecorator : public TextEditor::ISnippetEditorDecorator
+{
+public:
+ QmlJSSnippetEditorDecorator();
+ virtual ~QmlJSSnippetEditorDecorator();
+
+public:
+ virtual bool supports(TextEditor::Snippet::Group group) const;
+ virtual void apply(TextEditor::SnippetEditor *editor) const;
+};
+
+} // Internal
+} // QmlJSEditor
+
+#endif // QMLJSSNIPPETEDITORDECORATOR_H
diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp
index 7fcea6ccda..d429277205 100644
--- a/src/plugins/texteditor/basetexteditor.cpp
+++ b/src/plugins/texteditor/basetexteditor.cpp
@@ -44,6 +44,7 @@
#include "tipcontents.h"
#include "indenter.h"
#include "autocompleter.h"
+#include "snippet.h"
#include <aggregation/aggregate.h>
#include <coreplugin/actionmanager/actionmanager.h>
@@ -1848,7 +1849,7 @@ void BaseTextEditor::_q_requestAutoCompletion()
void BaseTextEditor::insertCodeSnippet(const QTextCursor &cursor_arg, const QString &snippet)
{
- if ((snippet.count('$') % 2) != 0) {
+ if ((snippet.count(Snippet::kVariableDelimiter) % 2) != 0) {
qWarning() << "invalid snippet";
return;
}
@@ -1864,21 +1865,21 @@ void BaseTextEditor::insertCodeSnippet(const QTextCursor &cursor_arg, const QStr
QMap<int, int> positions;
while (pos < snippet.size()) {
- if (snippet.at(pos) != QChar::ObjectReplacementCharacter) {
+ if (snippet.at(pos) != Snippet::kVariableDelimiter) {
const int start = pos;
do { ++pos; }
- while (pos < snippet.size() && snippet.at(pos) != QChar::ObjectReplacementCharacter);
+ while (pos < snippet.size() && snippet.at(pos) != Snippet::kVariableDelimiter);
cursor.insertText(snippet.mid(start, pos - start));
} else {
// the start of a place holder.
const int start = ++pos;
for (; pos < snippet.size(); ++pos) {
- if (snippet.at(pos) == QChar::ObjectReplacementCharacter)
+ if (snippet.at(pos) == Snippet::kVariableDelimiter)
break;
}
Q_ASSERT(pos < snippet.size());
- Q_ASSERT(snippet.at(pos) == QChar::ObjectReplacementCharacter);
+ Q_ASSERT(snippet.at(pos) == Snippet::kVariableDelimiter);
const QString textToInsert = snippet.mid(start, pos - start);
diff --git a/src/plugins/texteditor/snippets/isnippeteditordecorator.cpp b/src/plugins/texteditor/snippets/isnippeteditordecorator.cpp
new file mode 100644
index 0000000000..5c94c6ec65
--- /dev/null
+++ b/src/plugins/texteditor/snippets/isnippeteditordecorator.cpp
@@ -0,0 +1,38 @@
+/**************************************************************************
+**
+** 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 "isnippeteditordecorator.h"
+
+using namespace TextEditor;
+
+ISnippetEditorDecorator::ISnippetEditorDecorator() : QObject()
+{}
+
+ISnippetEditorDecorator::~ISnippetEditorDecorator()
+{}
diff --git a/src/plugins/texteditor/snippets/isnippeteditordecorator.h b/src/plugins/texteditor/snippets/isnippeteditordecorator.h
new file mode 100644
index 0000000000..945461f308
--- /dev/null
+++ b/src/plugins/texteditor/snippets/isnippeteditordecorator.h
@@ -0,0 +1,58 @@
+/**************************************************************************
+**
+** 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 ISNIPPETEDITORDECORATOR_H
+#define ISNIPPETEDITORDECORATOR_H
+
+#include "snippet.h"
+
+#include <texteditor/texteditor_global.h>
+
+#include <QtCore/QObject>
+
+namespace TextEditor {
+
+class SnippetEditor;
+
+class TEXTEDITOR_EXPORT ISnippetEditorDecorator : public QObject
+{
+ Q_OBJECT
+public:
+ virtual ~ISnippetEditorDecorator();
+
+ virtual bool supports(Snippet::Group group) const = 0;
+ virtual void apply(SnippetEditor *editor) const = 0;
+
+protected:
+ ISnippetEditorDecorator();
+};
+
+} // TextEditor
+
+#endif // ISNIPPETEDITORDECORATOR_H
diff --git a/src/plugins/texteditor/snippets/reuse.h b/src/plugins/texteditor/snippets/reuse.h
new file mode 100644
index 0000000000..5ab7b403ec
--- /dev/null
+++ b/src/plugins/texteditor/snippets/reuse.h
@@ -0,0 +1,85 @@
+/**************************************************************************
+**
+** 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 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)
+ return true;
+ return false;
+}
+
+inline QString fromBool(bool b)
+{
+ if (b)
+ return kTrue;
+ return kFalse;
+}
+
+} // Internal
+} // TextEditor
+
+#endif // REUSE_H
diff --git a/src/plugins/texteditor/snippets/snippet.cpp b/src/plugins/texteditor/snippets/snippet.cpp
new file mode 100644
index 0000000000..b00056110c
--- /dev/null
+++ b/src/plugins/texteditor/snippets/snippet.cpp
@@ -0,0 +1,148 @@
+/**************************************************************************
+**
+** 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 "snippet.h"
+
+#include <QtCore/QLatin1Char>
+#include <QtCore/QLatin1String>
+#include <QtGui/QTextDocument>
+
+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 &Snippet::id() const
+{
+ return m_id;
+}
+
+bool Snippet::isBuiltIn() const
+{
+ return !m_id.isEmpty();
+}
+
+void Snippet::setTrigger(const QString &trigger)
+{
+ m_trigger = trigger;
+}
+
+const QString &Snippet::trigger() const
+{
+ return m_trigger;
+}
+
+void Snippet::setContent(const QString &content)
+{
+ m_content = content;
+}
+
+const QString &Snippet::content() const
+{
+ return m_content;
+}
+
+void Snippet::setComplement(const QString &complement)
+{
+ m_complement = complement;
+}
+
+const QString &Snippet::complement() const
+{
+ return m_complement;
+}
+
+void Snippet::setIsRemoved(bool removed)
+{
+ m_isRemoved = removed;
+}
+
+bool Snippet::isRemoved() const
+{
+ return m_isRemoved;
+}
+
+void Snippet::setIsModified(bool modified)
+{
+ m_isModified = modified;
+}
+
+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');
+ static const QLatin1Char kSpace(' ');
+ static const QLatin1String kBr("<br>");
+ static const QLatin1String kNbsp("&nbsp;");
+ static const QLatin1String kNoBr("<nobr>");
+ static const QLatin1String kOpenBold("<b>");
+ static const QLatin1String kCloseBold("</b>");
+ static const QLatin1String kEllipsis("...");
+
+ QString escapedContent(Qt::escape(m_content));
+ escapedContent.replace(kNewLine, kBr);
+ escapedContent.replace(kSpace, kNbsp);
+
+ QString tip(kNoBr);
+ int count = 0;
+ for (int i = 0; i < escapedContent.count(); ++i) {
+ if (escapedContent.at(i) != kVariableDelimiter) {
+ tip += escapedContent.at(i);
+ continue;
+ }
+ if (++count % 2) {
+ tip += kOpenBold;
+ } else {
+ if (escapedContent.at(i-1) == kVariableDelimiter)
+ tip += kEllipsis;
+ tip += kCloseBold;
+ }
+ }
+
+ return tip;
+}
diff --git a/src/plugins/texteditor/snippets/snippet.h b/src/plugins/texteditor/snippets/snippet.h
new file mode 100644
index 0000000000..d9d6c42245
--- /dev/null
+++ b/src/plugins/texteditor/snippets/snippet.h
@@ -0,0 +1,98 @@
+/**************************************************************************
+**
+** 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 SNIPPET_H
+#define SNIPPET_H
+
+#include <texteditor/texteditor_global.h>
+
+#include <QtCore/QChar>
+#include <QtCore/QString>
+
+namespace TextEditor {
+
+class TEXTEDITOR_EXPORT Snippet
+{
+public:
+ Snippet(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;
+
+ bool isBuiltIn() const;
+
+ void setTrigger(const QString &trigger);
+ const QString &trigger() const;
+
+ void setContent(const QString &content);
+ const QString &content() const;
+
+ void setComplement(const QString &complement);
+ const QString &complement() const;
+
+ void setIsRemoved(bool removed);
+ bool isRemoved() const;
+
+ void setIsModified(bool modified);
+ bool isModified() const;
+
+ void setGroup(Group group);
+ Group group() const;
+
+ QString generateTip() const;
+
+ static const QChar kVariableDelimiter;
+
+private:
+ bool m_isRemoved;
+ bool m_isModified;
+ QString m_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/snippeteditor.cpp b/src/plugins/texteditor/snippets/snippeteditor.cpp
new file mode 100644
index 0000000000..cf40373bfe
--- /dev/null
+++ b/src/plugins/texteditor/snippets/snippeteditor.cpp
@@ -0,0 +1,92 @@
+/**************************************************************************
+**
+** 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 "snippeteditor.h"
+
+#include <texteditor/basetextdocument.h>
+#include <texteditor/texteditorconstants.h>
+#include <texteditor/normalindenter.h>
+
+#include <QtGui/QTextDocument>
+
+using namespace TextEditor;
+
+SnippetEditorEditable::SnippetEditorEditable(SnippetEditor *editor) :
+ BaseTextEditorEditable(editor),
+ m_context(Constants::SNIPPET_EDITOR_ID, Constants::C_TEXTEDITOR)
+{}
+
+SnippetEditorEditable::~SnippetEditorEditable()
+{}
+
+QString SnippetEditorEditable::id() const
+{
+ return Constants::SNIPPET_EDITOR_ID;
+}
+
+SnippetEditor::SnippetEditor(QWidget *parent) :
+ BaseTextEditor(parent),
+ m_indenter(new NormalIndenter)
+{
+ setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
+
+ setHighlightCurrentLine(false);
+ setLineNumbersVisible(false);
+}
+
+SnippetEditor::~SnippetEditor()
+{}
+
+void SnippetEditor::installSyntaxHighlighter(TextEditor::SyntaxHighlighter *highlighter)
+{
+ baseTextDocument()->setSyntaxHighlighter(highlighter);
+}
+
+void SnippetEditor::installIndenter(Indenter *indenter)
+{
+ m_indenter.reset(indenter);
+}
+
+void SnippetEditor::focusOutEvent(QFocusEvent *event)
+{
+ Q_UNUSED(event);
+ if (document()->isModified())
+ emit snippetContentChanged();
+}
+
+BaseTextEditorEditable *SnippetEditor::createEditableInterface()
+{
+ return new SnippetEditorEditable(this);
+}
+
+void SnippetEditor::indentBlock(QTextDocument *doc, QTextBlock block, QChar typedChar)
+{
+ if (!m_indenter.isNull())
+ m_indenter->indentBlock(doc, block, typedChar, tabSettings());
+}
diff --git a/src/plugins/texteditor/snippets/snippeteditor.h b/src/plugins/texteditor/snippets/snippeteditor.h
new file mode 100644
index 0000000000..a4273f5e66
--- /dev/null
+++ b/src/plugins/texteditor/snippets/snippeteditor.h
@@ -0,0 +1,92 @@
+/**************************************************************************
+**
+** 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 SNIPPETEDITOR_H
+#define SNIPPETEDITOR_H
+
+#include <texteditor/texteditor_global.h>
+#include <texteditor/basetexteditor.h>
+
+#include <QtCore/QScopedPointer>
+
+QT_FORWARD_DECLARE_CLASS(QFocusEvent)
+
+namespace TextEditor {
+
+class SnippetEditor;
+class SyntaxHighlighter;
+class Indenter;
+
+// Should not be necessary in this case, but the base text editor assumes a
+// valid editable interface.
+class TEXTEDITOR_EXPORT SnippetEditorEditable : public BaseTextEditorEditable
+{
+ Q_OBJECT
+public:
+ SnippetEditorEditable(SnippetEditor *editor);
+ virtual ~SnippetEditorEditable();
+
+ Core::Context context() const { return m_context; }
+
+ bool duplicateSupported() const { return false; }
+ Core::IEditor *duplicate(QWidget * /* parent */ ) { return 0; }
+ bool isTemporary() const { return false; }
+ virtual QString id() const;
+
+private:
+ const Core::Context m_context;
+};
+
+class TEXTEDITOR_EXPORT SnippetEditor : public BaseTextEditor
+{
+ Q_OBJECT
+public:
+ SnippetEditor(QWidget *parent);
+ virtual ~SnippetEditor();
+
+ void installSyntaxHighlighter(SyntaxHighlighter *highlighter);
+ void installIndenter(Indenter *indenter);
+
+signals:
+ void snippetContentChanged();
+
+protected:
+ virtual void focusOutEvent(QFocusEvent *event);
+
+ virtual int extraAreaWidth(int * /* markWidthPtr */ = 0) const { return 0; }
+ virtual BaseTextEditorEditable *createEditableInterface();
+ virtual void indentBlock(QTextDocument *doc, QTextBlock block, QChar typedChar);
+
+private:
+ QScopedPointer<Indenter> m_indenter;
+};
+
+} // TextEditor
+
+#endif // SNIPPETEDITOR_H
diff --git a/src/plugins/texteditor/snippets/snippetprovider.cpp b/src/plugins/texteditor/snippets/snippetprovider.cpp
new file mode 100644
index 0000000000..26361d1989
--- /dev/null
+++ b/src/plugins/texteditor/snippets/snippetprovider.cpp
@@ -0,0 +1,62 @@
+/**************************************************************************
+**
+** 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 "snippetprovider.h"
+#include "snippetsmanager.h"
+#include "snippetscollection.h"
+
+using namespace TextEditor;
+using namespace Internal;
+
+SnippetProvider::SnippetProvider(Snippet::Group group, const QIcon &icon, int order) :
+ m_group(group), m_icon(icon), m_order(order)
+{}
+
+SnippetProvider::~SnippetProvider()
+{}
+
+QList<CompletionItem> SnippetProvider::getSnippets(ICompletionCollector *collector) const
+{
+ QList<CompletionItem> completionItems;
+ QSharedPointer<SnippetsCollection> collection =
+ SnippetsManager::instance()->snippetsCollection();
+ const int size = collection->totalActiveSnippets(m_group);
+ for (int i = 0; i < size; ++i) {
+ const Snippet &snippet = collection->snippet(i, m_group);
+ CompletionItem item(collector);
+ item.text = snippet.trigger() + QLatin1Char(' ') + snippet.complement();
+ item.data = snippet.content();
+ item.details = snippet.generateTip();
+ item.icon = m_icon;
+ item.order = m_order;
+
+ completionItems.append(item);
+ }
+ return completionItems;
+}
diff --git a/src/plugins/texteditor/snippetsparser.h b/src/plugins/texteditor/snippets/snippetprovider.h
index 90cb6c18cf..486ebcf165 100644
--- a/src/plugins/texteditor/snippetsparser.h
+++ b/src/plugins/texteditor/snippets/snippetprovider.h
@@ -27,34 +27,33 @@
**
**************************************************************************/
-#ifndef SNIPPETSPARSER_H
-#define SNIPPETSPARSER_H
+#ifndef SNIPPETPROVIDER_H
+#define SNIPPETPROVIDER_H
-#include "texteditor_global.h"
-#include "icompletioncollector.h"
+#include "snippet.h"
+
+#include <texteditor/texteditor_global.h>
+#include <texteditor/icompletioncollector.h>
-#include <QtCore/QString>
#include <QtCore/QList>
-#include <QtCore/QDateTime>
#include <QtGui/QIcon>
namespace TextEditor {
-class TEXTEDITOR_EXPORT SnippetsParser
+class TEXTEDITOR_EXPORT SnippetProvider
{
public:
- SnippetsParser(const QString &fileName);
+ SnippetProvider(Snippet::Group group, const QIcon &icon, int order = 0);
+ ~SnippetProvider();
- const QList<CompletionItem> &execute(ICompletionCollector *collector,
- const QIcon &icon,
- int order = 0);
+ QList<CompletionItem> getSnippets(ICompletionCollector *collector) const;
private:
- QString m_fileName;
- QDateTime m_lastTrackedFileChange;
- QList<CompletionItem> m_snippets;
+ Snippet::Group m_group;
+ QIcon m_icon;
+ int m_order;
};
-} // namespace TextEditor
+} // TextEditor
-#endif // SNIPPETSPARSER_H
+#endif // SNIPPETPROVIDER_H
diff --git a/src/plugins/texteditor/snippets/snippets.xml b/src/plugins/texteditor/snippets/snippets.xml
new file mode 100644
index 0000000000..0d511a8d41
--- /dev/null
+++ b/src/plugins/texteditor/snippets/snippets.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<snippets>
+<snippet group="C++" trigger="class" id="genericclass">class $name$
+{
+public:
+ $name$() {}
+};</snippet>
+<snippet group="C++" trigger="class" id="qobjectclass" complement="derived from QObject">class $name$ : public QObject
+{
+ Q_OBJECT
+public:
+ $name$() {}
+ virtual ~$name$() {}
+};</snippet>
+<snippet group="C++" trigger="class" id="qwidgetclass" complement="derived from QWidget">class $name$ : public QWidget
+{
+ Q_OBJECT
+public:
+ $name$() {}
+ virtual ~$name$() {}
+};</snippet>
+<snippet group="C++" trigger="class" id="classtemplate" complement="template">template &lt;typename $T$&gt;
+class $name$
+{
+public:
+ $name$() {}
+};</snippet>
+<snippet group="C++" trigger="do" id="do">do {
+
+} while ($condition$);</snippet>
+<snippet group="C++" trigger="else" id="else" >else {
+
+}</snippet>
+<snippet group="C++" trigger="else" id="elsewithif" complement="with if">else if ($condition$) {
+
+}</snippet>
+<snippet group="C++" trigger="for" id="for">for (int $var$ = 0; $var$ &lt; $total$; ++$var$) {
+
+}</snippet>
+<snippet group="C++" trigger="foreach" id="foreach">foreach ($var$, $container$) {
+
+}</snippet>
+<snippet group="C++" trigger="if" id="if">if ($condition$) {
+
+}</snippet>
+<snippet group="C++" trigger="if" id="ifandelse" complement="and else">if ($condition$) {
+
+} else {
+
+}</snippet>
+<snippet group="C++" trigger="namespace" id="namespace">namespace $name$ {
+
+}</snippet>
+<snippet group="C++" trigger="try" id="trycatch" complement="and catch">try {
+
+} catch (...) {
+
+}</snippet>
+<snippet group="C++" trigger="using" id="usingnamespace" complement="namespace">using namespace $name$;</snippet>
+<snippet group="C++" trigger="while" id="while">while ($condition$) {
+
+}</snippet>
+<snippet group="QML" trigger="property" id="property">property $type$ $name$: $value$</snippet>
+<snippet group="QML" trigger="Item" id="item">Item {
+ id: $name$
+}</snippet>
+<snippet group="QML" trigger="BorderImage" id="borderimage">BorderImage {
+ id: $name$
+ source: "$file$"
+ width: $100$; height: $100$
+ border.left: $5$; border.top: $5$
+ border.right: $5$; border.bottom: $5$
+}</snippet>
+<snippet group="QML" trigger="Image" id="image">Image {
+ id: $name$
+ source: "$file$"
+}</snippet>
+<snippet group="QML" trigger="Text" id="text">Text {
+ id: $name$
+ text: "$text$"
+}</snippet>
+<snippet group="QML" trigger="states" id="states">states: [
+ State {
+ name: "$name$"
+ PropertyChanges {
+ target: $name$
+ $$
+ }
+ }
+]</snippet>
+<snippet group="QML" trigger="State" id="state">State {
+ name: "$name$"
+ PropertyChanges {
+ target: $name$
+ $$
+ }
+}</snippet>
+<snippet group="QML" trigger="transitions" id="transitions">transitions: [
+ Transition {
+ from: "$name$"
+ to: "$name$"
+ $$
+ }
+]</snippet>
+<snippet group="QML" trigger="Transition" id="transition">Transition {
+ from: "$name$"
+ to: "$name$"
+ $$
+}</snippet>
+<snippet group="QML" trigger="PropertyChanges" id="propertychanges">PropertyChanges {
+ target: $name$
+ $$
+}</snippet>
+<snippet group="QML" trigger="NumberAnimation" id="numberanimationwithtargets" complement="with targets">NumberAnimation { targets: [$name$]; properties: "$name$"; duration: $200$ }</snippet>
+<snippet group="QML" trigger="NumberAnimation" id="numberanimationwithtarget" complement="with target">NumberAnimation { target: $name$; property: "$name$"; to: $value$; duration: $200$ }</snippet>
+<snippet group="QML" trigger="PropertyAction" id="propertyactionwithtargets" complement="with targets">PropertyAction { targets: [$name$]; properties: "$name$" }</snippet>
+<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>
+</snippets>
diff --git a/src/plugins/texteditor/snippets/snippetscollection.cpp b/src/plugins/texteditor/snippets/snippetscollection.cpp
new file mode 100644
index 0000000000..a2f7320cf0
--- /dev/null
+++ b/src/plugins/texteditor/snippets/snippetscollection.cpp
@@ -0,0 +1,212 @@
+/**************************************************************************
+**
+** 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 "snippetscollection.h"
+
+#include <QtAlgorithms>
+
+#include <iterator>
+#include <algorithm>
+
+using namespace TextEditor;
+using namespace Internal;
+
+namespace {
+
+struct SnippetComp
+{
+ bool operator()(const Snippet &a, const Snippet &b) const
+ {
+ const int comp = a.trigger().toLower().localeAwareCompare(b.trigger().toLower());
+ if (comp < 0)
+ return true;
+ else if (comp == 0 &&
+ a.complement().toLower().localeAwareCompare(b.complement().toLower()) < 0)
+ return true;
+ return false;
+ }
+};
+SnippetComp snippetComp;
+
+struct RemovedSnippetPred
+{
+ bool operator()(const Snippet &s) const
+ {
+ return s.isRemoved();
+ }
+};
+RemovedSnippetPred removedSnippetPred;
+
+} // Anonymous
+
+// Hint
+SnippetsCollection::Hint::Hint(int index) : m_index(index)
+{}
+
+SnippetsCollection::Hint::Hint(int index, QList<Snippet>::iterator it) : m_index(index), m_it(it)
+{}
+
+int SnippetsCollection::Hint::index() const
+{
+ return m_index;
+}
+
+// SnippetsCollection
+SnippetsCollection::SnippetsCollection() :
+ m_snippets(Snippet::GroupSize),
+ m_activeSnippetsEnd(Snippet::GroupSize)
+{
+ for (Snippet::Group group = Snippet::Cpp; group < Snippet::GroupSize; ++group)
+ m_activeSnippetsEnd[group] = m_snippets[group].end();
+}
+
+SnippetsCollection::~SnippetsCollection()
+{}
+
+void SnippetsCollection::insertSnippet(const Snippet &snippet, Snippet::Group group)
+{
+ insertSnippet(snippet, group, computeInsertionHint(snippet, group));
+}
+
+void SnippetsCollection::insertSnippet(const Snippet &snippet,
+ Snippet::Group group,
+ const Hint &hint)
+{
+ if (snippet.isBuiltIn() && snippet.isRemoved()) {
+ m_activeSnippetsEnd[group] = m_snippets[group].insert(m_activeSnippetsEnd[group], snippet);
+ } else {
+ m_snippets[group].insert(hint.m_it, snippet);
+ updateActiveSnippetsEnd(group);
+ }
+}
+
+SnippetsCollection::Hint SnippetsCollection::computeInsertionHint(const Snippet &snippet,
+ Snippet::Group group)
+{
+ 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)
+{
+ replaceSnippet(index, snippet, group, computeReplacementHint(index, snippet, group));
+}
+
+void SnippetsCollection::replaceSnippet(int index,
+ const Snippet &snippet,
+ Snippet::Group group,
+ const Hint &hint)
+{
+ Snippet replacement(snippet);
+ if (replacement.isBuiltIn() && !replacement.isModified())
+ replacement.setIsModified(true);
+
+ if (index == hint.index()) {
+ m_snippets[group][index] = replacement;
+ } else {
+ insertSnippet(replacement, group, hint);
+ // Consider whether the row moved up towards the beginning or down towards the end.
+ if (index < hint.index())
+ m_snippets[group].removeAt(index);
+ else
+ m_snippets[group].removeAt(index + 1);
+ updateActiveSnippetsEnd(group);
+ }
+}
+
+SnippetsCollection::Hint SnippetsCollection::computeReplacementHint(int index,
+ const Snippet &snippet,
+ Snippet::Group group)
+{
+ QList<Snippet> &snippets = m_snippets[group];
+ QList<Snippet>::iterator it = qLowerBound(
+ snippets.begin(), m_activeSnippetsEnd.at(group), snippet, snippetComp);
+ int hintIndex = static_cast<int>(std::distance(snippets.begin(), it));
+ if (index < hintIndex - 1)
+ return Hint(hintIndex - 1, it);
+ it = qUpperBound(it, m_activeSnippetsEnd.at(group), snippet, snippetComp);
+ hintIndex = static_cast<int>(std::distance(snippets.begin(), it));
+ if (index > hintIndex)
+ return Hint(hintIndex, it);
+ // Even if the snipet is at a different index it is still inside a valid range.
+ return Hint(index);
+}
+
+void SnippetsCollection::removeSnippet(int index, Snippet::Group group)
+{
+ Snippet snippet(m_snippets.at(group).at(index));
+ m_snippets[group].removeAt(index);
+ if (snippet.isBuiltIn()) {
+ snippet.setIsRemoved(true);
+ m_activeSnippetsEnd[group] = m_snippets[group].insert(m_activeSnippetsEnd[group], snippet);
+ } else {
+ updateActiveSnippetsEnd(group);
+ }
+}
+
+const Snippet &SnippetsCollection::snippet(int index, Snippet::Group group) const
+{
+ return m_snippets.at(group).at(index);
+}
+
+void SnippetsCollection::setSnippetContent(int index, Snippet::Group group, const QString &content)
+{
+ Snippet &snippet = m_snippets[group][index];
+ snippet.setContent(content);
+ if (snippet.isBuiltIn() && !snippet.isModified())
+ snippet.setIsModified(true);
+}
+
+int SnippetsCollection::totalActiveSnippets(Snippet::Group group) const
+{
+ return std::distance<QList<Snippet>::const_iterator>(m_snippets.at(group).begin(),
+ m_activeSnippetsEnd.at(group));
+}
+
+int SnippetsCollection::totalSnippets(Snippet::Group group) const
+{
+ return m_snippets.at(group).size();
+}
+
+void SnippetsCollection::clear()
+{
+ for (Snippet::Group group = Snippet::Cpp; group < Snippet::GroupSize; ++group) {
+ m_snippets[group].clear();
+ m_activeSnippetsEnd[group] = m_snippets[group].end();
+ }
+}
+
+void SnippetsCollection::updateActiveSnippetsEnd(Snippet::Group group)
+{
+ m_activeSnippetsEnd[group] = std::find_if(m_snippets[group].begin(),
+ m_snippets[group].end(),
+ removedSnippetPred);
+}
diff --git a/src/plugins/texteditor/snippets/snippetscollection.h b/src/plugins/texteditor/snippets/snippetscollection.h
new file mode 100644
index 0000000000..88546db929
--- /dev/null
+++ b/src/plugins/texteditor/snippets/snippetscollection.h
@@ -0,0 +1,97 @@
+/**************************************************************************
+**
+** 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 SNIPPETSCOLLECTION_H
+#define SNIPPETSCOLLECTION_H
+
+#include "snippet.h"
+
+#include <QtCore/QVector>
+#include <QtCore/QList>
+
+namespace TextEditor {
+namespace Internal {
+
+// Characteristics of this collection:
+// - Store snippets by group.
+// - Keep groups of snippets sorted.
+// - Allow snippet insertion/replacement based on a hint.
+// - Allow modification of snippet members that are not sorting keys.
+// - Track removed/modified built-in snippets.
+// - Provide fast index access.
+// - Not thread-safe.
+
+class SnippetsCollection
+{
+public:
+ SnippetsCollection();
+ ~SnippetsCollection();
+
+ class Hint
+ {
+ friend class SnippetsCollection;
+ public:
+ int index() const;
+ private:
+ 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 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);
+
+ void removeSnippet(int index, Snippet::Group group);
+
+ void setSnippetContent(int index, Snippet::Group group, const QString &content);
+
+ const Snippet &snippet(int index, Snippet::Group group) const;
+
+ int totalActiveSnippets(Snippet::Group group) const;
+ int totalSnippets(Snippet::Group group) const;
+
+ void clear();
+
+private:
+ void updateActiveSnippetsEnd(Snippet::Group group);
+
+ QVector<QList<Snippet> > m_snippets;
+ QVector<QList<Snippet>::iterator> m_activeSnippetsEnd;
+};
+
+} // Internal
+} // TextEditor
+
+#endif // SNIPPETSCOLLECTION_H
diff --git a/src/plugins/texteditor/snippets/snippetsmanager.cpp b/src/plugins/texteditor/snippets/snippetsmanager.cpp
new file mode 100644
index 0000000000..8c0b9c099c
--- /dev/null
+++ b/src/plugins/texteditor/snippets/snippetsmanager.cpp
@@ -0,0 +1,192 @@
+/**************************************************************************
+**
+** 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 "snippetsmanager.h"
+#include "isnippeteditordecorator.h"
+#include "snippetscollection.h"
+#include "reuse.h"
+
+#include <coreplugin/icore.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>
+
+using namespace TextEditor;
+using namespace Internal;
+
+const QLatin1String SnippetsManager::kSnippet("snippet");
+const QLatin1String SnippetsManager::kSnippets("snippets");
+const QLatin1String SnippetsManager::kTrigger("trigger");
+const QLatin1String SnippetsManager::kId("id");
+const QLatin1String SnippetsManager::kComplement("complement");
+const QLatin1String SnippetsManager::kGroup("group");
+const QLatin1String SnippetsManager::kRemoved("removed");
+const QLatin1String SnippetsManager::kModified("modified");
+
+SnippetsManager::SnippetsManager() :
+ m_collectionLoaded(false),
+ m_collection(new SnippetsCollection),
+ m_builtInSnippetsPath(QLatin1String(":/texteditor/snippets/")),
+ m_userSnippetsPath(Core::ICore::instance()->userResourcePath() + QLatin1String("/snippets/")),
+ m_snippetsFileName(QLatin1String("snippets.xml"))
+{}
+
+SnippetsManager::~SnippetsManager()
+{}
+
+SnippetsManager *SnippetsManager::instance()
+{
+ static SnippetsManager manager;
+ return &manager;
+}
+
+void SnippetsManager::loadSnippetsCollection()
+{
+ QHash<QString, Snippet> activeBuiltInSnippets;
+ const QList<Snippet> &builtInSnippets = readXML(m_builtInSnippetsPath + m_snippetsFileName);
+ foreach (const Snippet &snippet, builtInSnippets)
+ activeBuiltInSnippets.insert(snippet.id(), snippet);
+
+ const QList<Snippet> &userSnippets = readXML(m_userSnippetsPath + m_snippetsFileName);
+ foreach (const Snippet &snippet, userSnippets) {
+ if (snippet.isBuiltIn())
+ // This user snippet overrides the corresponding built-in snippet.
+ activeBuiltInSnippets.remove(snippet.id());
+ m_collection->insertSnippet(snippet, snippet.group());
+ }
+
+ foreach (const Snippet &snippet, activeBuiltInSnippets)
+ m_collection->insertSnippet(snippet, snippet.group());
+}
+
+void SnippetsManager::reloadSnippetsCollection()
+{
+ m_collection->clear();
+ loadSnippetsCollection();
+}
+
+void SnippetsManager::persistSnippetsCollection()
+{
+ if (QFile::exists(m_userSnippetsPath) || QDir().mkpath(m_userSnippetsPath)) {
+ QFile file(m_userSnippetsPath + m_snippetsFileName);
+ if (file.open(QFile::WriteOnly | QFile::Truncate)) {
+ QXmlStreamWriter writer(&file);
+ writer.setAutoFormatting(true);
+ writer.writeStartDocument();
+ writer.writeStartElement(kSnippets);
+ for (Snippet::Group group = Snippet::Cpp; group < Snippet::GroupSize; ++group) {
+ const int size = m_collection->totalSnippets(group);
+ for (int i = 0; i < size; ++i) {
+ const Snippet &snippet = m_collection->snippet(i, group);
+ if (!snippet.isBuiltIn() ||
+ (snippet.isBuiltIn() && (snippet.isRemoved() || snippet.isModified()))) {
+ writeSnippetXML(snippet, &writer);
+ }
+ }
+ }
+ writer.writeEndElement();
+ writer.writeEndDocument();
+ file.close();
+ }
+ }
+}
+
+void SnippetsManager::writeSnippetXML(const Snippet &snippet, QXmlStreamWriter *writer)
+{
+ writer->writeStartElement(kSnippet);
+ writer->writeAttribute(kGroup, fromSnippetGroup(snippet.group()));
+ writer->writeAttribute(kTrigger, snippet.trigger());
+ writer->writeAttribute(kId, snippet.id());
+ writer->writeAttribute(kComplement, snippet.complement());
+ writer->writeAttribute(kRemoved, fromBool(snippet.isRemoved()));
+ writer->writeAttribute(kModified, fromBool(snippet.isModified()));
+ writer->writeCharacters(snippet.content());
+ writer->writeEndElement();
+}
+
+QList<Snippet> SnippetsManager::readXML(const QString &fileName)
+{
+ QList<Snippet> snippets;
+ QFile file(fileName);
+ if (file.exists() && file.open(QIODevice::ReadOnly)) {
+ QXmlStreamReader xml(&file);
+ if (xml.readNextStartElement()) {
+ if (xml.name() == kSnippets) {
+ while (xml.readNextStartElement()) {
+ if (xml.name() == kSnippet) {
+ const QXmlStreamAttributes &atts = xml.attributes();
+
+ 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);
+ break;
+ }
+ }
+ } else {
+ xml.skipCurrentElement();
+ }
+ }
+ } else {
+ xml.skipCurrentElement();
+ }
+ }
+ if (xml.hasError())
+ qWarning() << fileName << xml.errorString() << xml.lineNumber() << xml.columnNumber();
+ file.close();
+ }
+
+ return snippets;
+}
+
+QSharedPointer<SnippetsCollection> SnippetsManager::snippetsCollection()
+{
+ if (!m_collectionLoaded) {
+ loadSnippetsCollection();
+ m_collectionLoaded = true;
+ }
+ return m_collection;
+}
diff --git a/src/plugins/texteditor/snippets/snippetsmanager.h b/src/plugins/texteditor/snippets/snippetsmanager.h
new file mode 100644
index 0000000000..6a07c72843
--- /dev/null
+++ b/src/plugins/texteditor/snippets/snippetsmanager.h
@@ -0,0 +1,86 @@
+/**************************************************************************
+**
+** 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 SNIPPETSMANAGER_H
+#define SNIPPETSMANAGER_H
+
+#include "snippet.h"
+
+#include <QtCore/QString>
+#include <QtCore/QSharedPointer>
+#include <QtCore/QList>
+
+QT_FORWARD_DECLARE_CLASS(QXmlStreamWriter)
+
+namespace TextEditor {
+namespace Internal {
+
+class SnippetsCollection;
+
+class SnippetsManager
+{
+private:
+ SnippetsManager();
+ Q_DISABLE_COPY(SnippetsManager)
+
+public:
+ ~SnippetsManager();
+
+ static SnippetsManager *instance();
+
+ void reloadSnippetsCollection();
+ void persistSnippetsCollection();
+ QSharedPointer<SnippetsCollection> snippetsCollection();
+
+private:
+ void loadSnippetsCollection();
+
+ static QList<Snippet> readXML(const QString &fileName);
+ static void writeSnippetXML(const Snippet &snippet, QXmlStreamWriter *writer);
+
+ static const QLatin1String kSnippet;
+ static const QLatin1String kSnippets;
+ static const QLatin1String kTrigger;
+ static const QLatin1String kId;
+ static const QLatin1String kComplement;
+ static const QLatin1String kGroup;
+ static const QLatin1String kRemoved;
+ static const QLatin1String kModified;
+
+ bool m_collectionLoaded;
+ QSharedPointer<SnippetsCollection> m_collection;
+ QString m_builtInSnippetsPath;
+ QString m_userSnippetsPath;
+ QString m_snippetsFileName;
+};
+
+} // Internal
+} // TextEditor
+
+#endif // SNIPPETSMANAGER_H
diff --git a/src/plugins/texteditor/snippets/snippetssettings.cpp b/src/plugins/texteditor/snippets/snippetssettings.cpp
new file mode 100644
index 0000000000..e99cbaf59e
--- /dev/null
+++ b/src/plugins/texteditor/snippets/snippetssettings.cpp
@@ -0,0 +1,78 @@
+/**************************************************************************
+**
+** 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 "snippetssettings.h"
+#include "reuse.h"
+
+#include <QtCore/QSettings>
+
+namespace {
+
+static const QLatin1String kGroupPostfix("SnippetsSettings");
+static const QLatin1String kLastUsedSnippetGroup("LastUsedSnippetGroup");
+
+} // Anonymous
+
+using namespace TextEditor;
+using namespace Internal;
+
+SnippetsSettings::SnippetsSettings()
+{}
+
+void SnippetsSettings::toSettings(const QString &category, QSettings *s) const
+{
+ const QString &group = category + kGroupPostfix;
+ s->beginGroup(group);
+ s->setValue(kLastUsedSnippetGroup, m_lastUsedSnippetGroup);
+ s->endGroup();
+}
+
+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();
+ s->endGroup();
+}
+
+void SnippetsSettings::setLastUsedSnippetGroup(const QString &lastUsed)
+{
+ m_lastUsedSnippetGroup = lastUsed;
+}
+
+const QString &SnippetsSettings::lastUsedSnippetGroup() const
+{
+ return m_lastUsedSnippetGroup;
+}
+
+bool SnippetsSettings::equals(const SnippetsSettings &snippetsSettings) const
+{
+ return m_lastUsedSnippetGroup == snippetsSettings.m_lastUsedSnippetGroup;
+}
diff --git a/src/plugins/texteditor/snippets/snippetssettings.h b/src/plugins/texteditor/snippets/snippetssettings.h
new file mode 100644
index 0000000000..9699d47f08
--- /dev/null
+++ b/src/plugins/texteditor/snippets/snippetssettings.h
@@ -0,0 +1,66 @@
+/**************************************************************************
+**
+** 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 SNIPPETSSETTINGS_H
+#define SNIPPETSSETTINGS_H
+
+#include <QtCore/QString>
+
+QT_BEGIN_NAMESPACE
+class QSettings;
+QT_END_NAMESPACE
+
+namespace TextEditor {
+
+class SnippetsSettings
+{
+public:
+ SnippetsSettings();
+
+ void toSettings(const QString &category, QSettings *s) const;
+ void fromSettings(const QString &category, QSettings *s);
+
+ void setLastUsedSnippetGroup(const QString &lastUsed);
+ const QString &lastUsedSnippetGroup() const;
+
+ bool equals(const SnippetsSettings &snippetsSettings) const;
+
+private:
+ QString m_lastUsedSnippetGroup;
+};
+
+inline bool operator==(const SnippetsSettings &a, const SnippetsSettings &b)
+{ return a.equals(b); }
+
+inline bool operator!=(const SnippetsSettings &a, const SnippetsSettings &b)
+{ return !a.equals(b); }
+
+} // TextEditor
+
+#endif // SNIPPETSSETTINGS_H
diff --git a/src/plugins/texteditor/snippets/snippetssettingspage.cpp b/src/plugins/texteditor/snippets/snippetssettingspage.cpp
new file mode 100644
index 0000000000..3302e1298c
--- /dev/null
+++ b/src/plugins/texteditor/snippets/snippetssettingspage.cpp
@@ -0,0 +1,512 @@
+/**************************************************************************
+**
+** 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 "snippetssettingspage.h"
+#include "snippetsmanager.h"
+#include "snippeteditor.h"
+#include "isnippeteditordecorator.h"
+#include "snippet.h"
+#include "snippetscollection.h"
+#include "snippetssettings.h"
+#include "reuse.h"
+#include "ui_snippetssettingspage.h"
+
+#include <coreplugin/icore.h>
+#include <extensionsystem/pluginmanager.h>
+
+#include <QtCore/QSharedPointer>
+#include <QtCore/QModelIndex>
+#include <QtCore/QAbstractTableModel>
+#include <QtCore/QList>
+#include <QtCore/QSettings>
+#include <QtCore/QTextStream>
+#include <QtGui/QMessageBox>
+
+namespace TextEditor {
+namespace Internal {
+
+// SnippetsTableModel
+class SnippetsTableModel : public QAbstractTableModel
+{
+ Q_OBJECT
+public:
+ SnippetsTableModel(QObject *parent);
+ virtual ~SnippetsTableModel() {}
+
+ virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
+ virtual Qt::ItemFlags flags(const QModelIndex &modelIndex) const;
+ virtual QVariant data(const QModelIndex &modelIndex, int role = Qt::DisplayRole) const;
+ virtual bool setData(const QModelIndex &modelIndex, const QVariant &value,
+ int role = Qt::EditRole);
+ virtual QVariant headerData(int section, Qt::Orientation orientation,
+ int role = Qt::DisplayRole) const;
+
+ void load(Snippet::Group group);
+
+ QModelIndex createSnippet();
+ QModelIndex insertSnippet(const Snippet &snippet);
+ void removeSnippet(const QModelIndex &modelIndex);
+ const Snippet &snippetAt(const QModelIndex &modelIndex) const;
+ void setSnippetContent(const QModelIndex &modelIndex, const QString &content);
+
+private:
+ static bool isValidTrigger(const QString &s);
+
+ Snippet::Group m_activeGroup;
+ QSharedPointer<SnippetsCollection> m_collection;
+};
+
+SnippetsTableModel::SnippetsTableModel(QObject *parent) :
+ QAbstractTableModel(parent),
+ m_activeGroup(Snippet::Cpp),
+ m_collection(SnippetsManager::instance()->snippetsCollection())
+{}
+
+int SnippetsTableModel::rowCount(const QModelIndex &) const
+{
+ if (m_collection.isNull())
+ return 0;
+ return m_collection->totalActiveSnippets(m_activeGroup);
+}
+
+int SnippetsTableModel::columnCount(const QModelIndex &) const
+{
+ if (m_collection.isNull())
+ return 0;
+ return 2;
+}
+
+Qt::ItemFlags SnippetsTableModel::flags(const QModelIndex &index) const
+{
+ Qt::ItemFlags itemFlags = QAbstractTableModel::flags(index);
+ if (index.isValid())
+ itemFlags |= Qt::ItemIsEditable;
+ return itemFlags;
+}
+
+QVariant SnippetsTableModel::data(const QModelIndex &modelIndex, int role) const
+{
+ if (!modelIndex.isValid())
+ return QVariant();
+
+ if (role == Qt::DisplayRole || role == Qt::EditRole) {
+ const Snippet &snippet = m_collection->snippet(modelIndex.row(), m_activeGroup);
+ if (modelIndex.column() == 0)
+ return snippet.trigger();
+ else
+ return snippet.complement();
+ } else {
+ return QVariant();
+ }
+}
+
+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));
+ if (modelIndex.column() == 0) {
+ const QString &s = value.toString();
+ if (!isValidTrigger(s)) {
+ QMessageBox::critical(0, tr("Error"), tr("Not a valid trigger."));
+ if (snippet.trigger().isEmpty())
+ removeSnippet(modelIndex);
+ return false;
+ }
+ snippet.setTrigger(s);
+ } else {
+ 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();
+ }
+
+ return true;
+ }
+ return false;
+}
+
+QVariant SnippetsTableModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ if (role != Qt::DisplayRole || orientation != Qt::Horizontal)
+ return QVariant();
+
+ if (section == 0)
+ return tr("Trigger");
+ else
+ return tr("Complement");
+}
+
+void SnippetsTableModel::load(Snippet::Group group)
+{
+ m_activeGroup = group;
+ reset();
+}
+
+QModelIndex SnippetsTableModel::createSnippet()
+{
+ Snippet snippet;
+ snippet.setGroup(m_activeGroup);
+ return insertSnippet(snippet);
+}
+
+QModelIndex SnippetsTableModel::insertSnippet(const Snippet &snippet)
+{
+ const SnippetsCollection::Hint &hint =
+ m_collection->computeInsertionHint(snippet, m_activeGroup);
+ beginInsertRows(QModelIndex(), hint.index(), hint.index());
+ m_collection->insertSnippet(snippet, m_activeGroup, hint);
+ endInsertRows();
+
+ return index(hint.index(), 0);
+}
+
+void SnippetsTableModel::removeSnippet(const QModelIndex &modelIndex)
+{
+ beginRemoveRows(QModelIndex(), modelIndex.row(), modelIndex.row());
+ m_collection->removeSnippet(modelIndex.row(), m_activeGroup);
+ endRemoveRows();
+}
+
+const Snippet &SnippetsTableModel::snippetAt(const QModelIndex &modelIndex) const
+{
+ return m_collection->snippet(modelIndex.row(), m_activeGroup);
+}
+
+void SnippetsTableModel::setSnippetContent(const QModelIndex &modelIndex, const QString &content)
+{
+ m_collection->setSnippetContent(modelIndex.row(), m_activeGroup, content);
+}
+
+bool SnippetsTableModel::isValidTrigger(const QString &s)
+{
+ if (s.isEmpty())
+ return false;
+ for (int i = 0; i < s.length(); ++i)
+ if (!s.at(i).isLetter())
+ return false;
+ return true;
+}
+
+// SnippetsSettingsPagePrivate
+class SnippetsSettingsPagePrivate : public QObject
+{
+ Q_OBJECT
+public:
+ SnippetsSettingsPagePrivate(const QString &id);
+ ~SnippetsSettingsPagePrivate() { delete m_model; }
+
+ const QString &id() const { return m_id; }
+ const QString &displayName() const { return m_displayName; }
+ bool isKeyword(const QString &s) const { return m_keywords.contains(s, Qt::CaseInsensitive); }
+ void configureUi(QWidget *parent);
+
+ void apply();
+ void finish();
+
+private slots:
+ void loadSnippetGroup(int index);
+ void markSnippetsCollection();
+ void addSnippet();
+ void removeSnippet();
+ void selectSnippet(const QModelIndex &parent, int row);
+ void selectMovedSnippet(const QModelIndex &, int, int, const QModelIndex &, int row);
+ void previewSnippet(const QModelIndex &modelIndex);
+ void updateSnippetContent();
+
+private:
+ SnippetEditor *currentEditor() const;
+ SnippetEditor *editorAt(int i) const;
+
+ static void decorateEditor(SnippetEditor *editor, Snippet::Group group);
+
+ void loadSettings();
+ bool settingsChanged() const;
+ void writeSettings();
+
+ const QString m_id;
+ const QString m_displayName;
+ const QString m_settingsPrefix;
+ SnippetsTableModel *m_model;
+ bool m_snippetsCollectionChanged;
+ QString m_keywords;
+ SnippetsSettings m_settings;
+ Ui::SnippetsSettingsPage m_ui;
+};
+
+SnippetsSettingsPagePrivate::SnippetsSettingsPagePrivate(const QString &id) :
+ m_id(id),
+ m_displayName(tr("Snippets")),
+ m_settingsPrefix(QLatin1String("Text")),
+ m_model(new SnippetsTableModel(0)),
+ m_snippetsCollectionChanged(false)
+{}
+
+SnippetEditor *SnippetsSettingsPagePrivate::currentEditor() const
+{
+ return editorAt(m_ui.snippetsEditorStack->currentIndex());
+}
+
+SnippetEditor *SnippetsSettingsPagePrivate::editorAt(int i) const
+{
+ return static_cast<SnippetEditor *>(m_ui.snippetsEditorStack->widget(i));
+}
+
+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));
+
+ m_ui.snippetsTable->setSelectionBehavior(QAbstractItemView::SelectRows);
+ m_ui.snippetsTable->setSelectionMode(QAbstractItemView::SingleSelection);
+ m_ui.snippetsTable->horizontalHeader()->setStretchLastSection(true);
+ m_ui.snippetsTable->horizontalHeader()->setHighlightSections(false);
+ m_ui.snippetsTable->verticalHeader()->setVisible(false);
+ 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);
+
+ QTextStream(&m_keywords) << m_displayName;
+
+ loadSettings();
+ loadSnippetGroup(m_ui.groupCombo->currentIndex());
+
+ connect(editorAt(Snippet::Cpp), SIGNAL(snippetContentChanged()),
+ this, SLOT(updateSnippetContent()));
+ connect(editorAt(Snippet::Qml), SIGNAL(snippetContentChanged()),
+ this, SLOT(updateSnippetContent()));
+ connect(editorAt(Snippet::PlainText), SIGNAL(snippetContentChanged()),
+ this, SLOT(updateSnippetContent()));
+
+ connect(m_model, SIGNAL(rowsInserted(QModelIndex, int, int)),
+ this, SLOT(selectSnippet(QModelIndex,int)));
+ connect(m_model, SIGNAL(rowsInserted(QModelIndex, int, int)),
+ this, SLOT(markSnippetsCollection()));
+ connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)),
+ this, SLOT(markSnippetsCollection()));
+ connect(m_model, SIGNAL(rowsMoved(QModelIndex, int, int, QModelIndex, int)),
+ this, SLOT(selectMovedSnippet(QModelIndex,int,int,QModelIndex,int)));
+ connect(m_model, SIGNAL(rowsMoved(QModelIndex, int, int, QModelIndex, int)),
+ this, SLOT(markSnippetsCollection()));
+ connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
+ 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.snippetsTable->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
+ this, SLOT(previewSnippet(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())
+ writeSettings();
+
+ if (m_snippetsCollectionChanged)
+ SnippetsManager::instance()->persistSnippetsCollection();
+}
+
+void SnippetsSettingsPagePrivate::finish()
+{
+ if (m_snippetsCollectionChanged) {
+ SnippetsManager::instance()->reloadSnippetsCollection();
+ m_snippetsCollectionChanged = false;
+ }
+}
+
+void SnippetsSettingsPagePrivate::loadSettings()
+{
+ if (QSettings *s = Core::ICore::instance()->settings()) {
+ m_settings.fromSettings(m_settingsPrefix, s);
+ m_ui.groupCombo->setCurrentIndex(toSnippetGroup(m_settings.lastUsedSnippetGroup()));
+ }
+}
+
+void SnippetsSettingsPagePrivate::writeSettings()
+{
+ if (QSettings *s = Core::ICore::instance()->settings()) {
+ m_settings.setLastUsedSnippetGroup(m_ui.groupCombo->currentText());
+ m_settings.toSettings(m_settingsPrefix, s);
+ }
+}
+
+bool SnippetsSettingsPagePrivate::settingsChanged() const
+{
+ if (m_settings.lastUsedSnippetGroup() != m_ui.groupCombo->currentText())
+ return true;
+ return false;
+}
+
+void SnippetsSettingsPagePrivate::loadSnippetGroup(int index)
+{
+ m_ui.snippetsEditorStack->setCurrentIndex(index);
+ currentEditor()->clear();
+ m_model->load(Snippet::Group(index));
+}
+
+void SnippetsSettingsPagePrivate::markSnippetsCollection()
+{
+ if (!m_snippetsCollectionChanged)
+ m_snippetsCollectionChanged = true;
+}
+
+void SnippetsSettingsPagePrivate::addSnippet()
+{
+ const QModelIndex &modelIndex = m_model->createSnippet();
+ selectSnippet(QModelIndex(), modelIndex.row());
+ m_ui.snippetsTable->edit(modelIndex);
+}
+
+void SnippetsSettingsPagePrivate::removeSnippet()
+{
+ const QModelIndex &modelIndex = m_ui.snippetsTable->selectionModel()->currentIndex();
+ if (!modelIndex.isValid()) {
+ QMessageBox::critical(0, tr("Error"), tr("No snippet selected."));
+ return;
+ }
+ m_model->removeSnippet(modelIndex);
+}
+
+void SnippetsSettingsPagePrivate::selectSnippet(const QModelIndex &parent, int row)
+{
+ QModelIndex topLeft = m_model->index(row, 0, parent);
+ QModelIndex bottomRight = m_model->index(row, 1, parent);
+ QItemSelection selection(topLeft, bottomRight);
+ m_ui.snippetsTable->selectionModel()->select(selection, QItemSelectionModel::SelectCurrent);
+ m_ui.snippetsTable->setCurrentIndex(topLeft);
+ m_ui.snippetsTable->scrollTo(topLeft);
+}
+
+void SnippetsSettingsPagePrivate::selectMovedSnippet(const QModelIndex &,
+ int sourceRow,
+ int,
+ const QModelIndex &destinationParent,
+ int destinationRow)
+{
+ QModelIndex modelIndex;
+ if (sourceRow < destinationRow)
+ modelIndex = m_model->index(destinationRow - 1, 0, destinationParent);
+ else
+ modelIndex = m_model->index(destinationRow, 0, destinationParent);
+ m_ui.snippetsTable->scrollTo(modelIndex);
+}
+
+void SnippetsSettingsPagePrivate::previewSnippet(const QModelIndex &modelIndex)
+{
+ currentEditor()->setPlainText(m_model->snippetAt(modelIndex).content());
+}
+
+void SnippetsSettingsPagePrivate::updateSnippetContent()
+{
+ const QModelIndex &modelIndex = m_ui.snippetsTable->selectionModel()->currentIndex();
+ if (modelIndex.isValid()) {
+ m_model->setSnippetContent(modelIndex, currentEditor()->toPlainText());
+ markSnippetsCollection();
+ }
+}
+
+// SnippetsSettingsPage
+SnippetsSettingsPage::SnippetsSettingsPage(const QString &id, QObject *parent) :
+ TextEditorOptionsPage(parent),
+ m_d(new SnippetsSettingsPagePrivate(id))
+{}
+
+SnippetsSettingsPage::~SnippetsSettingsPage()
+{
+ delete m_d;
+}
+
+QString SnippetsSettingsPage::id() const
+{
+ return m_d->id();
+}
+
+QString SnippetsSettingsPage::displayName() const
+{
+ return m_d->displayName();
+}
+
+bool SnippetsSettingsPage::matches(const QString &s) const
+{
+ return m_d->isKeyword(s);
+}
+
+QWidget *SnippetsSettingsPage::createPage(QWidget *parent)
+{
+ QWidget *w = new QWidget(parent);
+ m_d->configureUi(w);
+ return w;
+}
+
+void SnippetsSettingsPage::apply()
+{
+ m_d->apply();
+}
+
+void SnippetsSettingsPage::finish()
+{
+ m_d->finish();
+}
+
+} // Internal
+} // TextEditor
+
+#include "snippetssettingspage.moc"
diff --git a/src/plugins/texteditor/snippets/snippetssettingspage.h b/src/plugins/texteditor/snippets/snippetssettingspage.h
new file mode 100644
index 0000000000..485d602592
--- /dev/null
+++ b/src/plugins/texteditor/snippets/snippetssettingspage.h
@@ -0,0 +1,61 @@
+/**************************************************************************
+**
+** 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 SNIPPETSSETTINGSPAGE_H
+#define SNIPPETSSETTINGSPAGE_H
+
+#include "texteditoroptionspage.h"
+
+namespace TextEditor {
+namespace Internal {
+
+class SnippetsSettingsPagePrivate;
+
+class SnippetsSettingsPage : public TextEditorOptionsPage
+{
+ Q_OBJECT
+public:
+ SnippetsSettingsPage(const QString &id, QObject *parent);
+ virtual ~SnippetsSettingsPage();
+
+ virtual QString id() const;
+ virtual QString displayName() const;
+ virtual bool matches(const QString &s) const;
+ virtual QWidget *createPage(QWidget *parent);
+ virtual void apply();
+ virtual void finish();
+
+private:
+ SnippetsSettingsPagePrivate *m_d;
+};
+
+} // Internal
+} // TextEditor
+
+#endif // SNIPPETSSETTINGSPAGE_H
diff --git a/src/plugins/texteditor/snippets/snippetssettingspage.ui b/src/plugins/texteditor/snippets/snippetssettingspage.ui
new file mode 100644
index 0000000000..df9917d9d9
--- /dev/null
+++ b/src/plugins/texteditor/snippets/snippetssettingspage.ui
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>SnippetsSettingsPage</class>
+ <widget class="QWidget" name="SnippetsSettingsPage">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>684</width>
+ <height>554</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLabel" name="groupLabel">
+ <property name="text">
+ <string>Group: </string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="groupCombo"/>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QTableView" name="snippetsTable">
+ <property name="editTriggers">
+ <set>QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QStackedWidget" name="snippetsEditorStack">
+ <property name="currentIndex">
+ <number>1</number>
+ </property>
+ <widget class="QWidget" name="page"/>
+ <widget class="QWidget" name="page_2"/>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QPushButton" name="addButton">
+ <property name="text">
+ <string>Add</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="removeButton">
+ <property name="text">
+ <string>Remove</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>groupCombo</tabstop>
+ <tabstop>addButton</tabstop>
+ <tabstop>removeButton</tabstop>
+ <tabstop>snippetsTable</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/plugins/texteditor/snippetsparser.cpp b/src/plugins/texteditor/snippetsparser.cpp
deleted file mode 100644
index ce3cf21704..0000000000
--- a/src/plugins/texteditor/snippetsparser.cpp
+++ /dev/null
@@ -1,144 +0,0 @@
-/**************************************************************************
-**
-** 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 "snippetsparser.h"
-
-#include <QtCore/QFile>
-#include <QtCore/QFileInfo>
-#include <QtCore/QLatin1String>
-#include <QtCore/QLatin1Char>
-#include <QtCore/QVariant>
-#include <QtCore/QXmlStreamReader>
-#include <QtCore/QDebug>
-#include <QtGui/QTextDocument>
-
-using namespace TextEditor;
-
-SnippetsParser::SnippetsParser(const QString &fileName) : m_fileName(fileName)
-{}
-
-const QList<CompletionItem> &SnippetsParser::execute(ICompletionCollector *collector,
- const QIcon &icon,
- int order)
-{
- if (!QFile::exists(m_fileName)) {
- m_snippets.clear();
- } else {
- const QDateTime &lastModified = QFileInfo(m_fileName).lastModified();
- if (m_lastTrackedFileChange.isNull() || m_lastTrackedFileChange != lastModified) {
- m_snippets.clear();
- QFile file(m_fileName);
- file.open(QIODevice::ReadOnly);
- QXmlStreamReader xml(&file);
- if (xml.readNextStartElement()) {
- if (xml.name() == QLatin1String("snippets")) {
- while (xml.readNextStartElement()) {
- if (xml.name() == QLatin1String("snippet")) {
- TextEditor::CompletionItem item(collector);
- QString title;
- QString data;
- QString description = xml.attributes().value("description").toString();
-
- while (!xml.atEnd()) {
- xml.readNext();
- if (xml.isEndElement()) {
- int i = 0;
- while (i < data.size() && data.at(i).isLetterOrNumber())
- ++i;
- title = data.left(i);
- item.text = title;
- if (!description.isEmpty()) {
- item.text += QLatin1Char(' ');
- item.text += description;
- }
- item.data = QVariant::fromValue(data.trimmed());
-
- QString infotip = data;
- while (infotip.size() && infotip.at(infotip.size()-1).isSpace())
- infotip.chop(1);
- infotip = Qt::escape(infotip);
- infotip.replace(QLatin1Char('\n'), QLatin1String("<br>"));
- infotip.replace(QLatin1Char(' '), QLatin1String("&nbsp;"));
- {
- QString s = QLatin1String("<nobr>");
- int count = 0;
- for (int i = 0; i < infotip.count(); ++i) {
- if (infotip.at(i) != QChar::ObjectReplacementCharacter) {
- s += infotip.at(i);
- continue;
- }
- if (++count % 2) {
- s += QLatin1String("<b>");
- } else {
- if (infotip.at(i-1) == QChar::ObjectReplacementCharacter)
- s += QLatin1String("...");
- s += QLatin1String("</b>");
- }
- }
- infotip = s;
- }
- item.details = infotip;
-
- item.icon = icon;
- item.order = order;
- item.isSnippet = true;
- m_snippets.append(item);
- break;
- }
-
- if (xml.isCharacters())
- data += xml.text();
- else if (xml.isStartElement()) {
- if (xml.name() != QLatin1String("tab"))
- xml.raiseError(QLatin1String("invalid snippets file"));
- else {
- data += QChar::ObjectReplacementCharacter;
- data += xml.readElementText();
- data += QChar::ObjectReplacementCharacter;
- }
- }
- }
- } else {
- xml.skipCurrentElement();
- }
- }
- } else {
- xml.skipCurrentElement();
- }
- }
- if (xml.hasError())
- qWarning() << m_fileName << xml.errorString() << xml.lineNumber() << xml.columnNumber();
- file.close();
-
- m_lastTrackedFileChange = lastModified;
- }
- }
-
- return m_snippets;
-}
diff --git a/src/plugins/texteditor/texteditor.pro b/src/plugins/texteditor/texteditor.pro
index 43ba19013a..fbc8b67cd4 100644
--- a/src/plugins/texteditor/texteditor.pro
+++ b/src/plugins/texteditor/texteditor.pro
@@ -5,9 +5,11 @@ QT += xml network
include(../../qtcreatorplugin.pri)
include(texteditor_dependencies.pri)
INCLUDEPATH += generichighlighter \
- tooltip
+ tooltip \
+ snippets
DEPENDPATH += generichighlighter \
- tooltip
+ tooltip \
+ snippets
SOURCES += texteditorplugin.cpp \
textfilewizard.cpp \
plaintexteditor.cpp \
@@ -70,8 +72,15 @@ SOURCES += texteditorplugin.cpp \
tooltip/tipfactory.cpp \
basehoverhandler.cpp \
helpitem.cpp \
- snippetsparser.cpp \
- autocompleter.cpp
+ autocompleter.cpp \
+ snippets/snippetssettingspage.cpp \
+ snippets/snippet.cpp \
+ snippets/snippetsmanager.cpp \
+ snippets/snippeteditor.cpp \
+ snippets/isnippeteditordecorator.cpp \
+ snippets/snippetscollection.cpp \
+ snippets/snippetssettings.cpp \
+ snippets/snippetprovider.cpp
HEADERS += texteditorplugin.h \
textfilewizard.h \
@@ -145,14 +154,23 @@ HEADERS += texteditorplugin.h \
tooltip/tipfactory.h \
basehoverhandler.h \
helpitem.h \
- snippetsparser.h \
- autocompleter.h
+ autocompleter.h \
+ snippets/snippetssettingspage.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
FORMS += behaviorsettingspage.ui \
displaysettingspage.ui \
fontsettingspage.ui \
colorschemeedit.ui \
generichighlighter/highlightersettingspage.ui \
- generichighlighter/managedefinitionsdialog.ui
+ generichighlighter/managedefinitionsdialog.ui \
+ snippets/snippetssettingspage.ui
RESOURCES += texteditor.qrc
OTHER_FILES += TextEditor.mimetypes.xml
diff --git a/src/plugins/texteditor/texteditor.qrc b/src/plugins/texteditor/texteditor.qrc
index 86fa6638cb..bba57a2fe6 100644
--- a/src/plugins/texteditor/texteditor.qrc
+++ b/src/plugins/texteditor/texteditor.qrc
@@ -5,5 +5,6 @@
<file>TextEditor.mimetypes.xml</file>
<file>images/refactormarker.png</file>
<file>images/snippet.png</file>
+ <file>snippets/snippets.xml</file>
</qresource>
</RCC>
diff --git a/src/plugins/texteditor/texteditorconstants.h b/src/plugins/texteditor/texteditorconstants.h
index 83b4261e02..a22917d2cd 100644
--- a/src/plugins/texteditor/texteditorconstants.h
+++ b/src/plugins/texteditor/texteditorconstants.h
@@ -140,6 +140,9 @@ const char * const TEXT_EDITOR_FONT_SETTINGS = "A.FontSettings";
const char * const TEXT_EDITOR_BEHAVIOR_SETTINGS = "B.BehaviourSettings";
const char * const TEXT_EDITOR_DISPLAY_SETTINGS = "D.DisplaySettings";
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";
} // namespace Constants
} // namespace TextEditor
diff --git a/src/plugins/texteditor/texteditorsettings.cpp b/src/plugins/texteditor/texteditorsettings.cpp
index da0d8965ce..fcd5c4f969 100644
--- a/src/plugins/texteditor/texteditorsettings.cpp
+++ b/src/plugins/texteditor/texteditorsettings.cpp
@@ -41,6 +41,7 @@
#include "tabsettings.h"
#include "texteditorplugin.h"
#include "highlightersettingspage.h"
+#include "snippetssettingspage.h"
#include <extensionsystem/pluginmanager.h>
#include <coreplugin/icore.h>
@@ -62,6 +63,7 @@ public:
BehaviorSettingsPage *m_behaviorSettingsPage;
DisplaySettingsPage *m_displaySettingsPage;
HighlighterSettingsPage *m_highlighterSettingsPage;
+ SnippetsSettingsPage *m_snippetsSettingsPage;
CompletionSettings m_completionSettings;
@@ -174,6 +176,10 @@ TextEditorSettings::TextEditorSettings(QObject *parent)
new HighlighterSettingsPage(QLatin1String(Constants::TEXT_EDITOR_HIGHLIGHTER_SETTINGS), this);
pm->addObject(m_d->m_highlighterSettingsPage);
+ m_d->m_snippetsSettingsPage =
+ new SnippetsSettingsPage(QLatin1String(Constants::TEXT_EDITOR_SNIPPETS_SETTINGS), this);
+ pm->addObject(m_d->m_snippetsSettingsPage);
+
connect(m_d->m_fontSettingsPage, SIGNAL(changed(TextEditor::FontSettings)),
this, SIGNAL(fontSettingsChanged(TextEditor::FontSettings)));
connect(m_d->m_behaviorSettingsPage, SIGNAL(tabSettingsChanged(TextEditor::TabSettings)),
@@ -197,6 +203,7 @@ TextEditorSettings::~TextEditorSettings()
pm->removeObject(m_d->m_behaviorSettingsPage);
pm->removeObject(m_d->m_displaySettingsPage);
pm->removeObject(m_d->m_highlighterSettingsPage);
+ pm->removeObject(m_d->m_snippetsSettingsPage);
delete m_d;