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