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