• 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
  • syntax
katesyntaxdocument.cpp
Go to the documentation of this file.
1 /* This file is part of the KDE libraries
2  Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
3  Copyright (C) 2000 Scott Manson <sdmanson@alltel.net>
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License version 2 as published by the Free Software Foundation.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Library General Public License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to
16  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  Boston, MA 02110-1301, USA.
18 */
19 
20 #include "katesyntaxdocument.h"
21 
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <unistd.h>
25 #include <time.h>
26 #include <sys/time.h>
27 
28 #include <kdebug.h>
29 #include <kstandarddirs.h>
30 #include <klocale.h>
31 #include <kmessagebox.h>
32 #include <kconfiggroup.h>
33 #include <kde_file.h>
34 
35 #include <QtGui/QApplication>
36 #include <QtCore/QFile>
37 
38 // use this to turn on over verbose debug output...
39 #undef KSD_OVER_VERBOSE
40 
41 KateSyntaxDocument::KateSyntaxDocument(KConfig *config, bool force)
42  : QDomDocument()
43  , m_config (config)
44 {
45  // Let's build the Mode List (katesyntaxhighlightingrc)
46  setupModeList(force);
47 }
48 
49 KateSyntaxDocument::~KateSyntaxDocument()
50 {
51  for (int i=0; i < myModeList.size(); i++)
52  delete myModeList[i];
53 }
54 
59 bool KateSyntaxDocument::setIdentifier(const QString& identifier)
60 {
61  // if the current file is the same as the new one don't do anything.
62  if(currentFile != identifier)
63  {
64  // let's open the new file
65  QFile f( identifier );
66 
67  if ( f.open(QIODevice::ReadOnly) )
68  {
69  // Let's parse the contets of the xml file
70  /* The result of this function should be check for robustness,
71  a false returned means a parse error */
72  QString errorMsg;
73  int line, col;
74  bool success=setContent(&f,&errorMsg,&line,&col);
75 
76  // Ok, now the current file is the pretended one (identifier)
77  currentFile = identifier;
78 
79  // Close the file, is not longer needed
80  f.close();
81 
82  if (!success)
83  {
84  KMessageBox::error(QApplication::activeWindow(),i18n("<qt>The error <b>%4</b><br /> has been detected in the file %1 at %2/%3</qt>", identifier,
85  line, col, i18nc("QXml",errorMsg.toUtf8())));
86  return false;
87  }
88  }
89  else
90  {
91  // Oh o, we couldn't open the file.
92  KMessageBox::error(QApplication::activeWindow(), i18n("Unable to open %1", identifier) );
93  return false;
94  }
95  }
96  return true;
97 }
98 
102 bool KateSyntaxDocument::nextGroup( KateSyntaxContextData* data)
103 {
104  if(!data)
105  return false;
106 
107  // No group yet so go to first child
108  if (data->currentGroup.isNull())
109  {
110  // Skip over non-elements. So far non-elements are just comments
111  QDomNode node = data->parent.firstChild();
112  while (node.isComment())
113  node = node.nextSibling();
114 
115  data->currentGroup = node.toElement();
116  }
117  else
118  {
119  // common case, iterate over siblings, skipping comments as we go
120  QDomNode node = data->currentGroup.nextSibling();
121  while (node.isComment())
122  node = node.nextSibling();
123 
124  data->currentGroup = node.toElement();
125  }
126 
127  return !data->currentGroup.isNull();
128 }
129 
133 bool KateSyntaxDocument::nextItem( KateSyntaxContextData* data)
134 {
135  if(!data)
136  return false;
137 
138  if (data->item.isNull())
139  {
140  QDomNode node = data->currentGroup.firstChild();
141  while (node.isComment())
142  node = node.nextSibling();
143 
144  data->item = node.toElement();
145  }
146  else
147  {
148  QDomNode node = data->item.nextSibling();
149  while (node.isComment())
150  node = node.nextSibling();
151 
152  data->item = node.toElement();
153  }
154 
155  return !data->item.isNull();
156 }
157 
161 QString KateSyntaxDocument::groupItemData( const KateSyntaxContextData* data, const QString& name){
162  if(!data)
163  return QString();
164 
165  // If there's no name just return the tag name of data->item
166  if ( (!data->item.isNull()) && (name.isEmpty()))
167  {
168  return data->item.tagName();
169  }
170 
171  // if name is not empty return the value of the attribute name
172  if (!data->item.isNull())
173  {
174  return data->item.attribute(name);
175  }
176 
177  return QString();
178 
179 }
180 
181 QString KateSyntaxDocument::groupData( const KateSyntaxContextData* data,const QString& name)
182 {
183  if(!data)
184  return QString();
185 
186  if (!data->currentGroup.isNull())
187  {
188  return data->currentGroup.attribute(name);
189  }
190  else
191  {
192  return QString();
193  }
194 }
195 
196 void KateSyntaxDocument::freeGroupInfo( KateSyntaxContextData* data)
197 {
198  delete data;
199 }
200 
201 KateSyntaxContextData* KateSyntaxDocument::getSubItems(KateSyntaxContextData* data)
202 {
203  KateSyntaxContextData *retval = new KateSyntaxContextData;
204 
205  if (data != 0)
206  {
207  retval->parent = data->currentGroup;
208  retval->currentGroup = data->item;
209  }
210 
211  return retval;
212 }
213 
214 bool KateSyntaxDocument::getElement (QDomElement &element, const QString &mainGroupName, const QString &config)
215 {
216 #ifdef KSD_OVER_VERBOSE
217  kDebug(13010) << "Looking for \"" << mainGroupName << "\" -> \"" << config << "\".";
218 #endif
219 
220  QDomNodeList nodes = documentElement().childNodes();
221 
222  // Loop over all these child nodes looking for mainGroupName
223  for (int i=0; i<nodes.count(); i++)
224  {
225  QDomElement elem = nodes.item(i).toElement();
226  if (elem.tagName() == mainGroupName)
227  {
228  // Found mainGroupName ...
229  QDomNodeList subNodes = elem.childNodes();
230 
231  // ... so now loop looking for config
232  for (int j=0; j<subNodes.count(); j++)
233  {
234  QDomElement subElem = subNodes.item(j).toElement();
235  if (subElem.tagName() == config)
236  {
237  // Found it!
238  element = subElem;
239  return true;
240  }
241  }
242 
243 #ifdef KSD_OVER_VERBOSE
244  kDebug(13010) << "WARNING: \""<< config <<"\" wasn't found!";
245 #endif
246 
247  return false;
248  }
249  }
250 
251 #ifdef KSD_OVER_VERBOSE
252  kDebug(13010) << "WARNING: \""<< mainGroupName <<"\" wasn't found!";
253 #endif
254 
255  return false;
256 }
257 
262 KateSyntaxContextData* KateSyntaxDocument::getConfig(const QString& mainGroupName, const QString &config)
263 {
264  QDomElement element;
265  if (getElement(element, mainGroupName, config))
266  {
267  KateSyntaxContextData *data = new KateSyntaxContextData;
268  data->item = element;
269  return data;
270  }
271  return 0;
272 }
273 
278 KateSyntaxContextData* KateSyntaxDocument::getGroupInfo(const QString& mainGroupName, const QString &group)
279 {
280  QDomElement element;
281  if (getElement(element, mainGroupName, group+'s'))
282  {
283  KateSyntaxContextData *data = new KateSyntaxContextData;
284  data->parent = element;
285  return data;
286  }
287  return 0;
288 }
289 
293 QStringList& KateSyntaxDocument::finddata(const QString& mainGroup, const QString& type, bool clearList)
294 {
295 #ifdef KSD_OVER_VERBOSE
296  kDebug(13010)<<"Create a list of keywords \""<<type<<"\" from \""<<mainGroup<<"\".";
297 #endif
298 
299  if (clearList)
300  m_data.clear();
301 
302  for(QDomNode node = documentElement().firstChild(); !node.isNull(); node = node.nextSibling())
303  {
304  QDomElement elem = node.toElement();
305  if (elem.tagName() == mainGroup)
306  {
307 #ifdef KSD_OVER_VERBOSE
308  kDebug(13010)<<"\""<<mainGroup<<"\" found.";
309 #endif
310 
311  QDomNodeList nodelist1 = elem.elementsByTagName("list");
312 
313  for (int l=0; l<nodelist1.count(); l++)
314  {
315  if (nodelist1.item(l).toElement().attribute("name") == type)
316  {
317 #ifdef KSD_OVER_VERBOSE
318  kDebug(13010)<<"List with attribute name=\""<<type<<"\" found.";
319 #endif
320 
321  QDomNodeList childlist = nodelist1.item(l).toElement().childNodes();
322 
323  for (int i=0; i<childlist.count(); i++)
324  {
325  QString element = childlist.item(i).toElement().text().trimmed();
326  if (element.isEmpty())
327  continue;
328 
329 #ifdef KSD_OVER_VERBOSE
330  if (i<6)
331  {
332  kDebug(13010)<<"\""<<element<<"\" added to the list \""<<type<<"\"";
333  }
334  else if(i==6)
335  {
336  kDebug(13010)<<"... The list continues ...";
337  }
338 #endif
339 
340  m_data += element;
341  }
342 
343  break;
344  }
345  }
346  break;
347  }
348  }
349 
350  return m_data;
351 }
352 
353 // Private
357 void KateSyntaxDocument::setupModeList (bool force)
358 {
359  // If there's something in myModeList the Mode List was already built so, don't do it again
360  if (!myModeList.isEmpty())
361  return;
362 
363  // We'll store the ModeList in katesyntaxhighlightingrc
364  KConfigGroup generalConfig(m_config, "General");
365 
366  // figure our if the kate install is too new
367  if (generalConfig.readEntry ("Version",0) > generalConfig.readEntry ("CachedVersion",0))
368  {
369  generalConfig.writeEntry ("CachedVersion", generalConfig.readEntry ("Version",0));
370  force = true;
371  }
372 
373  // Let's get a list of all the xml files for hl
374  const QStringList list = KGlobal::dirs()->findAllResources("data","katepart/syntax/*.xml",
375  KStandardDirs::NoDuplicates);
376 
377  // Let's iterate through the list and build the Mode List
378  for ( QStringList::ConstIterator it = list.begin(); it != list.end(); ++it )
379  {
380  // Each file has a group called:
381  QString Group="Cache "+ *it;
382 
383  // Let's go to this group
384  KConfigGroup config(m_config, Group);
385 
386  // stat the file
387  KDE_struct_stat sbuf;
388  memset (&sbuf, 0, sizeof(sbuf));
389  KDE::stat(*it, &sbuf);
390 
391  // If the group exist and we're not forced to read the xml file, let's build myModeList for katesyntax..rc
392  if (!force && config.exists() && (sbuf.st_mtime == config.readEntry("lastModified",0)))
393  {
394  // Let's make a new KateSyntaxModeListItem to instert in myModeList from the information in katesyntax..rc
395  KateSyntaxModeListItem *mli=new KateSyntaxModeListItem;
396  mli->name = config.readEntry("name");
397  mli->nameTranslated = i18nc("Language",mli->name.toUtf8());
398  mli->section = i18nc("Language Section",config.readEntry("section").toUtf8());
399  mli->mimetype = config.readEntry("mimetype");
400  mli->extension = config.readEntry("extension");
401  mli->version = config.readEntry("version");
402  mli->priority = config.readEntry("priority");
403  mli->style = config.readEntry("style");
404  mli->author = config.readEntry("author");
405  mli->license = config.readEntry("license");
406  mli->indenter = config.readEntry("indenter");
407  mli->hidden = config.readEntry("hidden", false);
408  mli->identifier = *it;
409 
410  // Apend the item to the list
411  myModeList.append(mli);
412  }
413  else
414  {
415 #ifdef KSD_OVER_VERBOSE
416  kDebug (13010) << "UPDATE hl cache for: " << *it;
417 #endif
418 
419  // We're forced to read the xml files or the mode doesn't exist in the katesyntax...rc
420  QFile f(*it);
421 
422  if (f.open(QIODevice::ReadOnly))
423  {
424  // Ok we opened the file, let's read the contents and close the file
425  /* the return of setContent should be checked because a false return shows a parsing error */
426  QString errMsg;
427  int line, col;
428 
429  bool success = setContent(&f,&errMsg,&line,&col);
430 
431  f.close();
432 
433  if (success)
434  {
435  QDomElement root = documentElement();
436 
437  if (!root.isNull())
438  {
439  // If the 'first' tag is language, go on
440  if (root.tagName()=="language")
441  {
442  // let's make the mode list item.
443  KateSyntaxModeListItem *mli = new KateSyntaxModeListItem;
444 
445  mli->name = root.attribute("name");
446  mli->section = root.attribute("section");
447  mli->mimetype = root.attribute("mimetype");
448  mli->extension = root.attribute("extensions");
449  mli->version = root.attribute("version");
450  mli->priority = root.attribute("priority");
451  mli->style = root.attribute("style");
452  mli->author = root.attribute("author");
453  mli->license = root.attribute("license");
454  mli->indenter = root.attribute("indenter");
455 
456  QString hidden = root.attribute("hidden");
457  mli->hidden = (hidden == "true" || hidden == "TRUE");
458 
459  mli->identifier = *it;
460 
461  // Now let's write or overwrite (if force==true) the entry in katesyntax...rc
462  config = KConfigGroup(m_config, Group);
463  config.writeEntry("name",mli->name);
464  config.writeEntry("section",mli->section);
465  config.writeEntry("mimetype",mli->mimetype);
466  config.writeEntry("extension",mli->extension);
467  config.writeEntry("version",mli->version);
468  config.writeEntry("priority",mli->priority);
469  config.writeEntry("style",mli->style);
470  config.writeEntry("author",mli->author);
471  config.writeEntry("license",mli->license);
472  config.writeEntry("indenter",mli->indenter);
473  config.writeEntry("hidden",mli->hidden);
474 
475  // modified time to keep cache in sync
476  config.writeEntry("lastModified", int(sbuf.st_mtime));
477 
478  // Now that the data is in the config file, translate section
479  mli->section = i18nc("Language Section",mli->section.toUtf8());
480  mli->nameTranslated = i18nc("Language",mli->name.toUtf8());
481 
482  // Append the new item to the list.
483  myModeList.append(mli);
484  }
485  }
486  }
487  else
488  {
489  KateSyntaxModeListItem *emli=new KateSyntaxModeListItem;
490 
491  emli->section=i18n("Errors!");
492  emli->mimetype="invalid_file/invalid_file";
493  emli->extension="invalid_file.invalid_file";
494  emli->version="1.";
495  emli->name=QString ("Error: %1").arg(*it); // internal
496  emli->nameTranslated=i18n("Error: %1", *it); // translated
497  emli->identifier=(*it);
498 
499  myModeList.append(emli);
500  }
501  }
502  }
503  }
504 
505  // Synchronize with the file katesyntax...rc
506  generalConfig.sync();
507 }
508 
509 // kate: space-indent on; indent-width 2; replace-tabs on;
QList::clear
void clear()
KateSyntaxDocument::freeGroupInfo
void freeGroupInfo(KateSyntaxContextData *data)
Definition: katesyntaxdocument.cpp:196
QDomElement::elementsByTagName
QDomNodeList elementsByTagName(const QString &tagname) const
Kate::Script::i18n
QScriptValue i18n(QScriptContext *context, QScriptEngine *engine)
i18n("text", arguments [optional])
Definition: katescripthelpers.cpp:186
QDomNodeList::item
QDomNode item(int index) const
KateSyntaxDocument::getSubItems
KateSyntaxContextData * getSubItems(KateSyntaxContextData *data)
Definition: katesyntaxdocument.cpp:201
KateSyntaxModeListItem::style
QString style
Default styles provided by the highlighter.
Definition: katesyntaxdocument.h:47
KateSyntaxModeListItem::section
QString section
Submenu section (eg. Assembly)
Definition: katesyntaxdocument.h:39
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
KateSyntaxModeListItem::hidden
bool hidden
Hides the mode from Kate's menus.
Definition: katesyntaxdocument.h:51
QDomNodeList
KateSyntaxModeListItem::mimetype
QString mimetype
Mimetypes this mode applies to.
Definition: katesyntaxdocument.h:40
KateSyntaxDocument::KateSyntaxDocument
KateSyntaxDocument(KConfig *config, bool force=false)
Constructor Sets the current file to nothing and build the ModeList (katesyntaxhighlightingrc) ...
Definition: katesyntaxdocument.cpp:41
QDomDocument::documentElement
QDomElement documentElement() const
QDomNode
QDomNode::childNodes
QDomNodeList childNodes() const
KateSyntaxDocument::nextGroup
bool nextGroup(KateSyntaxContextData *data)
Jump to the next group, KateSyntaxContextData::currentGroup will point to the next group...
Definition: katesyntaxdocument.cpp:102
QFile
KateSyntaxModeListItem::version
QString version
Definition: katesyntaxdocument.h:43
QList::size
int size() const
KateSyntaxModeListItem::nameTranslated
QString nameTranslated
i18n of same, for display purposes
Definition: katesyntaxdocument.h:38
QDomNode::nextSibling
QDomNode nextSibling() const
QDomNode::toElement
QDomElement toElement() const
KateSyntaxModeListItem::priority
QString priority
Priority (mapped to an integer?) for conflict- resolution when the same file extension has multiple h...
Definition: katesyntaxdocument.h:44
QApplication::activeWindow
QWidget * activeWindow()
QDomNodeList::count
int count() const
QList::append
void append(const T &value)
KateSyntaxDocument::~KateSyntaxDocument
~KateSyntaxDocument()
Desctructor.
Definition: katesyntaxdocument.cpp:49
QDomElement::text
QString text() const
KateSyntaxDocument::groupData
QString groupData(const KateSyntaxContextData *data, const QString &name)
Definition: katesyntaxdocument.cpp:181
KateSyntaxDocument::nextItem
bool nextItem(KateSyntaxContextData *data)
Jump to the next item, KateSyntaxContextData::item will point to the next item.
Definition: katesyntaxdocument.cpp:133
KateSyntaxDocument::getConfig
KateSyntaxContextData * getConfig(const QString &mainGroupName, const QString &config)
Get the KateSyntaxContextData of the DomElement Config inside mainGroupName It just fills KateSyntaxC...
Definition: katesyntaxdocument.cpp:262
QList::isEmpty
bool isEmpty() const
KateSyntaxContextData::parent
QDomElement parent
Definition: katesyntaxdocument.h:65
QString::isEmpty
bool isEmpty() const
QString::trimmed
QString trimmed() const
katesyntaxdocument.h
KateSyntaxModeListItem::author
QString author
Author's name.
Definition: katesyntaxdocument.h:48
KateSyntaxDocument::finddata
QStringList & finddata(const QString &mainGroup, const QString &type, bool clearList=true)
Returns a list with all the keywords inside the list type.
Definition: katesyntaxdocument.cpp:293
QString
QFile::open
virtual bool open(QFlags< QIODevice::OpenModeFlag > mode)
QStringList
QList::end
iterator end()
QDomDocument
QFile::close
virtual void close()
KateSyntaxModeListItem::identifier
QString identifier
Definition: katesyntaxdocument.h:42
QDomNode::isNull
bool isNull() const
KateSyntaxDocument::setIdentifier
bool setIdentifier(const QString &identifier)
If the open hl file is different from the one needed, it opens the new one and assign some other thin...
Definition: katesyntaxdocument.cpp:59
QDomNode::firstChild
QDomNode firstChild() const
KateSyntaxContextData::currentGroup
QDomElement currentGroup
Definition: katesyntaxdocument.h:66
KateSyntaxModeListItem
Information about each syntax hl Mode.
Definition: katesyntaxdocument.h:34
QDomNode::isComment
bool isComment() const
KateSyntaxModeListItem::extension
QString extension
Semicolon-separated list of file extensions.
Definition: katesyntaxdocument.h:41
QList::ConstIterator
typedef ConstIterator
KateSyntaxModeListItem::indenter
QString indenter
Indenter to use for this highlighting.
Definition: katesyntaxdocument.h:50
QDomElement::tagName
QString tagName() const
QDomElement
QString::arg
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
KateSyntaxContextData::item
QDomElement item
Definition: katesyntaxdocument.h:67
KateSyntaxModeListItem::name
QString name
Name of the mode (eg. Asm6502)
Definition: katesyntaxdocument.h:37
KateSyntaxContextData
Class holding the data around the current QDomElement.
Definition: katesyntaxdocument.h:62
QList::begin
iterator begin()
KateSyntaxModeListItem::license
QString license
License; for example: "LGPL".
Definition: katesyntaxdocument.h:49
KateSyntaxDocument::getGroupInfo
KateSyntaxContextData * getGroupInfo(const QString &mainGroupName, const QString &group)
Get the KateSyntaxContextData of the QDomElement Config inside mainGroupName KateSyntaxContextData::p...
Definition: katesyntaxdocument.cpp:278
KateSyntaxDocument::groupItemData
QString groupItemData(const KateSyntaxContextData *data, const QString &name)
This function is used to fetch the atributes of the tags.
Definition: katesyntaxdocument.cpp:161
QDomDocument::setContent
bool setContent(const QByteArray &data, bool namespaceProcessing, QString *errorMsg, int *errorLine, int *errorColumn)
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:58 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