• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • kate
 

kate

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

kate

Skip menu "kate"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kate

Skip menu "kate"
  • arts
  • dcop
  • dnssd
  • interfaces
  •     interface
  •     library
  •   kspeech
  •   ktexteditor
  • kabc
  • kate
  • kcmshell
  • kdecore
  • kded
  • kdefx
  • kdeprint
  • kdesu
  • kdeui
  • kdoctools
  • khtml
  • kimgio
  • kinit
  • kio
  •   bookmarks
  •   httpfilter
  •   kfile
  •   kio
  •   kioexec
  •   kpasswdserver
  •   kssl
  • kioslave
  •   http
  • kjs
  • kmdi
  •   kmdi
  • knewstuff
  • kparts
  • krandr
  • kresources
  • kspell2
  • kunittest
  • kutils
  • kwallet
  • libkmid
  • libkscreensaver
Generated for kate by doxygen 1.7.6.1
This website is maintained by Timothy Pearson.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. |