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