00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
#include "katesyntaxdocument.h"
00021
00022
#include <sys/types.h>
00023
#include <sys/stat.h>
00024
#include <unistd.h>
00025
00026
#include <kdebug.h>
00027
#include <kstandarddirs.h>
00028
#include <klocale.h>
00029
#include <kmessagebox.h>
00030
#include <kconfig.h>
00031
00032
#include <qfile.h>
00033
00034 KateSyntaxDocument::KateSyntaxDocument(
bool force)
00035 :
QDomDocument()
00036 {
00037
00038 setupModeList(force);
00039 myModeList.setAutoDelete(
true );
00040 }
00041
00042 KateSyntaxDocument::~KateSyntaxDocument()
00043 {
00044 }
00045
00050 bool KateSyntaxDocument::setIdentifier(
const QString& identifier)
00051 {
00052
00053
if(currentFile != identifier)
00054 {
00055
00056
QFile f( identifier );
00057
00058
if ( f.open(IO_ReadOnly) )
00059 {
00060
00061
00062
00063
QString errorMsg;
00064
int line, col;
00065
bool success=setContent(&f,&errorMsg,&line,&col);
00066
00067
00068 currentFile = identifier;
00069
00070
00071 f.close();
00072
00073
if (!success)
00074 {
00075
KMessageBox::error(0L,i18n(
"<qt>The error <b>%4</b><br> has been detected in the file %1 at %2/%3</qt>").arg(identifier)
00076 .arg(line).arg(col).arg(i18n(
"QXml",errorMsg.utf8())));
00077
return false;
00078 }
00079 }
00080
else
00081 {
00082
00083
KMessageBox::error( 0L, i18n(
"Unable to open %1").arg(identifier) );
00084
return false;
00085 }
00086 }
00087
return true;
00088 }
00089
00093 bool KateSyntaxDocument::nextGroup(
KateSyntaxContextData* data)
00094 {
00095
if(!data)
00096
return false;
00097
00098
00099
if (data->
currentGroup.isNull())
00100 {
00101
00102
QDomNode node = data->
parent.firstChild();
00103
while (node.isComment())
00104 node = node.nextSibling();
00105
00106 data->
currentGroup = node.toElement();
00107 }
00108
else
00109 {
00110
00111
QDomNode node = data->
currentGroup.nextSibling();
00112
while (node.isComment())
00113 node = node.nextSibling();
00114
00115 data->
currentGroup = node.toElement();
00116 }
00117
00118
return !data->
currentGroup.isNull();
00119 }
00120
00124 bool KateSyntaxDocument::nextItem(
KateSyntaxContextData* data)
00125 {
00126
if(!data)
00127
return false;
00128
00129
if (data->
item.isNull())
00130 {
00131
QDomNode node = data->
currentGroup.firstChild();
00132
while (node.isComment())
00133 node = node.nextSibling();
00134
00135 data->
item = node.toElement();
00136 }
00137
else
00138 {
00139
QDomNode node = data->
item.nextSibling();
00140
while (node.isComment())
00141 node = node.nextSibling();
00142
00143 data->
item = node.toElement();
00144 }
00145
00146
return !data->
item.isNull();
00147 }
00148
00152 QString KateSyntaxDocument::groupItemData(
const KateSyntaxContextData* data,
const QString& name){
00153
if(!data)
00154
return QString::null;
00155
00156
00157
if ( (!data->
item.isNull()) && (name.isEmpty()))
00158 {
00159
return data->
item.tagName();
00160 }
00161
00162
00163
if (!data->
item.isNull())
00164 {
00165
return data->
item.attribute(name);
00166 }
00167
00168
return QString::null;
00169
00170 }
00171
00172
QString KateSyntaxDocument::groupData(
const KateSyntaxContextData* data,
const QString& name)
00173 {
00174
if(!data)
00175
return QString::null;
00176
00177
if (!data->
currentGroup.isNull())
00178 {
00179
return data->
currentGroup.attribute(name);
00180 }
00181
else
00182 {
00183
return QString::null;
00184 }
00185 }
00186
00187
void KateSyntaxDocument::freeGroupInfo(
KateSyntaxContextData* data)
00188 {
00189
if (data)
00190
delete data;
00191 }
00192
00193
KateSyntaxContextData* KateSyntaxDocument::getSubItems(
KateSyntaxContextData* data)
00194 {
00195
KateSyntaxContextData *retval =
new KateSyntaxContextData;
00196
00197
if (data != 0)
00198 {
00199 retval->
parent = data->
currentGroup;
00200 retval->
currentGroup = data->
item;
00201 }
00202
00203
return retval;
00204 }
00205
00206
bool KateSyntaxDocument::getElement (
QDomElement &element,
const QString &mainGroupName,
const QString &config)
00207 {
00208
kdDebug(13010) <<
"Looking for \"" << mainGroupName <<
"\" -> \"" << config <<
"\"." <<
endl;
00209
00210
QDomNodeList nodes = documentElement().childNodes();
00211
00212
00213
for (
unsigned int i=0; i<nodes.count(); i++)
00214 {
00215
QDomElement elem = nodes.item(i).toElement();
00216
if (elem.tagName() == mainGroupName)
00217 {
00218
00219
QDomNodeList subNodes = elem.childNodes();
00220
00221
00222
for (
unsigned int j=0; j<subNodes.count(); j++)
00223 {
00224
QDomElement subElem = subNodes.item(j).toElement();
00225
if (subElem.tagName() == config)
00226 {
00227
00228 element = subElem;
00229
return true;
00230 }
00231 }
00232
00233
kdDebug(13010) <<
"WARNING: \""<< config <<
"\" wasn't found!" <<
endl;
00234
return false;
00235 }
00236 }
00237
00238
kdDebug(13010) <<
"WARNING: \""<< mainGroupName <<
"\" wasn't found!" <<
endl;
00239
return false;
00240 }
00241
00246 KateSyntaxContextData*
KateSyntaxDocument::getConfig(
const QString& mainGroupName,
const QString &config)
00247 {
00248
QDomElement element;
00249
if (getElement(element, mainGroupName, config))
00250 {
00251
KateSyntaxContextData *data =
new KateSyntaxContextData;
00252 data->
item = element;
00253
return data;
00254 }
00255
return 0;
00256 }
00257
00262 KateSyntaxContextData*
KateSyntaxDocument::getGroupInfo(
const QString& mainGroupName,
const QString &group)
00263 {
00264
QDomElement element;
00265
if (getElement(element, mainGroupName, group+
"s"))
00266 {
00267
KateSyntaxContextData *data =
new KateSyntaxContextData;
00268 data->
parent = element;
00269
return data;
00270 }
00271
return 0;
00272 }
00273
00277 QStringList&
KateSyntaxDocument::finddata(
const QString& mainGroup,
const QString& type,
bool clearList)
00278 {
00279
kdDebug(13010)<<
"Create a list of keywords \""<<type<<
"\" from \""<<mainGroup<<
"\"."<<
endl;
00280
if (clearList)
00281 m_data.clear();
00282
00283
for(
QDomNode node = documentElement().firstChild(); !node.isNull(); node = node.nextSibling())
00284 {
00285
QDomElement elem = node.toElement();
00286
if (elem.tagName() == mainGroup)
00287 {
00288
kdDebug(13010)<<
"\""<<mainGroup<<
"\" found."<<
endl;
00289
QDomNodeList nodelist1 = elem.elementsByTagName(
"list");
00290
00291
for (uint l=0; l<nodelist1.count(); l++)
00292 {
00293
if (nodelist1.item(l).toElement().attribute(
"name") == type)
00294 {
00295
kdDebug(13010)<<
"List with attribute name=\""<<type<<
"\" found."<<
endl;
00296
QDomNodeList childlist = nodelist1.item(l).toElement().childNodes();
00297
00298
for (uint i=0; i<childlist.count(); i++)
00299 {
00300
QString element = childlist.item(i).toElement().text().stripWhiteSpace();
00301
if (element.isEmpty())
00302
continue;
00303
#ifndef NDEBUG
00304
if (i<6)
00305 {
00306
kdDebug(13010)<<
"\""<<element<<
"\" added to the list \""<<type<<
"\""<<
endl;
00307 }
00308
else if(i==6)
00309 {
00310
kdDebug(13010)<<
"... The list continues ..."<<
endl;
00311 }
00312
#endif
00313
m_data += element;
00314 }
00315
00316
break;
00317 }
00318 }
00319
break;
00320 }
00321 }
00322
00323
return m_data;
00324 }
00325
00326
00330
void KateSyntaxDocument::setupModeList (
bool force)
00331 {
00332
00333
if (!myModeList.isEmpty())
00334
return;
00335
00336
00337
KConfig config(
"katesyntaxhighlightingrc",
false,
false);
00338
00339
00340 config.setGroup (
"General");
00341
if (config.readNumEntry (
"Version") > config.readNumEntry (
"CachedVersion"))
00342 {
00343 config.writeEntry (
"CachedVersion", config.readNumEntry (
"Version"));
00344 force =
true;
00345 }
00346
00347
00348
QStringList list =
KGlobal::dirs()->
findAllResources(
"data",
"katepart/syntax/*.xml",
false,
true);
00349
00350
00351
for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it )
00352 {
00353
00354
QString Group=
"Cache "+ *it;
00355
00356
00357 config.setGroup(Group);
00358
00359
00360
struct stat sbuf;
00361 memset (&sbuf, 0,
sizeof(sbuf));
00362
stat(QFile::encodeName(*it), &sbuf);
00363
00364
00365
if (!force && config.hasGroup(Group) && (sbuf.st_mtime == config.readNumEntry(
"lastModified")))
00366 {
00367
00368
KateSyntaxModeListItem *mli=
new KateSyntaxModeListItem;
00369 mli->
name = config.readEntry(
"name");
00370 mli->
nameTranslated = i18n(
"Language",mli->
name.utf8());
00371 mli->
section = i18n(
"Language Section",config.readEntry(
"section").utf8());
00372 mli->
mimetype = config.readEntry(
"mimetype");
00373 mli->
extension = config.readEntry(
"extension");
00374 mli->
version = config.readEntry(
"version");
00375 mli->
priority = config.readEntry(
"priority");
00376 mli->
author = config.readEntry(
"author");
00377 mli->
license = config.readEntry(
"license");
00378 mli->
hidden = config.readBoolEntry(
"hidden");
00379 mli->
identifier = *it;
00380
00381
00382 myModeList.append(mli);
00383 }
00384
else
00385 {
00386
kdDebug (13010) <<
"UPDATE hl cache for: " << *it <<
endl;
00387
00388
00389
QFile f(*it);
00390
00391
if (f.open(IO_ReadOnly))
00392 {
00393
00394
00395
QString errMsg;
00396
int line, col;
00397
00398
bool success = setContent(&f,&errMsg,&line,&col);
00399
00400 f.close();
00401
00402
if (success)
00403 {
00404
QDomElement root = documentElement();
00405
00406
if (!root.isNull())
00407 {
00408
00409
if (root.tagName()==
"language")
00410 {
00411
00412
KateSyntaxModeListItem *mli =
new KateSyntaxModeListItem;
00413
00414 mli->
name = root.attribute(
"name");
00415 mli->
section = root.attribute(
"section");
00416 mli->
mimetype = root.attribute(
"mimetype");
00417 mli->
extension = root.attribute(
"extensions");
00418 mli->
version = root.attribute(
"version");
00419 mli->
priority = root.attribute(
"priority");
00420 mli->
author = root.attribute(
"author");
00421 mli->
license = root.attribute(
"license");
00422
00423
QString hidden = root.attribute(
"hidden");
00424 mli->
hidden = (hidden ==
"true" || hidden ==
"TRUE");
00425
00426 mli->
identifier = *it;
00427
00428
00429 config.setGroup(Group);
00430 config.writeEntry(
"name",mli->
name);
00431 config.writeEntry(
"section",mli->
section);
00432 config.writeEntry(
"mimetype",mli->
mimetype);
00433 config.writeEntry(
"extension",mli->
extension);
00434 config.writeEntry(
"version",mli->
version);
00435 config.writeEntry(
"priority",mli->
priority);
00436 config.writeEntry(
"author",mli->
author);
00437 config.writeEntry(
"license",mli->
license);
00438 config.writeEntry(
"hidden",mli->
hidden);
00439
00440
00441 config.writeEntry(
"lastModified", sbuf.st_mtime);
00442
00443
00444 mli->
section = i18n(
"Language Section",mli->
section.utf8());
00445 mli->
nameTranslated = i18n(
"Language",mli->
name.utf8());
00446
00447
00448 myModeList.append(mli);
00449 }
00450 }
00451 }
00452
else
00453 {
00454
KateSyntaxModeListItem *emli=
new KateSyntaxModeListItem;
00455
00456 emli->
section=i18n(
"Errors!");
00457 emli->
mimetype=
"invalid_file/invalid_file";
00458 emli->
extension=
"invalid_file.invalid_file";
00459 emli->
version=
"1.";
00460 emli->
name=
QString (
"Error: %1").arg(*it);
00461 emli->
nameTranslated=i18n(
"Error: %1").arg(*it);
00462 emli->
identifier=(*it);
00463
00464 myModeList.append(emli);
00465 }
00466 }
00467 }
00468 }
00469
00470
00471 config.sync();
00472 }
00473
00474