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