kate Library: katehighlight.cpp Source File (kate Library)

| # kate Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# katehighlight.cpp

    00001 /* This file is part of the KDE libraries
    00002    Copyright (C) 2003, 2004 Anders Lund <anders@alweb.dk>
    00003    Copyright (C) 2003 Hamish Rodda <rodda@kde.org>
    00004    Copyright (C) 2001,2002 Joseph Wenninger <jowenn@kde.org>
    00005    Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
    00006    Copyright (C) 1999 Jochen Wilhelmy <digisnap@cs.tu-berlin.de>
    00007
    00008    This library is free software; you can redistribute it and/or
    00009    modify it under the terms of the GNU Library General Public
    00010    License version 2 as published by the Free Software Foundation.
    00011
    00012    This library is distributed in the hope that it will be useful,
    00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
    00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00015    Library General Public License for more details.
    00016
    00017    You should have received a copy of the GNU Library General Public License
    00018    along with this library; see the file COPYING.LIB.  If not, write to
    00019    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    00020    Boston, MA 02111-1307, USA.
    00021 */
    00022
    00023 //BEGIN INCLUDES
    00024 #include "katehighlight.h"
    00025 #include "katehighlight.moc"
    00026
    00027 #include "katetextline.h"
    00028 #include "katedocument.h"
    00029 #include "katesyntaxdocument.h"
    00030 #include "katerenderer.h"
    00031 #include "katefactory.h"
    00032 #include "kateschema.h"
    00033 #include "kateconfig.h"
    00034
    00035 #include <kconfig.h>
    00036 #include <kglobal.h>
    00037 #include <kinstance.h>
    00038 #include <kmimetype.h>
    00039 #include <klocale.h>
    00040 #include <kregexp.h>
    00041 #include <kpopupmenu.h>
    00042 #include <kglobalsettings.h>
    00043 #include <kdebug.h>
    00044 #include <kstandarddirs.h>
    00045 #include <kmessagebox.h>
    00046 #include <kstaticdeleter.h>
    00047 #include <kapplication.h>
    00048
    00049 #include <qstringlist.h>
    00050 #include <qtextstream.h>
    00051 //END
    00052
    00053 //BEGIN defines
    00054 // same as in kmimemagic, no need to feed more data
    00055 #define KATE_HL_HOWMANY 1024
    00056
    00057 // min. x seconds between two dynamic contexts reset
    00058 static const int KATE_DYNAMIC_CONTEXTS_RESET_DELAY = 30 * 1000;
    00059
    00060 // x is a QString. if x is "true" or "1" this expression returns "true"
    00061 #define IS_TRUE(x) x.lower() == QString("true") || x.toInt() == 1
    00062 //END defines
    00063
    00064 //BEGIN  Prviate HL classes
    00065
    00066 inline bool kateInsideString (const QString &str, QChar ch)
    00067 {
    00068   for (uint i=0; i < str.length(); i++)
    00069     if (*(str.unicode()+i) == ch)
    00070       return true;
    00071
    00072   return false;
    00073 }
    00074
    00075 class KateHlItem
    00076 {
    00077   public:
    00078     KateHlItem(int attribute, int context,signed char regionId, signed char regionId2);
    00079     virtual ~KateHlItem();
    00080
    00081   public:
    00082     // caller must keep in mind: LEN > 0 is a must !!!!!!!!!!!!!!!!!!!!!1
    00083     // Now, the function returns the offset detected, or 0 if no match is found.
    00084     // bool linestart isn't needed, this is equivalent to offset == 0.
    00085     virtual int checkHgl(const QString& text, int offset, int len) = 0;
    00086
    00087     virtual bool lineContinue(){return false;}
    00088
    00089     virtual QStringList *capturedTexts() {return 0;}
    00090     virtual KateHlItem *clone(const QStringList *) {return this;}
    00091
    00092     static void dynamicSubstitute(QString& str, const QStringList *args);
    00093
    00094     QMemArray<KateHlItem*> subItems;
    00095     int attr;
    00096     int ctx;
    00097     signed char region;
    00098     signed char region2;
    00099
    00100     bool lookAhead;
    00101
    00102     bool dynamic;
    00103     bool dynamicChild;
    00104     bool firstNonSpace;
    00105     bool onlyConsume;
    00106     int column;
    00107
    00108     // start enable flags, nicer than the virtual methodes
    00109     // saves function calls
    00110     bool alwaysStartEnable;
    00111     bool customStartEnable;
    00112 };
    00113
    00114 class KateHlContext
    00115 {
    00116   public:
    00117     KateHlContext(const QString &_hlId, int attribute, int lineEndContext,int _lineBeginContext,
    00118                   bool _fallthrough, int _fallthroughContext, bool _dynamic);
    00119     virtual ~KateHlContext();
    00120     KateHlContext *clone(const QStringList *args);
    00121
    00122     QValueVector<KateHlItem*> items;
    00123     QString hlId;
    00124     int attr;
    00125     int ctx;
    00126     int lineBeginContext;
    00132     bool fallthrough;
    00133     int ftctx; // where to go after no rules matched
    00134
    00135     bool dynamic;
    00136     bool dynamicChild;
    00137 };
    00138
    00139 class KateEmbeddedHlInfo
    00140 {
    00141   public:
    00142     KateEmbeddedHlInfo() {loaded=false;context0=-1;}
    00143     KateEmbeddedHlInfo(bool l, int ctx0) {loaded=l;context0=ctx0;}
    00144
    00145   public:
    00146     bool loaded;
    00147     int context0;
    00148 };
    00149
    00150 class KateHlIncludeRule
    00151 {
    00152   public:
    00153     KateHlIncludeRule(int ctx_=0, uint pos_=0, const QString &incCtxN_="", bool incAttrib=false)
    00154       : ctx(ctx_)
    00155       , pos( pos_)
    00156       , incCtxN( incCtxN_ )
    00157       , includeAttrib( incAttrib )
    00158     {
    00159       incCtx=-1;
    00160     }
    00161     //KateHlIncludeRule(int ctx_, uint  pos_, bool incAttrib) {ctx=ctx_;pos=pos_;incCtx=-1;incCtxN="";includeAttrib=incAttrib}
    00162
    00163   public:
    00164     int ctx;
    00165     uint pos;
    00166     int incCtx;
    00167     QString incCtxN;
    00168     bool includeAttrib;
    00169 };
    00170
    00171 class KateHlCharDetect : public KateHlItem
    00172 {
    00173   public:
    00174     KateHlCharDetect(int attribute, int context,signed char regionId,signed char regionId2, QChar);
    00175
    00176     virtual int checkHgl(const QString& text, int offset, int len);
    00177     virtual KateHlItem *clone(const QStringList *args);
    00178
    00179   private:
    00180     QChar sChar;
    00181 };
    00182
    00183 class KateHl2CharDetect : public KateHlItem
    00184 {
    00185   public:
    00186     KateHl2CharDetect(int attribute, int context, signed char regionId,signed char regionId2,  QChar ch1, QChar ch2);
    00187     KateHl2CharDetect(int attribute, int context,signed char regionId,signed char regionId2,  const QChar *ch);
    00188
    00189     virtual int checkHgl(const QString& text, int offset, int len);
    00190     virtual KateHlItem *clone(const QStringList *args);
    00191
    00192   private:
    00193     QChar sChar1;
    00194     QChar sChar2;
    00195 };
    00196
    00197 class KateHlStringDetect : public KateHlItem
    00198 {
    00199   public:
    00200     KateHlStringDetect(int attribute, int context, signed char regionId,signed char regionId2, const QString &, bool inSensitive=false);
    00201
    00202     virtual int checkHgl(const QString& text, int offset, int len);
    00203     virtual KateHlItem *clone(const QStringList *args);
    00204
    00205   private:
    00206     const QString str;
    00207     const int strLen;
    00208     const bool _inSensitive;
    00209 };
    00210
    00211 class KateHlRangeDetect : public KateHlItem
    00212 {
    00213   public:
    00214     KateHlRangeDetect(int attribute, int context, signed char regionId,signed char regionId2, QChar ch1, QChar ch2);
    00215
    00216     virtual int checkHgl(const QString& text, int offset, int len);
    00217
    00218   private:
    00219     QChar sChar1;
    00220     QChar sChar2;
    00221 };
    00222
    00223 class KateHlKeyword : public KateHlItem
    00224 {
    00225   public:
    00226     KateHlKeyword(int attribute, int context,signed char regionId,signed char regionId2, bool casesensitive, const QString& delims);
    00227     virtual ~KateHlKeyword ();
    00228
    00229     void addList(const QStringList &);
    00230     virtual int checkHgl(const QString& text, int offset, int len);
    00231
    00232   private:
    00233     QMemArray< QDict<bool>* > dict;
    00234     bool _caseSensitive;
    00235     const QString& deliminators;
    00236     int minLen;
    00237     int maxLen;
    00238 };
    00239
    00240 class KateHlInt : public KateHlItem
    00241 {
    00242   public:
    00243     KateHlInt(int attribute, int context, signed char regionId,signed char regionId2);
    00244
    00245     virtual int checkHgl(const QString& text, int offset, int len);
    00246 };
    00247
    00248 class KateHlFloat : public KateHlItem
    00249 {
    00250   public:
    00251     KateHlFloat(int attribute, int context, signed char regionId,signed char regionId2);
    00252     virtual ~KateHlFloat () {}
    00253
    00254     virtual int checkHgl(const QString& text, int offset, int len);
    00255 };
    00256
    00257 class KateHlCFloat : public KateHlFloat
    00258 {
    00259   public:
    00260     KateHlCFloat(int attribute, int context, signed char regionId,signed char regionId2);
    00261
    00262     virtual int checkHgl(const QString& text, int offset, int len);
    00263     int checkIntHgl(const QString& text, int offset, int len);
    00264 };
    00265
    00266 class KateHlCOct : public KateHlItem
    00267 {
    00268   public:
    00269     KateHlCOct(int attribute, int context, signed char regionId,signed char regionId2);
    00270
    00271     virtual int checkHgl(const QString& text, int offset, int len);
    00272 };
    00273
    00274 class KateHlCHex : public KateHlItem
    00275 {
    00276   public:
    00277     KateHlCHex(int attribute, int context, signed char regionId,signed char regionId2);
    00278
    00279     virtual int checkHgl(const QString& text, int offset, int len);
    00280 };
    00281
    00282 class KateHlLineContinue : public KateHlItem
    00283 {
    00284   public:
    00285     KateHlLineContinue(int attribute, int context, signed char regionId,signed char regionId2);
    00286
    00287     virtual bool endEnable(QChar c) {return c == '\0';}
    00288     virtual int checkHgl(const QString& text, int offset, int len);
    00289     virtual bool lineContinue(){return true;}
    00290 };
    00291
    00292 class KateHlCStringChar : public KateHlItem
    00293 {
    00294   public:
    00295     KateHlCStringChar(int attribute, int context, signed char regionId,signed char regionId2);
    00296
    00297     virtual int checkHgl(const QString& text, int offset, int len);
    00298 };
    00299
    00300 class KateHlCChar : public KateHlItem
    00301 {
    00302   public:
    00303     KateHlCChar(int attribute, int context,signed char regionId,signed char regionId2);
    00304
    00305     virtual int checkHgl(const QString& text, int offset, int len);
    00306 };
    00307
    00308 class KateHlAnyChar : public KateHlItem
    00309 {
    00310   public:
    00311     KateHlAnyChar(int attribute, int context, signed char regionId,signed char regionId2, const QString& charList);
    00312
    00313     virtual int checkHgl(const QString& text, int offset, int len);
    00314
    00315   private:
    00316     const QString _charList;
    00317 };
    00318
    00319 class KateHlRegExpr : public KateHlItem
    00320 {
    00321   public:
    00322     KateHlRegExpr(int attribute, int context,signed char regionId,signed char regionId2 ,QString expr, bool insensitive, bool minimal);
    00323     ~KateHlRegExpr() { delete Expr; };
    00324
    00325     virtual int checkHgl(const QString& text, int offset, int len);
    00326     virtual QStringList *capturedTexts();
    00327     virtual KateHlItem *clone(const QStringList *args);
    00328
    00329   private:
    00330     QRegExp *Expr;
    00331     bool handlesLinestart;
    00332     QString _regexp;
    00333     bool _insensitive;
    00334     bool _minimal;
    00335 };
    00336
    00337 class KateHlDetectSpaces : public KateHlItem
    00338 {
    00339   public:
    00340     KateHlDetectSpaces (int attribute, int context,signed char regionId,signed char regionId2)
    00341       : KateHlItem(attribute,context,regionId,regionId2) {}
    00342
    00343     virtual int checkHgl(const QString& text, int offset, int len)
    00344     {
    00345       int len2 = offset + len;
    00346       while ((offset < len2) && text[offset].isSpace()) offset++;
    00347       return offset;
    00348     }
    00349 };
    00350
    00351 class KateHlDetectIdentifier : public KateHlItem
    00352 {
    00353   public:
    00354     KateHlDetectIdentifier (int attribute, int context,signed char regionId,signed char regionId2)
    00355       : KateHlItem(attribute,context,regionId,regionId2) { alwaysStartEnable = false; }
    00356
    00357     virtual int checkHgl(const QString& text, int offset, int len)
    00358     {
    00359       // first char should be a letter or underscore
    00360       if ( text[offset].isLetter() || text[offset] == QChar ('_') )
    00361       {
    00362         // memorize length
    00363         int len2 = offset+len;
    00364
    00365         // one char seen
    00366         offset++;
    00367
    00368         // now loop for all other thingies
    00369         while (
    00370                (offset < len2)
    00371                && (text[offset].isLetterOrNumber() || (text[offset] == QChar ('_')))
    00372               )
    00373           offset++;
    00374
    00375         return offset;
    00376       }
    00377
    00378       return 0;
    00379     }
    00380 };
    00381
    00382 //END
    00383
    00384 //BEGIN STATICS
    00385 KateHlManager *KateHlManager::s_self = 0;
    00386
    00387 static const bool trueBool = true;
    00388 static const QString stdDeliminator = QString (" \t.():!+,-<=>%&*/;?[]^{|}~\\");
    00389 //END
    00390
    00391 //BEGIN NON MEMBER FUNCTIONS
    00392 static KateHlItemData::ItemStyles getDefStyleNum(QString name)
    00393 {
    00394   if (name=="dsNormal") return KateHlItemData::dsNormal;
    00395   else if (name=="dsKeyword") return KateHlItemData::dsKeyword;
    00396   else if (name=="dsDataType") return KateHlItemData::dsDataType;
    00397   else if (name=="dsDecVal") return KateHlItemData::dsDecVal;
    00398   else if (name=="dsBaseN") return KateHlItemData::dsBaseN;
    00399   else if (name=="dsFloat") return KateHlItemData::dsFloat;
    00400   else if (name=="dsChar") return KateHlItemData::dsChar;
    00401   else if (name=="dsString") return KateHlItemData::dsString;
    00402   else if (name=="dsComment") return KateHlItemData::dsComment;
    00403   else if (name=="dsOthers")  return KateHlItemData::dsOthers;
    00404   else if (name=="dsAlert") return KateHlItemData::dsAlert;
    00405   else if (name=="dsFunction") return KateHlItemData::dsFunction;
    00406   else if (name=="dsRegionMarker") return KateHlItemData::dsRegionMarker;
    00407   else if (name=="dsError") return KateHlItemData::dsError;
    00408
    00409   return KateHlItemData::dsNormal;
    00410 }
    00411 //END
    00412
    00413 //BEGIN KateHlItem
    00414 KateHlItem::KateHlItem(int attribute, int context,signed char regionId,signed char regionId2)
    00415   : attr(attribute),
    00416     ctx(context),
    00417     region(regionId),
    00418     region2(regionId2),
    00419     lookAhead(false),
    00420     dynamic(false),
    00421     dynamicChild(false),
    00422     firstNonSpace(false),
    00423     onlyConsume(false),
    00424     column (-1),
    00425     alwaysStartEnable (true),
    00426     customStartEnable (false)
    00427 {
    00428 }
    00429
    00430 KateHlItem::~KateHlItem()
    00431 {
    00432   //kdDebug(13010)<<"In hlItem::~KateHlItem()"<<endl;
    00433   for (uint i=0; i < subItems.size(); i++)
    00434     delete subItems[i];
    00435 }
    00436
    00437 void KateHlItem::dynamicSubstitute(QString &str, const QStringList *args)
    00438 {
    00439   for (uint i = 0; i < str.length() - 1; ++i)
    00440   {
    00441     if (str[i] == '%')
    00442     {
    00443       char c = str[i + 1].latin1();
    00444       if (c == '%')
    00445         str.replace(i, 1, "");
    00446       else if (c >= '0' && c <= '9')
    00447       {
    00448         if ((uint)(c - '0') < args->size())
    00449         {
    00450           str.replace(i, 2, (*args)[c - '0']);
    00451           i += ((*args)[c - '0']).length() - 1;
    00452         }
    00453         else
    00454         {
    00455           str.replace(i, 2, "");
    00456           --i;
    00457         }
    00458       }
    00459     }
    00460   }
    00461 }
    00462 //END
    00463
    00464 //BEGIN KateHlCharDetect
    00465 KateHlCharDetect::KateHlCharDetect(int attribute, int context, signed char regionId,signed char regionId2, QChar c)
    00466   : KateHlItem(attribute,context,regionId,regionId2)
    00467   , sChar(c)
    00468 {
    00469 }
    00470
    00471 int KateHlCharDetect::checkHgl(const QString& text, int offset, int /*len*/)
    00472 {
    00473   if (text[offset] == sChar)
    00474     return offset + 1;
    00475
    00476   return 0;
    00477 }
    00478
    00479 KateHlItem *KateHlCharDetect::clone(const QStringList *args)
    00480 {
    00481   char c = sChar.latin1();
    00482
    00483   if (c < '0' || c > '9' || (unsigned)(c - '0') >= args->size())
    00484     return this;
    00485
    00486   KateHlCharDetect *ret = new KateHlCharDetect(attr, ctx, region, region2, (*args)[c - '0'][0]);
    00487   ret->dynamicChild = true;
    00488   return ret;
    00489 }
    00490 //END
    00491
    00492 //BEGIN KateHl2CharDetect
    00493 KateHl2CharDetect::KateHl2CharDetect(int attribute, int context, signed char regionId,signed char regionId2, QChar ch1, QChar ch2)
    00494   : KateHlItem(attribute,context,regionId,regionId2)
    00495   , sChar1 (ch1)
    00496   , sChar2 (ch2)
    00497 {
    00498 }
    00499
    00500 int KateHl2CharDetect::checkHgl(const QString& text, int offset, int len)
    00501 {
    00502   if ((len >= 2) && text[offset++] == sChar1 && text[offset++] == sChar2)
    00503     return offset;
    00504
    00505   return 0;
    00506 }
    00507
    00508 KateHlItem *KateHl2CharDetect::clone(const QStringList *args)
    00509 {
    00510   char c1 = sChar1.latin1();
    00511   char c2 = sChar2.latin1();
    00512
    00513   if (c1 < '0' || c1 > '9' || (unsigned)(c1 - '0') >= args->size())
    00514     return this;
    00515
    00516   if (c2 < '0' || c2 > '9' || (unsigned)(c2 - '0') >= args->size())
    00517     return this;
    00518
    00519   KateHl2CharDetect *ret = new KateHl2CharDetect(attr, ctx, region, region2, (*args)[c1 - '0'][0], (*args)[c2 - '0'][0]);
    00520   ret->dynamicChild = true;
    00521   return ret;
    00522 }
    00523 //END
    00524
    00525 //BEGIN KateHlStringDetect
    00526 KateHlStringDetect::KateHlStringDetect(int attribute, int context, signed char regionId,signed char regionId2,const QString &s, bool inSensitive)
    00527   : KateHlItem(attribute, context,regionId,regionId2)
    00528   , str(inSensitive ? s.upper() : s)
    00529   , strLen (str.length())
    00530   , _inSensitive(inSensitive)
    00531 {
    00532 }
    00533
    00534 int KateHlStringDetect::checkHgl(const QString& text, int offset, int len)
    00535 {
    00536   if (len < strLen)
    00537     return 0;
    00538
    00539   if (_inSensitive)
    00540   {
    00541     for (int i=0; i < strLen; i++)
    00542       if (text[offset++].upper() != str[i])
    00543         return 0;
    00544
    00545     return offset;
    00546   }
    00547   else
    00548   {
    00549     for (int i=0; i < strLen; i++)
    00550       if (text[offset++] != str[i])
    00551         return 0;
    00552
    00553     return offset;
    00554   }
    00555
    00556   return 0;
    00557 }
    00558
    00559 KateHlItem *KateHlStringDetect::clone(const QStringList *args)
    00560 {
    00561   QString newstr = str;
    00562
    00563   dynamicSubstitute(newstr, args);
    00564
    00565   if (newstr == str)
    00566     return this;
    00567
    00568   KateHlStringDetect *ret = new KateHlStringDetect(attr, ctx, region, region2, newstr, _inSensitive);
    00569   ret->dynamicChild = true;
    00570   return ret;
    00571 }
    00572 //END
    00573
    00574 //BEGIN KateHlRangeDetect
    00575 KateHlRangeDetect::KateHlRangeDetect(int attribute, int context, signed char regionId,signed char regionId2, QChar ch1, QChar ch2)
    00576   : KateHlItem(attribute,context,regionId,regionId2)
    00577   , sChar1 (ch1)
    00578   , sChar2 (ch2)
    00579 {
    00580 }
    00581
    00582 int KateHlRangeDetect::checkHgl(const QString& text, int offset, int len)
    00583 {
    00584   if (text[offset] == sChar1)
    00585   {
    00586     do
    00587     {
    00588       offset++;
    00589       len--;
    00590       if (len < 1) return 0;
    00591     }
    00592     while (text[offset] != sChar2);
    00593
    00594     return offset + 1;
    00595   }
    00596   return 0;
    00597 }
    00598 //END
    00599
    00600 //BEGIN KateHlKeyword
    00601 KateHlKeyword::KateHlKeyword (int attribute, int context, signed char regionId,signed char regionId2, bool casesensitive, const QString& delims)
    00602   : KateHlItem(attribute,context,regionId,regionId2)
    00603   , _caseSensitive(casesensitive)
    00604   , deliminators(delims)
    00605   , minLen (0xFFFFFF)
    00606   , maxLen (0)
    00607 {
    00608   alwaysStartEnable = false;
    00609   customStartEnable = true;
    00610 }
    00611
    00612 KateHlKeyword::~KateHlKeyword ()
    00613 {
    00614   for (uint i=0; i < dict.size(); ++i)
    00615     delete dict[i];
    00616 }
    00617
    00618 void KateHlKeyword::addList(const QStringList& list)
    00619 {
    00620   for(uint i=0; i < list.count(); ++i)
    00621   {
    00622     int len = list[i].length();
    00623
    00624     if (minLen > len)
    00625       minLen = len;
    00626
    00627     if (maxLen < len)
    00628       maxLen = len;
    00629
    00630     if ((uint)len >= dict.size())
    00631     {
    00632       uint oldSize = dict.size();
    00633       dict.resize (len+1);
    00634
    00635       for (uint m=oldSize; m < dict.size(); ++m)
    00636         dict[m] = 0;
    00637     }
    00638
    00639     if (!dict[len])
    00640       dict[len] = new QDict<bool> (17, _caseSensitive);
    00641
    00642     dict[len]->insert(list[i], &trueBool);
    00643   }
    00644 }
    00645
    00646 int KateHlKeyword::checkHgl(const QString& text, int offset, int len)
    00647 {
    00648   int offset2 = offset;
    00649   int wordLen = 0;
    00650
    00651   while ((len > wordLen) && !kateInsideString (deliminators, text[offset2]))
    00652   {
    00653     offset2++;
    00654     wordLen++;
    00655
    00656     if (wordLen > maxLen) return 0;
    00657   }
    00658
    00659   if (wordLen < minLen) return 0;
    00660
    00661   if ( dict[wordLen] && dict[wordLen]->find(QConstString(text.unicode() + offset, wordLen).string()) )
    00662     return offset2;
    00663
    00664   return 0;
    00665 }
    00666 //END
    00667
    00668 //BEGIN KateHlInt
    00669 KateHlInt::KateHlInt(int attribute, int context, signed char regionId,signed char regionId2)
    00670   : KateHlItem(attribute,context,regionId,regionId2)
    00671 {
    00672   alwaysStartEnable = false;
    00673 }
    00674
    00675 int KateHlInt::checkHgl(const QString& text, int offset, int len)
    00676 {
    00677   int offset2 = offset;
    00678
    00679   while ((len > 0) && text[offset2].isDigit())
    00680   {
    00681     offset2++;
    00682     len--;
    00683   }
    00684
    00685   if (offset2 > offset)
    00686   {
    00687     if (len > 0)
    00688     {
    00689       for (uint i=0; i < subItems.size(); i++)
    00690       {
    00691         if ( (offset = subItems[i]->checkHgl(text, offset2, len)) )
    00692           return offset;
    00693       }
    00694     }
    00695
    00696     return offset2;
    00697   }
    00698
    00699   return 0;
    00700 }
    00701 //END
    00702
    00703 //BEGIN KateHlFloat
    00704 KateHlFloat::KateHlFloat(int attribute, int context, signed char regionId,signed char regionId2)
    00705   : KateHlItem(attribute,context, regionId,regionId2)
    00706 {
    00707   alwaysStartEnable = false;
    00708 }
    00709
    00710 int KateHlFloat::checkHgl(const QString& text, int offset, int len)
    00711 {
    00712   bool b = false;
    00713   bool p = false;
    00714
    00715   while ((len > 0) && text[offset].isDigit())
    00716   {
    00717     offset++;
    00718     len--;
    00719     b = true;
    00720   }
    00721
    00722   if ((len > 0) && (p = (text[offset] == '.')))
    00723   {
    00724     offset++;
    00725     len--;
    00726
    00727     while ((len > 0) && text[offset].isDigit())
    00728     {
    00729       offset++;
    00730       len--;
    00731       b = true;
    00732     }
    00733   }
    00734
    00735   if (!b)
    00736     return 0;
    00737
    00738   if ((len > 0) && ((text[offset] & 0xdf) == 'E'))
    00739   {
    00740     offset++;
    00741     len--;
    00742   }
    00743   else
    00744   {
    00745     if (!p)
    00746       return 0;
    00747     else
    00748     {
    00749       if (len > 0)
    00750       {
    00751         for (uint i=0; i < subItems.size(); i++)
    00752         {
    00753           int offset2 = subItems[i]->checkHgl(text, offset, len);
    00754
    00755           if (offset2)
    00756             return offset2;
    00757         }
    00758       }
    00759
    00760       return offset;
    00761     }
    00762   }
    00763
    00764   if ((len > 0) && (text[offset] == '-' || text[offset] =='+'))
    00765   {
    00766     offset++;
    00767     len--;
    00768   }
    00769
    00770   b = false;
    00771
    00772   while ((len > 0) && text[offset].isDigit())
    00773   {
    00774     offset++;
    00775     len--;
    00776     b = true;
    00777   }
    00778
    00779   if (b)
    00780   {
    00781     if (len > 0)
    00782     {
    00783       for (uint i=0; i < subItems.size(); i++)
    00784       {
    00785         int offset2 = subItems[i]->checkHgl(text, offset, len);
    00786
    00787         if (offset2)
    00788           return offset2;
    00789       }
    00790     }
    00791
    00792     return offset;
    00793   }
    00794
    00795   return 0;
    00796 }
    00797 //END
    00798
    00799 //BEGIN KateHlCOct
    00800 KateHlCOct::KateHlCOct(int attribute, int context, signed char regionId,signed char regionId2)
    00801   : KateHlItem(attribute,context,regionId,regionId2)
    00802 {
    00803   alwaysStartEnable = false;
    00804 }
    00805
    00806 int KateHlCOct::checkHgl(const QString& text, int offset, int len)
    00807 {
    00808   if (text[offset] == '0')
    00809   {
    00810     offset++;
    00811     len--;
    00812
    00813     int offset2 = offset;
    00814
    00815     while ((len > 0) && (text[offset2] >= '0' && text[offset2] <= '7'))
    00816     {
    00817       offset2++;
    00818       len--;
    00819     }
    00820
    00821     if (offset2 > offset)
    00822     {
    00823       if ((len > 0) && ((text[offset2] & 0xdf) == 'L' || (text[offset] & 0xdf) == 'U' ))
    00824         offset2++;
    00825
    00826       return offset2;
    00827     }
    00828   }
    00829
    00830   return 0;
    00831 }
    00832 //END
    00833
    00834 //BEGIN KateHlCHex
    00835 KateHlCHex::KateHlCHex(int attribute, int context,signed char regionId,signed char regionId2)
    00836   : KateHlItem(attribute,context,regionId,regionId2)
    00837 {
    00838   alwaysStartEnable = false;
    00839 }
    00840
    00841 int KateHlCHex::checkHgl(const QString& text, int offset, int len)
    00842 {
    00843   if ((len > 1) && (text[offset++] == '0') && ((text[offset++] & 0xdf) == 'X' ))
    00844   {
    00845     len -= 2;
    00846
    00847     int offset2 = offset;
    00848
    00849     while ((len > 0) && (text[offset2].isDigit() || ((text[offset2] & 0xdf) >= 'A' && (text[offset2] & 0xdf) <= 'F')))
    00850     {
    00851       offset2++;
    00852       len--;
    00853     }
    00854
    00855     if (offset2 > offset)
    00856     {
    00857       if ((len > 0) && ((text[offset2] & 0xdf) == 'L' || (text[offset2] & 0xdf) == 'U' ))
    00858         offset2++;
    00859
    00860       return offset2;
    00861     }
    00862   }
    00863
    00864   return 0;
    00865 }
    00866 //END
    00867
    00868 //BEGIN KateHlCFloat
    00869 KateHlCFloat::KateHlCFloat(int attribute, int context, signed char regionId,signed char regionId2)
    00870   : KateHlFloat(attribute,context,regionId,regionId2)
    00871 {
    00872   alwaysStartEnable = false;
    00873 }
    00874
    00875 int KateHlCFloat::checkIntHgl(const QString& text, int offset, int len)
    00876 {
    00877   int offset2 = offset;
    00878
    00879   while ((len > 0) && text[offset].isDigit()) {
    00880     offset2++;
    00881     len--;
    00882   }
    00883
    00884   if (offset2 > offset)
    00885      return offset2;
    00886
    00887   return 0;
    00888 }
    00889
    00890 int KateHlCFloat::checkHgl(const QString& text, int offset, int len)
    00891 {
    00892   int offset2 = KateHlFloat::checkHgl(text, offset, len);
    00893
    00894   if (offset2)
    00895   {
    00896     if ((text[offset2] & 0xdf) == 'F' )
    00897       offset2++;
    00898
    00899     return offset2;
    00900   }
    00901   else
    00902   {
    00903     offset2 = checkIntHgl(text, offset, len);
    00904
    00905     if (offset2 && ((text[offset2] & 0xdf) == 'F' ))
    00906       return ++offset2;
    00907     else
    00908       return 0;
    00909   }
    00910 }
    00911 //END
    00912
    00913 //BEGIN KateHlAnyChar
    00914 KateHlAnyChar::KateHlAnyChar(int attribute, int context, signed char regionId,signed char regionId2, const QString& charList)
    00915   : KateHlItem(attribute, context,regionId,regionId2)
    00916   , _charList(charList)
    00917 {
    00918 }
    00919
    00920 int KateHlAnyChar::checkHgl(const QString& text, int offset, int)
    00921 {
    00922   if (kateInsideString (_charList, text[offset]))
    00923     return ++offset;
    00924
    00925   return 0;
    00926 }
    00927 //END
    00928
    00929 //BEGIN KateHlRegExpr
    00930 KateHlRegExpr::KateHlRegExpr( int attribute, int context, signed char regionId,signed char regionId2, QString regexp, bool insensitive, bool minimal)
    00931   : KateHlItem(attribute, context, regionId,regionId2)
    00932   , handlesLinestart (regexp.startsWith("^"))
    00933   , _regexp(regexp)
    00934   , _insensitive(insensitive)
    00935   , _minimal(minimal)
    00936 {
    00937   if (!handlesLinestart)
    00938     regexp.prepend("^");
    00939
    00940   Expr = new QRegExp(regexp, !_insensitive);
    00941   Expr->setMinimal(_minimal);
    00942 }
    00943
    00944 int KateHlRegExpr::checkHgl(const QString& text, int offset, int /*len*/)
    00945 {
    00946   if (offset && handlesLinestart)
    00947     return 0;
    00948
    00949   int offset2 = Expr->search( text, offset, QRegExp::CaretAtOffset );
    00950
    00951   if (offset2 == -1) return 0;
    00952
    00953   return (offset + Expr->matchedLength());
    00954 }
    00955
    00956 QStringList *KateHlRegExpr::capturedTexts()
    00957 {
    00958   return new QStringList(Expr->capturedTexts());
    00959 }
    00960
    00961 KateHlItem *KateHlRegExpr::clone(const QStringList *args)
    00962 {
    00963   QString regexp = _regexp;
    00964   QStringList escArgs = *args;
    00965
    00966   for (QStringList::Iterator it = escArgs.begin(); it != escArgs.end(); ++it)
    00967   {
    00968     (*it).replace(QRegExp("(\\W)"), "\\\\1");
    00969   }
    00970
    00971   dynamicSubstitute(regexp, &escArgs);
    00972
    00973   if (regexp == _regexp)
    00974     return this;
    00975
    00976   // kdDebug (13010) << "clone regexp: " << regexp << endl;
    00977
    00978   KateHlRegExpr *ret = new KateHlRegExpr(attr, ctx, region, region2, regexp, _insensitive, _minimal);
    00979   ret->dynamicChild = true;
    00980   return ret;
    00981 }
    00982 //END
    00983
    00984 //BEGIN KateHlLineContinue
    00985 KateHlLineContinue::KateHlLineContinue(int attribute, int context, signed char regionId,signed char regionId2)
    00986   : KateHlItem(attribute,context,regionId,regionId2) {
    00987 }
    00988
    00989 int KateHlLineContinue::checkHgl(const QString& text, int offset, int len)
    00990 {
    00991   if ((len == 1) && (text[offset] == '\\'))
    00992     return ++offset;
    00993
    00994   return 0;
    00995 }
    00996 //END
    00997
    00998 //BEGIN KateHlCStringChar
    00999 KateHlCStringChar::KateHlCStringChar(int attribute, int context,signed char regionId,signed char regionId2)
    01000   : KateHlItem(attribute,context,regionId,regionId2) {
    01001 }
    01002
    01003 // checks for C escaped chars \n and escaped hex/octal chars
    01004 static int checkEscapedChar(const QString& text, int offset, int& len)
    01005 {
    01006   int i;
    01007   if (text[offset] == '\\' && len > 1)
    01008   {
    01009     offset++;
    01010     len--;
    01011
    01012     switch(text[offset])
    01013     {
    01014       case  'a': // checks for control chars
    01015       case  'b': // we want to fall through
    01016       case  'e':
    01017       case  'f':
    01018
    01019       case  'n':
    01020       case  'r':
    01021       case  't':
    01022       case  'v':
    01023       case '\'':
    01024       case '\"':
    01025       case '?' : // added ? ANSI C classifies this as an escaped char
    01026       case '\\':
    01027         offset++;
    01028         len--;
    01029         break;
    01030
    01031       case 'x': // if it's like \xff
    01032         offset++; // eat the x
    01033         len--;
    01034         // these for loops can probably be
    01035         // replaced with something else but
    01036         // for right now they work
    01037         // check for hexdigits
    01038         for (i = 0; (len > 0) && (i < 2) && (text[offset] >= '0' && text[offset] <= '9' || (text[offset] & 0xdf) >= 'A' && (text[offset] & 0xdf) <= 'F'); i++)
    01039         {
    01040           offset++;
    01041           len--;
    01042         }
    01043
    01044         if (i == 0)
    01045           return 0; // takes care of case '\x'
    01046
    01047         break;
    01048
    01049       case '0': case '1': case '2': case '3' :
    01050       case '4': case '5': case '6': case '7' :
    01051         for (i = 0; (len > 0) && (i < 3) && (text[offset] >='0'&& text[offset] <='7'); i++)
    01052         {
    01053           offset++;
    01054           len--;
    01055         }
    01056         break;
    01057
    01058       default:
    01059         return 0;
    01060     }
    01061
    01062     return offset;
    01063   }
    01064
    01065   return 0;
    01066 }
    01067
    01068 int KateHlCStringChar::checkHgl(const QString& text, int offset, int len)
    01069 {
    01070   return checkEscapedChar(text, offset, len);
    01071 }
    01072 //END
    01073
    01074 //BEGIN KateHlCChar
    01075 KateHlCChar::KateHlCChar(int attribute, int context,signed char regionId,signed char regionId2)
    01076   : KateHlItem(attribute,context,regionId,regionId2) {
    01077 }
    01078
    01079 int KateHlCChar::checkHgl(const QString& text, int offset, int len)
    01080 {
    01081   if ((len > 1) && (text[offset] == '\'') && (text[offset+1] != '\''))
    01082   {
    01083     int oldl;
    01084     oldl = len;
    01085
    01086     len--;
    01087
    01088     int offset2 = checkEscapedChar(text, offset + 1, len);
    01089
    01090     if (!offset2)
    01091     {
    01092       if (oldl > 2)
    01093       {
    01094         offset2 = offset + 2;
    01095         len = oldl - 2;
    01096       }
    01097       else
    01098       {
    01099         return 0;
    01100       }
    01101     }
    01102
    01103     if ((len > 0) && (text[offset2] == '\''))
    01104       return ++offset2;
    01105   }
    01106
    01107   return 0;
    01108 }
    01109 //END
    01110
    01111 //BEGIN KateHl2CharDetect
    01112 KateHl2CharDetect::KateHl2CharDetect(int attribute, int context, signed char regionId,signed char regionId2, const QChar *s)
    01113   : KateHlItem(attribute,context,regionId,regionId2) {
    01114   sChar1 = s[0];
    01115   sChar2 = s[1];
    01116   }
    01117 //END KateHl2CharDetect
    01118
    01119 KateHlItemData::KateHlItemData(const QString  name, int defStyleNum)
    01120   : name(name), defStyleNum(defStyleNum) {
    01121 }
    01122
    01123 KateHlData::KateHlData(const QString &wildcards, const QString &mimetypes, const QString &identifier, int priority)
    01124   : wildcards(wildcards), mimetypes(mimetypes), identifier(identifier), priority(priority)
    01125 {
    01126 }
    01127
    01128 //BEGIN KateHlContext
    01129 KateHlContext::KateHlContext (const QString &_hlId, int attribute, int lineEndContext, int _lineBeginContext, bool _fallthrough, int _fallthroughContext, bool _dynamic)
    01130 {
    01131   hlId = _hlId;
    01132   attr = attribute;
    01133   ctx = lineEndContext;
    01134   lineBeginContext = _lineBeginContext;
    01135   fallthrough = _fallthrough;
    01136   ftctx = _fallthroughContext;
    01137   dynamic = _dynamic;
    01138   dynamicChild = false;
    01139 }
    01140
    01141 KateHlContext *KateHlContext::clone(const QStringList *args)
    01142 {
    01143   KateHlContext *ret = new KateHlContext(hlId, attr, ctx, lineBeginContext, fallthrough, ftctx, false);
    01144
    01145   for (uint n=0; n < items.size(); ++n)
    01146   {
    01147     KateHlItem *item = items[n];
    01148     KateHlItem *i = (item->dynamic ? item->clone(args) : item);
    01149     ret->items.append(i);
    01150   }
    01151
    01152   ret->dynamicChild = true;
    01153
    01154   return ret;
    01155 }
    01156
    01157 KateHlContext::~KateHlContext()
    01158 {
    01159   if (dynamicChild)
    01160   {
    01161     for (uint n=0; n < items.size(); ++n)
    01162     {
    01163       if (items[n]->dynamicChild)
    01164         delete items[n];
    01165     }
    01166   }
    01167 }
    01168 //END
    01169
    01170 //BEGIN KateHighlighting
    01171 KateHighlighting::KateHighlighting(const KateSyntaxModeListItem *def) : refCount(0)
    01172 {
    01173   m_attributeArrays.setAutoDelete (true);
    01174
    01175   errorsAndWarnings = "";
    01176   building=false;
    01177   noHl = false;
    01178   m_foldingIndentationSensitive = false;
    01179   folding=false;
    01180   internalIDList.setAutoDelete(true);
    01181
    01182   if (def == 0)
    01183   {
    01184     noHl = true;
    01185     iName = "None"; // not translated internal name (for config and more)
    01186     iNameTranslated = i18n("None"); // user visible name
    01187     iSection = "";
    01188     m_priority = 0;
    01189     iHidden = false;
    01190     m_additionalData.insert( "none", new HighlightPropertyBag );
    01191     m_additionalData["none"]->deliminator = stdDeliminator;
    01192     m_additionalData["none"]->wordWrapDeliminator = stdDeliminator;
    01193     m_hlIndex[0] = "none";
    01194   }
    01195   else
    01196   {
    01197     iName = def->name;
    01198     iNameTranslated = def->nameTranslated;
    01199     iSection = def->section;
    01200     iHidden = def->hidden;
    01201     iWildcards = def->extension;
    01202     iMimetypes = def->mimetype;
    01203     identifier = def->identifier;
    01204     iVersion=def->version;
    01205     iAuthor=def->author;
    01206     iLicense=def->license;
    01207     m_priority=def->priority.toInt();
    01208   }
    01209
    01210    deliminator = stdDeliminator;
    01211 }
    01212
    01213 KateHighlighting::~KateHighlighting()
    01214 {
    01215   for (uint i=0; i < m_contexts.size(); ++i)
    01216     delete m_contexts[i];
    01217 }
    01218
    01219 void KateHighlighting::generateContextStack(int *ctxNum, int ctx, QMemArray<short>* ctxs, int *prevLine)
    01220 {
    01221   //kdDebug(13010)<<QString("Entering generateContextStack with %1").arg(ctx)<<endl;
    01222   while (true)
    01223   {
    01224     if (ctx >= 0)
    01225     {
    01226       (*ctxNum) = ctx;
    01227
    01228       ctxs->resize (ctxs->size()+1, QGArray::SpeedOptim);
    01229       (*ctxs)[ctxs->size()-1]=(*ctxNum);
    01230
    01231       return;
    01232     }
    01233     else
    01234     {
    01235       if (ctx == -1)
    01236       {
    01237         (*ctxNum)=( (ctxs->isEmpty() ) ? 0 : (*ctxs)[ctxs->size()-1]);
    01238       }
    01239       else
    01240       {
    01241         int size = ctxs->size() + ctx + 1;
    01242
    01243         if (size > 0)
    01244         {
    01245           ctxs->resize (size, QGArray::SpeedOptim);
    01246           (*ctxNum)=(*ctxs)[size-1];
    01247         }
    01248         else
    01249         {
    01250           ctxs->resize (0, QGArray::SpeedOptim);
    01251           (*ctxNum)=0;
    01252         }
    01253
    01254         ctx = 0;
    01255
    01256         if ((*prevLine) >= (int)(ctxs->size()-1))
    01257         {
    01258           *prevLine=ctxs->size()-1;
    01259
    01260           if ( ctxs->isEmpty() )
    01261             return;
    01262
    01263           KateHlContext *c = contextNum((*ctxs)[ctxs->size()-1]);
    01264           if (c && (c->ctx != -1))
    01265           {
    01266             //kdDebug(13010)<<"PrevLine > size()-1 and ctx!=-1)"<<endl;
    01267             ctx = c->ctx;
    01268
    01269             continue;
    01270           }
    01271         }
    01272       }
    01273
    01274       return;
    01275     }
    01276   }
    01277 }
    01278
    01282 int KateHighlighting::makeDynamicContext(KateHlContext *model, const QStringList *args)
    01283 {
    01284   QPair<KateHlContext *, QString> key(model, args->front());
    01285   short value;
    01286
    01287   if (dynamicCtxs.contains(key))
    01288     value = dynamicCtxs[key];
    01289   else
    01290   {
    01291     kdDebug(13010) << "new stuff: " << startctx << endl;
    01292
    01293     KateHlContext *newctx = model->clone(args);
    01294
    01295     m_contexts.push_back (newctx);
    01296
    01297     value = startctx++;
    01298     dynamicCtxs[key] = value;
    01299     KateHlManager::self()->incDynamicCtxs();
    01300   }
    01301
    01302   // kdDebug(13010) << "Dynamic context: using context #" << value << " (for model " << model << " with args " << *args << ")" << endl;
    01303
    01304   return value;
    01305 }
    01306
    01311 void KateHighlighting::dropDynamicContexts()
    01312 {
    01313   for (uint i=base_startctx; i < m_contexts.size(); ++i)
    01314     delete m_contexts[i];
    01315
    01316   m_contexts.resize (base_startctx);
    01317
    01318   dynamicCtxs.clear();
    01319   startctx = base_startctx;
    01320 }
    01321
    01330 void KateHighlighting::doHighlight ( KateTextLine *prevLine,
    01331                                      KateTextLine *textLine,
    01332                                      QMemArray<uint>* foldingList,
    01333                                      bool *ctxChanged )
    01334 {
    01335   if (!textLine)
    01336     return;
    01337
    01338   if (noHl)
    01339   {
    01340     if (textLine->length() > 0)
    01341       memset (textLine->attributes(), 0, textLine->length());
    01342
    01343     return;
    01344   }
    01345
    01346   // duplicate the ctx stack, only once !
    01347   QMemArray<short> ctx;
    01348   ctx.duplicate (prevLine->ctxArray());
    01349
    01350   int ctxNum = 0;
    01351   int previousLine = -1;
    01352   KateHlContext *context;
    01353
    01354   if (ctx.isEmpty())
    01355   {
    01356     // If the stack is empty, we assume to be in Context 0 (Normal)
    01357     context = contextNum(ctxNum);
    01358   }
    01359   else
    01360   {
    01361     // There does an old context stack exist -> find the context at the line start
    01362     ctxNum = ctx[ctx.size()-1]; //context ID of the last character in the previous line
    01363
    01364     //kdDebug(13010) << "\t\tctxNum = " << ctxNum << " contextList[ctxNum] = " << contextList[ctxNum] << endl; // ellis
    01365
    01366     //if (lineContinue)   kdDebug(13010)<<QString("The old context should be %1").arg((int)ctxNum)<<endl;
    01367
    01368     if (!(context = contextNum(ctxNum)))
    01369       context = contextNum(0);
    01370
    01371     //kdDebug(13010)<<"test1-2-1-text2"<<endl;
    01372
    01373     previousLine=ctx.size()-1; //position of the last context ID of th previous line within the stack
    01374
    01375     // hl continue set or not ???
    01376     if (prevLine->hlLineContinue())
    01377     {
    01378       prevLine--;
    01379     }
    01380     else
    01381     {
    01382       generateContextStack(&ctxNum, context->ctx, &ctx, &previousLine); //get stack ID to use
    01383
    01384       if (!(context = contextNum(ctxNum)))
    01385         context = contextNum(0);
    01386     }
    01387
    01388     //kdDebug(13010)<<"test1-2-1-text4"<<endl;
    01389
    01390     //if (lineContinue)   kdDebug(13010)<<QString("The new context is %1").arg((int)ctxNum)<<endl;
    01391   }
    01392
    01393   // text, for programming convenience :)
    01394   QChar lastChar = ' ';
    01395   const QString& text = textLine->string();
    01396   const int len = textLine->length();
    01397
    01398   // calc at which char the first char occurs, set it to lenght of line if never
    01399   const int firstChar = textLine->firstChar();
    01400   const int startNonSpace = (firstChar == -1) ? len : firstChar;
    01401
    01402   // last found item
    01403   KateHlItem *item = 0;
    01404
    01405   // loop over the line, offset gives current offset
    01406   int offset = 0;
    01407   while (offset < len)
    01408   {
    01409     bool anItemMatched = false;
    01410     bool standardStartEnableDetermined = false;
    01411     bool customStartEnableDetermined = false;
    01412
    01413     uint index = 0;
    01414     for (item = context->items.empty() ? 0 : context->items[0]; item; item = (++index < context->items.size()) ? context->items[index] : 0 )
    01415     {
    01416       // does we only match if we are firstNonSpace?
    01417       if (item->firstNonSpace && (offset > startNonSpace))
    01418         continue;
    01419
    01420       // have we a column specified? if yes, only match at this column
    01421       if ((item->column != -1) && (item->column != offset))
    01422         continue;
    01423
    01424       if (!item->alwaysStartEnable)
    01425       {
    01426         if (item->customStartEnable)
    01427         {
    01428             if (customStartEnableDetermined || kateInsideString (m_additionalData[context->hlId]->deliminator, lastChar))
    01429             customStartEnableDetermined = true;
    01430           else
    01431             continue;
    01432         }
    01433         else
    01434         {
    01435           if (standardStartEnableDetermined || kateInsideString (stdDeliminator, lastChar))
    01436             standardStartEnableDetermined = true;
    01437           else
    01438             continue;
    01439         }
    01440       }
    01441
    01442       int offset2 = item->checkHgl(text, offset, len-offset);
    01443
    01444       if (offset2 <= offset)
    01445         continue;
    01446
    01447       if (item->region2)
    01448       {
    01449         // kdDebug(13010)<<QString("Region mark 2 detected: %1").arg(item->region2)<<endl;
    01450         if ( !foldingList->isEmpty() && ((item->region2 < 0) && (*foldingList)[foldingList->size()-2] == -item->region2 ) )
    01451         {
    01452           foldingList->resize (foldingList->size()-2, QGArray::SpeedOptim);
    01453         }
    01454         else
    01455         {
    01456           foldingList->resize (foldingList->size()+2, QGArray::SpeedOptim);
    01457           (*foldingList)[foldingList->size()-2] = (uint)item->region2;
    01458           if (item->region2<0) //check not really needed yet
    01459             (*foldingList)[foldingList->size()-1] = offset2;
    01460           else
    01461           (*foldingList)[foldingList->size()-1] = offset;
    01462         }
    01463
    01464       }
    01465
    01466       if (item->region)
    01467       {
    01468         // kdDebug(13010)<<QString("Region mark detected: %1").arg(item->region)<<endl;
    01469
    01470       /* if ( !foldingList->isEmpty() && ((item->region < 0) && (*foldingList)[foldingList->size()-1] == -item->region ) )
    01471         {
    01472           foldingList->resize (foldingList->size()-1, QGArray::SpeedOptim);
    01473         }
    01474         else*/
    01475         {
    01476           foldingList->resize (foldingList->size()+2, QGArray::SpeedOptim);
    01477           (*foldingList)[foldingList->size()-2] = item->region;
    01478           if (item->region<0) //check not really needed yet
    01479             (*foldingList)[foldingList->size()-1] = offset2;
    01480           else
    01481             (*foldingList)[foldingList->size()-1] = offset;
    01482         }
    01483
    01484       }
    01485
    01486       // regenerate context stack if needed
    01487       if (item->ctx != -1)
    01488       {
    01489         generateContextStack (&ctxNum, item->ctx, &ctx, &previousLine);
    01490         context = contextNum(ctxNum);
    01491       }
    01492
    01493       // dynamic context: substitute the model with an 'instance'
    01494       if (context->dynamic)
    01495       {
    01496         QStringList *lst = item->capturedTexts();
    01497         if (lst != 0)
    01498         {
    01499           // Replace the top of the stack and the current context
    01500           int newctx = makeDynamicContext(context, lst);
    01501           if (ctx.size() > 0)
    01502             ctx[ctx.size() - 1] = newctx;
    01503           ctxNum = newctx;
    01504           context = contextNum(ctxNum);
    01505         }
    01506         delete lst;
    01507       }
    01508
    01509       // dominik: look ahead w/o changing offset?
    01510       if (!item->lookAhead)
    01511       {
    01512         if (offset2 > len)
    01513           offset2 = len;
    01514
    01515         // even set attributes ;)
    01516         memset ( textLine->attributes()+offset
    01517                , item->onlyConsume ? context->attr : item->attr
    01518                , len-offset);
    01519
    01520         offset = offset2;
    01521         lastChar = text[offset-1];
    01522       }
    01523
    01524       anItemMatched = true;
    01525       break;
    01526     }
    01527
    01528     // something matched, continue loop
    01529     if (anItemMatched)
    01530       continue;
    01531
    01532     // nothing found: set attribute of one char
    01533     // anders: unless this context does not want that!
    01534     if ( context->fallthrough )
    01535     {
    01536     // set context to context->ftctx.
    01537       generateContextStack(&ctxNum, context->ftctx, &ctx, &previousLine);  //regenerate context stack
    01538       context=contextNum(ctxNum);
    01539     //kdDebug(13010)<<"context num after fallthrough at col "<<z<<": "<<ctxNum<<endl;
    01540     // the next is nessecary, as otherwise keyword (or anything using the std delimitor check)
    01541     // immediately after fallthrough fails. Is it bad?
    01542     // jowenn, can you come up with a nicer way to do this?
    01543     /*  if (offset)
    01544         lastChar = text[offset - 1];
    01545       else
    01546         lastChar = '\\';*/
    01547       continue;
    01548     }
    01549     else
    01550     {
    01551       *(textLine->attributes() + offset) = context->attr;
    01552       lastChar = text[offset];
    01553       offset++;
    01554     }
    01555   }
    01556
    01557   // has the context stack changed ?
    01558   if (ctx == textLine->ctxArray())
    01559   {
    01560     if (ctxChanged)
    01561       (*ctxChanged) = false;
    01562   }
    01563   else
    01564   {
    01565     if (ctxChanged)
    01566       (*ctxChanged) = true;
    01567
    01568     // assign ctx stack !
    01569     textLine->setContext(ctx);
    01570   }
    01571
    01572   // write hl continue flag
    01573   textLine->setHlLineContinue (item && item->lineContinue());
    01574 }
    01575
    01576 void KateHighlighting::loadWildcards()
    01577 {
    01578   KConfig *config = KateHlManager::self()->getKConfig();
    01579   config->setGroup("Highlighting " + iName);
    01580
    01581   QString extensionString = config->readEntry("Wildcards", iWildcards);
    01582
    01583   if (extensionSource != extensionString) {
    01584     regexpExtensions.clear();
    01585     plainExtensions.clear();
    01586
    01587     extensionSource = extensionString;
    01588
    01589     static QRegExp sep("\\s*;\\s*");
    01590
    01591     QStringList l = QStringList::split( sep, extensionSource );
    01592
    01593     static QRegExp boringExpression("\\*\\.[\\d\\w]+");
    01594
    01595     for( QStringList::Iterator it = l.begin(); it != l.end(); ++it )
    01596       if (boringExpression.exactMatch(*it))
    01597         plainExtensions.append((*it).mid(1));
    01598       else
    01599         regexpExtensions.append(QRegExp((*it), true, true));
    01600   }
    01601 }
    01602
    01603 QValueList<QRegExp>& KateHighlighting::getRegexpExtensions()
    01604 {
    01605   return regexpExtensions;
    01606 }
    01607
    01608 QStringList& KateHighlighting::getPlainExtensions()
    01609 {
    01610   return plainExtensions;
    01611 }
    01612
    01613 QString KateHighlighting::getMimetypes()
    01614 {
    01615   KConfig *config = KateHlManager::self()->getKConfig();
    01616   config->setGroup("Highlighting " + iName);
    01617
    01618   return config->readEntry("Mimetypes", iMimetypes);
    01619 }
    01620
    01621 int KateHighlighting::priority()
    01622 {
    01623   KConfig *config = KateHlManager::self()->getKConfig();
    01624   config->setGroup("Highlighting " + iName);
    01625
    01626   return config->readNumEntry("Priority", m_priority);
    01627 }
    01628
    01629 KateHlData *KateHighlighting::getData()
    01630 {
    01631   KConfig *config = KateHlManager::self()->getKConfig();
    01632   config->setGroup("Highlighting " + iName);
    01633
    01634   KateHlData *hlData = new KateHlData(
    01635   config->readEntry("Wildcards", iWildcards),
    01636   config->readEntry("Mimetypes", iMimetypes),
    01637   config->readEntry("Identifier", identifier),
    01638   config->readNumEntry("Priority", m_priority));
    01639
    01640  return hlData;
    01641 }
    01642
    01643 void KateHighlighting::setData(KateHlData *hlData)
    01644 {
    01645   KConfig *config = KateHlManager::self()->getKConfig();
    01646   config->setGroup("Highlighting " + iName);
    01647
    01648   config->writeEntry("Wildcards",hlData->wildcards);
    01649   config->writeEntry("Mimetypes",hlData->mimetypes);
    01650   config->writeEntry("Priority",hlData->priority);
    01651 }
    01652
    01653 void KateHighlighting::getKateHlItemDataList (uint schema, KateHlItemDataList &list)
    01654 {
    01655   KConfig *config = KateHlManager::self()->getKConfig();
    01656   config->setGroup("Highlighting " + iName + " - Schema " + KateFactory::self()->schemaManager()->name(schema));
    01657
    01658   list.clear();
    01659   createKateHlItemData(list);
    01660
    01661   for (KateHlItemData *p = list.first(); p != 0L; p = list.next())
    01662   {
    01663     QStringList s = config->readListEntry(p->name);
    01664
    01665 //    kdDebug(13010)<<p->name<<s.count()<<endl;
    01666     if (s.count()>0)
    01667     {
    01668
    01669       while(s.count()<9) s<<"";
    01670       p->clear();
    01671
    01672       QString tmp=s[0]; if (!tmp.isEmpty()) p->defStyleNum=tmp.toInt();
    01673
    01674       QRgb col;
    01675
    01676       tmp=s[1]; if (!tmp.isEmpty()) {
    01677          col=tmp.toUInt(0,16); p->setTextColor(col); }
    01678
    01679       tmp=s[2]; if (!tmp.isEmpty()) {
    01680          col=tmp.toUInt(0,16); p->setSelectedTextColor(col); }
    01681
    01682       tmp=s[3]; if (!tmp.isEmpty()) p->setBold(tmp!="0");
    01683
    01684       tmp=s[4]; if (!tmp.isEmpty()) p->setItalic(tmp!="0");
    01685
    01686       tmp=s[5]; if (!tmp.isEmpty()) p->setStrikeOut(tmp!="0");
    01687
    01688       tmp=s[6]; if (!tmp.isEmpty()) p->setUnderline(tmp!="0");
    01689
    01690       tmp=s[7]; if (!tmp.isEmpty()) {
    01691          col=tmp.toUInt(0,16); p->setBGColor(col); }
    01692
    01693       tmp=s[8]; if (!tmp.isEmpty()) {
    01694          col=tmp.toUInt(0,16); p->setSelectedBGColor(col); }
    01695
    01696     }
    01697   }
    01698 }
    01699
    01706 void KateHighlighting::setKateHlItemDataList(uint schema, KateHlItemDataList &list)
    01707 {
    01708   KConfig *config = KateHlManager::self()->getKConfig();
    01709   config->setGroup("Highlighting " + iName + " - Schema "
    01710       + KateFactory::self()->schemaManager()->name(schema));
    01711
    01712   QStringList settings;
    01713
    01714   for (KateHlItemData *p = list.first(); p != 0L; p = list.next())
    01715   {
    01716     settings.clear();
    01717     settings<<QString::number(p->defStyleNum,10);
    01718     settings<<(p->itemSet(KateAttribute::TextColor)?QString::number(p->textColor().rgb(),16):"");
    01719     settings<<(p->itemSet(KateAttribute::SelectedTextColor)?QString::number(p->selectedTextColor().rgb(),16):"");
    01720     settings<<(p->itemSet(KateAttribute::Weight)?(p->bold()?"1":"0"):"");
    01721     settings<<(p->itemSet(KateAttribute::Italic)?(p->italic()?"1":"0"):"");
    01722     settings<<(p->itemSet(KateAttribute::StrikeOut)?(p->strikeOut()?"1":"0"):"");
    01723     settings<<(p->itemSet(KateAttribute::Underline)?(p->underline()?"1":"0"):"");
    01724     settings<<(p->itemSet(KateAttribute::BGColor)?QString::number(p->bgColor().rgb(),16):"");
    01725     settings<<(p->itemSet(KateAttribute::SelectedBGColor)?QString::number(p->selectedBGColor().rgb(),16):"");
    01726     settings<<"---";
    01727     config->writeEntry(p->name,settings);
    01728   }
    01729 }
    01730
    01734 void KateHighlighting::use()
    01735 {
    01736   if (refCount == 0)
    01737     init();
    01738
    01739   refCount++;
    01740 }
    01741
    01745 void KateHighlighting::release()
    01746 {
    01747   refCount--;
    01748
    01749   if (refCount == 0)
    01750     done();
    01751 }
    01752
    01757 void KateHighlighting::init()
    01758 {
    01759   if (noHl)
    01760     return;
    01761
    01762   m_contexts.clear ();
    01763   makeContextList();
    01764 }
    01765
    01766
    01771 void KateHighlighting::done()
    01772 {
    01773   if (noHl)
    01774     return;
    01775
    01776   m_contexts.clear ();
    01777   internalIDList.clear();
    01778 }
    01779
    01787 void KateHighlighting::createKateHlItemData(KateHlItemDataList &list)
    01788 {
    01789   // If no highlighting is selected we need only one default.
    01790   if (noHl)
    01791   {
    01792     list.append(new KateHlItemData(i18n("Normal Text"), KateHlItemData::dsNormal));
    01793     return;
    01794   }
    01795
    01796   // If the internal list isn't already available read the config file
    01797   if (internalIDList.isEmpty())
    01798     makeContextList();
    01799
    01800   list=internalIDList;
    01801 }
    01802
    01806 void KateHighlighting::addToKateHlItemDataList()
    01807 {
    01808   //Tell the syntax document class which file we want to parse and which data group
    01809   KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
    01810   KateSyntaxContextData *data = KateHlManager::self()->syntax->getGroupInfo("highlighting","itemData");
    01811
    01812   //begin with the real parsing
    01813   while (KateHlManager::self()->syntax->nextGroup(data))
    01814   {
    01815     // read all attributes
    01816     QString color = KateHlManager::self()->syntax->groupData(data,QString("color"));
    01817     QString selColor = KateHlManager::self()->syntax->groupData(data,QString("selColor"));
    01818     QString bold = KateHlManager::self()->syntax->groupData(data,QString("bold"));
    01819     QString italic = KateHlManager::self()->syntax->groupData(data,QString("italic"));
    01820     QString underline = KateHlManager::self()->syntax->groupData(data,QString("underline"));
    01821     QString strikeOut = KateHlManager::self()->syntax->groupData(data,QString("strikeOut"));
    01822     QString bgColor = KateHlManager::self()->syntax->groupData(data,QString("backgroundColor"));
    01823     QString selBgColor = KateHlManager::self()->syntax->groupData(data,QString("selBackgroundColor"));
    01824
    01825     KateHlItemData* newData = new KateHlItemData(
    01826             buildPrefix+KateHlManager::self()->syntax->groupData(data,QString("name")).simplifyWhiteSpace(),
    01827             getDefStyleNum(KateHlManager::self()->syntax->groupData(data,QString("defStyleNum"))));
    01828
    01829     /* here the custom style overrides are specified, if needed */
    01830     if (!color.isEmpty()) newData->setTextColor(QColor(color));
    01831     if (!selColor.isEmpty()) newData->setSelectedTextColor(QColor(selColor));
    01832     if (!bold.isEmpty()) newData->setBold( IS_TRUE(bold) );
    01833     if (!italic.isEmpty()) newData->setItalic( IS_TRUE(italic) );
    01834     // new attributes for the new rendering view
    01835     if (!underline.isEmpty()) newData->setUnderline( IS_TRUE(underline) );
    01836     if (!strikeOut.isEmpty()) newData->setStrikeOut( IS_TRUE(strikeOut) );
    01837     if (!bgColor.isEmpty()) newData->setBGColor(QColor(bgColor));
    01838     if (!selBgColor.isEmpty()) newData->setSelectedBGColor(QColor(selBgColor));
    01839
    01840     internalIDList.append(newData);
    01841   }
    01842
    01843   //clean up
    01844   if (data)
    01845     KateHlManager::self()->syntax->freeGroupInfo(data);
    01846 }
    01847
    01858 int  KateHighlighting::lookupAttrName(const QString& name, KateHlItemDataList &iDl)
    01859 {
    01860   for (uint i = 0; i < iDl.count(); i++)
    01861     if (iDl.at(i)->name == buildPrefix+name)
    01862       return i;
    01863
    01864   kdDebug(13010)<<"Couldn't resolve itemDataName:"<<name<<endl;
    01865   return 0;
    01866 }
    01867
    01881 KateHlItem *KateHighlighting::createKateHlItem(KateSyntaxContextData *data,
    01882                                                KateHlItemDataList &iDl,
    01883                                                QStringList *RegionList,
    01884                                                QStringList *ContextNameList)
    01885 {
    01886   // No highlighting -> exit
    01887   if (noHl)
    01888     return 0;
    01889
    01890   // get the (tagname) itemd type
    01891   QString dataname=KateHlManager::self()->syntax->groupItemData(data,QString(""));
    01892
    01893   // code folding region handling:
    01894   QString beginRegionStr=KateHlManager::self()->syntax->groupItemData(data,QString("beginRegion"));
    01895   QString endRegionStr=KateHlManager::self()->syntax->groupItemData(data,QString("endRegion"));
    01896
    01897   signed char regionId=0;
    01898   signed char regionId2=0;
    01899
    01900   if (!beginRegionStr.isEmpty())
    01901   {
    01902     regionId = RegionList->findIndex(beginRegionStr);
    01903
    01904     if (regionId==-1) // if the region name doesn't already exist, add it to the list
    01905     {
    01906       (*RegionList)<<beginRegionStr;
    01907       regionId = RegionList->findIndex(beginRegionStr);
    01908     }
    01909
    01910     regionId++;
    01911
    01912     kdDebug(13010) << "########### BEG REG: "  << beginRegionStr << " NUM: " << regionId << endl;
    01913   }
    01914
    01915   if (!endRegionStr.isEmpty())
    01916   {
    01917     regionId2 = RegionList->findIndex(endRegionStr);
    01918
    01919     if (regionId2==-1) // if the region name doesn't already exist, add it to the list
    01920     {
    01921       (*RegionList)<<endRegionStr;
    01922       regionId2 = RegionList->findIndex(endRegionStr);
    01923     }
    01924
    01925     regionId2 = -regionId2 - 1;
    01926
    01927     kdDebug(13010) << "########### END REG: "  << endRegionStr << " NUM: " << regionId2 << endl;
    01928   }
    01929
    01930   int attr = 0;
    01931   QString tmpAttr=KateHlManager::self()->syntax->groupItemData(data,QString("attribute")).simplifyWhiteSpace();
    01932   bool onlyConsume = tmpAttr.isEmpty();
    01933
    01934   // only relevant for non consumer
    01935   if (!onlyConsume)
    01936   {
    01937     if (QString("%1").arg(tmpAttr.toInt())==tmpAttr)
    01938     {
    01939       errorsAndWarnings+=i18n(
    01940           "<B>%1</B>: Deprecated syntax. Attribute (%2) not addressed by symbolic name<BR>").
    01941       arg(buildIdentifier).arg(tmpAttr);
    01942       attr=tmpAttr.toInt();
    01943     }
    01944     else
    01945       attr=lookupAttrName(tmpAttr,iDl);
    01946   }
    01947
    01948   // Info about context switch
    01949   int context = -1;
    01950   QString unresolvedContext;
    01951   QString tmpcontext=KateHlManager::self()->syntax->groupItemData(data,QString("context"));
    01952   if (!tmpcontext.isEmpty())
    01953     context=getIdFromString(ContextNameList, tmpcontext,unresolvedContext);
    01954
    01955   // Get the char parameter (eg DetectChar)
    01956   char chr;
    01957   if (! KateHlManager::self()->syntax->groupItemData(data,QString("char")).isEmpty())
    01958     chr= (KateHlManager::self()->syntax->groupItemData(data,QString("char")).latin1())[0];
    01959   else
    01960     chr=0;
    01961
    01962   // Get the String parameter (eg. StringDetect)
    01963   QString stringdata=KateHlManager::self()->syntax->groupItemData(data,QString("String"));
    01964
    01965   // Get a second char parameter (char1) (eg Detect2Chars)
    01966   char chr1;
    01967   if (! KateHlManager::self()->syntax->groupItemData(data,QString("char1")).isEmpty())
    01968     chr1= (KateHlManager::self()->syntax->groupItemData(data,QString("char1")).latin1())[0];
    01969   else
    01970     chr1=0;
    01971
    01972   // Will be removed eventuall. Atm used for StringDetect and RegExp
    01973   bool insensitive = IS_TRUE( KateHlManager::self()->syntax->groupItemData(data,QString("insensitive")) );
    01974
    01975   // for regexp only
    01976   bool minimal = IS_TRUE( KateHlManager::self()->syntax->groupItemData(data,QString("minimal")) );
    01977
    01978   // dominik: look ahead and do not change offset. so we can change contexts w/o changing offset1.
    01979   bool lookAhead = IS_TRUE( KateHlManager::self()->syntax->groupItemData(data,QString("lookAhead")) );
    01980
    01981   bool dynamic= IS_TRUE(KateHlManager::self()->syntax->groupItemData(data,QString("dynamic")) );
    01982
    01983   bool firstNonSpace = IS_TRUE(KateHlManager::self()->syntax->groupItemData(data,QString("firstNonSpace")) );
    01984
    01985   int column = -1;
    01986   QString colStr = KateHlManager::self()->syntax->groupItemData(data,QString("column"));
    01987   if (!colStr.isEmpty())
    01988     column = colStr.toInt();
    01989
    01990   //Create the item corresponding to it's type and set it's parameters
    01991   KateHlItem *tmpItem;
    01992
    01993   if (dataname=="keyword")
    01994   {
    01995     KateHlKeyword *keyword=new KateHlKeyword(attr,context,regionId,regionId2,casesensitive,
    01996                                              m_additionalData[ buildIdentifier ]->deliminator);
    01997
    01998     //Get the entries for the keyword lookup list
    01999     keyword->addList(KateHlManager::self()->syntax->finddata("highlighting",stringdata));
    02000     tmpItem=keyword;
    02001   }
    02002   else if (dataname=="Float") tmpItem= (new KateHlFloat(attr,context,regionId,regionId2));
    02003   else if (dataname=="Int") tmpItem=(new KateHlInt(attr,context,regionId,regionId2));
    02004   else if (dataname=="DetectChar") tmpItem=(new KateHlCharDetect(attr,context,regionId,regionId2,chr));
    02005   else if (dataname=="Detect2Chars") tmpItem=(new KateHl2CharDetect(attr,context,regionId,regionId2,chr,chr1));
    02006   else if (dataname=="RangeDetect") tmpItem=(new KateHlRangeDetect(attr,context,regionId,regionId2, chr, chr1));
    02007   else if (dataname=="LineContinue") tmpItem=(new KateHlLineContinue(attr,context,regionId,regionId2));
    02008   else if (dataname=="StringDetect") tmpItem=(new KateHlStringDetect(attr,context,regionId,regionId2,stringdata,insensitive));
    02009   else if (dataname=="AnyChar") tmpItem=(new KateHlAnyChar(attr,context,regionId,regionId2,stringdata));
    02010   else if (dataname=="RegExpr") tmpItem=(new KateHlRegExpr(attr,context,regionId,regionId2,stringdata, insensitive, minimal));
    02011   else if (dataname=="HlCChar") tmpItem= ( new KateHlCChar(attr,context,regionId,regionId2));
    02012   else if (dataname=="HlCHex") tmpItem= (new KateHlCHex(attr,context,regionId,regionId2));
    02013   else if (dataname=="HlCOct") tmpItem= (new KateHlCOct(attr,context,regionId,regionId2));
    02014   else if (dataname=="HlCFloat") tmpItem= (new KateHlCFloat(attr,context,regionId,regionId2));
    02015   else if (dataname=="HlCStringChar") tmpItem= (new KateHlCStringChar(attr,context,regionId,regionId2));
    02016   else if (dataname=="DetectSpaces") tmpItem= (new KateHlDetectSpaces(attr,context,regionId,regionId2));
    02017   else if (dataname=="DetectIdentifier") tmpItem= (new KateHlDetectIdentifier(attr,context,regionId,regionId2));
    02018   else
    02019   {
    02020     // oops, unknown type. Perhaps a spelling error in the xml file
    02021     return 0;
    02022   }
    02023
    02024   // set lookAhead & dynamic properties
    02025   tmpItem->lookAhead = lookAhead;
    02026   tmpItem->dynamic = dynamic;
    02027   tmpItem->firstNonSpace = firstNonSpace;
    02028   tmpItem->column = column;
    02029   tmpItem->onlyConsume = onlyConsume;
    02030
    02031   if (!unresolvedContext.isEmpty())
    02032   {
    02033     unresolvedContextReferences.insert(&(tmpItem->ctx),unresolvedContext);
    02034   }
    02035
    02036   return tmpItem;
    02037 }
    02038
    02039 QString KateHighlighting::hlKeyForAttrib( int i ) const
    02040 {
    02041   int k = 0;
    02042   QMap<int,QString>::const_iterator it = m_hlIndex.constEnd();
    02043   while ( it != m_hlIndex.constBegin() )
    02044   {
    02045     --it;
    02046     k = it.key();
    02047     if ( i >= k )
    02048       break;
    02049   }
    02050   return it.data();
    02051 }
    02052
    02053 bool KateHighlighting::isInWord( QChar c, int attrib ) const
    02054 {
    02055   static const QString& sq = KGlobal::staticQString(" \"'");
    02056   return m_additionalData[ hlKeyForAttrib( attrib ) ]->deliminator.find(c) < 0 && sq.find(c) < 0;
    02057 }
    02058
    02059 bool KateHighlighting::canBreakAt( QChar c, int attrib ) const
    02060 {
    02061   static const QString& sq = KGlobal::staticQString("\"'");
    02062   return (m_additionalData[ hlKeyForAttrib( attrib ) ]->wordWrapDeliminator.find(c) != -1) && (sq.find(c) == -1);
    02063 }
    02064
    02065 signed char KateHighlighting::commentRegion(int attr) const {
    02066   QString commentRegion=m_additionalData[ hlKeyForAttrib( attr ) ]->multiLineRegion;
    02067   return (commentRegion.isEmpty()?0:(commentRegion.toShort()));
    02068 }
    02069
    02070 bool KateHighlighting::canComment( int startAttrib, int endAttrib ) const
    02071 {
    02072   QString k = hlKeyForAttrib( startAttrib );
    02073   return ( k == hlKeyForAttrib( endAttrib ) &&
    02074       ( ( !m_additionalData[k]->multiLineCommentStart.isEmpty() && !m_additionalData[k]->multiLineCommentEnd.isEmpty() ) ||
    02075        ! m_additionalData[k]->singleLineCommentMarker.isEmpty() ) );
    02076 }
    02077
    02078 QString KateHighlighting::getCommentStart( int attrib ) const
    02079 {
    02080   return m_additionalData[ hlKeyForAttrib( attrib) ]->multiLineCommentStart;
    02081 }
    02082
    02083 QString KateHighlighting::getCommentEnd( int attrib ) const
    02084 {
    02085   return m_additionalData[ hlKeyForAttrib( attrib ) ]->multiLineCommentEnd;
    02086 }
    02087
    02088 QString KateHighlighting::getCommentSingleLineStart( int attrib ) const
    02089 {
    02090   return m_additionalData[ hlKeyForAttrib( attrib) ]->singleLineCommentMarker;
    02091 }
    02092
    02097 void KateHighlighting::readCommentConfig()
    02098 {
    02099   KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
    02100   KateSyntaxContextData *data=KateHlManager::self()->syntax->getGroupInfo("general","comment");
    02101
    02102   QString cmlStart, cmlEnd, cmlRegion, cslStart  ;
    02103
    02104   if (data)
    02105   {
    02106     while  (KateHlManager::self()->syntax->nextGroup(data))
    02107     {
    02108       if (KateHlManager::self()->syntax->groupData(data,"name")=="singleLine")
    02109         cslStart=KateHlManager::self()->syntax->groupData(data,"start");
    02110
    02111       if (KateHlManager::self()->syntax->groupData(data,"name")=="multiLine")
    02112       {
    02113         cmlStart=KateHlManager::self()->syntax->groupData(data,"start");
    02114         cmlEnd=KateHlManager::self()->syntax->groupData(data,"end");
    02115         cmlRegion=KateHlManager::self()->syntax->groupData(data,"region");
    02116       }
    02117     }
    02118
    02119     KateHlManager::self()->syntax->freeGroupInfo(data);
    02120   }
    02121   else
    02122   {
    02123     cslStart = "";
    02124     cmlStart = "";
    02125     cmlEnd = "";
    02126     cmlRegion = "";
    02127   }
    02128   m_additionalData[buildIdentifier]->singleLineCommentMarker = cslStart;
    02129   m_additionalData[buildIdentifier]->multiLineCommentStart = cmlStart;
    02130   m_additionalData[buildIdentifier]->multiLineCommentEnd = cmlEnd;
    02131   m_additionalData[buildIdentifier]->multiLineRegion = cmlRegion;
    02132 }
    02133
    02139 void KateHighlighting::readGlobalKeywordConfig()
    02140 {
    02141   deliminator = stdDeliminator;
    02142   // Tell the syntax document class which file we want to parse
    02143   kdDebug(13010)<<"readGlobalKeywordConfig:BEGIN"<<endl;
    02144
    02145   KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
    02146   KateSyntaxContextData *data = KateHlManager::self()->syntax->getConfig("general","keywords");
    02147
    02148   if (data)
    02149   {
    02150     kdDebug(13010)<<"Found global keyword config"<<endl;
    02151
    02152     if (KateHlManager::self()->syntax->groupItemData(data,QString("casesensitive"))!="0")
    02153       casesensitive=true;
    02154     else
    02155       casesensitive=false;
    02156
    02157     //get the weak deliminators
    02158     weakDeliminator=(KateHlManager::self()->syntax->groupItemData(data,QString("weakDeliminator")));
    02159
    02160     kdDebug(13010)<<"weak delimiters are: "<<weakDeliminator<<endl;
    02161
    02162     // remove any weakDelimitars (if any) from the default list and store this list.
    02163     for (uint s=0; s < weakDeliminator.length(); s++)
    02164     {
    02165       int f = deliminator.find (weakDeliminator[s]);
    02166
    02167       if (f > -1)
    02168         deliminator.remove (f, 1);
    02169     }
    02170
    02171     QString addDelim = (KateHlManager::self()->syntax->groupItemData(data,QString("additionalDeliminator")));
    02172
    02173     if (!addDelim.isEmpty())
    02174       deliminator=deliminator+addDelim;
    02175
    02176     KateHlManager::self()->syntax->freeGroupInfo(data);
    02177   }
    02178   else
    02179   {
    02180     //Default values
    02181     casesensitive=true;
    02182     weakDeliminator=QString("");
    02183   }
    02184
    02185   kdDebug(13010)<<"readGlobalKeywordConfig:END"<<endl;
    02186
    02187   kdDebug(13010)<<"delimiterCharacters are: "<<deliminator<<endl;
    02188
    02189   m_additionalData[buildIdentifier]->deliminator = deliminator;
    02190 }
    02191
    02202 void KateHighlighting::readWordWrapConfig()
    02203 {
    02204   // Tell the syntax document class which file we want to parse
    02205   kdDebug(13010)<<"readWordWrapConfig:BEGIN"<<endl;
    02206
    02207   KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
    02208   KateSyntaxContextData *data = KateHlManager::self()->syntax->getConfig("general","keywords");
    02209
    02210   QString wordWrapDeliminator = stdDeliminator;
    02211   if (data)
    02212   {
    02213     kdDebug(13010)<<"Found global keyword config"<<endl;
    02214
    02215     wordWrapDeliminator = (KateHlManager::self()->syntax->groupItemData(data,QString("wordWrapDeliminator")));
    02216     //when no wordWrapDeliminator is defined use the deliminator list
    02217     if ( wordWrapDeliminator.length() == 0 ) wordWrapDeliminator = deliminator;
    02218
    02219     kdDebug(13010) << "word wrap deliminators are " << wordWrapDeliminator << endl;
    02220
    02221     KateHlManager::self()->syntax->freeGroupInfo(data);
    02222   }
    02223
    02224   kdDebug(13010)<<"readWordWrapConfig:END"<<endl;
    02225
    02226   m_additionalData[buildIdentifier]->wordWrapDeliminator = wordWrapDeliminator;
    02227 }
    02228
    02229 void KateHighlighting::readIndentationConfig()
    02230 {
    02231   m_indentation = "";
    02232
    02233   KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
    02234   KateSyntaxContextData *data = KateHlManager::self()->syntax->getConfig("general","indentation");
    02235
    02236   if (data)
    02237   {
    02238     m_indentation = (KateHlManager::self()->syntax->groupItemData(data,QString("mode")));
    02239
    02240     KateHlManager::self()->syntax->freeGroupInfo(data);
    02241   }
    02242 }
    02243
    02244 void KateHighlighting::readFoldingConfig()
    02245 {
    02246   // Tell the syntax document class which file we want to parse
    02247   kdDebug(13010)<<"readfoldignConfig:BEGIN"<<endl;
    02248
    02249   KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
    02250   KateSyntaxContextData *data = KateHlManager::self()->syntax->getConfig("general","folding");
    02251
    02252   if (data)
    02253   {
    02254     kdDebug(13010)<<"Found global keyword config"<<endl;
    02255
    02256     if (KateHlManager::self()->syntax->groupItemData(data,QString("indentationsensitive"))!="1")
    02257       m_foldingIndentationSensitive=false;
    02258     else
    02259       m_foldingIndentationSensitive=true;
    02260
    02261     KateHlManager::self()->syntax->freeGroupInfo(data);
    02262   }
    02263   else
    02264   {
    02265     //Default values
    02266     m_foldingIndentationSensitive = false;
    02267   }
    02268
    02269   kdDebug(13010)<<"readfoldingConfig:END"<<endl;
    02270
    02271   kdDebug(13010)<<"############################ use indent for fold are: "<<m_foldingIndentationSensitive<<endl;
    02272 }
    02273
    02274 void  KateHighlighting::createContextNameList(QStringList *ContextNameList,int ctx0)
    02275 {
    02276   kdDebug(13010)<<"creatingContextNameList:BEGIN"<<endl;
    02277
    02278   if (ctx0 == 0)
    02279       ContextNameList->clear();
    02280
    02281   KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
    02282
    02283   KateSyntaxContextData *data=KateHlManager::self()->syntax->getGroupInfo("highlighting","context");
    02284
    02285   int id=ctx0;
    02286
    02287   if (data)
    02288   {
    02289      while (KateHlManager::self()->syntax->nextGroup(data))
    02290      {
    02291           QString tmpAttr=KateHlManager::self()->syntax->groupData(data,QString("name")).simplifyWhiteSpace();
    02292     if (tmpAttr.isEmpty())
    02293     {
    02294      tmpAttr=QString("!KATE_INTERNAL_DUMMY! %1").arg(id);
    02295      errorsAndWarnings +=i18n("<B>%1</B>: Deprecated syntax. Context %2 has no symbolic name<BR>").arg(buildIdentifier).arg(id-ctx0);
    02296     }
    02297           else tmpAttr=buildPrefix+tmpAttr;
    02298     (*ContextNameList)<<tmpAttr;
    02299           id++;
    02300      }
    02301      KateHlManager::self()->syntax->freeGroupInfo(data);
    02302   }
    02303   kdDebug(13010)<<"creatingContextNameList:END"<<endl;
    02304
    02305 }
    02306
    02307 int KateHighlighting::getIdFromString(QStringList *ContextNameList, QString tmpLineEndContext, /*NO CONST*/ QString &unres)
    02308 {
    02309   unres="";
    02310   int context;
    02311   if ((tmpLineEndContext=="#stay") || (tmpLineEndContext.simplifyWhiteSpace().isEmpty()))
    02312     context=-1;
    02313
    02314   else if (tmpLineEndContext.startsWith("#pop"))
    02315   {
    02316     context=-1;
    02317     for(;tmpLineEndContext.startsWith("#pop");context--)
    02318     {
    02319       tmpLineEndContext.remove(0,4);
    02320       kdDebug(13010)<<"#pop found"<<endl;
    02321     }
    02322   }
    02323
    02324   else if ( tmpLineEndContext.startsWith("##"))
    02325   {
    02326     QString tmp=tmpLineEndContext.right(tmpLineEndContext.length()-2);
    02327     if (!embeddedHls.contains(tmp))  embeddedHls.insert(tmp,KateEmbeddedHlInfo());
    02328     unres=tmp;
    02329     context=0;
    02330   }
    02331
    02332   else
    02333   {
    02334     context=ContextNameList->findIndex(buildPrefix+tmpLineEndContext);
    02335     if (context==-1)
    02336     {
    02337       context=tmpLineEndContext.toInt();
    02338       errorsAndWarnings+=i18n(
    02339         "<B>%1</B>:Deprecated syntax. Context %2 not addressed by a symbolic name"
    02340         ).arg(buildIdentifier).arg(tmpLineEndContext);
    02341     }
    02342 //#warning restructure this the name list storage.
    02343 //    context=context+buildContext0Offset;
    02344   }
    02345   return context;
    02346 }
    02347
    02353 void KateHighlighting::makeContextList()
    02354 {
    02355   if (noHl)  // if this a highlighting for "normal texts" only, tere is no need for a context list creation
    02356     return;
    02357
    02358   embeddedHls.clear();
    02359   unresolvedContextReferences.clear();
    02360   RegionList.clear();
    02361   ContextNameList.clear();
    02362
    02363   // prepare list creation. To reuse as much code as possible handle this
    02364   // highlighting the same way as embedded onces
    02365   embeddedHls.insert(iName,KateEmbeddedHlInfo());
    02366
    02367   bool something_changed;
    02368   // the context "0" id is 0 for this hl, all embedded context "0"s have offsets
    02369   startctx=base_startctx=0;
    02370   // inform everybody that we are building the highlighting contexts and itemlists
    02371   building=true;
    02372
    02373   do
    02374   {
    02375     kdDebug(13010)<<"**************** Outter loop in make ContextList"<<endl;
    02376     kdDebug(13010)<<"**************** Hl List count:"<<embeddedHls.count()<<endl;
    02377     something_changed=false; //assume all "embedded" hls have already been loaded
    02378     for (KateEmbeddedHlInfos::const_iterator it=embeddedHls.begin(); it!=embeddedHls.end();++it)
    02379     {
    02380       if (!it.data().loaded)  // we found one, we still have to load
    02381       {
    02382         kdDebug(13010)<<"**************** Inner loop in make ContextList"<<endl;
    02383         QString identifierToUse;
    02384         kdDebug(13010)<<"Trying to open highlighting definition file: "<< it.key()<<endl;
    02385         if (iName==it.key()) // the own identifier is known
    02386           identifierToUse=identifier;
    02387         else                 // all others have to be looked up
    02388           identifierToUse=KateHlManager::self()->identifierForName(it.key());
    02389
    02390         kdDebug(13010)<<"Location is:"<< identifierToUse<<endl;
    02391
    02392         buildPrefix=it.key()+':';  // attribute names get prefixed by the names
    02393                                    // of the highlighting definitions they belong to
    02394
    02395         if (identifierToUse.isEmpty() )
    02396           kdDebug(13010)<<"OHOH, unknown highlighting description referenced"<<endl;
    02397
    02398         kdDebug(13010)<<"setting ("<<it.key()<<") to loaded"<<endl;
    02399
    02400         //mark hl as loaded
    02401         it=embeddedHls.insert(it.key(),KateEmbeddedHlInfo(true,startctx));
    02402         //set class member for context 0 offset, so we don't need to pass it around
    02403         buildContext0Offset=startctx;
    02404         //parse one hl definition file
    02405         startctx=addToContextList(identifierToUse,startctx);
    02406
    02407         if (noHl) return;  // an error occurred
    02408
    02409         base_startctx = startctx;
    02410         something_changed=true; // something has been loaded
    02411       }
    02412     }
    02413   } while (something_changed);  // as long as there has been another file parsed
    02414                   // repeat everything, there could be newly added embedded hls.
    02415
    02416
    02417   // at this point all needed highlighing (sub)definitions are loaded. It's time
    02418   // to resolve cross file  references (if there are any )
    02419   kdDebug(13010)<<"Unresolved contexts, which need attention: "<<unresolvedContextReferences.count()<<endl;
    02420
    02421   //optimize this a littlebit
    02422   for (KateHlUnresolvedCtxRefs::iterator unresIt=unresolvedContextReferences.begin();
    02423     unresIt!=unresolvedContextReferences.end();++unresIt)
    02424   {
    02425     //try to find the context0 id for a given unresolvedReference
    02426     KateEmbeddedHlInfos::const_iterator hlIt=embeddedHls.find(unresIt.data());
    02427     if (hlIt!=embeddedHls.end())
    02428       *(unresIt.key())=hlIt.data().context0;
    02429   }
    02430
    02431   // eventually handle KateHlIncludeRules items, if they exist.
    02432   // This has to be done after the cross file references, because it is allowed
    02433   // to include the context0 from a different definition, than the one the rule
    02434   // belongs to
    02435   handleKateHlIncludeRules();
    02436
    02437   embeddedHls.clear(); //save some memory.
    02438   unresolvedContextReferences.clear(); //save some memory
    02439   RegionList.clear();  // I think you get the idea ;)
    02440   ContextNameList.clear();
    02441
    02442
    02443   // if there have been errors show them
    02444   if (!errorsAndWarnings.isEmpty())
    02445   KMessageBox::detailedSorry(0L,i18n(
    02446         "There were warning(s) and/or error(s) while parsing the syntax "
    02447         "highlighting configuration."),
    02448         errorsAndWarnings, i18n("Kate Syntax Highlighting Parser"));
    02449
    02450   // we have finished
    02451   building=false;
    02452 }
    02453
    02454 void KateHighlighting::handleKateHlIncludeRules()
    02455 {
    02456   // if there are noe include rules to take care of, just return
    02457   kdDebug(13010)<<"KateHlIncludeRules, which need attention: " <<includeRules.count()<<endl;
    02458   if (includeRules.isEmpty()) return;
    02459
    02460   buildPrefix="";
    02461   QString dummy;
    02462
    02463   // By now the context0 references are resolved, now more or less only inner
    02464   // file references are resolved. If we decide that arbitrary inclusion is
    02465   // needed, this doesn't need to be changed, only the addToContextList
    02466   // method.
    02467
    02468   //resolove context names
    02469   for (KateHlIncludeRules::iterator it=includeRules.begin();it!=includeRules.end();)
    02470   {
    02471     if ((*it)->incCtx==-1) // context unresolved ?
    02472     {
    02473
    02474       if ((*it)->incCtxN.isEmpty())
    02475       {
    02476         // no context name given, and no valid context id set, so this item is
    02477         // going to be removed
    02478         KateHlIncludeRules::iterator it1=it;
    02479         ++it1;
    02480         delete (*it);
    02481         includeRules.remove(it);
    02482         it=it1;
    02483       }
    02484       else
    02485       {
    02486         // resolve name to id
    02487         (*it)->incCtx=getIdFromString(&ContextNameList,(*it)->incCtxN,dummy);
    02488         kdDebug(13010)<<"Resolved "<<(*it)->incCtxN<< " to "<<(*it)->incCtx<<" for include rule"<<endl;
    02489         // It would be good to look here somehow, if the result is valid
    02490       }
    02491     }
    02492     else ++it; //nothing to do, already resolved (by the cross defintion reference resolver
    02493   }
    02494
    02495   // now that all KateHlIncludeRule items should be valid and completely resolved,
    02496   // do the real inclusion of the rules.
    02497   // recursiveness is needed, because context 0 could include context 1, which
    02498   // itself includes context 2 and so on.
    02499   //  In that case we have to handle context 2 first, then 1, 0
    02500   //TODO: catch circular references: eg 0->1->2->3->1
    02501   while (!includeRules.isEmpty())
    02502     handleKateHlIncludeRulesRecursive(includeRules.begin(),&includeRules);
    02503 }
    02504
    02505 void KateHighlighting::handleKateHlIncludeRulesRecursive(KateHlIncludeRules::iterator it, KateHlIncludeRules *list)
    02506 {
    02507   if (it==list->end()) return;  //invalid iterator, shouldn't happen, but better have a rule prepared ;)
    02508
    02509   KateHlIncludeRules::iterator it1=it;
    02510   int ctx=(*it1)->ctx;
    02511
    02512   // find the last entry for the given context in the KateHlIncludeRules list
    02513   // this is need if one context includes more than one. This saves us from
    02514   // updating all insert positions:
    02515   // eg: context 0:
    02516   // pos 3 - include context 2
    02517   // pos 5 - include context 3
    02518   // During the building of the includeRules list the items are inserted in
    02519   // ascending order, now we need it descending to make our life easier.
    02520   while ((it!=list->end()) && ((*it)->ctx==ctx))
    02521   {
    02522     it1=it;
    02523     ++it;
    02524   }
    02525
    02526   // iterate over each include rule for the context the function has been called for.
    02527   while ((it1!=list->end()) && ((*it1)->ctx==ctx))
    02528   {
    02529     int ctx1=(*it1)->incCtx;
    02530
    02531     //let's see, if the the included context includes other contexts
    02532     for (KateHlIncludeRules::iterator it2=list->begin();it2!=list->end();++it2)
    02533     {
    02534       if ((*it2)->ctx==ctx1)
    02535       {
    02536         //yes it does, so first handle that include rules, since we want to
    02537         // include those subincludes too
    02538         handleKateHlIncludeRulesRecursive(it2,list);
    02539         break;
    02540       }
    02541     }
    02542
    02543     // if the context we want to include had sub includes, they are already inserted there.
    02544     KateHlContext *dest=m_contexts[ctx];
    02545     KateHlContext *src=m_contexts[ctx1];
    02546 //     kdDebug(3010)<<"linking included rules from "<<ctx<<" to "<<ctx1<<endl;
    02547
    02548     // If so desired, change the dest attribute to the one of the src.
    02549     // Required to make commenting work, if text matched by the included context
    02550     // is a different highlight than the host context.
    02551     if ( (*it1)->includeAttrib )
    02552       dest->attr = src->attr;
    02553
    02554     // insert the included context's rules starting at position p
    02555     int p=(*it1)->pos;
    02556
    02557     // remember some stuff
    02558     int oldLen = dest->items.size();
    02559     uint itemsToInsert = src->items.size();
    02560
    02561     // resize target
    02562     dest->items.resize (oldLen + itemsToInsert);
    02563
    02564     // move old elements
    02565     for (int i=oldLen-1; i >= p; --i)
    02566       dest->items[i+itemsToInsert] = dest->items[i];
    02567
    02568     // insert new stuff
    02569     for (uint i=0; i < itemsToInsert; ++i  )
    02570       dest->items[p+i] = src->items[i];
    02571
    02572     it=it1; //backup the iterator
    02573     --it1;  //move to the next entry, which has to be take care of
    02574     delete (*it); //free the already handled data structure
    02575     list->remove(it); // remove it from the list
    02576   }
    02577 }
    02578
    02584 int KateHighlighting::addToContextList(const QString &ident, int ctx0)
    02585 {
    02586   kdDebug(13010)<<"=== Adding hl with ident '"<<ident<<"'"<<endl;
    02587
    02588   buildIdentifier=ident;
    02589   KateSyntaxContextData *data, *datasub;
    02590   KateHlItem *c;
    02591
    02592   QString dummy;
    02593
    02594   // Let the syntax document class know, which file we'd like to parse
    02595   if (!KateHlManager::self()->syntax->setIdentifier(ident))
    02596   {
    02597     noHl=true;
    02598     KMessageBox::information(0L,i18n(
    02599         "Since there has been an error parsing the highlighting description, "
    02600         "this highlighting will be disabled"));
    02601     return 0;
    02602   }
    02603
    02604   // only read for the own stuff
    02605   if (identifier == ident)
    02606   {
    02607     readIndentationConfig ();
    02608   }
    02609
    02610   RegionList<<"!KateInternal_TopLevel!";
    02611
    02612   m_hlIndex[internalIDList.count()] = ident;
    02613   m_additionalData.insert( ident, new HighlightPropertyBag );
    02614
    02615   // fill out the propertybag
    02616   readCommentConfig();
    02617   readGlobalKeywordConfig();
    02618   readWordWrapConfig();
    02619
    02620   readFoldingConfig ();
    02621
    02622   QString ctxName;
    02623
    02624   // This list is needed for the translation of the attribute parameter,
    02625   // if the itemData name is given instead of the index
    02626   addToKateHlItemDataList();
    02627   KateHlItemDataList iDl = internalIDList;
    02628
    02629   createContextNameList(&ContextNameList,ctx0);
    02630
    02631
    02632   kdDebug(13010)<<"Parsing Context structure"<<endl;
    02633   //start the real work
    02634   data=KateHlManager::self()->syntax->getGroupInfo("highlighting","context");
    02635   uint i=buildContext0Offset;
    02636   if (data)
    02637   {
    02638     while (KateHlManager::self()->syntax->nextGroup(data))
    02639     {
    02640       kdDebug(13010)<<"Found a context in file, building structure now"<<endl;
    02641       //BEGIN - Translation of the attribute parameter
    02642       QString tmpAttr=KateHlManager::self()->syntax->groupData(data,QString("attribute")).simplifyWhiteSpace();
    02643       int attr;
    02644       if (QString("%1").arg(tmpAttr.toInt())==tmpAttr)
    02645         attr=tmpAttr.toInt();
    02646       else
    02647         attr=lookupAttrName(tmpAttr,iDl);
    02648       //END - Translation of the attribute parameter
    02649
    02650       ctxName=buildPrefix+KateHlManager::self()->syntax->groupData(data,QString("lineEndContext")).simplifyWhiteSpace();
    02651
    02652       QString tmpLineEndContext=KateHlManager::self()->syntax->groupData(data,QString("lineEndContext")).simplifyWhiteSpace();
    02653       int context;
    02654
    02655       context=getIdFromString(&ContextNameList, tmpLineEndContext,dummy);
    02656
    02657       //BEGIN get fallthrough props
    02658       bool ft = false;
    02659       int ftc = 0; // fallthrough context
    02660       if ( i > 0 )  // fallthrough is not smart in context 0
    02661       {
    02662         QString tmpFt = KateHlManager::self()->syntax->groupData(data, QString("fallthrough") );
    02663         if ( IS_TRUE(tmpFt) )
    02664           ft = true;
    02665         if ( ft )
    02666         {
    02667           QString tmpFtc = KateHlManager::self()->syntax->groupData( data, QString("fallthroughContext") );
    02668
    02669           ftc=getIdFromString(&ContextNameList, tmpFtc,dummy);
    02670           if (ftc == -1) ftc =0;
    02671
    02672           kdDebug(13010)<<"Setting fall through context (context "<<i<<"): "<<ftc<<endl;
    02673         }
    02674       }
    02675       //END falltrhough props
    02676
    02677       bool dynamic = false;
    02678       QString tmpDynamic = KateHlManager::self()->syntax->groupData(data, QString("dynamic") );
    02679       if ( tmpDynamic.lower() == "true" ||  tmpDynamic.toInt() == 1 )
    02680         dynamic = true;
    02681
    02682       KateHlContext *ctxNew = new KateHlContext (
    02683         ident,
    02684         attr,
    02685         context,
    02686         (KateHlManager::self()->syntax->groupData(data,QString("lineBeginContext"))).isEmpty()?-1:
    02687         (KateHlManager::self()->syntax->groupData(data,QString("lineBeginContext"))).toInt(),
    02688         ft, ftc, dynamic);
    02689
    02690       m_contexts.push_back (ctxNew);
    02691
    02692       kdDebug(13010) << "INDEX: " << i << " LENGTH " << m_contexts.size()-1 << endl;
    02693
    02694       //Let's create all items for the context
    02695       while (KateHlManager::self()->syntax->nextItem(data))
    02696       {
    02697 //    kdDebug(13010)<< "In make Contextlist: Item:"<<endl;
    02698
    02699       // KateHlIncludeRules : add a pointer to each item in that context
    02700         // TODO add a attrib includeAttrib
    02701       QString tag = KateHlManager::self()->syntax->groupItemData(data,QString(""));
    02702       if ( tag == "IncludeRules" ) //if the new item is an Include rule, we have to take special care
    02703       {
    02704         QString incCtx = KateHlManager::self()->syntax->groupItemData( data, QString("context"));
    02705         QString incAttrib = KateHlManager::self()->syntax->groupItemData( data, QString("includeAttrib"));
    02706         bool includeAttrib = ( incAttrib.lower() == "true" || incAttrib.toInt() == 1 );
    02707         // only context refernces of type NAME and ##Name are allowed
    02708         if (incCtx.startsWith("##") || (!incCtx.startsWith("#")))
    02709         {
    02710           //#stay, #pop is not interesting here
    02711           if (!incCtx.startsWith("#"))
    02712           {
    02713             // a local reference -> just initialize the include rule structure
    02714             incCtx=buildPrefix+incCtx.simplifyWhiteSpace();
    02715             includeRules.append(new KateHlIncludeRule(i,m_contexts[i]->items.count(),incCtx, includeAttrib));
    02716           }
    02717           else
    02718           {
    02719             //a cross highlighting reference
    02720             kdDebug(13010)<<"Cross highlight reference <IncludeRules>"<<endl;
    02721             KateHlIncludeRule *ir=new KateHlIncludeRule(i,m_contexts[i]->items.count(),"",includeAttrib);
    02722
    02723             //use the same way to determine cross hl file references as other items do
    02724             if (!embeddedHls.contains(incCtx.right(incCtx.length()-2)))
    02725               embeddedHls.insert(incCtx.right(incCtx.length()-2),KateEmbeddedHlInfo());
    02726
    02727             unresolvedContextReferences.insert(&(ir->incCtx),
    02728                 incCtx.right(incCtx.length()-2));
    02729
    02730             includeRules.append(ir);
    02731           }
    02732         }
    02733
    02734         continue;
    02735       }
    02736       // TODO -- can we remove the block below??
    02737 #if 0
    02738                 QString tag = KateHlManager::self()->syntax->groupKateHlItemData(data,QString(""));
    02739                 if ( tag == "IncludeRules" ) {
    02740                   // attrib context: the index (jowenn, i think using names here
    02741                   // would be a cool feat, goes for mentioning the context in
    02742                   // any item. a map or dict?)
    02743                   int ctxId = getIdFromString(&ContextNameList,
    02744                                                KateHlManager::self()->syntax->groupKateHlItemData( data, QString("context")),dummy); // the index is *required*
    02745                   if ( ctxId > -1) { // we can even reuse rules of 0 if we want to:)
    02746                     kdDebug(13010)<<"makeContextList["<<i<<"]: including all items of context "<<ctxId<<endl;
    02747                     if ( ctxId < (int) i ) { // must be defined
    02748                       for ( c = m_contexts[ctxId]->items.first(); c; c = m_contexts[ctxId]->items.next() )
    02749                         m_contexts[i]->items.append(c);
    02750                     }
    02751                     else
    02752                       kdDebug(13010)<<"Context "<<ctxId<<"not defined. You can not include the rules of an undefined context"<<endl;
    02753                   }
    02754                   continue; // while nextItem
    02755                 }
    02756 #endif
    02757       c=createKateHlItem(data,iDl,&RegionList,&ContextNameList);
    02758       if (c)
    02759       {
    02760         m_contexts[i]->items.append(c);
    02761
    02762         // Not supported completely atm and only one level. Subitems.(all have
    02763         // to be matched to at once)
    02764         datasub=KateHlManager::self()->syntax->getSubItems(data);
    02765         bool tmpbool;
    02766         if (tmpbool=KateHlManager::self()->syntax->nextItem(datasub))
    02767         {
    02768           for (;tmpbool;tmpbool=KateHlManager::self()->syntax->nextItem(datasub))
    02769           {
    02770             c->subItems.resize (c->subItems.size()+1);
    02771             c->subItems[c->subItems.size()-1] = createKateHlItem(datasub,iDl,&RegionList,&ContextNameList);
    02772           }                             }
    02773           KateHlManager::self()->syntax->freeGroupInfo(datasub);
    02774                               // end of sublevel
    02775         }
    02776       }
    02777       i++;
    02778     }
    02779   }
    02780
    02781   KateHlManager::self()->syntax->freeGroupInfo(data);
    02782
    02783   if (RegionList.count()!=1)
    02784     folding=true;
    02785
    02786   folding = folding || m_foldingIndentationSensitive;
    02787
    02788   //BEGIN Resolve multiline region if possible
    02789   if (!m_additionalData[ ident ]->multiLineRegion.isEmpty()) {
    02790     long commentregionid=RegionList.findIndex( m_additionalData[ ident ]->multiLineRegion );
    02791     if (-1==commentregionid) {
    02792       errorsAndWarnings+=i18n(
    02793           "<B>%1</B>: Specified multiline comment region (%2) could not be resolved<BR>"
    02794                              ).arg(buildIdentifier).arg( m_additionalData[ ident ]->multiLineRegion );
    02795       m_additionalData[ ident ]->multiLineRegion = QString();
    02796       kdDebug(13010)<<"ERROR comment region attribute could not be resolved"<<endl;
    02797
    02798     } else {
    02799       m_additionalData[ ident ]->multiLineRegion=QString::number(commentregionid+1);
    02800       kdDebug(13010)<<"comment region resolved to:"<<m_additionalData[ ident ]->multiLineRegion<<endl;
    02801     }
    02802   }
    02803   //END Resolve multiline region if possible
    02804   return i;
    02805 }
    02806
    02807 void KateHighlighting::clearAttributeArrays ()
    02808 {
    02809   for ( QIntDictIterator< QMemArray<KateAttribute> > it( m_attributeArrays ); it.current(); ++it )
    02810   {
    02811     // k, schema correct, let create the data
    02812     KateAttributeList defaultStyleList;
    02813     defaultStyleList.setAutoDelete(true);
    02814     KateHlManager::self()->getDefaults(it.currentKey(), defaultStyleList);
    02815
    02816     KateHlItemDataList itemDataList;
    02817     getKateHlItemDataList(it.currentKey(), itemDataList);
    02818
    02819     uint nAttribs = itemDataList.count();
    02820     QMemArray<KateAttribute> *array = it.current();
    02821     array->resize (nAttribs);
    02822
    02823     for (uint z = 0; z < nAttribs; z++)
    02824     {
    02825       KateHlItemData *itemData = itemDataList.at(z);
    02826       KateAttribute n = *defaultStyleList.at(itemData->defStyleNum);
    02827
    02828       if (itemData && itemData->isSomethingSet())
    02829         n += *itemData;
    02830
    02831       array->at(z) = n;
    02832     }
    02833   }
    02834 }
    02835
    02836 QMemArray<KateAttribute> *KateHighlighting::attributes (uint schema)
    02837 {
    02838   QMemArray<KateAttribute> *array;
    02839
    02840   // found it, allready floating around
    02841   if ((array = m_attributeArrays[schema]))
    02842     return array;
    02843
    02844   // ohh, not found, check if valid schema number
    02845   if (!KateFactory::self()->schemaManager()->validSchema(schema))
    02846   {
    02847     // uhh, not valid :/, stick with normal default schema, it's always there !
    02848     return attributes (0);
    02849   }
    02850
    02851   // k, schema correct, let create the data
    02852   KateAttributeList defaultStyleList;
    02853   defaultStyleList.setAutoDelete(true);
    02854   KateHlManager::self()->getDefaults(schema, defaultStyleList);
    02855
    02856   KateHlItemDataList itemDataList;
    02857   getKateHlItemDataList(schema, itemDataList);
    02858
    02859   uint nAttribs = itemDataList.count();
    02860   array = new QMemArray<KateAttribute> (nAttribs);
    02861
    02862   for (uint z = 0; z < nAttribs; z++)
    02863   {
    02864     KateHlItemData *itemData = itemDataList.at(z);
    02865     KateAttribute n = *defaultStyleList.at(itemData->defStyleNum);
    02866
    02867     if (itemData && itemData->isSomethingSet())
    02868       n += *itemData;
    02869
    02870     array->at(z) = n;
    02871   }
    02872
    02873   m_attributeArrays.insert(schema, array);
    02874
    02875   return array;
    02876 }
    02877
    02878 void KateHighlighting::getKateHlItemDataListCopy (uint schema, KateHlItemDataList &outlist)
    02879 {
    02880   KateHlItemDataList itemDataList;
    02881   getKateHlItemDataList(schema, itemDataList);
    02882
    02883   outlist.clear ();
    02884   outlist.setAutoDelete (true);
    02885   for (uint z=0; z < itemDataList.count(); z++)
    02886     outlist.append (new KateHlItemData (*itemDataList.at(z)));
    02887 }
    02888
    02889 //END
    02890
    02891 //BEGIN KateHlManager
    02892 KateHlManager::KateHlManager()
    02893   : QObject()
    02894   , m_config ("katesyntaxhighlightingrc", false, false)
    02895   , commonSuffixes (QStringList::split(";", ".orig;.new;~;.bak;.BAK"))
    02896   , syntax (new KateSyntaxDocument())
    02897   , dynamicCtxsCount(0)
    02898   , forceNoDCReset(false)
    02899 {
    02900   hlList.setAutoDelete(true);
    02901   hlDict.setAutoDelete(false);
    02902
    02903   KateSyntaxModeList modeList = syntax->modeList();
    02904   for (uint i=0; i < modeList.count(); i++)
    02905   {
    02906     KateHighlighting *hl = new KateHighlighting(modeList[i]);
    02907
    02908     uint insert = 0;
    02909     for (; insert <= hlList.count(); insert++)
    02910     {
    02911       if (insert == hlList.count())
    02912         break;
    02913
    02914       if ( QString(hlList.at(insert)->section() + hlList.at(insert)->nameTranslated()).lower()
    02915             > QString(hl->section() + hl->nameTranslated()).lower() )
    02916         break;
    02917     }
    02918
    02919     hlList.insert (insert, hl);
    02920     hlDict.insert (hl->name(), hl);
    02921   }
    02922
    02923   // Normal HL
    02924   KateHighlighting *hl = new KateHighlighting(0);
    02925   hlList.prepend (hl);
    02926   hlDict.insert (hl->name(), hl);
    02927
    02928   lastCtxsReset.start();
    02929 }
    02930
    02931 KateHlManager::~KateHlManager()
    02932 {
    02933   delete syntax;
    02934 }
    02935
    02936 static KStaticDeleter<KateHlManager> sdHlMan;
    02937
    02938 KateHlManager *KateHlManager::self()
    02939 {
    02940   if ( !s_self )
    02941     sdHlMan.setObject(s_self, new KateHlManager ());
    02942
    02943   return s_self;
    02944 }
    02945
    02946 KateHighlighting *KateHlManager::getHl(int n)
    02947 {
    02948   if (n < 0 || n >= (int) hlList.count())
    02949     n = 0;
    02950
    02951   return hlList.at(n);
    02952 }
    02953
    02954 int KateHlManager::nameFind(const QString &name)
    02955 {
    02956   int z (hlList.count() - 1);
    02957   for (; z > 0; z--)
    02958     if (hlList.at(z)->name() == name)
    02959       return z;
    02960
    02961   return z;
    02962 }
    02963
    02964 int KateHlManager::detectHighlighting (KateDocument *doc)
    02965 {
    02966   int hl = wildcardFind( doc->url().filename() );
    02967   if ( hl < 0 )
    02968     hl = mimeFind ( doc );
    02969
    02970   return hl;
    02971 }
    02972
    02973 int KateHlManager::wildcardFind(const QString &fileName)
    02974 {
    02975   int result = -1;
    02976   if ((result = realWildcardFind(fileName)) != -1)
    02977     return result;
    02978
    02979   int length = fileName.length();
    02980   QString backupSuffix = KateDocumentConfig::global()->backupSuffix();
    02981   if (fileName.endsWith(backupSuffix)) {
    02982     if ((result = realWildcardFind(fileName.left(length - backupSuffix.length()))) != -1)
    02983       return result;
    02984   }
    02985
    02986   for (QStringList::Iterator it = commonSuffixes.begin(); it != commonSuffixes.end(); ++it) {
    02987     if (*it != backupSuffix && fileName.endsWith(*it)) {
    02988       if ((result = realWildcardFind(fileName.left(length - (*it).length()))) != -1)
    02989         return result;
    02990     }
    02991   }
    02992
    02993   return -1;
    02994 }
    02995
    02996 int KateHlManager::realWildcardFind(const QString &fileName)
    02997 {
    02998   static QRegExp sep("\\s*;\\s*");
    02999
    03000   QPtrList<KateHighlighting> highlights;
    03001
    03002   for (KateHighlighting *highlight = hlList.first(); highlight != 0L; highlight = hlList.next()) {
    03003     highlight->loadWildcards();
    03004
    03005     for (QStringList::Iterator it = highlight->getPlainExtensions().begin(); it != highlight->getPlainExtensions().end(); ++it)
    03006       if (fileName.endsWith((*it)))
    03007         highlights.append(highlight);
    03008
    03009     for (int i = 0; i < (int)highlight->getRegexpExtensions().count(); i++) {
    03010       QRegExp re = highlight->getRegexpExtensions()[i];
    03011       if (re.exactMatch(fileName))
    03012         highlights.append(highlight);
    03013     }
    03014   }
    03015
    03016   if ( !highlights.isEmpty() )
    03017   {
    03018     int pri = -1;
    03019     int hl = -1;
    03020
    03021     for (KateHighlighting *highlight = highlights.first(); highlight != 0L; highlight = highlights.next())
    03022     {
    03023       if (highlight->priority() > pri)
    03024       {
    03025         pri = highlight->priority();
    03026         hl = hlList.findRef (highlight);
    03027       }
    03028     }
    03029     return hl;
    03030   }
    03031
    03032   return -1;
    03033 }
    03034
    03035 int KateHlManager::mimeFind( KateDocument *doc )
    03036 {
    03037   static QRegExp sep("\\s*;\\s*");
    03038
    03039   KMimeType::Ptr mt = doc->mimeTypeForContent();
    03040
    03041   QPtrList<KateHighlighting> highlights;
    03042
    03043   for (KateHighlighting *highlight = hlList.first(); highlight != 0L; highlight = hlList.next())
    03044   {
    03045     QStringList l = QStringList::split( sep, highlight->getMimetypes() );
    03046
    03047     for( QStringList::Iterator it = l.begin(); it != l.end(); ++it )
    03048     {
    03049       if ( *it == mt->name() ) // faster than a regexp i guess?
    03050         highlights.append (highlight);
    03051     }
    03052   }
    03053
    03054   if ( !highlights.isEmpty() )
    03055   {
    03056     int pri = -1;
    03057     int hl = -1;
    03058
    03059     for (KateHighlighting *highlight = highlights.first(); highlight != 0L; highlight = highlights.next())
    03060     {
    03061       if (highlight->priority() > pri)
    03062       {
    03063         pri = highlight->priority();
    03064         hl = hlList.findRef (highlight);
    03065       }
    03066     }
    03067
    03068     return hl;
    03069   }
    03070
    03071   return -1;
    03072 }
    03073
    03074 uint KateHlManager::defaultStyles()
    03075 {
    03076   return 14;
    03077 }
    03078
    03079 QString KateHlManager::defaultStyleName(int n, bool translateNames)
    03080 {
    03081   static QStringList names;
    03082   static QStringList translatedNames;
    03083
    03084   if (names.isEmpty())
    03085   {
    03086     names << "Normal";
    03087     names << "Keyword";
    03088     names << "Data Type";
    03089     names << "Decimal/Value";
    03090     names << "Base-N Integer";
    03091     names << "Floating Point";
    03092     names << "Character";
    03093     names << "String";
    03094     names << "Comment";
    03095     names << "Others";
    03096     names << "Alert";
    03097     names << "Function";
    03098     // this next one is for denoting the beginning/end of a user defined folding region
    03099     names << "Region Marker";
    03100     // this one is for marking invalid input
    03101     names << "Error";
    03102
    03103     translatedNames << i18n("Normal");
    03104     translatedNames << i18n("Keyword");
    03105     translatedNames << i18n("Data Type");
    03106     translatedNames << i18n("Decimal/Value");
    03107     translatedNames << i18n("Base-N Integer");
    03108     translatedNames << i18n("Floating Point");
    03109     translatedNames << i18n("Character");
    03110     translatedNames << i18n("String");
    03111     translatedNames << i18n("Comment");
    03112     translatedNames << i18n("Others");
    03113     translatedNames << i18n("Alert");
    03114     translatedNames << i18n("Function");
    03115     // this next one is for denoting the beginning/end of a user defined folding region
    03116     translatedNames << i18n("Region Marker");
    03117     // this one is for marking invalid input
    03118     translatedNames << i18n("Error");
    03119   }
    03120
    03121   return translateNames ? translatedNames[n] : names[n];
    03122 }
    03123
    03124 void KateHlManager::getDefaults(uint schema, KateAttributeList &list)
    03125 {
    03126   list.setAutoDelete(true);
    03127
    03128   KateAttribute* normal = new KateAttribute();
    03129   normal->setTextColor(Qt::black);
    03130   normal->setSelectedTextColor(Qt::white);
    03131   list.append(normal);
    03132
    03133   KateAttribute* keyword = new KateAttribute();
    03134   keyword->setTextColor(Qt::black);
    03135   keyword->setSelectedTextColor(Qt::white);
    03136   keyword->setBold(true);
    03137   list.append(keyword);
    03138
    03139   KateAttribute* dataType = new KateAttribute();
    03140   dataType->setTextColor(Qt::darkRed);
    03141   dataType->setSelectedTextColor(Qt::white);
    03142   list.append(dataType);
    03143
    03144   KateAttribute* decimal = new KateAttribute();
    03145   decimal->setTextColor(Qt::blue);
    03146   decimal->setSelectedTextColor(Qt::cyan);
    03147   list.append(decimal);
    03148
    03149   KateAttribute* basen = new KateAttribute();
    03150   basen->setTextColor(Qt::darkCyan);
    03151   basen->setSelectedTextColor(Qt::cyan);
    03152   list.append(basen);
    03153
    03154   KateAttribute* floatAttribute = new KateAttribute();
    03155   floatAttribute->setTextColor(Qt::darkMagenta);
    03156   floatAttribute->setSelectedTextColor(Qt::cyan);
    03157   list.append(floatAttribute);
    03158
    03159   KateAttribute* charAttribute = new KateAttribute();
    03160   charAttribute->setTextColor(Qt::magenta);
    03161   charAttribute->setSelectedTextColor(Qt::magenta);
    03162   list.append(charAttribute);
    03163
    03164   KateAttribute* string = new KateAttribute();
    03165   string->setTextColor(QColor::QColor("#D00"));
    03166   string->setSelectedTextColor(Qt::red);
    03167   list.append(string);
    03168
    03169   KateAttribute* comment = new KateAttribute();
    03170   comment->setTextColor(Qt::darkGray);
    03171   comment->setSelectedTextColor(Qt::gray);
    03172   comment->setItalic(true);
    03173   list.append(comment);
    03174
    03175   KateAttribute* others = new KateAttribute();
    03176   others->setTextColor(Qt::darkGreen);
    03177   others->setSelectedTextColor(Qt::green);
    03178   list.append(others);
    03179
    03180   KateAttribute* alert = new KateAttribute();
    03181   alert->setTextColor(Qt::white);
    03182   alert->setSelectedTextColor( QColor::QColor("#FCC") );
    03183   alert->setBold(true);
    03184   alert->setBGColor( QColor::QColor("#FCC") );
    03185   list.append(alert);
    03186
    03187   KateAttribute* functionAttribute = new KateAttribute();
    03188   functionAttribute->setTextColor(Qt::darkBlue);
    03189   functionAttribute->setSelectedTextColor(Qt::white);
    03190   list.append(functionAttribute);
    03191
    03192   KateAttribute* regionmarker = new KateAttribute();
    03193   regionmarker->setTextColor(Qt::white);
    03194   regionmarker->setBGColor(Qt::gray);
    03195   regionmarker->setSelectedTextColor(Qt::gray);
    03196   list.append(regionmarker);
    03197
    03198   KateAttribute* error = new KateAttribute();
    03199   error->setTextColor(Qt::red);
    03200   error->setUnderline(true);
    03201   error->setSelectedTextColor(Qt::red);
    03202   list.append(error);
    03203
    03204   KConfig *config = KateHlManager::self()->self()->getKConfig();
    03205   config->setGroup("Default Item Styles - Schema " + KateFactory::self()->schemaManager()->name(schema));
    03206
    03207   for (uint z = 0; z < defaultStyles(); z++)
    03208   {
    03209     KateAttribute *i = list.at(z);
    03210     QStringList s = config->readListEntry(defaultStyleName(z));
    03211     if (!s.isEmpty())
    03212     {
    03213       while( s.count()<8)
    03214         s << "";
    03215
    03216       QString tmp;
    03217       QRgb col;
    03218
    03219       tmp=s[0]; if (!tmp.isEmpty()) {
    03220          col=tmp.toUInt(0,16); i->setTextColor(col); }
    03221
    03222       tmp=s[1]; if (!tmp.isEmpty()) {
    03223          col=tmp.toUInt(0,16); i->setSelectedTextColor(col); }
    03224
    03225       tmp=s[2]; if (!tmp.isEmpty()) i->setBold(tmp!="0");
    03226
    03227       tmp=s[3]; if (!tmp.isEmpty()) i->setItalic(tmp!="0");
    03228
    03229       tmp=s[4]; if (!tmp.isEmpty()) i->setStrikeOut(tmp!="0");
    03230
    03231       tmp=s[5]; if (!tmp.isEmpty()) i->setUnderline(tmp!="0");
    03232
    03233       tmp=s[6]; if (!tmp.isEmpty()) {
    03234         if ( tmp != "-" )
    03235         {
    03236           col=tmp.toUInt(0,16);
    03237           i->setBGColor(col);
    03238         }
    03239         else
    03240           i->clearAttribute(KateAttribute::BGColor);
    03241       }
    03242       tmp=s[7]; if (!tmp.isEmpty()) {
    03243         if ( tmp != "-" )
    03244         {
    03245           col=tmp.toUInt(0,16);
    03246           i->setSelectedBGColor(col);
    03247         }
    03248         else
    03249           i->clearAttribute(KateAttribute::SelectedBGColor);
    03250       }
    03251     }
    03252   }
    03253 }
    03254
    03255 void KateHlManager::setDefaults(uint schema, KateAttributeList &list)
    03256 {
    03257   KConfig *config =  KateHlManager::self()->self()->getKConfig();
    03258   config->setGroup("Default Item Styles - Schema " + KateFactory::self()->schemaManager()->name(schema));
    03259
    03260   for (uint z = 0; z < defaultStyles(); z++)
    03261   {
    03262     QStringList settings;
    03263     KateAttribute *i = list.at(z);
    03264
    03265     settings<<(i->itemSet(KateAttribute::TextColor)?QString::number(i->textColor().rgb(),16):"");
    03266     settings<<(i->itemSet(KateAttribute::SelectedTextColor)?QString::number(i->selectedTextColor().rgb(),16):"");
    03267     settings<<(i->itemSet(KateAttribute::Weight)?(i->bold()?"1":"0"):"");
    03268     settings<<(i->itemSet(KateAttribute::Italic)?(i->italic()?"1":"0"):"");
    03269     settings<<(i->itemSet(KateAttribute::StrikeOut)?(i->strikeOut()?"1":"0"):"");
    03270     settings<<(i->itemSet(KateAttribute::Underline)?(i->underline()?"1":"0"):"");
    03271     settings<<(i->itemSet(KateAttribute::BGColor)?QString::number(i->bgColor().rgb(),16):"-");
    03272     settings<<(i->itemSet(KateAttribute::SelectedBGColor)?QString::number(i->selectedBGColor().rgb(),16):"-");
    03273     settings<<"---";
    03274
    03275     config->writeEntry(defaultStyleName(z),settings);
    03276   }
    03277
    03278   emit changed();
    03279 }
    03280
    03281 int KateHlManager::highlights()
    03282 {
    03283   return (int) hlList.count();
    03284 }
    03285
    03286 QString KateHlManager::hlName(int n)
    03287 {
    03288   return hlList.at(n)->name();
    03289 }
    03290
    03291 QString KateHlManager::hlNameTranslated(int n)
    03292 {
    03293   return hlList.at(n)->nameTranslated();
    03294 }
    03295
    03296 QString KateHlManager::hlSection(int n)
    03297 {
    03298   return hlList.at(n)->section();
    03299 }
    03300
    03301 bool KateHlManager::hlHidden(int n)
    03302 {
    03303   return hlList.at(n)->hidden();
    03304 }
    03305
    03306 QString KateHlManager::identifierForName(const QString& name)
    03307 {
    03308   KateHighlighting *hl = 0;
    03309
    03310   if ((hl = hlDict[name]))
    03311     return hl->getIdentifier ();
    03312
    03313   return QString();
    03314 }
    03315
    03316 bool KateHlManager::resetDynamicCtxs()
    03317 {
    03318   if (forceNoDCReset)
    03319     return false;
    03320
    03321   if (lastCtxsReset.elapsed() < KATE_DYNAMIC_CONTEXTS_RESET_DELAY)
    03322     return false;
    03323
    03324   KateHighlighting *hl;
    03325   for (hl = hlList.first(); hl; hl = hlList.next())
    03326     hl->dropDynamicContexts();
    03327
    03328   dynamicCtxsCount = 0;
    03329   lastCtxsReset.start();
    03330
    03331   return true;
    03332 }
    03333 //END
    03334
    03335 //BEGIN KateHighlightAction
    03336 void KateViewHighlightAction::init()
    03337 {
    03338   m_doc = 0;
    03339   subMenus.setAutoDelete( true );
    03340
    03341   connect(popupMenu(),SIGNAL(aboutToShow()),this,SLOT(slotAboutToShow()));
    03342 }
    03343
    03344 void KateViewHighlightAction::updateMenu (Kate::Document *doc)
    03345 {
    03346   m_doc = doc;
    03347 }
    03348
    03349 void KateViewHighlightAction::slotAboutToShow()
    03350 {
    03351   Kate::Document *doc=m_doc;
    03352   int count = KateHlManager::self()->highlights();
    03353
    03354   for (int z=0; z<count; z++)
    03355   {
    03356     QString hlName = KateHlManager::self()->hlNameTranslated (z);
    03357     QString hlSection = KateHlManager::self()->hlSection (z);
    03358
    03359     if (!KateHlManager::self()->hlHidden(z))
    03360     {
    03361       if ( !hlSection.isEmpty() && (names.contains(hlName) < 1) )
    03362       {
    03363         if (subMenusName.contains(hlSection) < 1)
    03364         {
    03365           subMenusName << hlSection;
    03366           QPopupMenu *menu = new QPopupMenu ();
    03367           subMenus.append(menu);
    03368           popupMenu()->insertItem ( '&' + hlSection, menu);
    03369         }
    03370
    03371         int m = subMenusName.findIndex (hlSection);
    03372         names << hlName;
    03373         subMenus.at(m)->insertItem ( '&' + hlName, this, SLOT(setHl(int)), 0,  z);
    03374       }
    03375       else if (names.contains(hlName) < 1)
    03376       {
    03377         names << hlName;
    03378         popupMenu()->insertItem ( '&' + hlName, this, SLOT(setHl(int)), 0,  z);
    03379       }
    03380     }
    03381   }
    03382
    03383   if (!doc) return;
    03384
    03385   for (uint i=0;i<subMenus.count();i++)
    03386   {
    03387     for (uint i2=0;i2<subMenus.at(i)->count();i2++)
    03388     {
    03389       subMenus.at(i)->setItemChecked(subMenus.at(i)->idAt(i2),false);
    03390     }
    03391   }
    03392   popupMenu()->setItemChecked (0, false);
    03393
    03394   int i = subMenusName.findIndex (KateHlManager::self()->hlSection(doc->hlMode()));
    03395   if (i >= 0 && subMenus.at(i))
    03396     subMenus.at(i)->setItemChecked (doc->hlMode(), true);
    03397   else
    03398     popupMenu()->setItemChecked (0, true);
    03399 }
    03400
    03401 void KateViewHighlightAction::setHl (int mode)
    03402 {
    03403   Kate::Document *doc=m_doc;
    03404
    03405   if (doc)
    03406     doc->setHlMode((uint)mode);
    03407 }
    03408 //END KateViewHighlightAction
    03409
    03410 // kate: space-indent on; indent-width 2; replace-tabs on;

This file is part of the documentation for kate Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:36:36 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003