diff --git a/plugins/snippet/editsnippet.cpp b/plugins/snippet/editsnippet.cpp index 9928e7ce2f..e479c2eb90 100644 --- a/plugins/snippet/editsnippet.cpp +++ b/plugins/snippet/editsnippet.cpp @@ -1,98 +1,102 @@ /*************************************************************************** * Copyright 2007 Robert Gruber * * Copyright 2010 Milian Wolff * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "editsnippet.h" #include "snippetrepository.h" #include #include #include +#include + #include "snippetstore.h" #include "snippet.h" EditSnippet::EditSnippet(SnippetRepository* repository, Snippet* snippet, QWidget* parent) : KDialog(parent), Ui::EditSnippetBase(), m_repo(repository), m_snippet(snippet) { Q_ASSERT(m_repo); setButtons(/*Reset | */Apply | Cancel | Ok); setupUi(mainWidget()); connect(this, SIGNAL(okClicked()), this, SLOT(save())); connect(this, SIGNAL(applyClicked()), this, SLOT(save())); connect(snippetNameEdit, SIGNAL(textEdited(QString)), this, SLOT(validate())); connect(snippetContentsEdit, SIGNAL(textChanged()), this, SLOT(validate())); // if we edit a snippet, add all existing data if ( m_snippet ) { snippetNameEdit->setText(m_repo->text()); setWindowTitle(i18n("Edit Snippet %1 in %2", m_snippet->text(), m_repo->text())); snippetArgumentsEdit->setText(m_snippet->arguments()); snippetContentsEdit->setPlainText(m_snippet->snippet()); snippetNameEdit->setText(m_snippet->text()); snippetPostfixEdit->setText(m_snippet->postfix()); snippetPrefixEdit->setText(m_snippet->prefix()); + snippetShortcutWidget->setShortcut(m_snippet->action()->shortcut()); } else { setWindowTitle(i18n("Create New Snippet in Repository %1", m_repo->text())); } validate(); snippetNameEdit->setFocus(); } EditSnippet::~EditSnippet() { } void EditSnippet::validate() { const QString& name = snippetNameEdit->text(); bool valid = !name.isEmpty() && !snippetContentsEdit->document()->isEmpty(); if (valid) { // make sure the snippetname includes no spaces for ( int i = 0; i < name.length(); ++i ) { if ( name.at(i).isSpace() ) { valid = false; break; } } } button(Ok)->setEnabled(valid); button(Apply)->setEnabled(valid); } void EditSnippet::save() { Q_ASSERT(!snippetNameEdit->text().isEmpty()); if ( !m_snippet ) { // save as new snippet m_snippet = new Snippet(); m_repo->appendRow(m_snippet); } m_snippet->setArguments(snippetArgumentsEdit->text()); m_snippet->setSnippet(snippetContentsEdit->document()->toPlainText()); m_snippet->setText(snippetNameEdit->text()); m_snippet->setPostfix(snippetPostfixEdit->text()); m_snippet->setPrefix(snippetPrefixEdit->text()); + m_snippet->action()->setShortcut(snippetShortcutWidget->shortcut()); m_repo->save(); setWindowTitle(i18n("Edit Snippet %1 in %2", m_snippet->text(), m_repo->text())); } #include "editsnippet.moc" diff --git a/plugins/snippet/editsnippet.ui b/plugins/snippet/editsnippet.ui index 17c412bd0b..f76f8c11e0 100644 --- a/plugins/snippet/editsnippet.ui +++ b/plugins/snippet/editsnippet.ui @@ -1,114 +1,137 @@ EditSnippetBase + + + 0 + 0 + 500 + 329 + + 500 0 Name: <p>The name will also be used as the identifier during code completion.</p> <p><b>Note:</b> No spaces allowed.</p> Display Prefix: The display prefix will be shown during code completion. Display Arguments: The arguments will be shown during code completion. Display Postfix: The postfix will be shown during code completion. - + Snippet: - + 0 0 The actual snippet contents that will be inserted. false + + + + Shortcut: + + + + + + KLineEdit QLineEdit
klineedit.h
+ + KShortcutWidget + QWidget +
kshortcutwidget.h
+
KTextEdit QTextEdit
ktextedit.h
snippetPrefixEdit snippetArgumentsEdit snippetPostfixEdit snippetContentsEdit
diff --git a/plugins/snippet/snippet.cpp b/plugins/snippet/snippet.cpp index 8fe7c60547..302387596c 100644 --- a/plugins/snippet/snippet.cpp +++ b/plugins/snippet/snippet.cpp @@ -1,80 +1,104 @@ /*************************************************************************** * Copyright 2007 Robert Gruber * * Copyright 2010 Milian Wolff * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "snippet.h" #include #include #include +#include "snippetplugin.h" +#include +#include +#include +#include +#include + Snippet::Snippet() - : QStandardItem(i18n("")) + : QStandardItem(i18n("")), m_action(0) { setIcon(KIcon("text-plain")); } Snippet::~Snippet() { + delete m_action; } QString Snippet::snippet() const { return m_snippet; } void Snippet::setSnippet(const QString& snippet) { m_snippet = snippet; } QString Snippet::prefix() const { return m_prefix; } void Snippet::setPrefix(const QString& prefix) { m_prefix = prefix; } QString Snippet::postfix() const { return m_postfix; } void Snippet::setPostfix(const QString& postfix) { m_postfix = postfix; } QString Snippet::arguments() const { return m_arguments; } void Snippet::setArguments(const QString& arguments) { m_arguments = arguments; } +KAction* Snippet::action() +{ + ///TODO: this is quite ugly, or is it? if someone knows how to do it better, please refactor + if ( !m_action ) { + static int actionCount = 0; + m_action = new KAction(QString("insertSnippet%1").arg(actionCount), SnippetPlugin::self()); + m_action->setData(QVariant::fromValue(this)); + SnippetPlugin::self()->connect(m_action, SIGNAL(triggered()), + SnippetPlugin::self(), SLOT(insertSnippetFromActionData())); + // action needs to be added to a widget before it can work... + KDevelop::ICore::self()->uiController()->activeMainWindow()->addAction(m_action); + } + m_action->setText(i18n("insert snippet %1").arg(text())); + return m_action; +} + QVariant Snippet::data(int role) const { if ( role == Qt::ToolTipRole ) { return m_snippet; } else if ( role == Qt::ForegroundRole && !parent()->isEnabled() ) { ///TODO: make the selected items also "disalbed" so the toggle action is seen directly KColorScheme scheme(QPalette::Disabled, KColorScheme::View); QColor c = scheme.foreground(KColorScheme::ActiveText).color(); return QVariant(c); } return QStandardItem::data(role); } diff --git a/plugins/snippet/snippet.h b/plugins/snippet/snippet.h index 867e9350af..ab776461a1 100644 --- a/plugins/snippet/snippet.h +++ b/plugins/snippet/snippet.h @@ -1,87 +1,97 @@ /*************************************************************************** * Copyright 2007 Robert Gruber * * Copyright 2010 Milian Wolff * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef __SNIPPET_H__ #define __SNIPPET_H__ #include class SnippetRepository; +class KAction; /** * One object of this class represents a single snippet. * Multiple snippets are stored in one repository (XML-file). * * To access the snippet's name (which should also be used for matching * during code completion) use @p QStandardItem::text(). * * @author Robert Gruber * @author Milian Wolff */ class Snippet : public QStandardItem { public: /** * Construct an empty snippet. */ Snippet(); ~Snippet(); /** * Returns the actual contents of this snippet. */ QString snippet() const; /** * Sets the actual contents of this snippet. */ void setSnippet(const QString& snippet); /** * Returns the display prefix of this snippet. */ QString prefix() const; /** * Sets the display prefix of this snippet. */ void setPrefix(const QString& prefix); /** * Returns the display postfix of this snippet. */ QString postfix() const; /** * Sets the display postfix of this snippet. */ void setPostfix(const QString& postfix); /** * Returns the display arguments of this snippet. */ QString arguments() const; /** * Sets the display arguments of this snippet. */ void setArguments(const QString& arguments); + /** + * Action to trigger insertion of this snippet. + */ + KAction* action(); + virtual QVariant data(int role = Qt::UserRole + 1) const; private: /// the actual snippet contents aka \code\endcode QString m_snippet; /// the display postfix aka \code\endcode QString m_postfix; /// the display prefix aka \code\endcode QString m_prefix; /// the display arguments aka \code\endcode QString m_arguments; + /// the insertion action for this snippet. + KAction* m_action; }; +Q_DECLARE_METATYPE ( Snippet* ) + #endif diff --git a/plugins/snippet/snippetplugin.cpp b/plugins/snippet/snippetplugin.cpp index 8a063d18f1..467cb16929 100644 --- a/plugins/snippet/snippetplugin.cpp +++ b/plugins/snippet/snippetplugin.cpp @@ -1,194 +1,214 @@ /*************************************************************************** * Copyright 2007 Robert Gruber * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "snippetplugin.h" #include #include #include #include #include #include #include #include #include #include #include #if KDE_VERSION >= KDE_MAKE_VERSION(4, 4, 0) #define HAVE_HIGHLIGHT_IFACE #include #endif #include #include #include #include #include #include #include "snippetview.h" #include "snippetcompletionmodel.h" #include "snippetstore.h" #include "snippet.h" #include "snippetrepository.h" #include "snippetcompletionitem.h" #include "editsnippet.h" K_PLUGIN_FACTORY(SnippetFactory, registerPlugin(); ) K_EXPORT_PLUGIN(SnippetFactory(KAboutData("kdevsnippet","kdevsnippet", ki18n("Snippets"), "0.1", ki18n("Support for managing and using code snippets"), KAboutData::License_GPL))) +SnippetPlugin* SnippetPlugin::m_self = 0; + class SnippetViewFactory: public KDevelop::IToolViewFactory{ public: SnippetViewFactory(SnippetPlugin *plugin): m_plugin(plugin) {} virtual QWidget* create(QWidget *parent = 0) { Q_UNUSED(parent) return new SnippetView( m_plugin, parent); } virtual Qt::DockWidgetArea defaultPosition() { return Qt::RightDockWidgetArea; } virtual QString id() const { return "org.kdevelop.SnippetView"; } private: SnippetPlugin *m_plugin; }; SnippetPlugin::SnippetPlugin(QObject *parent, const QVariantList &) : KDevelop::IPlugin(SnippetFactory::componentData(), parent) { + Q_ASSERT(!m_self); + m_self = this; + SnippetStore::init(this); m_model = new SnippetCompletionModel; new KDevelop::CodeCompletion(this, m_model, QString()); setXMLFile( "kdevsnippet.rc" ); m_factory = new SnippetViewFactory(this); core()->uiController()->addToolView(i18n("Snippets"), m_factory); connect( core()->partController(), SIGNAL(partAdded(KParts::Part*)), this, SLOT(documentLoaded(KParts::Part*)) ); } SnippetPlugin::~SnippetPlugin() { + m_self = 0; +} + +SnippetPlugin* SnippetPlugin::self() +{ + return m_self; } void SnippetPlugin::unload() { core()->uiController()->removeToolView(m_factory); delete SnippetStore::self(); } void SnippetPlugin::insertSnippet(Snippet* snippet) { KDevelop::IDocument* doc = core()->documentController()->activeDocument(); if (!doc) return; if (doc->isTextDocument()) { SnippetCompletionItem item(snippet, static_cast(snippet->parent())); KTextEditor::Range range = doc->textSelection(); if ( !range.isValid() ) { range = KTextEditor::Range(doc->cursorPosition(), doc->cursorPosition()); } item.execute(doc->textDocument(), range); if ( doc->textDocument()->activeView() ) { doc->textDocument()->activeView()->setFocus(); } } } +void SnippetPlugin::insertSnippetFromActionData() +{ + KAction* action = dynamic_cast(sender()); + Q_ASSERT(action); + Snippet* snippet = action->data().value(); + Q_ASSERT(snippet); + insertSnippet(snippet); +} + void SnippetPlugin::viewCreated( KTextEditor::Document*, KTextEditor::View* view ) { KAction* selectionAction = view->actionCollection()->addAction("edit_selection_snippet", this, SLOT(createSnippetFromSelection())); selectionAction->setData(QVariant::fromValue(view)); } void SnippetPlugin::documentLoaded( KParts::Part* part ) { KTextEditor::Document *textDocument = dynamic_cast( part ); if ( textDocument ) { foreach( KTextEditor::View* view, textDocument->views() ) viewCreated( textDocument, view ); connect( textDocument, SIGNAL( viewCreated( KTextEditor::Document*, KTextEditor::View* ) ), SLOT( viewCreated(KTextEditor::Document*, KTextEditor::View* ) ) ); } } KDevelop::ContextMenuExtension SnippetPlugin::contextMenuExtension(KDevelop::Context* context) { KDevelop::ContextMenuExtension extension = KDevelop::IPlugin::contextMenuExtension(context); if ( context->type() == KDevelop::Context::EditorContext ) { KDevelop::EditorContext *econtext = dynamic_cast(context); if ( econtext->view()->selection() ) { QAction* action = new QAction(KIcon("document-new"), i18n("Create Snippet"), this); connect(action, SIGNAL(triggered(bool)), this, SLOT(createSnippetFromSelection())); action->setData(QVariant::fromValue(econtext->view())); extension.addAction(KDevelop::ContextMenuExtension::ExtensionGroup, action); } } return extension; } void SnippetPlugin::createSnippetFromSelection() { QAction * action = qobject_cast(sender()); Q_ASSERT(action); KTextEditor::View* view = static_cast(action->data().value()); Q_ASSERT(view); QString mode; #ifdef HAVE_HIGHLIGHT_IFACE if ( KTextEditor::HighlightInterface* iface = qobject_cast(view->document()) ) { mode = iface->highlightingModeAt(view->selectionRange().start()); } #endif if ( mode.isEmpty() ) { mode = view->document()->mode(); } // try to look for a fitting repo SnippetRepository* match = 0; for ( int i = 0; i < SnippetStore::self()->rowCount(); ++i ) { SnippetRepository* repo = dynamic_cast( SnippetStore::self()->item(i) ); if ( repo && repo->fileTypes().count() == 1 && repo->fileTypes().first() == mode ) { match = repo; break; } } bool created = !match; if ( created ) { match = SnippetRepository::createRepoFromName(i18n("%1 snippets", mode)); match->setFileTypes(QStringList() << mode); } EditSnippet dlg(match, 0, view); dlg.snippetContentsEdit->setPlainText(view->selectionText()); int status = dlg.exec(); if ( created && status != KDialog::Accepted ) { // cleanup match->remove(); } } #include "snippetplugin.moc" diff --git a/plugins/snippet/snippetplugin.h b/plugins/snippet/snippetplugin.h index 9d1dbb8091..d7a85cf150 100644 --- a/plugins/snippet/snippetplugin.h +++ b/plugins/snippet/snippetplugin.h @@ -1,70 +1,74 @@ /*************************************************************************** * Copyright 2007 Robert Gruber * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef __SNIPPETPLUGIN_H__ #define __SNIPPETPLUGIN_H__ #include #include #include class SnippetCompletionModel; namespace KTextEditor { class Document; class View; } namespace KParts { class Part; } class Snippet; class KAction; class QMenu; /** * This is the main class of KDevelop's snippet plugin. * @author Robert Gruber */ class SnippetPlugin : public KDevelop::IPlugin { Q_OBJECT public: SnippetPlugin(QObject *parent, const QVariantList &args = QVariantList() ); virtual ~SnippetPlugin(); /** * Inserts the given @p snippet into the currently active view. * If the current active view is not inherited from KTextEditor::View * nothing will happen. */ void insertSnippet(Snippet* snippet); virtual KDevelop::ContextMenuExtension contextMenuExtension(KDevelop::Context* context); // KDevelop::IPlugin methods virtual void unload(); + static SnippetPlugin* self();; + private slots: void viewCreated( KTextEditor::Document*, KTextEditor::View* view ); void documentLoaded(KParts::Part*); public slots: void createSnippetFromSelection(); + void insertSnippetFromActionData(); private: class SnippetViewFactory *m_factory; class SnippetCompletionModel* m_model; + static SnippetPlugin* m_self; }; #endif diff --git a/plugins/snippet/snippetrepository.cpp b/plugins/snippet/snippetrepository.cpp index 611e2dc4b7..e9d5397fff 100644 --- a/plugins/snippet/snippetrepository.cpp +++ b/plugins/snippet/snippetrepository.cpp @@ -1,352 +1,378 @@ /*************************************************************************** * Copyright 2007 Robert Gruber * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "snippetrepository.h" #include "snippet.h" #include #include #include #include #include #include #include #include #include #include #include #include #include +#include +#include + #include "snippetstore.h" SnippetRepository::SnippetRepository(const QString& file) : QStandardItem(i18n("")), m_file(file) { setIcon( KIcon("folder") ); bool activated = SnippetStore::self()->getConfig().readEntry("enabledRepositories", QStringList()).contains(file); setCheckState(activated ? Qt::Checked : Qt::Unchecked); if ( QFile::exists(file) ) { // Tell the new repository to load it's snippets QTimer::singleShot(0, this, SLOT(slotParseFile())); } kDebug() << "created new snippet repo" << file << this; } SnippetRepository::~SnippetRepository() { // remove all our children from both the model and our internal data structures removeRows( 0, rowCount() ); } SnippetRepository* SnippetRepository::createRepoFromName(const QString& name) { QString cleanName = name; cleanName.replace('/', '-'); SnippetRepository* repo = new SnippetRepository(KGlobal::dirs()->locateLocal( "data", "ktexteditor_snippets/data/" + cleanName + ".xml" )); repo->setText(name); repo->setCheckState(Qt::Checked); KUser user; repo->setAuthors(user.property(KUser::FullName).toString()); SnippetStore::self()->appendRow(repo); return repo; } const QString& SnippetRepository::file() const { return m_file; } QString SnippetRepository::authors() const { return m_authors; } void SnippetRepository::setAuthors(const QString& authors) { m_authors = authors; } QStringList SnippetRepository::fileTypes() const { return m_filetypes; } void SnippetRepository::setFileTypes(const QStringList& filetypes) { if ( filetypes.contains("*") ) { m_filetypes.clear(); } else { m_filetypes = filetypes; } } QString SnippetRepository::license() const { return m_license; } void SnippetRepository::setLicense(const QString& license) { m_license = license; } QString SnippetRepository::completionNamespace() const { return m_namespace; } void SnippetRepository::setCompletionNamespace(const QString& completionNamespace) { m_namespace = completionNamespace; } QString SnippetRepository::script() const { return m_script; } QString SnippetRepository::scriptToken() const { return m_scriptToken; } void SnippetRepository::setScript(const QString& script) { m_script = script; m_scriptToken = SnippetStore::self()->registerScript(m_script); } void SnippetRepository::remove() { QFile::remove(m_file); setCheckState(Qt::Unchecked); model()->invisibleRootItem()->removeRow(row()); } ///copied code from snippets_tng/lib/completionmodel.cpp ///@copyright 2009 Joseph Wenninger static void addAndCreateElement(QDomDocument& doc, QDomElement& item, const QString& name, const QString &content) { QDomElement element=doc.createElement(name); element.appendChild(doc.createTextNode(content)); item.appendChild(element); } void SnippetRepository::save() { ///based on the code from snippets_tng/lib/completionmodel.cpp ///@copyright 2009 Joseph Wenninger /* prefix test1 postfix (param1, param2) This is a test testtemplate This is a test ${WHAT} template */ QDomDocument doc; QDomElement root = doc.createElement("snippets"); root.setAttribute("name", text()); root.setAttribute("filetypes", m_filetypes.isEmpty() ? "*" : m_filetypes.join(";")); root.setAttribute("authors", m_authors); root.setAttribute("license", m_license); root.setAttribute("namespace", m_namespace); doc.appendChild(root); addAndCreateElement(doc, root, "script", m_script); for ( int i = 0; i < rowCount(); ++i ) { Snippet* snippet = dynamic_cast(child(i)); if ( !snippet ) { continue; } QDomElement item = doc.createElement("item"); addAndCreateElement(doc, item, "displayprefix", snippet->prefix()); addAndCreateElement(doc, item, "match", snippet->text()); addAndCreateElement(doc, item, "displaypostfix", snippet->postfix()); addAndCreateElement(doc, item, "displayarguments", snippet->arguments()); addAndCreateElement(doc, item, "fillin", snippet->snippet()); root.appendChild(item); } //KMessageBox::information(0,doc.toString()); QFileInfo fi(m_file); QString outname = KGlobal::dirs()->locateLocal( "data", "ktexteditor_snippets/data/" + fi.fileName() ); if ( m_file != outname) { QFileInfo fiout(outname); // if (fiout.exists()) { // there could be cases that new new name clashes with a global file, but I guess it is not that often. int i = 0; while(QFile::exists(outname)) { outname = KGlobal::dirs()->locateLocal( "data", "ktexteditor_snippets/data/"+QString("%1_").arg(i++)+fi.fileName()); } KMessageBox::information(QApplication::activeWindow(), i18n("You have edited a data file not located in your personal data directory; as such, a renamed clone of the original data file has been created within your personal data directory.")); } QFile outfile(outname); if (!outfile.open(QIODevice::WriteOnly)) { KMessageBox::error(0, i18n("Output file '%1' could not be opened for writing", outname)); return; } outfile.write(doc.toByteArray()); outfile.close(); m_file = outname; + + // save shortcuts + KConfigGroup config = SnippetStore::self()->getConfig().group("repository " + m_file); + for ( int i = 0; i < rowCount(); ++i ) { + Snippet* snippet = dynamic_cast(child(i)); + if ( !snippet ) { + continue; + } + config.writeEntry("shortcut " + snippet->text(), + QStringList() << snippet->action()->shortcut().primary().toString() + << snippet->action()->shortcut().alternate().toString()); + } + config.sync(); } void SnippetRepository::slotParseFile() { ///based on the code from snippets_tng/lib/completionmodel.cpp ///@copyright 2009 Joseph Wenninger QFile f(m_file); if ( !f.open(QIODevice::ReadOnly) ) { KMessageBox::error( QApplication::activeWindow(), i18n("Cannot open snippet repository %1.", m_file) ); return; } QDomDocument doc; QString errorMsg; int line, col; bool success = doc.setContent(&f, &errorMsg, &line, &col); f.close(); if (!success) { KMessageBox::error( QApplication::activeWindow(), i18n("The error %4
has been detected in the file %1 at %2/%3
", m_file, line, col, i18nc("QXml", errorMsg.toUtf8())) ); return; } // parse root item const QDomElement& docElement = doc.documentElement(); if (docElement.tagName() != "snippets") { KMessageBox::error( QApplication::activeWindow(), i18n("Invalid XML snippet file: %1", m_file) ); return; } setLicense(docElement.attribute("license")); setAuthors(docElement.attribute("authors")); setFileTypes(docElement.attribute("filetypes").split(';', QString::SkipEmptyParts)); setText(docElement.attribute("name")); setCompletionNamespace(docElement.attribute("namespace")); + // load shortcuts + KConfigGroup config = SnippetStore::self()->getConfig().group("repository " + m_file); + // parse children, i.e. 's const QDomNodeList& nodes = docElement.childNodes(); for(int i = 0; i < nodes.size(); ++i ) { const QDomNode& node = nodes.at(i); if ( !node.isElement() ) { continue; } const QDomElement& item = node.toElement(); if ( item.tagName() == "script" ) { setScript(item.text()); } if ( item.tagName() != "item" ) { continue; } Snippet* snippet = new Snippet; const QDomNodeList& children = node.childNodes(); for(int j = 0; j < children.size(); ++j) { const QDomNode& childNode = children.at(j); if ( !childNode.isElement() ) { continue; } const QDomElement& child = childNode.toElement(); if ( child.tagName() == "match" ) { snippet->setText(child.text()); } else if ( child.tagName() == "fillin" ) { snippet->setSnippet(child.text()); } else if ( child.tagName() == "displayprefix" ) { snippet->setPrefix(child.text()); } else if ( child.tagName() == "displaypostfix" ) { snippet->setPostfix(child.text()); } else if ( child.tagName() == "displayarguments" ) { snippet->setArguments(child.text()); } } // require at least a non-empty name and snippet if ( snippet->text().isEmpty() || snippet->snippet().isEmpty() ) { delete snippet; continue; } else { + const QStringList shortcuts = config.readEntry("shortcut " + snippet->text(), QStringList()); + if ( shortcuts.count() >= 2 ) { + KShortcut shortcut; + shortcut.setPrimary(shortcuts.value(0)); + shortcut.setAlternate(shortcuts.value(1)); + snippet->action()->setShortcut(shortcut); + } appendRow(snippet); } } } QVariant SnippetRepository::data(int role) const { if ( role == Qt::ToolTipRole ) { if ( checkState() != Qt::Checked ) { return i18n("Repository is disabled, the contained snippets will not be shown during code-completion."); } if ( m_filetypes.isEmpty() ) { return i18n("Applies to all filetypes"); } else { return i18n("Applies to the following filetypes: %1", m_filetypes.join(", ")); } } else if ( role == Qt::ForegroundRole && checkState() != Qt::Checked ) { ///TODO: make the selected items also "disalbed" so the toggle action is seen directly KColorScheme scheme(QPalette::Disabled, KColorScheme::View); QColor c = scheme.foreground(KColorScheme::ActiveText).color(); return QVariant(c); } return QStandardItem::data(role); } void SnippetRepository::setData(const QVariant& value, int role) { if ( role == Qt::CheckStateRole ) { const int state = value.toInt(); if ( state != checkState() ) { KConfigGroup config = SnippetStore::self()->getConfig(); QStringList currentlyEnabled = config.readEntry("enabledRepositories", QStringList()); bool shouldSave = false; if ( state == Qt::Checked && !currentlyEnabled.contains(m_file) ) { currentlyEnabled << m_file; shouldSave = true; } else if ( state == Qt::Unchecked && currentlyEnabled.contains(m_file) ) { currentlyEnabled.removeAll(m_file); shouldSave = true; } if ( shouldSave ) { config.writeEntry("enabledRepositories", currentlyEnabled); config.sync(); } } } QStandardItem::setData(value, role); } #include "snippetrepository.moc"