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