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("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 if ( noHl )
01993 return which == 3 ? stdDeliminator : "";
01994
01995 int k = hlKeyForAttrib( attrib );
01996 const QStringList& lst = m_additionalData[k];
01997 return lst.isEmpty() ? QString::null : lst[which];
01998 }
01999
02000 QString KateHighlighting::getCommentStart( int attrib ) const
02001 {
02002 return getCommentString( Start, attrib );
02003 }
02004
02005 QString KateHighlighting::getCommentEnd( int attrib ) const
02006 {
02007 return getCommentString( End, attrib );
02008 }
02009
02010 QString KateHighlighting::getCommentSingleLineStart( int attrib ) const
02011 {
02012 return getCommentString( SingleLine, attrib );
02013 }
02014
02022 QStringList KateHighlighting::readCommentConfig()
02023 {
02024 KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
02025 KateSyntaxContextData *data=KateHlManager::self()->syntax->getGroupInfo("general","comment");
02026
02027 QString cmlStart, cmlEnd, cslStart;
02028
02029 if (data)
02030 {
02031 while (KateHlManager::self()->syntax->nextGroup(data))
02032 {
02033 if (KateHlManager::self()->syntax->groupData(data,"name")=="singleLine")
02034 cslStart=KateHlManager::self()->syntax->groupData(data,"start");
02035
02036 if (KateHlManager::self()->syntax->groupData(data,"name")=="multiLine")
02037 {
02038 cmlStart=KateHlManager::self()->syntax->groupData(data,"start");
02039 cmlEnd=KateHlManager::self()->syntax->groupData(data,"end");
02040 }
02041 }
02042
02043 KateHlManager::self()->syntax->freeGroupInfo(data);
02044 }
02045 else
02046 {
02047 cslStart = "";
02048 cmlStart = "";
02049 cmlEnd = "";
02050 }
02051 QStringList res;
02052 res << cmlStart << cmlEnd << cslStart;
02053 return res;
02054 }
02055
02063 QString KateHighlighting::readGlobalKeywordConfig()
02064 {
02065
02066 kdDebug(13010)<<"readGlobalKeywordConfig:BEGIN"<<endl;
02067
02068 KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
02069 KateSyntaxContextData *data = KateHlManager::self()->syntax->getConfig("general","keywords");
02070
02071 if (data)
02072 {
02073 kdDebug(13010)<<"Found global keyword config"<<endl;
02074
02075 if (KateHlManager::self()->syntax->groupItemData(data,QString("casesensitive"))!="0")
02076 casesensitive=true;
02077 else
02078 casesensitive=false;
02079
02080
02081 weakDeliminator=(KateHlManager::self()->syntax->groupItemData(data,QString("weakDeliminator")));
02082
02083 kdDebug(13010)<<"weak delimiters are: "<<weakDeliminator<<endl;
02084
02085
02086 for (uint s=0; s < weakDeliminator.length(); s++)
02087 {
02088 int f = deliminator.find (weakDeliminator[s]);
02089
02090 if (f > -1)
02091 deliminator.remove (f, 1);
02092 }
02093
02094 QString addDelim = (KateHlManager::self()->syntax->groupItemData(data,QString("additionalDeliminator")));
02095
02096 if (!addDelim.isEmpty())
02097 deliminator=deliminator+addDelim;
02098
02099 KateHlManager::self()->syntax->freeGroupInfo(data);
02100 }
02101 else
02102 {
02103
02104 casesensitive=true;
02105 weakDeliminator=QString("");
02106 }
02107
02108 kdDebug(13010)<<"readGlobalKeywordConfig:END"<<endl;
02109
02110 kdDebug(13010)<<"delimiterCharacters are: "<<deliminator<<endl;
02111
02112 return deliminator;
02113 }
02114
02124 QString KateHighlighting::readWordWrapConfig()
02125 {
02126
02127 kdDebug(13010)<<"readWordWrapConfig:BEGIN"<<endl;
02128
02129 KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
02130 KateSyntaxContextData *data = KateHlManager::self()->syntax->getConfig("general","keywords");
02131
02132 QString wordWrapDeliminator = stdDeliminator;
02133 if (data)
02134 {
02135 kdDebug(13010)<<"Found global keyword config"<<endl;
02136
02137 wordWrapDeliminator = (KateHlManager::self()->syntax->groupItemData(data,QString("wordWrapDeliminator")));
02138
02139 if ( wordWrapDeliminator.length() == 0 ) wordWrapDeliminator = deliminator;
02140
02141 kdDebug(13010) << "word wrap deliminators are " << wordWrapDeliminator << endl;
02142
02143 KateHlManager::self()->syntax->freeGroupInfo(data);
02144 }
02145
02146 kdDebug(13010)<<"readWordWrapConfig:END"<<endl;
02147
02148 return wordWrapDeliminator;
02149 }
02150
02151 void KateHighlighting::readFoldingConfig()
02152 {
02153
02154 kdDebug(13010)<<"readfoldignConfig:BEGIN"<<endl;
02155
02156 KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
02157 KateSyntaxContextData *data = KateHlManager::self()->syntax->getConfig("general","folding");
02158
02159 if (data)
02160 {
02161 kdDebug(13010)<<"Found global keyword config"<<endl;
02162
02163 if (KateHlManager::self()->syntax->groupItemData(data,QString("indentationsensitive"))!="1")
02164 m_foldingIndentationSensitive=false;
02165 else
02166 m_foldingIndentationSensitive=true;
02167
02168 KateHlManager::self()->syntax->freeGroupInfo(data);
02169 }
02170 else
02171 {
02172
02173 m_foldingIndentationSensitive = false;
02174 }
02175
02176 kdDebug(13010)<<"readfoldingConfig:END"<<endl;
02177
02178 kdDebug(13010)<<"############################ use indent for fold are: "<<m_foldingIndentationSensitive<<endl;
02179 }
02180
02181 void KateHighlighting::createContextNameList(QStringList *ContextNameList,int ctx0)
02182 {
02183 kdDebug(13010)<<"creatingContextNameList:BEGIN"<<endl;
02184
02185 if (ctx0 == 0)
02186 ContextNameList->clear();
02187
02188 KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
02189
02190 KateSyntaxContextData *data=KateHlManager::self()->syntax->getGroupInfo("highlighting","context");
02191
02192 int id=ctx0;
02193
02194 if (data)
02195 {
02196 while (KateHlManager::self()->syntax->nextGroup(data))
02197 {
02198 QString tmpAttr=KateHlManager::self()->syntax->groupData(data,QString("name")).simplifyWhiteSpace();
02199 if (tmpAttr.isEmpty())
02200 {
02201 tmpAttr=QString("!KATE_INTERNAL_DUMMY! %1").arg(id);
02202 errorsAndWarnings +=i18n("<B>%1</B>: Deprecated syntax. Context %2 has no symbolic name<BR>").arg(buildIdentifier).arg(id-ctx0);
02203 }
02204 else tmpAttr=buildPrefix+tmpAttr;
02205 (*ContextNameList)<<tmpAttr;
02206 id++;
02207 }
02208 KateHlManager::self()->syntax->freeGroupInfo(data);
02209 }
02210 kdDebug(13010)<<"creatingContextNameList:END"<<endl;
02211
02212 }
02213
02214 int KateHighlighting::getIdFromString(QStringList *ContextNameList, QString tmpLineEndContext, QString &unres)
02215 {
02216 unres="";
02217 int context;
02218 if ((tmpLineEndContext=="#stay") || (tmpLineEndContext.simplifyWhiteSpace().isEmpty()))
02219 context=-1;
02220
02221 else if (tmpLineEndContext.startsWith("#pop"))
02222 {
02223 context=-1;
02224 for(;tmpLineEndContext.startsWith("#pop");context--)
02225 {
02226 tmpLineEndContext.remove(0,4);
02227 kdDebug(13010)<<"#pop found"<<endl;
02228 }
02229 }
02230
02231 else if ( tmpLineEndContext.startsWith("##"))
02232 {
02233 QString tmp=tmpLineEndContext.right(tmpLineEndContext.length()-2);
02234 if (!embeddedHls.contains(tmp)) embeddedHls.insert(tmp,KateEmbeddedHlInfo());
02235 unres=tmp;
02236 context=0;
02237 }
02238
02239 else
02240 {
02241 context=ContextNameList->findIndex(buildPrefix+tmpLineEndContext);
02242 if (context==-1)
02243 {
02244 context=tmpLineEndContext.toInt();
02245 errorsAndWarnings+=i18n(
02246 "<B>%1</B>:Deprecated syntax. Context %2 not addressed by a symbolic name"
02247 ).arg(buildIdentifier).arg(tmpLineEndContext);
02248 }
02249
02250
02251 }
02252 return context;
02253 }
02254
02260 void KateHighlighting::makeContextList()
02261 {
02262 if (noHl)
02263 return;
02264
02265 embeddedHls.clear();
02266 unresolvedContextReferences.clear();
02267 RegionList.clear();
02268 ContextNameList.clear();
02269
02270
02271
02272 embeddedHls.insert(iName,KateEmbeddedHlInfo());
02273
02274 bool something_changed;
02275
02276 startctx=base_startctx=0;
02277
02278 building=true;
02279
02280 do
02281 {
02282 kdDebug(13010)<<"**************** Outter loop in make ContextList"<<endl;
02283 kdDebug(13010)<<"**************** Hl List count:"<<embeddedHls.count()<<endl;
02284 something_changed=false;
02285 for (KateEmbeddedHlInfos::const_iterator it=embeddedHls.begin(); it!=embeddedHls.end();++it)
02286 {
02287 if (!it.data().loaded)
02288 {
02289 kdDebug(13010)<<"**************** Inner loop in make ContextList"<<endl;
02290 QString identifierToUse;
02291 kdDebug(13010)<<"Trying to open highlighting definition file: "<< it.key()<<endl;
02292 if (iName==it.key())
02293 identifierToUse=identifier;
02294 else
02295 identifierToUse=KateHlManager::self()->identifierForName(it.key());
02296
02297 kdDebug(13010)<<"Location is:"<< identifierToUse<<endl;
02298
02299 buildPrefix=it.key()+':';
02300
02301 if (identifierToUse.isEmpty() ) kdDebug(13010)<<"OHOH, unknown highlighting description referenced"<<endl;
02302
02303 kdDebug(13010)<<"setting ("<<it.key()<<") to loaded"<<endl;
02304
02305
02306 it=embeddedHls.insert(it.key(),KateEmbeddedHlInfo(true,startctx));
02307
02308 buildContext0Offset=startctx;
02309
02310 startctx=addToContextList(identifierToUse,startctx);
02311
02312 if (noHl) return;
02313
02314 base_startctx = startctx;
02315 something_changed=true;
02316 }
02317 }
02318 } while (something_changed);
02319
02320
02321
02322
02323
02324 kdDebug(13010)<<"Unresolved contexts, which need attention: "<<unresolvedContextReferences.count()<<endl;
02325
02326
02327 for (KateHlUnresolvedCtxRefs::iterator unresIt=unresolvedContextReferences.begin();
02328 unresIt!=unresolvedContextReferences.end();++unresIt)
02329 {
02330
02331 KateEmbeddedHlInfos::const_iterator hlIt=embeddedHls.find(unresIt.data());
02332 if (hlIt!=embeddedHls.end())
02333 *(unresIt.key())=hlIt.data().context0;
02334 }
02335
02336
02337
02338
02339
02340 handleKateHlIncludeRules();
02341
02342 embeddedHls.clear();
02343 unresolvedContextReferences.clear();
02344 RegionList.clear();
02345 ContextNameList.clear();
02346
02347
02348
02349 if (!errorsAndWarnings.isEmpty())
02350 KMessageBox::detailedSorry(0L,i18n("There were warning(s) and/or error(s) while parsing the syntax highlighting configuration."), errorsAndWarnings, i18n("Kate Syntax Highlighting Parser"));
02351
02352
02353 building=false;
02354 }
02355
02356 void KateHighlighting::handleKateHlIncludeRules()
02357 {
02358
02359 kdDebug(13010)<<"KateHlIncludeRules, which need attention: " <<includeRules.count()<<endl;
02360 if (includeRules.isEmpty()) return;
02361
02362 buildPrefix="";
02363 QString dummy;
02364
02365
02366
02367
02368
02369
02370
02371 for (KateHlIncludeRules::iterator it=includeRules.begin();it!=includeRules.end();)
02372 {
02373 if ((*it)->incCtx==-1)
02374 {
02375
02376 if ((*it)->incCtxN.isEmpty())
02377 {
02378
02379 KateHlIncludeRules::iterator it1=it;
02380 ++it1;
02381 delete (*it);
02382 includeRules.remove(it);
02383 it=it1;
02384 }
02385 else
02386 {
02387
02388 (*it)->incCtx=getIdFromString(&ContextNameList,(*it)->incCtxN,dummy);
02389 kdDebug(13010)<<"Resolved "<<(*it)->incCtxN<< " to "<<(*it)->incCtx<<" for include rule"<<endl;
02390
02391 }
02392 }
02393 else ++it;
02394 }
02395
02396
02397
02398
02399
02400 while (!includeRules.isEmpty())
02401 handleKateHlIncludeRulesRecursive(includeRules.begin(),&includeRules);
02402 }
02403
02404 void KateHighlighting::handleKateHlIncludeRulesRecursive(KateHlIncludeRules::iterator it, KateHlIncludeRules *list)
02405 {
02406 if (it==list->end()) return;
02407 KateHlIncludeRules::iterator it1=it;
02408 int ctx=(*it1)->ctx;
02409
02410
02411
02412
02413
02414
02415
02416
02417
02418 while ((it!=list->end()) && ((*it)->ctx==ctx))
02419 {
02420 it1=it;
02421 ++it;
02422 }
02423
02424
02425 while ((it1!=list->end()) && ((*it1)->ctx==ctx))
02426 {
02427 int ctx1=(*it1)->incCtx;
02428
02429
02430 for (KateHlIncludeRules::iterator it2=list->begin();it2!=list->end();++it2)
02431 {
02432 if ((*it2)->ctx==ctx1)
02433 {
02434
02435
02436 handleKateHlIncludeRulesRecursive(it2,list);
02437 break;
02438 }
02439 }
02440
02441
02442 KateHlContext *dest=contextList[ctx];
02443 KateHlContext *src=contextList[ctx1];
02444
02445
02446
02447
02448
02449 if ( (*it1)->includeAttrib )
02450 dest->attr = src->attr;
02451
02452 uint p=(*it1)->pos;
02453 for ( KateHlItem *c = src->items.first(); c; c=src->items.next(), p++ )
02454 dest->items.insert(p,c);
02455
02456 it=it1;
02457 --it1;
02458 delete (*it);
02459 list->remove(it);
02460 }
02461 }
02462
02468 int KateHighlighting::addToContextList(const QString &ident, int ctx0)
02469 {
02470 buildIdentifier=ident;
02471 KateSyntaxContextData *data, *datasub;
02472 KateHlItem *c;
02473
02474 QString dummy;
02475
02476
02477 if (!KateHlManager::self()->syntax->setIdentifier(ident))
02478 {
02479 noHl=true;
02480 KMessageBox::information(0L,i18n("Since there has been an error parsing the highlighting description, this highlighting will be disabled"));
02481 return 0;
02482 }
02483
02484
02485 RegionList<<"!KateInternal_TopLevel!";
02486
02487
02488
02489
02490 QStringList additionaldata = readCommentConfig();
02491 additionaldata << readGlobalKeywordConfig();
02492 additionaldata << readWordWrapConfig();
02493
02494 readFoldingConfig ();
02495
02496 m_additionalData.insert( internalIDList.count(), additionaldata );
02497 m_hlIndex.append( (int)internalIDList.count() );
02498
02499 QString ctxName;
02500
02501
02502
02503 addToKateHlItemDataList();
02504 KateHlItemDataList iDl = internalIDList;
02505
02506 createContextNameList(&ContextNameList,ctx0);
02507
02508
02509 kdDebug(13010)<<"Parsing Context structure"<<endl;
02510
02511 data=KateHlManager::self()->syntax->getGroupInfo("highlighting","context");
02512 uint i=buildContext0Offset;
02513 if (data)
02514 {
02515 while (KateHlManager::self()->syntax->nextGroup(data))
02516 {
02517 kdDebug(13010)<<"Found a context in file, building structure now"<<endl;
02518
02519 QString tmpAttr=KateHlManager::self()->syntax->groupData(data,QString("attribute")).simplifyWhiteSpace();
02520 int attr;
02521 if (QString("%1").arg(tmpAttr.toInt())==tmpAttr)
02522 attr=tmpAttr.toInt();
02523 else
02524 attr=lookupAttrName(tmpAttr,iDl);
02525
02526
02527 ctxName=buildPrefix+KateHlManager::self()->syntax->groupData(data,QString("lineEndContext")).simplifyWhiteSpace();
02528
02529 QString tmpLineEndContext=KateHlManager::self()->syntax->groupData(data,QString("lineEndContext")).simplifyWhiteSpace();
02530 int context;
02531
02532 context=getIdFromString(&ContextNameList, tmpLineEndContext,dummy);
02533
02534
02535 bool ft = false;
02536 int ftc = 0;
02537 if ( i > 0 )
02538 {
02539 QString tmpFt = KateHlManager::self()->syntax->groupData(data, QString("fallthrough") );
02540 if ( IS_TRUE(tmpFt) )
02541 ft = true;
02542 if ( ft )
02543 {
02544 QString tmpFtc = KateHlManager::self()->syntax->groupData( data, QString("fallthroughContext") );
02545
02546 ftc=getIdFromString(&ContextNameList, tmpFtc,dummy);
02547 if (ftc == -1) ftc =0;
02548
02549 kdDebug(13010)<<"Setting fall through context (context "<<i<<"): "<<ftc<<endl;
02550 }
02551 }
02552
02553
02554 bool dynamic = false;
02555 QString tmpDynamic = KateHlManager::self()->syntax->groupData(data, QString("dynamic") );
02556 if ( tmpDynamic.lower() == "true" || tmpDynamic.toInt() == 1 )
02557 dynamic = true;
02558
02559 contextList.insert (i, new KateHlContext (
02560 attr,
02561 context,
02562 (KateHlManager::self()->syntax->groupData(data,QString("lineBeginContext"))).isEmpty()?-1:
02563 (KateHlManager::self()->syntax->groupData(data,QString("lineBeginContext"))).toInt(),
02564 ft, ftc, dynamic ));
02565
02566
02567 while (KateHlManager::self()->syntax->nextItem(data))
02568 {
02569
02570
02571
02572
02573 QString tag = KateHlManager::self()->syntax->groupItemData(data,QString(""));
02574 if ( tag == "IncludeRules" )
02575 {
02576 QString incCtx = KateHlManager::self()->syntax->groupItemData( data, QString("context"));
02577 QString incAttrib = KateHlManager::self()->syntax->groupItemData( data, QString("includeAttrib"));
02578 bool includeAttrib = ( incAttrib.lower() == "true" || incAttrib.toInt() == 1 );
02579
02580 if (incCtx.startsWith("##") || (!incCtx.startsWith("#")))
02581 {
02582
02583 if (!incCtx.startsWith("#"))
02584 {
02585
02586 incCtx=buildPrefix+incCtx.simplifyWhiteSpace();
02587 includeRules.append(new KateHlIncludeRule(i,contextList[i]->items.count(),incCtx, includeAttrib));
02588 }
02589 else
02590 {
02591
02592 kdDebug(13010)<<"Cross highlight reference <IncludeRules>"<<endl;
02593 KateHlIncludeRule *ir=new KateHlIncludeRule(i,contextList[i]->items.count(),"",includeAttrib);
02594
02595
02596 if (!embeddedHls.contains(incCtx.right(incCtx.length()-2)))
02597 embeddedHls.insert(incCtx.right(incCtx.length()-2),KateEmbeddedHlInfo());
02598
02599 unresolvedContextReferences.insert(&(ir->incCtx),
02600 incCtx.right(incCtx.length()-2));
02601
02602 includeRules.append(ir);
02603 }
02604 }
02605
02606 continue;
02607 }
02608
02609 #if 0
02610 QString tag = KateHlManager::self()->syntax->groupKateHlItemData(data,QString(""));
02611 if ( tag == "IncludeRules" ) {
02612
02613 int ctxId = getIdFromString(&ContextNameList,
02614 KateHlManager::self()->syntax->groupKateHlItemData( data, QString("context")),dummy);
02615 if ( ctxId > -1) {
02616 kdDebug(13010)<<"makeContextList["<<i<<"]: including all items of context "<<ctxId<<endl;
02617 if ( ctxId < (int) i ) {
02618 for ( c = contextList[ctxId]->items.first(); c; c = contextList[ctxId]->items.next() )
02619 contextList[i]->items.append(c);
02620 }
02621 else
02622 kdDebug(13010)<<"Context "<<ctxId<<"not defined. You can not include the rules of an undefined context"<<endl;
02623 }
02624 continue;
02625 }
02626 #endif
02627 c=createKateHlItem(data,iDl,&RegionList,&ContextNameList);
02628 if (c)
02629 {
02630 contextList[i]->items.append(c);
02631
02632
02633 datasub=KateHlManager::self()->syntax->getSubItems(data);
02634 bool tmpbool;
02635 if (tmpbool=KateHlManager::self()->syntax->nextItem(datasub))
02636 {
02637 c->subItems=new QPtrList<KateHlItem>;
02638 for (;tmpbool;tmpbool=KateHlManager::self()->syntax->nextItem(datasub))
02639 {
02640 c->subItems->append(createKateHlItem(datasub,iDl,&RegionList,&ContextNameList));
02641 } }
02642 KateHlManager::self()->syntax->freeGroupInfo(datasub);
02643
02644 }
02645 }
02646 i++;
02647 }
02648 }
02649
02650 KateHlManager::self()->syntax->freeGroupInfo(data);
02651
02652 if (RegionList.count()!=1)
02653 folding=true;
02654
02655 folding = folding || m_foldingIndentationSensitive;
02656
02657 return i;
02658 }
02659
02660 void KateHighlighting::clearAttributeArrays ()
02661 {
02662 for ( QIntDictIterator< QMemArray<KateAttribute> > it( m_attributeArrays ); it.current(); ++it )
02663 {
02664
02665 KateAttributeList defaultStyleList;
02666 defaultStyleList.setAutoDelete(true);
02667 KateHlManager::self()->getDefaults(it.currentKey(), defaultStyleList);
02668
02669 KateHlItemDataList itemDataList;
02670 getKateHlItemDataList(it.currentKey(), itemDataList);
02671
02672 uint nAttribs = itemDataList.count();
02673 QMemArray<KateAttribute> *array = it.current();
02674 array->resize (nAttribs);
02675
02676 for (uint z = 0; z < nAttribs; z++)
02677 {
02678 KateHlItemData *itemData = itemDataList.at(z);
02679 KateAttribute n = *defaultStyleList.at(itemData->defStyleNum);
02680
02681 if (itemData && itemData->isSomethingSet())
02682 n += *itemData;
02683
02684 array->at(z) = n;
02685 }
02686 }
02687 }
02688
02689 QMemArray<KateAttribute> *KateHighlighting::attributes (uint schema)
02690 {
02691 QMemArray<KateAttribute> *array;
02692
02693
02694 if ((array = m_attributeArrays[schema]))
02695 return array;
02696
02697
02698 if (!KateFactory::self()->schemaManager()->validSchema(schema))
02699 {
02700
02701 return attributes (0);
02702 }
02703
02704
02705 KateAttributeList defaultStyleList;
02706 defaultStyleList.setAutoDelete(true);
02707 KateHlManager::self()->getDefaults(schema, defaultStyleList);
02708
02709 KateHlItemDataList itemDataList;
02710 getKateHlItemDataList(schema, itemDataList);
02711
02712 uint nAttribs = itemDataList.count();
02713 array = new QMemArray<KateAttribute> (nAttribs);
02714
02715 for (uint z = 0; z < nAttribs; z++)
02716 {
02717 KateHlItemData *itemData = itemDataList.at(z);
02718 KateAttribute n = *defaultStyleList.at(itemData->defStyleNum);
02719
02720 if (itemData && itemData->isSomethingSet())
02721 n += *itemData;
02722
02723 array->at(z) = n;
02724 }
02725
02726 m_attributeArrays.insert(schema, array);
02727
02728 return array;
02729 }
02730
02731 void KateHighlighting::getKateHlItemDataListCopy (uint schema, KateHlItemDataList &outlist)
02732 {
02733 KateHlItemDataList itemDataList;
02734 getKateHlItemDataList(schema, itemDataList);
02735
02736 outlist.clear ();
02737 outlist.setAutoDelete (true);
02738 for (uint z=0; z < itemDataList.count(); z++)
02739 outlist.append (new KateHlItemData (*itemDataList.at(z)));
02740 }
02741
02742
02743
02744
02745 KateHlManager::KateHlManager()
02746 : QObject()
02747 , m_config ("katesyntaxhighlightingrc", false, false)
02748 , commonSuffixes (QStringList::split(";", ".orig;.new;~;.bak;.BAK"))
02749 , syntax (new KateSyntaxDocument())
02750 , dynamicCtxsCount(0)
02751 , forceNoDCReset(false)
02752 {
02753 hlList.setAutoDelete(true);
02754 hlDict.setAutoDelete(false);
02755
02756 KateSyntaxModeList modeList = syntax->modeList();
02757 for (uint i=0; i < modeList.count(); i++)
02758 {
02759 KateHighlighting *hl = new KateHighlighting(modeList.at(i));
02760
02761 uint insert = 0;
02762 for (; insert <= hlList.count(); insert++)
02763 {
02764 if (insert == hlList.count())
02765 break;
02766
02767 if ( QString(hlList.at(insert)->section() + hlList.at(insert)->nameTranslated()).lower()
02768 > QString(hl->section() + hl->nameTranslated()).lower() )
02769 break;
02770 }
02771
02772 hlList.insert (insert, hl);
02773 hlDict.insert (hl->name(), hl);
02774 }
02775
02776 // Normal HL
02777 KateHighlighting *hl = new KateHighlighting(0);
02778 hlList.prepend (hl);
02779 hlDict.insert (hl->name(), hl);
02780
02781 lastCtxsReset.start();
02782 }
02783
02784 KateHlManager::~KateHlManager()
02785 {
02786 delete syntax;
02787 }
02788
02789 static KStaticDeleter<KateHlManager> sdHlMan;
02790
02791 KateHlManager *KateHlManager::self()
02792 {
02793 if ( !s_self )
02794 sdHlMan.setObject(s_self, new KateHlManager ());
02795
02796 return s_self;
02797 }
02798
02799 KateHighlighting *KateHlManager::getHl(int n)
02800 {
02801 if (n < 0 || n >= (int) hlList.count())
02802 n = 0;
02803
02804 return hlList.at(n);
02805 }
02806
02807 int KateHlManager::nameFind(const QString &name)
02808 {
02809 int z (hlList.count() - 1);
02810 for (; z > 0; z--)
02811 if (hlList.at(z)->name() == name)
02812 return z;
02813
02814 return z;
02815 }
02816
02817 int KateHlManager::detectHighlighting (KateDocument *doc)
02818 {
02819 int hl = wildcardFind( doc->url().filename() );
02820 if ( hl < 0 )
02821 hl = mimeFind ( doc );
02822
02823 return hl;
02824 }
02825
02826 int KateHlManager::wildcardFind(const QString &fileName)
02827 {
02828 int result = -1;
02829 if ((result = realWildcardFind(fileName)) != -1)
02830 return result;
02831
02832 int length = fileName.length();
02833 QString backupSuffix = KateDocumentConfig::global()->backupSuffix();
02834 if (fileName.endsWith(backupSuffix)) {
02835 if ((result = realWildcardFind(fileName.left(length - backupSuffix.length()))) != -1)
02836 return result;
02837 }
02838
02839 for (QStringList::Iterator it = commonSuffixes.begin(); it != commonSuffixes.end(); ++it) {
02840 if (*it != backupSuffix && fileName.endsWith(*it)) {
02841 if ((result = realWildcardFind(fileName.left(length - (*it).length()))) != -1)
02842 return result;
02843 }
02844 }
02845
02846 return -1;
02847 }
02848
02849 int KateHlManager::realWildcardFind(const QString &fileName)
02850 {
02851 static QRegExp sep("\\s*;\\s*");
02852
02853 QPtrList<KateHighlighting> highlights;
02854
02855 for (KateHighlighting *highlight = hlList.first(); highlight != 0L; highlight = hlList.next()) {
02856 highlight->loadWildcards();
02857
02858 for (QStringList::Iterator it = highlight->getPlainExtensions().begin(); it != highlight->getPlainExtensions().end(); ++it)
02859 if (fileName.endsWith((*it)))
02860 highlights.append(highlight);
02861
02862 for (int i = 0; i < (int)highlight->getRegexpExtensions().count(); i++) {
02863 QRegExp re = highlight->getRegexpExtensions()[i];
02864 if (re.exactMatch(fileName))
02865 highlights.append(highlight);
02866 }
02867 }
02868
02869 if ( !highlights.isEmpty() )
02870 {
02871 int pri = -1;
02872 int hl = -1;
02873
02874 for (KateHighlighting *highlight = highlights.first(); highlight != 0L; highlight = highlights.next())
02875 {
02876 if (highlight->priority() > pri)
02877 {
02878 pri = highlight->priority();
02879 hl = hlList.findRef (highlight);
02880 }
02881 }
02882 return hl;
02883 }
02884
02885 return -1;
02886 }
02887
02888 int KateHlManager::mimeFind( KateDocument *doc )
02889 {
02890 static QRegExp sep("\\s*;\\s*");
02891
02892 KMimeType::Ptr mt = doc->mimeTypeForContent();
02893
02894 QPtrList<KateHighlighting> highlights;
02895
02896 for (KateHighlighting *highlight = hlList.first(); highlight != 0L; highlight = hlList.next())
02897 {
02898 QStringList l = QStringList::split( sep, highlight->getMimetypes() );
02899
02900 for( QStringList::Iterator it = l.begin(); it != l.end(); ++it )
02901 {
02902 if ( *it == mt->name() ) // faster than a regexp i guess?
02903 highlights.append (highlight);
02904 }
02905 }
02906
02907 if ( !highlights.isEmpty() )
02908 {
02909 int pri = -1;
02910 int hl = -1;
02911
02912 for (KateHighlighting *highlight = highlights.first(); highlight != 0L; highlight = highlights.next())
02913 {
02914 if (highlight->priority() > pri)
02915 {
02916 pri = highlight->priority();
02917 hl = hlList.findRef (highlight);
02918 }
02919 }
02920
02921 return hl;
02922 }
02923
02924 return -1;
02925 }
02926
02927 uint KateHlManager::defaultStyles()
02928 {
02929 return 14;
02930 }
02931
02932 QString KateHlManager::defaultStyleName(int n, bool translateNames)
02933 {
02934 static QStringList names;
02935 static QStringList translatedNames;
02936
02937 if (names.isEmpty())
02938 {
02939 names << "Normal";
02940 names << "Keyword";
02941 names << "Data Type";
02942 names << "Decimal/Value";
02943 names << "Base-N Integer";
02944 names << "Floating Point";
02945 names << "Character";
02946 names << "String";
02947 names << "Comment";
02948 names << "Others";
02949 names << "Alert";
02950 names << "Function";
02951 // this next one is for denoting the beginning/end of a user defined folding region
02952 names << "Region Marker";
02953 // this one is for marking invalid input
02954 names << "Error";
02955
02956 translatedNames << i18n("Normal");
02957 translatedNames << i18n("Keyword");
02958 translatedNames << i18n("Data Type");
02959 translatedNames << i18n("Decimal/Value");
02960 translatedNames << i18n("Base-N Integer");
02961 translatedNames << i18n("Floating Point");
02962 translatedNames << i18n("Character");
02963 translatedNames << i18n("String");
02964 translatedNames << i18n("Comment");
02965 translatedNames << i18n("Others");
02966 translatedNames << i18n("Alert");
02967 translatedNames << i18n("Function");
02968 // this next one is for denoting the beginning/end of a user defined folding region
02969 translatedNames << i18n("Region Marker");
02970 // this one is for marking invalid input
02971 translatedNames << i18n("Error");
02972 }
02973
02974 return translateNames ? translatedNames[n] : names[n];
02975 }
02976
02977 void KateHlManager::getDefaults(uint schema, KateAttributeList &list)
02978 {
02979 list.setAutoDelete(true);
02980
02981 KateAttribute* normal = new KateAttribute();
02982 normal->setTextColor(Qt::black);
02983 normal->setSelectedTextColor(Qt::white);
02984 list.append(normal);
02985
02986 KateAttribute* keyword = new KateAttribute();
02987 keyword->setTextColor(Qt::black);
02988 keyword->setSelectedTextColor(Qt::white);
02989 keyword->setBold(true);
02990 list.append(keyword);
02991
02992 KateAttribute* dataType = new KateAttribute();
02993 dataType->setTextColor(Qt::darkRed);
02994 dataType->setSelectedTextColor(Qt::white);
02995 list.append(dataType);
02996
02997 KateAttribute* decimal = new KateAttribute();
02998 decimal->setTextColor(Qt::blue);
02999 decimal->setSelectedTextColor(Qt::cyan);
03000 list.append(decimal);
03001
03002 KateAttribute* basen = new KateAttribute();
03003 basen->setTextColor(Qt::darkCyan);
03004 basen->setSelectedTextColor(Qt::cyan);
03005 list.append(basen);
03006
03007 KateAttribute* floatAttribute = new KateAttribute();
03008 floatAttribute->setTextColor(Qt::darkMagenta);
03009 floatAttribute->setSelectedTextColor(Qt::cyan);
03010 list.append(floatAttribute);
03011
03012 KateAttribute* charAttribute = new KateAttribute();
03013 charAttribute->setTextColor(Qt::magenta);
03014 charAttribute->setSelectedTextColor(Qt::magenta);
03015 list.append(charAttribute);
03016
03017 KateAttribute* string = new KateAttribute();
03018 string->setTextColor(QColor::QColor("#D00"));
03019 string->setSelectedTextColor(Qt::red);
03020 list.append(string);
03021
03022 KateAttribute* comment = new KateAttribute();
03023 comment->setTextColor(Qt::darkGray);
03024 comment->setSelectedTextColor(Qt::gray);
03025 comment->setItalic(true);
03026 list.append(comment);
03027
03028 KateAttribute* others = new KateAttribute();
03029 others->setTextColor(Qt::darkGreen);
03030 others->setSelectedTextColor(Qt::green);
03031 list.append(others);
03032
03033 KateAttribute* alert = new KateAttribute();
03034 alert->setTextColor(Qt::white);
03035 alert->setSelectedTextColor( QColor::QColor("#FCC") );
03036 alert->setBold(true);
03037 alert->setBGColor( QColor::QColor("#FCC") );
03038 list.append(alert);
03039
03040 KateAttribute* functionAttribute = new KateAttribute();
03041 functionAttribute->setTextColor(Qt::darkBlue);
03042 functionAttribute->setSelectedTextColor(Qt::white);
03043 list.append(functionAttribute);
03044
03045 KateAttribute* regionmarker = new KateAttribute();
03046 regionmarker->setTextColor(Qt::white);
03047 regionmarker->setBGColor(Qt::gray);
03048 regionmarker->setSelectedTextColor(Qt::gray);
03049 list.append(regionmarker);
03050
03051 KateAttribute* error = new KateAttribute();
03052 error->setTextColor(Qt::red);
03053 error->setUnderline(true);
03054 error->setSelectedTextColor(Qt::red);
03055 list.append(error);
03056
03057 KConfig *config = KateHlManager::self()->self()->getKConfig();
03058 config->setGroup("Default Item Styles - Schema " + KateFactory::self()->schemaManager()->name(schema));
03059
03060 for (uint z = 0; z < defaultStyles(); z++)
03061 {
03062 KateAttribute *i = list.at(z);
03063 QStringList s = config->readListEntry(defaultStyleName(z));
03064 if (!s.isEmpty())
03065 {
03066 while( s.count()<8)
03067 s << "";
03068
03069 QString tmp;
03070 QRgb col;
03071
03072 tmp=s[0]; if (!tmp.isEmpty()) {
03073 col=tmp.toUInt(0,16); i->setTextColor(col); }
03074
03075 tmp=s[1]; if (!tmp.isEmpty()) {
03076 col=tmp.toUInt(0,16); i->setSelectedTextColor(col); }
03077
03078 tmp=s[2]; if (!tmp.isEmpty()) i->setBold(tmp!="0");
03079
03080 tmp=s[3]; if (!tmp.isEmpty()) i->setItalic(tmp!="0");
03081
03082 tmp=s[4]; if (!tmp.isEmpty()) i->setStrikeOut(tmp!="0");
03083
03084 tmp=s[5]; if (!tmp.isEmpty()) i->setUnderline(tmp!="0");
03085
03086 tmp=s[6]; if (!tmp.isEmpty()) {
03087 col=tmp.toUInt(0,16); i->setBGColor(col); }
03088
03089 tmp=s[7]; if (!tmp.isEmpty()) {
03090 col=tmp.toUInt(0,16); i->setSelectedBGColor(col); }
03091 }
03092 }
03093 }
03094
03095 void KateHlManager::setDefaults(uint schema, KateAttributeList &list)
03096 {
03097 KConfig *config = KateHlManager::self()->self()->getKConfig();
03098 config->setGroup("Default Item Styles - Schema " + KateFactory::self()->schemaManager()->name(schema));
03099
03100 for (uint z = 0; z < defaultStyles(); z++)
03101 {
03102 QStringList settings;
03103 KateAttribute *i = list.at(z);
03104
03105 settings<<(i->itemSet(KateAttribute::TextColor)?QString::number(i->textColor().rgb(),16):"");
03106 settings<<(i->itemSet(KateAttribute::SelectedTextColor)?QString::number(i->selectedTextColor().rgb(),16):"");
03107 settings<<(i->itemSet(KateAttribute::Weight)?(i->bold()?"1":"0"):"");
03108 settings<<(i->itemSet(KateAttribute::Italic)?(i->italic()?"1":"0"):"");
03109 settings<<(i->itemSet(KateAttribute::StrikeOut)?(i->strikeOut()?"1":"0"):"");
03110 settings<<(i->itemSet(KateAttribute::Underline)?(i->underline()?"1":"0"):"");
03111 settings<<(i->itemSet(KateAttribute::BGColor)?QString::number(i->bgColor().rgb(),16):"");
03112 settings<<(i->itemSet(KateAttribute::SelectedBGColor)?QString::number(i->selectedBGColor().rgb(),16):"");
03113 settings<<"---";
03114
03115 config->writeEntry(defaultStyleName(z),settings);
03116 }
03117
03118 emit changed();
03119 }
03120
03121 int KateHlManager::highlights()
03122 {
03123 return (int) hlList.count();
03124 }
03125
03126 QString KateHlManager::hlName(int n)
03127 {
03128 return hlList.at(n)->name();
03129 }
03130
03131 QString KateHlManager::hlNameTranslated(int n)
03132 {
03133 return hlList.at(n)->nameTranslated();
03134 }
03135
03136 QString KateHlManager::hlSection(int n)
03137 {
03138 return hlList.at(n)->section();
03139 }
03140
03141 bool KateHlManager::hlHidden(int n)
03142 {
03143 return hlList.at(n)->hidden();
03144 }
03145
03146 QString KateHlManager::identifierForName(const QString& name)
03147 {
03148 KateHighlighting *hl = 0;
03149
03150 if ((hl = hlDict[name]))
03151 return hl->getIdentifier ();
03152
03153 return QString();
03154 }
03155
03156 bool KateHlManager::resetDynamicCtxs()
03157 {
03158 if (forceNoDCReset)
03159 return false;
03160
03161 if (lastCtxsReset.elapsed() < KATE_DYNAMIC_CONTEXTS_RESET_DELAY)
03162 return false;
03163
03164 KateHighlighting *hl;
03165 for (hl = hlList.first(); hl; hl = hlList.next())
03166 hl->dropDynamicContexts();
03167
03168 dynamicCtxsCount = 0;
03169 lastCtxsReset.start();
03170
03171 return true;
03172 }
03173 //END
03174
03175 //BEGIN KateHighlightAction
03176 void KateViewHighlightAction::init()
03177 {
03178 m_doc = 0;
03179 subMenus.setAutoDelete( true );
03180
03181 connect(popupMenu(),SIGNAL(aboutToShow()),this,SLOT(slotAboutToShow()));
03182 }
03183
03184 void KateViewHighlightAction::updateMenu (Kate::Document *doc)
03185 {
03186 m_doc = doc;
03187 }
03188
03189 void KateViewHighlightAction::slotAboutToShow()
03190 {
03191 Kate::Document *doc=m_doc;
03192 int count = KateHlManager::self()->highlights();
03193
03194 for (int z=0; z<count; z++)
03195 {
03196 QString hlName = KateHlManager::self()->hlNameTranslated (z);
03197 QString hlSection = KateHlManager::self()->hlSection (z);
03198
03199 if (!KateHlManager::self()->hlHidden(z))
03200 {
03201 if ( !hlSection.isEmpty() && (names.contains(hlName) < 1) )
03202 {
03203 if (subMenusName.contains(hlSection) < 1)
03204 {
03205 subMenusName << hlSection;
03206 QPopupMenu *menu = new QPopupMenu ();
03207 subMenus.append(menu);
03208 popupMenu()->insertItem (hlSection, menu);
03209 }
03210
03211 int m = subMenusName.findIndex (hlSection);
03212 names << hlName;
03213 subMenus.at(m)->insertItem ( hlName, this, SLOT(setHl(int)), 0, z);
03214 }
03215 else if (names.contains(hlName) < 1)
03216 {
03217 names << hlName;
03218 popupMenu()->insertItem ( hlName, this, SLOT(setHl(int)), 0, z);
03219 }
03220 }
03221 }
03222
03223 if (!doc) return;
03224
03225 for (uint i=0;i<subMenus.count();i++)
03226 {
03227 for (uint i2=0;i2<subMenus.at(i)->count();i2++)
03228 {
03229 subMenus.at(i)->setItemChecked(subMenus.at(i)->idAt(i2),false);
03230 }
03231 }
03232 popupMenu()->setItemChecked (0, false);
03233
03234 int i = subMenusName.findIndex (KateHlManager::self()->hlSection(doc->hlMode()));
03235 if (i >= 0 && subMenus.at(i))
03236 subMenus.at(i)->setItemChecked (doc->hlMode(), true);
03237 else
03238 popupMenu()->setItemChecked (0, true);
03239 }
03240
03241 void KateViewHighlightAction::setHl (int mode)
03242 {
03243 Kate::Document *doc=m_doc;
03244
03245 if (doc)
03246 doc->setHlMode((uint)mode);
03247 }
03248 //END KateViewHighlightAction
03249
03250 // kate: space-indent on; indent-width 2; replace-tabs on;