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