• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • applications API Reference
  • KDE Home
  • Contact Us
 

Kate

  • kde-4.14
  • applications
  • kate
  • part
  • snippet
snippetrepository.cpp
Go to the documentation of this file.
1 /* This file is part of the Kate project.
2  * Based on the snippet plugin from KDevelop 4.
3  *
4  * Copyright (C) 2007 Robert Gruber <rgruber@users.sourceforge.net>
5  * Copyright (C) 2010 Milian Wolff <mail@milianw.de>
6  * Copyright (C) 2012 Christoph Cullmann <cullmann@kde.org>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public License
19  * along with this library; see the file COPYING.LIB. If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  */
23 
24 #include "snippetrepository.h"
25 
26 #include "snippet.h"
27 
28 #include <QTimer>
29 #include <QFile>
30 #include <QFileInfo>
31 
32 #include <KIcon>
33 #include <KDebug>
34 
35 #include <QDomDocument>
36 #include <QDomElement>
37 #include <KStandardDirs>
38 
39 #include <KMessageBox>
40 #include <KLocalizedString>
41 #include <QApplication>
42 
43 #include <KColorScheme>
44 
45 #include <KUser>
46 
47 #include <KAction>
48 #include <KShortcut>
49 
50 #include "snippetstore.h"
51 
52 SnippetRepository::SnippetRepository(const QString& file)
53  : QStandardItem(i18n("<empty repository>")), m_file(file), m_registeredScript(0)
54 {
55  setIcon( KIcon("folder") );
56  bool activated = SnippetStore::self()->getConfig().readEntry<QStringList>("enabledRepositories", QStringList()).contains(file);
57  setCheckState(activated ? Qt::Checked : Qt::Unchecked);
58 
59  if ( QFile::exists(file) ) {
60  // Tell the new repository to load it's snippets
61  QTimer::singleShot(0, this, SLOT(slotParseFile()));
62  }
63 
64  kDebug() << "created new snippet repo" << file << this;
65 }
66 
67 SnippetRepository::~SnippetRepository()
68 {
69  // remove all our children from both the model and our internal data structures
70  removeRows( 0, rowCount() );
71 }
72 
73 SnippetRepository* SnippetRepository::createRepoFromName(const QString& name)
74 {
75  QString cleanName = name;
76  cleanName.replace('/', '-');
77 
78  SnippetRepository* repo = new SnippetRepository(KGlobal::dirs()->locateLocal( "data",
79  "ktexteditor_snippets/data/" + cleanName + ".xml" ));
80  repo->setText(name);
81  repo->setCheckState(Qt::Checked);
82  KUser user;
83  repo->setAuthors(user.property(KUser::FullName).toString());
84  SnippetStore::self()->appendRow(repo);
85  return repo;
86 }
87 
88 const QString& SnippetRepository::file() const
89 {
90  return m_file;
91 }
92 
93 QString SnippetRepository::authors() const
94 {
95  return m_authors;
96 }
97 
98 void SnippetRepository::setAuthors(const QString& authors)
99 {
100  m_authors = authors;
101 }
102 
103 QStringList SnippetRepository::fileTypes() const
104 {
105  return m_filetypes;
106 }
107 
108 void SnippetRepository::setFileTypes(const QStringList& filetypes)
109 {
110  if ( filetypes.contains("*") ) {
111  m_filetypes.clear();
112  } else {
113  m_filetypes = filetypes;
114  }
115 }
116 
117 QString SnippetRepository::license() const
118 {
119  return m_license;
120 }
121 
122 void SnippetRepository::setLicense(const QString& license)
123 {
124  m_license = license;
125 }
126 
127 QString SnippetRepository::completionNamespace() const
128 {
129  return m_namespace;
130 }
131 
132 void SnippetRepository::setCompletionNamespace(const QString& completionNamespace)
133 {
134  m_namespace = completionNamespace;
135 }
136 
137 QString SnippetRepository::script() const
138 {
139  return m_script;
140 }
141 
142 KTextEditor::TemplateScript* SnippetRepository::registeredScript() const
143 {
144  return m_registeredScript;
145 }
146 
147 void SnippetRepository::setScript(const QString& script)
148 {
149  m_script = script;
150  if ( m_registeredScript ) {
151  SnippetStore::self()->unregisterScript(m_registeredScript);
152  }
153  m_registeredScript = SnippetStore::self()->registerScript(m_script);
154 }
155 
156 void SnippetRepository::remove()
157 {
158  QFile::remove(m_file);
159  setCheckState(Qt::Unchecked);
160  model()->invisibleRootItem()->removeRow(row());
161 }
162 
165 static void addAndCreateElement(QDomDocument& doc, QDomElement& item, const QString& name, const QString &content)
166 {
167  QDomElement element=doc.createElement(name);
168  element.appendChild(doc.createTextNode(content));
169  item.appendChild(element);
170 }
171 
172 void SnippetRepository::save()
173 {
176  /*
177  <snippets name="Testsnippets" filetype="*" authors="Joseph Wenninger" license="BSD" namespace="test::">
178  <script>
179  JavaScript
180  </script>
181  <item>
182  <displayprefix>prefix</displayprefix>
183  <match>test1</match>
184  <displaypostfix>postfix</displaypostfix>
185  <displayarguments>(param1, param2)</displayarguments>
186  <fillin>This is a test</fillin>
187  </item>
188  <item>
189  <match>testtemplate</match>
190  <fillin>This is a test ${WHAT} template</fillin>
191  </item>
192  </snippets>
193  */
194  QDomDocument doc;
195 
196  QDomElement root = doc.createElement("snippets");
197  root.setAttribute("name", text());
198  root.setAttribute("filetypes", m_filetypes.isEmpty() ? "*" : m_filetypes.join(";"));
199  root.setAttribute("authors", m_authors);
200  root.setAttribute("license", m_license);
201  root.setAttribute("namespace", m_namespace);
202 
203  doc.appendChild(root);
204 
205  addAndCreateElement(doc, root, "script", m_script);
206 
207  for ( int i = 0; i < rowCount(); ++i ) {
208  Snippet* snippet = dynamic_cast<Snippet*>(child(i));
209  if ( !snippet ) {
210  continue;
211  }
212  QDomElement item = doc.createElement("item");
213  addAndCreateElement(doc, item, "displayprefix", snippet->prefix());
214  addAndCreateElement(doc, item, "match", snippet->text());
215  addAndCreateElement(doc, item, "displaypostfix", snippet->postfix());
216  addAndCreateElement(doc, item, "displayarguments", snippet->arguments());
217  addAndCreateElement(doc, item, "fillin", snippet->snippet());
218  root.appendChild(item);
219  }
220  //KMessageBox::information(0,doc.toString());
221  QFileInfo fi(m_file);
222  QString outname = KGlobal::dirs()->locateLocal( "data", "ktexteditor_snippets/data/" + fi.fileName() );
223  if ( m_file != outname) {
224  QFileInfo fiout(outname);
225 // if (fiout.exists()) {
226 // there could be cases that new new name clashes with a global file, but I guess it is not that often.
227  int i = 0;
228  while(QFile::exists(outname)) {
229  outname = KGlobal::dirs()->locateLocal( "data", "ktexteditor_snippets/data/"+QString("%1_").arg(i++)+fi.fileName());
230  }
231  KMessageBox::information(QApplication::activeWindow(),
232  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."));
233  }
234 
235  QFile outfile(outname);
236  if (!outfile.open(QIODevice::WriteOnly)) {
237  KMessageBox::error(0, i18n("Output file '%1' could not be opened for writing", outname));
238  return;
239  }
240  outfile.write(doc.toByteArray());
241  outfile.close();
242  m_file = outname;
243 
244  // save shortcuts
245  KConfigGroup config = SnippetStore::self()->getConfig().group("repository " + m_file);
246  for ( int i = 0; i < rowCount(); ++i ) {
247  Snippet* snippet = dynamic_cast<Snippet*>(child(i));
248  if ( !snippet ) {
249  continue;
250  }
251  config.writeEntry("shortcut " + snippet->text(),
252  QStringList() << snippet->action()->shortcut().primary().toString()
253  << snippet->action()->shortcut().alternate().toString());
254  }
255  config.sync();
256 }
257 
258 void SnippetRepository::slotParseFile()
259 {
262 
263  QFile f(m_file);
264 
265  if ( !f.open(QIODevice::ReadOnly) ) {
266  KMessageBox::error( QApplication::activeWindow(), i18n("Cannot open snippet repository %1.", m_file) );
267  return;
268  }
269 
270  QDomDocument doc;
271  QString errorMsg;
272  int line, col;
273  bool success = doc.setContent(&f, &errorMsg, &line, &col);
274  f.close();
275 
276  if (!success) {
277  KMessageBox::error( QApplication::activeWindow(),
278  i18n("<qt>The error <b>%4</b><br /> has been detected in the file %1 at %2/%3</qt>",
279  m_file, line, col, i18nc("QXml", errorMsg.toUtf8())) );
280  return;
281  }
282 
283  // parse root item
284  const QDomElement& docElement = doc.documentElement();
285  if (docElement.tagName() != "snippets") {
286  KMessageBox::error( QApplication::activeWindow(), i18n("Invalid XML snippet file: %1", m_file) );
287  return;
288  }
289  setLicense(docElement.attribute("license"));
290  setAuthors(docElement.attribute("authors"));
291  setFileTypes(docElement.attribute("filetypes").split(';', QString::SkipEmptyParts));
292  setText(docElement.attribute("name"));
293  setCompletionNamespace(docElement.attribute("namespace"));
294 
295  // load shortcuts
296  KConfigGroup config = SnippetStore::self()->getConfig().group("repository " + m_file);
297 
298  // parse children, i.e. <item>'s
299  const QDomNodeList& nodes = docElement.childNodes();
300  for(int i = 0; i < nodes.size(); ++i ) {
301  const QDomNode& node = nodes.at(i);
302  if ( !node.isElement() ) {
303  continue;
304  }
305  const QDomElement& item = node.toElement();
306  if ( item.tagName() == "script" ) {
307  setScript(item.text());
308  }
309  if ( item.tagName() != "item" ) {
310  continue;
311  }
312  Snippet* snippet = new Snippet;
313  const QDomNodeList& children = node.childNodes();
314  for(int j = 0; j < children.size(); ++j) {
315  const QDomNode& childNode = children.at(j);
316  if ( !childNode.isElement() ) {
317  continue;
318  }
319  const QDomElement& child = childNode.toElement();
320  if ( child.tagName() == "match" ) {
321  snippet->setText(child.text());
322  } else if ( child.tagName() == "fillin" ) {
323  snippet->setSnippet(child.text());
324  } else if ( child.tagName() == "displayprefix" ) {
325  snippet->setPrefix(child.text());
326  } else if ( child.tagName() == "displaypostfix" ) {
327  snippet->setPostfix(child.text());
328  } else if ( child.tagName() == "displayarguments" ) {
329  snippet->setArguments(child.text());
330  }
331  }
332  // require at least a non-empty name and snippet
333  if ( snippet->text().isEmpty() || snippet->snippet().isEmpty() ) {
334  delete snippet;
335  continue;
336  } else {
337  const QStringList shortcuts = config.readEntry("shortcut " + snippet->text(), QStringList());
338  if ( shortcuts.count() >= 2 ) {
339  KShortcut shortcut;
340  shortcut.setPrimary(shortcuts.value(0));
341  shortcut.setAlternate(shortcuts.value(1));
342  snippet->action()->setShortcut(shortcut);
343  }
344  appendRow(snippet);
345  }
346  }
347 }
348 
349 QVariant SnippetRepository::data(int role) const
350 {
351  if ( role == Qt::ToolTipRole ) {
352  if ( checkState() != Qt::Checked ) {
353  return i18n("Repository is disabled, the contained snippets will not be shown during code-completion.");
354  }
355  if ( m_filetypes.isEmpty() ) {
356  return i18n("Applies to all filetypes");
357  } else {
358  return i18n("Applies to the following filetypes: %1", m_filetypes.join(", "));
359  }
360  } else if ( role == Qt::ForegroundRole && checkState() != Qt::Checked ) {
362  KColorScheme scheme(QPalette::Disabled, KColorScheme::View);
363  QColor c = scheme.foreground(KColorScheme::ActiveText).color();
364  return QVariant(c);
365  }
366  return QStandardItem::data(role);
367 }
368 
369 void SnippetRepository::setData(const QVariant& value, int role)
370 {
371  if ( role == Qt::CheckStateRole ) {
372  const int state = value.toInt();
373  if ( state != checkState() ) {
374  KConfigGroup config = SnippetStore::self()->getConfig();
375  QStringList currentlyEnabled = config.readEntry("enabledRepositories", QStringList());
376  bool shouldSave = false;
377  if ( state == Qt::Checked && !currentlyEnabled.contains(m_file) ) {
378  currentlyEnabled << m_file;
379  shouldSave = true;
380  } else if ( state == Qt::Unchecked && currentlyEnabled.contains(m_file) ) {
381  currentlyEnabled.removeAll(m_file);
382  shouldSave = true;
383  }
384 
385  if ( shouldSave ) {
386  config.writeEntry("enabledRepositories", currentlyEnabled);
387  config.sync();
388  }
389  }
390  }
391  QStandardItem::setData(value, role);
392 }
393 
394 #include "snippetrepository.moc"
QList::clear
void clear()
Snippet::setSnippet
void setSnippet(const QString &snippet)
Sets the actual contents of this snippet.
Definition: snippet.cpp:52
Kate::Script::i18n
QScriptValue i18n(QScriptContext *context, QScriptEngine *engine)
i18n("text", arguments [optional])
Definition: katescripthelpers.cpp:186
SnippetRepository::data
virtual QVariant data(int role=Qt::UserRole+1) const
Definition: snippetrepository.cpp:349
QStandardItem::setIcon
void setIcon(const QIcon &icon)
SnippetRepository::setData
virtual void setData(const QVariant &value, int role=Qt::UserRole+1)
Definition: snippetrepository.cpp:369
SnippetRepository::setCompletionNamespace
void setCompletionNamespace(const QString &completionNamespace)
Sets the code completion namespace for this repository.
Definition: snippetrepository.cpp:132
SnippetStore::unregisterScript
void unregisterScript(KTextEditor::TemplateScript *token)
Unregister script identified by token.
Definition: snippetstore.cpp:128
QDomNode::appendChild
QDomNode appendChild(const QDomNode &newChild)
QStandardItemModel::invisibleRootItem
QStandardItem * invisibleRootItem() const
QDomElement::attribute
QString attribute(const QString &name, const QString &defValue) const
Kate::Script::i18nc
QScriptValue i18nc(QScriptContext *context, QScriptEngine *engine)
i18nc("context", "text", arguments [optional])
Definition: katescripthelpers.cpp:210
QFile::remove
bool remove()
SnippetRepository::createRepoFromName
static SnippetRepository * createRepoFromName(const QString &name)
Creates a snippet repository for the given name and adds it to the SnippetStore.
Definition: snippetrepository.cpp:73
QString::split
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
SnippetRepository::~SnippetRepository
~SnippetRepository()
Definition: snippetrepository.cpp:67
QDomNode::isElement
bool isElement() const
QDomNodeList
SnippetStore::registerScript
KTextEditor::TemplateScript * registerScript(const QString &script)
Register script to make it available in snippets.
Definition: snippetstore.cpp:135
QObject::children
const QObjectList & children() const
Snippet::setArguments
void setArguments(const QString &arguments)
Sets the display arguments of this snippet.
Definition: snippet.cpp:82
QStringList::contains
bool contains(const QString &str, Qt::CaseSensitivity cs) const
Snippet::setPrefix
void setPrefix(const QString &prefix)
Sets the display prefix of this snippet.
Definition: snippet.cpp:62
QStandardItem::removeRow
void removeRow(int row)
Snippet::action
KAction * action()
Action to trigger insertion of this snippet.
Definition: snippet.cpp:87
QDomDocument::documentElement
QDomElement documentElement() const
QDomNode
QStringList::join
QString join(const QString &separator) const
QFile::exists
bool exists() const
QDomNode::childNodes
QDomNodeList childNodes() const
SnippetRepository::license
QString license() const
The license for the snippets contained in this repository.
Definition: snippetrepository.cpp:117
QStandardItem::text
QString text() const
QFile
QStandardItem::checkState
Qt::CheckState checkState() const
QStandardItem::setData
virtual void setData(const QVariant &value, int role)
QList::value
T value(int i) const
QDomNode::toElement
QDomElement toElement() const
SnippetRepository::setFileTypes
void setFileTypes(const QStringList &filetypes)
Sets the valid filetypes for the snippets contained in this repository.
Definition: snippetrepository.cpp:108
QObject::name
const char * name() const
QApplication::activeWindow
QWidget * activeWindow()
QList::count
int count(const T &value) const
QDomElement::text
QString text() const
QVariant::toInt
int toInt(bool *ok) const
QFileInfo::fileName
QString fileName() const
addAndCreateElement
static void addAndCreateElement(QDomDocument &doc, QDomElement &item, const QString &name, const QString &content)
copied code from snippets_tng/lib/completionmodel.cpp
Definition: snippetrepository.cpp:165
QDomElement::setAttribute
void setAttribute(const QString &name, const QString &value)
SnippetRepository::save
void save()
Save this repository to disk.
Definition: snippetrepository.cpp:172
QStandardItem::appendRow
void appendRow(const QList< QStandardItem * > &items)
QList::isEmpty
bool isEmpty() const
QString::isEmpty
bool isEmpty() const
QList::removeAll
int removeAll(const T &value)
SnippetRepository::authors
QString authors() const
The author(s) of the snippets contained in this repository.
Definition: snippetrepository.cpp:93
SnippetRepository::completionNamespace
QString completionNamespace() const
The namespace associated with this repository.
Definition: snippetrepository.cpp:127
Snippet::setPostfix
void setPostfix(const QString &postfix)
Sets the display postfix of this snippet.
Definition: snippet.cpp:72
SnippetRepository::script
QString script() const
The QtScript(s) associated with this repository.
Definition: snippetrepository.cpp:137
QStandardItem::removeRows
void removeRows(int row, int count)
QString
QColor
SnippetRepository
Each object of this type represents a repository of snippets.
Definition: snippetrepository.h:52
QFile::open
virtual bool open(QFlags< QIODevice::OpenModeFlag > mode)
Snippet
One object of this class represents a single snippet.
Definition: snippet.h:42
QStandardItem::child
QStandardItem * child(int row, int column) const
QStringList
QDomDocument::createTextNode
QDomText createTextNode(const QString &value)
QFileInfo
Snippet::prefix
QString prefix() const
Returns the display prefix of this snippet.
Definition: snippet.cpp:57
SnippetRepository::setAuthors
void setAuthors(const QString &authors)
Sets the author(s) of the snippets contained in this repository.
Definition: snippetrepository.cpp:98
SnippetRepository::SnippetRepository
SnippetRepository(const QString &file)
Creates a new SnippetRepository.
Definition: snippetrepository.cpp:52
QDomDocument
QFile::close
virtual void close()
SnippetRepository::setScript
void setScript(const QString &script)
Sets the QtScript(s) associated with this repository.
Definition: snippetrepository.cpp:147
QStandardItem::setText
void setText(const QString &text)
QString::replace
QString & replace(int position, int n, QChar after)
SnippetRepository::remove
void remove()
Remove this repository from the disk.
Definition: snippetrepository.cpp:156
SnippetRepository::file
const QString & file() const
The path to this repository's file.
Definition: snippetrepository.cpp:88
Snippet::snippet
QString snippet() const
Returns the actual contents of this snippet.
Definition: snippet.cpp:47
SnippetStore::self
static SnippetStore * self()
Retuns the SnippetStore.
Definition: snippetstore.cpp:67
SnippetStore::getConfig
KConfigGroup getConfig()
Definition: snippetstore.cpp:81
QStandardItem::model
QStandardItemModel * model() const
QIODevice::write
qint64 write(const char *data, qint64 maxSize)
QStandardItem::rowCount
int rowCount() const
QDomElement::tagName
QString tagName() const
QStandardItem::setCheckState
void setCheckState(Qt::CheckState state)
QStandardItem
Snippet::arguments
QString arguments() const
Returns the display arguments of this snippet.
Definition: snippet.cpp:77
QDomNodeList::size
int size() const
snippetstore.h
QDomDocument::createElement
QDomElement createElement(const QString &tagName)
Snippet::postfix
QString postfix() const
Returns the display postfix of this snippet.
Definition: snippet.cpp:67
QDomElement
SnippetRepository::registeredScript
KTextEditor::TemplateScript * registeredScript() const
The token identifying the script in this repository.
Definition: snippetrepository.cpp:142
QStandardItem::row
int row() const
QStandardItemModel::appendRow
void appendRow(const QList< QStandardItem * > &items)
QStandardItem::data
virtual QVariant data(int role) const
SnippetRepository::fileTypes
QStringList fileTypes() const
The valid filetypes for the snippets contained in this repository.
Definition: snippetrepository.cpp:103
snippetrepository.h
SnippetRepository::setLicense
void setLicense(const QString &license)
Sets the license for the snippets contained in this repository.
Definition: snippetrepository.cpp:122
snippet.h
QDomDocument::toByteArray
QByteArray toByteArray(int indent) const
QDomNodeList::at
QDomNode at(int index) const
QDomDocument::setContent
bool setContent(const QByteArray &data, bool namespaceProcessing, QString *errorMsg, int *errorLine, int *errorColumn)
QTimer::singleShot
singleShot
QVariant
QString::toUtf8
QByteArray toUtf8() const
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Sat May 9 2020 03:56:59 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

Kate

Skip menu "Kate"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

applications API Reference

Skip menu "applications API Reference"
  •   kate
  •       kate
  •   KTextEditor
  •   Kate
  • Konsole

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal