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 casesensitive, 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 _caseSensitive;
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 casesensitive, const QString& delims)
00605 : KateHlItem(attribute,context,regionId,regionId2)
00606 , _caseSensitive(casesensitive)
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, _caseSensitive);
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 if (item->region2)
01457 {
01458
01459 if ( !foldingList->isEmpty() && ((item->region2 < 0) && (*foldingList)[foldingList->size()-2] == -item->region2 ) )
01460 {
01461 foldingList->resize (foldingList->size()-2, QGArray::SpeedOptim);
01462 }
01463 else
01464 {
01465 foldingList->resize (foldingList->size()+2, QGArray::SpeedOptim);
01466 (*foldingList)[foldingList->size()-2] = (uint)item->region2;
01467 if (item->region2<0)
01468 (*foldingList)[foldingList->size()-1] = offset2;
01469 else
01470 (*foldingList)[foldingList->size()-1] = offset;
01471 }
01472
01473 }
01474
01475 if (item->region)
01476 {
01477
01478
01479
01480
01481
01482
01483
01484 {
01485 foldingList->resize (foldingList->size()+2, QGArray::SpeedOptim);
01486 (*foldingList)[foldingList->size()-2] = item->region;
01487 if (item->region<0)
01488 (*foldingList)[foldingList->size()-1] = offset2;
01489 else
01490 (*foldingList)[foldingList->size()-1] = offset;
01491 }
01492
01493 }
01494
01495
01496 if (item->ctx != -1)
01497 {
01498 generateContextStack (&ctxNum, item->ctx, &ctx, &previousLine);
01499 context = contextNum(ctxNum);
01500 }
01501
01502
01503 if (context->dynamic)
01504 {
01505 QStringList *lst = item->capturedTexts();
01506 if (lst != 0)
01507 {
01508
01509 int newctx = makeDynamicContext(context, lst);
01510 if (ctx.size() > 0)
01511 ctx[ctx.size() - 1] = newctx;
01512 ctxNum = newctx;
01513 context = contextNum(ctxNum);
01514 }
01515 delete lst;
01516 }
01517
01518
01519 if (!item->lookAhead)
01520 {
01521 if (offset2 > len)
01522 offset2 = len;
01523
01524
01525 memset ( textLine->attributes()+offset
01526 , item->onlyConsume ? context->attr : item->attr
01527 , offset2-offset);
01528
01529 offset = offset2;
01530 lastChar = text[offset-1];
01531 }
01532
01533 anItemMatched = true;
01534 break;
01535 }
01536
01537
01538 if (anItemMatched)
01539 continue;
01540
01541
01542
01543 if ( context->fallthrough )
01544 {
01545
01546 generateContextStack(&ctxNum, context->ftctx, &ctx, &previousLine);
01547 context=contextNum(ctxNum);
01548
01549
01550
01551
01552
01553
01554
01555
01556 continue;
01557 }
01558 else
01559 {
01560 *(textLine->attributes() + offset) = context->attr;
01561 lastChar = text[offset];
01562 offset++;
01563 }
01564 }
01565
01566
01567 if (ctx == textLine->ctxArray())
01568 {
01569 if (ctxChanged)
01570 (*ctxChanged) = false;
01571 }
01572 else
01573 {
01574 if (ctxChanged)
01575 (*ctxChanged) = true;
01576
01577
01578 textLine->setContext(ctx);
01579 }
01580
01581
01582 textLine->setHlLineContinue (item && item->lineContinue());
01583
01584 if (m_foldingIndentationSensitive) {
01585 bool noindent=false;
01586 for(int i=ctx.size()-1; i>=0; --i) {
01587 if (contextNum(ctx[i])->noIndentationBasedFolding) {
01588 noindent=true;
01589 break;
01590 }
01591 }
01592 textLine->setNoIndentBasedFolding(noindent);
01593 }
01594 }
01595
01596 void KateHighlighting::loadWildcards()
01597 {
01598 KConfig *config = KateHlManager::self()->getKConfig();
01599 config->setGroup("Highlighting " + iName);
01600
01601 QString extensionString = config->readEntry("Wildcards", iWildcards);
01602
01603 if (extensionSource != extensionString) {
01604 regexpExtensions.clear();
01605 plainExtensions.clear();
01606
01607 extensionSource = extensionString;
01608
01609 static QRegExp sep("\\s*;\\s*");
01610
01611 QStringList l = QStringList::split( sep, extensionSource );
01612
01613 static QRegExp boringExpression("\\*\\.[\\d\\w]+");
01614
01615 for( QStringList::Iterator it = l.begin(); it != l.end(); ++it )
01616 if (boringExpression.exactMatch(*it))
01617 plainExtensions.append((*it).mid(1));
01618 else
01619 regexpExtensions.append(QRegExp((*it), true, true));
01620 }
01621 }
01622
01623 QValueList<QRegExp>& KateHighlighting::getRegexpExtensions()
01624 {
01625 return regexpExtensions;
01626 }
01627
01628 QStringList& KateHighlighting::getPlainExtensions()
01629 {
01630 return plainExtensions;
01631 }
01632
01633 QString KateHighlighting::getMimetypes()
01634 {
01635 KConfig *config = KateHlManager::self()->getKConfig();
01636 config->setGroup("Highlighting " + iName);
01637
01638 return config->readEntry("Mimetypes", iMimetypes);
01639 }
01640
01641 int KateHighlighting::priority()
01642 {
01643 KConfig *config = KateHlManager::self()->getKConfig();
01644 config->setGroup("Highlighting " + iName);
01645
01646 return config->readNumEntry("Priority", m_priority);
01647 }
01648
01649 KateHlData *KateHighlighting::getData()
01650 {
01651 KConfig *config = KateHlManager::self()->getKConfig();
01652 config->setGroup("Highlighting " + iName);
01653
01654 KateHlData *hlData = new KateHlData(
01655 config->readEntry("Wildcards", iWildcards),
01656 config->readEntry("Mimetypes", iMimetypes),
01657 config->readEntry("Identifier", identifier),
01658 config->readNumEntry("Priority", m_priority));
01659
01660 return hlData;
01661 }
01662
01663 void KateHighlighting::setData(KateHlData *hlData)
01664 {
01665 KConfig *config = KateHlManager::self()->getKConfig();
01666 config->setGroup("Highlighting " + iName);
01667
01668 config->writeEntry("Wildcards",hlData->wildcards);
01669 config->writeEntry("Mimetypes",hlData->mimetypes);
01670 config->writeEntry("Priority",hlData->priority);
01671 }
01672
01673 void KateHighlighting::getKateHlItemDataList (uint schema, KateHlItemDataList &list)
01674 {
01675 KConfig *config = KateHlManager::self()->getKConfig();
01676 config->setGroup("Highlighting " + iName + " - Schema " + KateFactory::self()->schemaManager()->name(schema));
01677
01678 list.clear();
01679 createKateHlItemData(list);
01680
01681 for (KateHlItemData *p = list.first(); p != 0L; p = list.next())
01682 {
01683 QStringList s = config->readListEntry(p->name);
01684
01685
01686 if (s.count()>0)
01687 {
01688
01689 while(s.count()<9) s<<"";
01690 p->clear();
01691
01692 QString tmp=s[0]; if (!tmp.isEmpty()) p->defStyleNum=tmp.toInt();
01693
01694 QRgb col;
01695
01696 tmp=s[1]; if (!tmp.isEmpty()) {
01697 col=tmp.toUInt(0,16); p->setTextColor(col); }
01698
01699 tmp=s[2]; if (!tmp.isEmpty()) {
01700 col=tmp.toUInt(0,16); p->setSelectedTextColor(col); }
01701
01702 tmp=s[3]; if (!tmp.isEmpty()) p->setBold(tmp!="0");
01703
01704 tmp=s[4]; if (!tmp.isEmpty()) p->setItalic(tmp!="0");
01705
01706 tmp=s[5]; if (!tmp.isEmpty()) p->setStrikeOut(tmp!="0");
01707
01708 tmp=s[6]; if (!tmp.isEmpty()) p->setUnderline(tmp!="0");
01709
01710 tmp=s[7]; if (!tmp.isEmpty()) {
01711 col=tmp.toUInt(0,16); p->setBGColor(col); }
01712
01713 tmp=s[8]; if (!tmp.isEmpty()) {
01714 col=tmp.toUInt(0,16); p->setSelectedBGColor(col); }
01715
01716 }
01717 }
01718 }
01719
01726 void KateHighlighting::setKateHlItemDataList(uint schema, KateHlItemDataList &list)
01727 {
01728 KConfig *config = KateHlManager::self()->getKConfig();
01729 config->setGroup("Highlighting " + iName + " - Schema "
01730 + KateFactory::self()->schemaManager()->name(schema));
01731
01732 QStringList settings;
01733
01734 for (KateHlItemData *p = list.first(); p != 0L; p = list.next())
01735 {
01736 settings.clear();
01737 settings<<QString::number(p->defStyleNum,10);
01738 settings<<(p->itemSet(KateAttribute::TextColor)?QString::number(p->textColor().rgb(),16):"");
01739 settings<<(p->itemSet(KateAttribute::SelectedTextColor)?QString::number(p->selectedTextColor().rgb(),16):"");
01740 settings<<(p->itemSet(KateAttribute::Weight)?(p->bold()?"1":"0"):"");
01741 settings<<(p->itemSet(KateAttribute::Italic)?(p->italic()?"1":"0"):"");
01742 settings<<(p->itemSet(KateAttribute::StrikeOut)?(p->strikeOut()?"1":"0"):"");
01743 settings<<(p->itemSet(KateAttribute::Underline)?(p->underline()?"1":"0"):"");
01744 settings<<(p->itemSet(KateAttribute::BGColor)?QString::number(p->bgColor().rgb(),16):"");
01745 settings<<(p->itemSet(KateAttribute::SelectedBGColor)?QString::number(p->selectedBGColor().rgb(),16):"");
01746 settings<<"---";
01747 config->writeEntry(p->name,settings);
01748 }
01749 }
01750
01754 void KateHighlighting::use()
01755 {
01756 if (refCount == 0)
01757 init();
01758
01759 refCount++;
01760 }
01761
01765 void KateHighlighting::release()
01766 {
01767 refCount--;
01768
01769 if (refCount == 0)
01770 done();
01771 }
01772
01777 void KateHighlighting::init()
01778 {
01779 if (noHl)
01780 return;
01781
01782
01783 for (uint i=0; i < m_contexts.size(); ++i)
01784 delete m_contexts[i];
01785 m_contexts.clear ();
01786
01787 makeContextList();
01788 }
01789
01790
01795 void KateHighlighting::done()
01796 {
01797 if (noHl)
01798 return;
01799
01800
01801 for (uint i=0; i < m_contexts.size(); ++i)
01802 delete m_contexts[i];
01803 m_contexts.clear ();
01804
01805 internalIDList.clear();
01806 }
01807
01815 void KateHighlighting::createKateHlItemData(KateHlItemDataList &list)
01816 {
01817
01818 if (noHl)
01819 {
01820 list.append(new KateHlItemData(i18n("Normal Text"), KateHlItemData::dsNormal));
01821 return;
01822 }
01823
01824
01825 if (internalIDList.isEmpty())
01826 makeContextList();
01827
01828 list=internalIDList;
01829 }
01830
01834 void KateHighlighting::addToKateHlItemDataList()
01835 {
01836
01837 KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
01838 KateSyntaxContextData *data = KateHlManager::self()->syntax->getGroupInfo("highlighting","itemData");
01839
01840
01841 while (KateHlManager::self()->syntax->nextGroup(data))
01842 {
01843
01844 QString color = KateHlManager::self()->syntax->groupData(data,QString("color"));
01845 QString selColor = KateHlManager::self()->syntax->groupData(data,QString("selColor"));
01846 QString bold = KateHlManager::self()->syntax->groupData(data,QString("bold"));
01847 QString italic = KateHlManager::self()->syntax->groupData(data,QString("italic"));
01848 QString underline = KateHlManager::self()->syntax->groupData(data,QString("underline"));
01849 QString strikeOut = KateHlManager::self()->syntax->groupData(data,QString("strikeOut"));
01850 QString bgColor = KateHlManager::self()->syntax->groupData(data,QString("backgroundColor"));
01851 QString selBgColor = KateHlManager::self()->syntax->groupData(data,QString("selBackgroundColor"));
01852
01853 KateHlItemData* newData = new KateHlItemData(
01854 buildPrefix+KateHlManager::self()->syntax->groupData(data,QString("name")).simplifyWhiteSpace(),
01855 getDefStyleNum(KateHlManager::self()->syntax->groupData(data,QString("defStyleNum"))));
01856
01857
01858 if (!color.isEmpty()) newData->setTextColor(QColor(color));
01859 if (!selColor.isEmpty()) newData->setSelectedTextColor(QColor(selColor));
01860 if (!bold.isEmpty()) newData->setBold( IS_TRUE(bold) );
01861 if (!italic.isEmpty()) newData->setItalic( IS_TRUE(italic) );
01862
01863 if (!underline.isEmpty()) newData->setUnderline( IS_TRUE(underline) );
01864 if (!strikeOut.isEmpty()) newData->setStrikeOut( IS_TRUE(strikeOut) );
01865 if (!bgColor.isEmpty()) newData->setBGColor(QColor(bgColor));
01866 if (!selBgColor.isEmpty()) newData->setSelectedBGColor(QColor(selBgColor));
01867
01868 internalIDList.append(newData);
01869 }
01870
01871
01872 if (data)
01873 KateHlManager::self()->syntax->freeGroupInfo(data);
01874 }
01875
01886 int KateHighlighting::lookupAttrName(const QString& name, KateHlItemDataList &iDl)
01887 {
01888 for (uint i = 0; i < iDl.count(); i++)
01889 if (iDl.at(i)->name == buildPrefix+name)
01890 return i;
01891
01892 kdDebug(13010)<<"Couldn't resolve itemDataName:"<<name<<endl;
01893 return 0;
01894 }
01895
01909 KateHlItem *KateHighlighting::createKateHlItem(KateSyntaxContextData *data,
01910 KateHlItemDataList &iDl,
01911 QStringList *RegionList,
01912 QStringList *ContextNameList)
01913 {
01914
01915 if (noHl)
01916 return 0;
01917
01918
01919 QString dataname=KateHlManager::self()->syntax->groupItemData(data,QString(""));
01920
01921
01922 QString beginRegionStr=KateHlManager::self()->syntax->groupItemData(data,QString("beginRegion"));
01923 QString endRegionStr=KateHlManager::self()->syntax->groupItemData(data,QString("endRegion"));
01924
01925 signed char regionId=0;
01926 signed char regionId2=0;
01927
01928 if (!beginRegionStr.isEmpty())
01929 {
01930 regionId = RegionList->findIndex(beginRegionStr);
01931
01932 if (regionId==-1)
01933 {
01934 (*RegionList)<<beginRegionStr;
01935 regionId = RegionList->findIndex(beginRegionStr);
01936 }
01937
01938 regionId++;
01939
01940 kdDebug(13010) << "########### BEG REG: " << beginRegionStr << " NUM: " << regionId << endl;
01941 }
01942
01943 if (!endRegionStr.isEmpty())
01944 {
01945 regionId2 = RegionList->findIndex(endRegionStr);
01946
01947 if (regionId2==-1)
01948 {
01949 (*RegionList)<<endRegionStr;
01950 regionId2 = RegionList->findIndex(endRegionStr);
01951 }
01952
01953 regionId2 = -regionId2 - 1;
01954
01955 kdDebug(13010) << "########### END REG: " << endRegionStr << " NUM: " << regionId2 << endl;
01956 }
01957
01958 int attr = 0;
01959 QString tmpAttr=KateHlManager::self()->syntax->groupItemData(data,QString("attribute")).simplifyWhiteSpace();
01960 bool onlyConsume = tmpAttr.isEmpty();
01961
01962
01963 if (!onlyConsume)
01964 {
01965 if (QString("%1").arg(tmpAttr.toInt())==tmpAttr)
01966 {
01967 errorsAndWarnings+=i18n(
01968 "<B>%1</B>: Deprecated syntax. Attribute (%2) not addressed by symbolic name<BR>").
01969 arg(buildIdentifier).arg(tmpAttr);
01970 attr=tmpAttr.toInt();
01971 }
01972 else
01973 attr=lookupAttrName(tmpAttr,iDl);
01974 }
01975
01976
01977 int context = -1;
01978 QString unresolvedContext;
01979 QString tmpcontext=KateHlManager::self()->syntax->groupItemData(data,QString("context"));
01980 if (!tmpcontext.isEmpty())
01981 context=getIdFromString(ContextNameList, tmpcontext,unresolvedContext);
01982
01983
01984 char chr;
01985 if (! KateHlManager::self()->syntax->groupItemData(data,QString("char")).isEmpty())
01986 chr= (KateHlManager::self()->syntax->groupItemData(data,QString("char")).latin1())[0];
01987 else
01988 chr=0;
01989
01990
01991 QString stringdata=KateHlManager::self()->syntax->groupItemData(data,QString("String"));
01992
01993
01994 char chr1;
01995 if (! KateHlManager::self()->syntax->groupItemData(data,QString("char1")).isEmpty())
01996 chr1= (KateHlManager::self()->syntax->groupItemData(data,QString("char1")).latin1())[0];
01997 else
01998 chr1=0;
01999
02000
02001 bool insensitive = IS_TRUE( KateHlManager::self()->syntax->groupItemData(data,QString("insensitive")) );
02002
02003
02004 bool minimal = IS_TRUE( KateHlManager::self()->syntax->groupItemData(data,QString("minimal")) );
02005
02006
02007 bool lookAhead = IS_TRUE( KateHlManager::self()->syntax->groupItemData(data,QString("lookAhead")) );
02008
02009 bool dynamic= IS_TRUE(KateHlManager::self()->syntax->groupItemData(data,QString("dynamic")) );
02010
02011 bool firstNonSpace = IS_TRUE(KateHlManager::self()->syntax->groupItemData(data,QString("firstNonSpace")) );
02012
02013 int column = -1;
02014 QString colStr = KateHlManager::self()->syntax->groupItemData(data,QString("column"));
02015 if (!colStr.isEmpty())
02016 column = colStr.toInt();
02017
02018
02019 KateHlItem *tmpItem;
02020
02021 if (dataname=="keyword")
02022 {
02023 KateHlKeyword *keyword=new KateHlKeyword(attr,context,regionId,regionId2,casesensitive,
02024 m_additionalData[ buildIdentifier ]->deliminator);
02025
02026
02027 keyword->addList(KateHlManager::self()->syntax->finddata("highlighting",stringdata));
02028 tmpItem=keyword;
02029 }
02030 else if (dataname=="Float") tmpItem= (new KateHlFloat(attr,context,regionId,regionId2));
02031 else if (dataname=="Int") tmpItem=(new KateHlInt(attr,context,regionId,regionId2));
02032 else if (dataname=="DetectChar") tmpItem=(new KateHlCharDetect(attr,context,regionId,regionId2,chr));
02033 else if (dataname=="Detect2Chars") tmpItem=(new KateHl2CharDetect(attr,context,regionId,regionId2,chr,chr1));
02034 else if (dataname=="RangeDetect") tmpItem=(new KateHlRangeDetect(attr,context,regionId,regionId2, chr, chr1));
02035 else if (dataname=="LineContinue") tmpItem=(new KateHlLineContinue(attr,context,regionId,regionId2));
02036 else if (dataname=="StringDetect") tmpItem=(new KateHlStringDetect(attr,context,regionId,regionId2,stringdata,insensitive));
02037 else if (dataname=="AnyChar") tmpItem=(new KateHlAnyChar(attr,context,regionId,regionId2,stringdata));
02038 else if (dataname=="RegExpr") tmpItem=(new KateHlRegExpr(attr,context,regionId,regionId2,stringdata, insensitive, minimal));
02039 else if (dataname=="HlCChar") tmpItem= ( new KateHlCChar(attr,context,regionId,regionId2));
02040 else if (dataname=="HlCHex") tmpItem= (new KateHlCHex(attr,context,regionId,regionId2));
02041 else if (dataname=="HlCOct") tmpItem= (new KateHlCOct(attr,context,regionId,regionId2));
02042 else if (dataname=="HlCFloat") tmpItem= (new KateHlCFloat(attr,context,regionId,regionId2));
02043 else if (dataname=="HlCStringChar") tmpItem= (new KateHlCStringChar(attr,context,regionId,regionId2));
02044 else if (dataname=="DetectSpaces") tmpItem= (new KateHlDetectSpaces(attr,context,regionId,regionId2));
02045 else if (dataname=="DetectIdentifier") tmpItem= (new KateHlDetectIdentifier(attr,context,regionId,regionId2));
02046 else
02047 {
02048
02049 return 0;
02050 }
02051
02052
02053 tmpItem->lookAhead = lookAhead;
02054 tmpItem->dynamic = dynamic;
02055 tmpItem->firstNonSpace = firstNonSpace;
02056 tmpItem->column = column;
02057 tmpItem->onlyConsume = onlyConsume;
02058
02059 if (!unresolvedContext.isEmpty())
02060 {
02061 unresolvedContextReferences.insert(&(tmpItem->ctx),unresolvedContext);
02062 }
02063
02064 return tmpItem;
02065 }
02066
02067 QString KateHighlighting::hlKeyForAttrib( int i ) const
02068 {
02069
02070
02071 int k = 0;
02072 QMap<int,QString>::const_iterator it = m_hlIndex.constEnd();
02073 while ( it != m_hlIndex.constBegin() )
02074 {
02075 --it;
02076 k = it.key();
02077 if ( i >= k )
02078 break;
02079 }
02080 return it.data();
02081 }
02082
02083 bool KateHighlighting::isInWord( QChar c, int attrib ) const
02084 {
02085 return m_additionalData[ hlKeyForAttrib( attrib ) ]->deliminator.find(c) < 0
02086 && !c.isSpace() && c != '"' && c != '\'';
02087 }
02088
02089 bool KateHighlighting::canBreakAt( QChar c, int attrib ) const
02090 {
02091 static const QString& sq = KGlobal::staticQString("\"'");
02092 return (m_additionalData[ hlKeyForAttrib( attrib ) ]->wordWrapDeliminator.find(c) != -1) && (sq.find(c) == -1);
02093 }
02094
02095 signed char KateHighlighting::commentRegion(int attr) const {
02096 QString commentRegion=m_additionalData[ hlKeyForAttrib( attr ) ]->multiLineRegion;
02097 return (commentRegion.isEmpty()?0:(commentRegion.toShort()));
02098 }
02099
02100 bool KateHighlighting::canComment( int startAttrib, int endAttrib ) const
02101 {
02102 QString k = hlKeyForAttrib( startAttrib );
02103 return ( k == hlKeyForAttrib( endAttrib ) &&
02104 ( ( !m_additionalData[k]->multiLineCommentStart.isEmpty() && !m_additionalData[k]->multiLineCommentEnd.isEmpty() ) ||
02105 ! m_additionalData[k]->singleLineCommentMarker.isEmpty() ) );
02106 }
02107
02108 QString KateHighlighting::getCommentStart( int attrib ) const
02109 {
02110 return m_additionalData[ hlKeyForAttrib( attrib) ]->multiLineCommentStart;
02111 }
02112
02113 QString KateHighlighting::getCommentEnd( int attrib ) const
02114 {
02115 return m_additionalData[ hlKeyForAttrib( attrib ) ]->multiLineCommentEnd;
02116 }
02117
02118 QString KateHighlighting::getCommentSingleLineStart( int attrib ) const
02119 {
02120 return m_additionalData[ hlKeyForAttrib( attrib) ]->singleLineCommentMarker;
02121 }
02122
02123 KateHighlighting::CSLPos KateHighlighting::getCommentSingleLinePosition( int attrib ) const
02124 {
02125 return m_additionalData[ hlKeyForAttrib( attrib) ]->singleLineCommentPosition;
02126 }
02127
02128
02133 void KateHighlighting::readCommentConfig()
02134 {
02135 KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
02136 KateSyntaxContextData *data=KateHlManager::self()->syntax->getGroupInfo("general","comment");
02137
02138 QString cmlStart="", cmlEnd="", cmlRegion="", cslStart="";
02139 CSLPos cslPosition=CSLPosColumn0;
02140
02141 if (data)
02142 {
02143 while (KateHlManager::self()->syntax->nextGroup(data))
02144 {
02145 if (KateHlManager::self()->syntax->groupData(data,"name")=="singleLine")
02146 {
02147 cslStart=KateHlManager::self()->syntax->groupData(data,"start");
02148 QString cslpos=KateHlManager::self()->syntax->groupData(data,"position");
02149 if (cslpos=="afterwhitespace")
02150 cslPosition=CSLPosAfterWhitespace;
02151 else
02152 cslPosition=CSLPosColumn0;
02153 }
02154 else if (KateHlManager::self()->syntax->groupData(data,"name")=="multiLine")
02155 {
02156 cmlStart=KateHlManager::self()->syntax->groupData(data,"start");
02157 cmlEnd=KateHlManager::self()->syntax->groupData(data,"end");
02158 cmlRegion=KateHlManager::self()->syntax->groupData(data,"region");
02159 }
02160 }
02161
02162 KateHlManager::self()->syntax->freeGroupInfo(data);
02163 }
02164
02165 m_additionalData[buildIdentifier]->singleLineCommentMarker = cslStart;
02166 m_additionalData[buildIdentifier]->singleLineCommentPosition = cslPosition;
02167 m_additionalData[buildIdentifier]->multiLineCommentStart = cmlStart;
02168 m_additionalData[buildIdentifier]->multiLineCommentEnd = cmlEnd;
02169 m_additionalData[buildIdentifier]->multiLineRegion = cmlRegion;
02170 }
02171
02177 void KateHighlighting::readGlobalKeywordConfig()
02178 {
02179 deliminator = stdDeliminator;
02180
02181 kdDebug(13010)<<"readGlobalKeywordConfig:BEGIN"<<endl;
02182
02183 KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
02184 KateSyntaxContextData *data = KateHlManager::self()->syntax->getConfig("general","keywords");
02185
02186 if (data)
02187 {
02188 kdDebug(13010)<<"Found global keyword config"<<endl;
02189
02190 if ( IS_TRUE( KateHlManager::self()->syntax->groupItemData(data,QString("casesensitive")) ) )
02191 casesensitive=true;
02192 else
02193 casesensitive=false;
02194
02195
02196 weakDeliminator=(KateHlManager::self()->syntax->groupItemData(data,QString("weakDeliminator")));
02197
02198 kdDebug(13010)<<"weak delimiters are: "<<weakDeliminator<<endl;
02199
02200
02201 for (uint s=0; s < weakDeliminator.length(); s++)
02202 {
02203 int f = deliminator.find (weakDeliminator[s]);
02204
02205 if (f > -1)
02206 deliminator.remove (f, 1);
02207 }
02208
02209 QString addDelim = (KateHlManager::self()->syntax->groupItemData(data,QString("additionalDeliminator")));
02210
02211 if (!addDelim.isEmpty())
02212 deliminator=deliminator+addDelim;
02213
02214 KateHlManager::self()->syntax->freeGroupInfo(data);
02215 }
02216 else
02217 {
02218
02219 casesensitive=true;
02220 weakDeliminator=QString("");
02221 }
02222
02223 kdDebug(13010)<<"readGlobalKeywordConfig:END"<<endl;
02224
02225 kdDebug(13010)<<"delimiterCharacters are: "<<deliminator<<endl;
02226
02227 m_additionalData[buildIdentifier]->deliminator = deliminator;
02228 }
02229
02240 void KateHighlighting::readWordWrapConfig()
02241 {
02242
02243 kdDebug(13010)<<"readWordWrapConfig:BEGIN"<<endl;
02244
02245 KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
02246 KateSyntaxContextData *data = KateHlManager::self()->syntax->getConfig("general","keywords");
02247
02248 QString wordWrapDeliminator = stdDeliminator;
02249 if (data)
02250 {
02251 kdDebug(13010)<<"Found global keyword config"<<endl;
02252
02253 wordWrapDeliminator = (KateHlManager::self()->syntax->groupItemData(data,QString("wordWrapDeliminator")));
02254
02255 if ( wordWrapDeliminator.length() == 0 ) wordWrapDeliminator = deliminator;
02256
02257 kdDebug(13010) << "word wrap deliminators are " << wordWrapDeliminator << endl;
02258
02259 KateHlManager::self()->syntax->freeGroupInfo(data);
02260 }
02261
02262 kdDebug(13010)<<"readWordWrapConfig:END"<<endl;
02263
02264 m_additionalData[buildIdentifier]->wordWrapDeliminator = wordWrapDeliminator;
02265 }
02266
02267 void KateHighlighting::readIndentationConfig()
02268 {
02269 m_indentation = "";
02270
02271 KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
02272 KateSyntaxContextData *data = KateHlManager::self()->syntax->getConfig("general","indentation");
02273
02274 if (data)
02275 {
02276 m_indentation = (KateHlManager::self()->syntax->groupItemData(data,QString("mode")));
02277
02278 KateHlManager::self()->syntax->freeGroupInfo(data);
02279 }
02280 }
02281
02282 void KateHighlighting::readFoldingConfig()
02283 {
02284
02285 kdDebug(13010)<<"readfoldignConfig:BEGIN"<<endl;
02286
02287 KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
02288 KateSyntaxContextData *data = KateHlManager::self()->syntax->getConfig("general","folding");
02289
02290 if (data)
02291 {
02292 kdDebug(13010)<<"Found global keyword config"<<endl;
02293
02294 if ( IS_TRUE( KateHlManager::self()->syntax->groupItemData(data,QString("indentationsensitive")) ) )
02295 m_foldingIndentationSensitive=true;
02296 else
02297 m_foldingIndentationSensitive=false;
02298
02299 KateHlManager::self()->syntax->freeGroupInfo(data);
02300 }
02301 else
02302 {
02303
02304 m_foldingIndentationSensitive = false;
02305 }
02306
02307 kdDebug(13010)<<"readfoldingConfig:END"<<endl;
02308
02309 kdDebug(13010)<<"############################ use indent for fold are: "<<m_foldingIndentationSensitive<<endl;
02310 }
02311
02312 void KateHighlighting::createContextNameList(QStringList *ContextNameList,int ctx0)
02313 {
02314 kdDebug(13010)<<"creatingContextNameList:BEGIN"<<endl;
02315
02316 if (ctx0 == 0)
02317 ContextNameList->clear();
02318
02319 KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
02320
02321 KateSyntaxContextData *data=KateHlManager::self()->syntax->getGroupInfo("highlighting","context");
02322
02323 int id=ctx0;
02324
02325 if (data)
02326 {
02327 while (KateHlManager::self()->syntax->nextGroup(data))
02328 {
02329 QString tmpAttr=KateHlManager::self()->syntax->groupData(data,QString("name")).simplifyWhiteSpace();
02330 if (tmpAttr.isEmpty())
02331 {
02332 tmpAttr=QString("!KATE_INTERNAL_DUMMY! %1").arg(id);
02333 errorsAndWarnings +=i18n("<B>%1</B>: Deprecated syntax. Context %2 has no symbolic name<BR>").arg(buildIdentifier).arg(id-ctx0);
02334 }
02335 else tmpAttr=buildPrefix+tmpAttr;
02336 (*ContextNameList)<<tmpAttr;
02337 id++;
02338 }
02339 KateHlManager::self()->syntax->freeGroupInfo(data);
02340 }
02341 kdDebug(13010)<<"creatingContextNameList:END"<<endl;
02342
02343 }
02344
02345 int KateHighlighting::getIdFromString(QStringList *ContextNameList, QString tmpLineEndContext, QString &unres)
02346 {
02347 unres="";
02348 int context;
02349 if ((tmpLineEndContext=="#stay") || (tmpLineEndContext.simplifyWhiteSpace().isEmpty()))
02350 context=-1;
02351
02352 else if (tmpLineEndContext.startsWith("#pop"))
02353 {
02354 context=-1;
02355 for(;tmpLineEndContext.startsWith("#pop");context--)
02356 {
02357 tmpLineEndContext.remove(0,4);
02358 kdDebug(13010)<<"#pop found"<<endl;
02359 }
02360 }
02361
02362 else if ( tmpLineEndContext.startsWith("##"))
02363 {
02364 QString tmp=tmpLineEndContext.right(tmpLineEndContext.length()-2);
02365 if (!embeddedHls.contains(tmp)) embeddedHls.insert(tmp,KateEmbeddedHlInfo());
02366 unres=tmp;
02367 context=0;
02368 }
02369
02370 else
02371 {
02372 context=ContextNameList->findIndex(buildPrefix+tmpLineEndContext);
02373 if (context==-1)
02374 {
02375 context=tmpLineEndContext.toInt();
02376 errorsAndWarnings+=i18n(
02377 "<B>%1</B>:Deprecated syntax. Context %2 not addressed by a symbolic name"
02378 ).arg(buildIdentifier).arg(tmpLineEndContext);
02379 }
02380
02381
02382 }
02383 return context;
02384 }
02385
02391 void KateHighlighting::makeContextList()
02392 {
02393 if (noHl)
02394 return;
02395
02396 embeddedHls.clear();
02397 unresolvedContextReferences.clear();
02398 RegionList.clear();
02399 ContextNameList.clear();
02400
02401
02402
02403 embeddedHls.insert(iName,KateEmbeddedHlInfo());
02404
02405 bool something_changed;
02406
02407 startctx=base_startctx=0;
02408
02409 building=true;
02410
02411 do
02412 {
02413 kdDebug(13010)<<"**************** Outter loop in make ContextList"<<endl;
02414 kdDebug(13010)<<"**************** Hl List count:"<<embeddedHls.count()<<endl;
02415 something_changed=false;
02416 for (KateEmbeddedHlInfos::const_iterator it=embeddedHls.begin(); it!=embeddedHls.end();++it)
02417 {
02418 if (!it.data().loaded)
02419 {
02420 kdDebug(13010)<<"**************** Inner loop in make ContextList"<<endl;
02421 QString identifierToUse;
02422 kdDebug(13010)<<"Trying to open highlighting definition file: "<< it.key()<<endl;
02423 if (iName==it.key())
02424 identifierToUse=identifier;
02425 else
02426 identifierToUse=KateHlManager::self()->identifierForName(it.key());
02427
02428 kdDebug(13010)<<"Location is:"<< identifierToUse<<endl;
02429
02430 buildPrefix=it.key()+':';
02431
02432
02433 if (identifierToUse.isEmpty() )
02434 kdDebug(13010)<<"OHOH, unknown highlighting description referenced"<<endl;
02435
02436 kdDebug(13010)<<"setting ("<<it.key()<<") to loaded"<<endl;
02437
02438
02439 it=embeddedHls.insert(it.key(),KateEmbeddedHlInfo(true,startctx));
02440
02441 buildContext0Offset=startctx;
02442
02443 startctx=addToContextList(identifierToUse,startctx);
02444
02445 if (noHl) return;
02446
02447 base_startctx = startctx;
02448 something_changed=true;
02449 }
02450 }
02451 } while (something_changed);
02452
02453
02454
02455
02456
02457 kdDebug(13010)<<"Unresolved contexts, which need attention: "<<unresolvedContextReferences.count()<<endl;
02458
02459
02460 for (KateHlUnresolvedCtxRefs::iterator unresIt=unresolvedContextReferences.begin();
02461 unresIt!=unresolvedContextReferences.end();++unresIt)
02462 {
02463
02464 KateEmbeddedHlInfos::const_iterator hlIt=embeddedHls.find(unresIt.data());
02465 if (hlIt!=embeddedHls.end())
02466 *(unresIt.key())=hlIt.data().context0;
02467 }
02468
02469
02470
02471
02472
02473 handleKateHlIncludeRules();
02474
02475 embeddedHls.clear();
02476 unresolvedContextReferences.clear();
02477 RegionList.clear();
02478 ContextNameList.clear();
02479
02480
02481
02482 if (!errorsAndWarnings.isEmpty())
02483 KMessageBox::detailedSorry(0L,i18n(
02484 "There were warning(s) and/or error(s) while parsing the syntax "
02485 "highlighting configuration."),
02486 errorsAndWarnings, i18n("Kate Syntax Highlighting Parser"));
02487
02488
02489 building=false;
02490 }
02491
02492 void KateHighlighting::handleKateHlIncludeRules()
02493 {
02494
02495 kdDebug(13010)<<"KateHlIncludeRules, which need attention: " <<includeRules.count()<<endl;
02496 if (includeRules.isEmpty()) return;
02497
02498 buildPrefix="";
02499 QString dummy;
02500
02501
02502
02503
02504
02505
02506
02507 for (KateHlIncludeRules::iterator it=includeRules.begin();it!=includeRules.end();)
02508 {
02509 if ((*it)->incCtx==-1)
02510 {
02511
02512 if ((*it)->incCtxN.isEmpty())
02513 {
02514
02515
02516 KateHlIncludeRules::iterator it1=it;
02517 ++it1;
02518 delete (*it);
02519 includeRules.remove(it);
02520 it=it1;
02521 }
02522 else
02523 {
02524
02525 (*it)->incCtx=getIdFromString(&ContextNameList,(*it)->incCtxN,dummy);
02526 kdDebug(13010)<<"Resolved "<<(*it)->incCtxN<< " to "<<(*it)->incCtx<<" for include rule"<<endl;
02527
02528 }
02529 }
02530 else ++it;
02531 }
02532
02533
02534
02535
02536
02537
02538
02539 while (!includeRules.isEmpty())
02540 handleKateHlIncludeRulesRecursive(includeRules.begin(),&includeRules);
02541 }
02542
02543 void KateHighlighting::handleKateHlIncludeRulesRecursive(KateHlIncludeRules::iterator it, KateHlIncludeRules *list)
02544 {
02545 if (it==list->end()) return;
02546
02547 KateHlIncludeRules::iterator it1=it;
02548 int ctx=(*it1)->ctx;
02549
02550
02551
02552
02553
02554
02555
02556
02557
02558 while ((it!=list->end()) && ((*it)->ctx==ctx))
02559 {
02560 it1=it;
02561 ++it;
02562 }
02563
02564
02565 while ((it1!=list->end()) && ((*it1)->ctx==ctx))
02566 {
02567 int ctx1=(*it1)->incCtx;
02568
02569
02570 for (KateHlIncludeRules::iterator it2=list->begin();it2!=list->end();++it2)
02571 {
02572 if ((*it2)->ctx==ctx1)
02573 {
02574
02575
02576 handleKateHlIncludeRulesRecursive(it2,list);
02577 break;
02578 }
02579 }
02580
02581
02582 KateHlContext *dest=m_contexts[ctx];
02583 KateHlContext *src=m_contexts[ctx1];
02584
02585
02586
02587
02588
02589 if ( (*it1)->includeAttrib )
02590 dest->attr = src->attr;
02591
02592
02593 int p=(*it1)->pos;
02594
02595
02596 int oldLen = dest->items.size();
02597 uint itemsToInsert = src->items.size();
02598
02599
02600 dest->items.resize (oldLen + itemsToInsert);
02601
02602
02603 for (int i=oldLen-1; i >= p; --i)
02604 dest->items[i+itemsToInsert] = dest->items[i];
02605
02606
02607 for (uint i=0; i < itemsToInsert; ++i )
02608 dest->items[p+i] = src->items[i];
02609
02610 it=it1;
02611 --it1;
02612 delete (*it);
02613 list->remove(it);
02614 }
02615 }
02616
02622 int KateHighlighting::addToContextList(const QString &ident, int ctx0)
02623 {
02624 kdDebug(13010)<<"=== Adding hl with ident '"<<ident<<"'"<<endl;
02625
02626 buildIdentifier=ident;
02627 KateSyntaxContextData *data, *datasub;
02628 KateHlItem *c;
02629
02630 QString dummy;
02631
02632
02633 if (!KateHlManager::self()->syntax->setIdentifier(ident))
02634 {
02635 noHl=true;
02636 KMessageBox::information(0L,i18n(
02637 "Since there has been an error parsing the highlighting description, "
02638 "this highlighting will be disabled"));
02639 return 0;
02640 }
02641
02642
02643 if (identifier == ident)
02644 {
02645 readIndentationConfig ();
02646 }
02647
02648 RegionList<<"!KateInternal_TopLevel!";
02649
02650 m_hlIndex[internalIDList.count()] = ident;
02651 m_additionalData.insert( ident, new HighlightPropertyBag );
02652
02653
02654 readCommentConfig();
02655 readGlobalKeywordConfig();
02656 readWordWrapConfig();
02657
02658 readFoldingConfig ();
02659
02660 QString ctxName;
02661
02662
02663
02664 addToKateHlItemDataList();
02665 KateHlItemDataList iDl = internalIDList;
02666
02667 createContextNameList(&ContextNameList,ctx0);
02668
02669
02670 kdDebug(13010)<<"Parsing Context structure"<<endl;
02671
02672 data=KateHlManager::self()->syntax->getGroupInfo("highlighting","context");
02673 uint i=buildContext0Offset;
02674 if (data)
02675 {
02676 while (KateHlManager::self()->syntax->nextGroup(data))
02677 {
02678 kdDebug(13010)<<"Found a context in file, building structure now"<<endl;
02679
02680 QString tmpAttr=KateHlManager::self()->syntax->groupData(data,QString("attribute")).simplifyWhiteSpace();
02681 int attr;
02682 if (QString("%1").arg(tmpAttr.toInt())==tmpAttr)
02683 attr=tmpAttr.toInt();
02684 else
02685 attr=lookupAttrName(tmpAttr,iDl);
02686
02687
02688 ctxName=buildPrefix+KateHlManager::self()->syntax->groupData(data,QString("lineEndContext")).simplifyWhiteSpace();
02689
02690 QString tmpLineEndContext=KateHlManager::self()->syntax->groupData(data,QString("lineEndContext")).simplifyWhiteSpace();
02691 int context;
02692
02693 context=getIdFromString(&ContextNameList, tmpLineEndContext,dummy);
02694
02695 QString tmpNIBF = KateHlManager::self()->syntax->groupData(data, QString("noIndentationBasedFolding") );
02696 bool noIndentationBasedFolding=IS_TRUE(tmpNIBF);
02697
02698
02699 bool ft = false;
02700 int ftc = 0;
02701 if ( i > 0 )
02702 {
02703 QString tmpFt = KateHlManager::self()->syntax->groupData(data, QString("fallthrough") );
02704 if ( IS_TRUE(tmpFt) )
02705 ft = true;
02706 if ( ft )
02707 {
02708 QString tmpFtc = KateHlManager::self()->syntax->groupData( data, QString("fallthroughContext") );
02709
02710 ftc=getIdFromString(&ContextNameList, tmpFtc,dummy);
02711 if (ftc == -1) ftc =0;
02712
02713 kdDebug(13010)<<"Setting fall through context (context "<<i<<"): "<<ftc<<endl;
02714 }
02715 }
02716
02717
02718 bool dynamic = false;
02719 QString tmpDynamic = KateHlManager::self()->syntax->groupData(data, QString("dynamic") );
02720 if ( tmpDynamic.lower() == "true" || tmpDynamic.toInt() == 1 )
02721 dynamic = true;
02722
02723 KateHlContext *ctxNew = new KateHlContext (
02724 ident,
02725 attr,
02726 context,
02727 (KateHlManager::self()->syntax->groupData(data,QString("lineBeginContext"))).isEmpty()?-1:
02728 (KateHlManager::self()->syntax->groupData(data,QString("lineBeginContext"))).toInt(),
02729 ft, ftc, dynamic,noIndentationBasedFolding);
02730
02731 m_contexts.push_back (ctxNew);
02732
02733 kdDebug(13010) << "INDEX: " << i << " LENGTH " << m_contexts.size()-1 << endl;
02734
02735
02736 while (KateHlManager::self()->syntax->nextItem(data))
02737 {
02738
02739
02740
02741
02742 QString tag = KateHlManager::self()->syntax->groupItemData(data,QString(""));
02743 if ( tag == "IncludeRules" )
02744 {
02745 QString incCtx = KateHlManager::self()->syntax->groupItemData( data, QString("context"));
02746 QString incAttrib = KateHlManager::self()->syntax->groupItemData( data, QString("includeAttrib"));
02747 bool includeAttrib = IS_TRUE( incAttrib );
02748
02749 if (incCtx.startsWith("##") || (!incCtx.startsWith("#")))
02750 {
02751
02752 if (!incCtx.startsWith("#"))
02753 {
02754
02755 incCtx=buildPrefix+incCtx.simplifyWhiteSpace();
02756 includeRules.append(new KateHlIncludeRule(i,m_contexts[i]->items.count(),incCtx, includeAttrib));
02757 }
02758 else
02759 {
02760
02761 kdDebug(13010)<<"Cross highlight reference <IncludeRules>"<<endl;
02762 KateHlIncludeRule *ir=new KateHlIncludeRule(i,m_contexts[i]->items.count(),"",includeAttrib);
02763
02764
02765 if (!embeddedHls.contains(incCtx.right(incCtx.length()-2)))
02766 embeddedHls.insert(incCtx.right(incCtx.length()-2),KateEmbeddedHlInfo());
02767
02768 unresolvedContextReferences.insert(&(ir->incCtx),
02769 incCtx.right(incCtx.length()-2));
02770
02771 includeRules.append(ir);
02772 }
02773 }
02774
02775 continue;
02776 }
02777
02778 #if 0
02779 QString tag = KateHlManager::self()->syntax->groupKateHlItemData(data,QString(""));
02780 if ( tag == "IncludeRules" ) {
02781
02782
02783
02784 int ctxId = getIdFromString(&ContextNameList,
02785 KateHlManager::self()->syntax->groupKateHlItemData( data, QString("context")),dummy);
02786 if ( ctxId > -1) {
02787 kdDebug(13010)<<"makeContextList["<<i<<"]: including all items of context "<<ctxId<<endl;
02788 if ( ctxId < (int) i ) {
02789 for ( c = m_contexts[ctxId]->items.first(); c; c = m_contexts[ctxId]->items.next() )
02790 m_contexts[i]->items.append(c);
02791 }
02792 else
02793 kdDebug(13010)<<"Context "<<ctxId<<"not defined. You can not include the rules of an undefined context"<<endl;
02794 }
02795 continue;
02796 }
02797 #endif
02798 c=createKateHlItem(data,iDl,&RegionList,&ContextNameList);
02799 if (c)
02800 {
02801 m_contexts[i]->items.append(c);
02802
02803
02804
02805 datasub=KateHlManager::self()->syntax->getSubItems(data);
02806 bool tmpbool;
02807 if (tmpbool=KateHlManager::self()->syntax->nextItem(datasub))
02808 {
02809 for (;tmpbool;tmpbool=KateHlManager::self()->syntax->nextItem(datasub))
02810 {
02811 c->subItems.resize (c->subItems.size()+1);
02812 c->subItems[c->subItems.size()-1] = createKateHlItem(datasub,iDl,&RegionList,&ContextNameList);
02813 } }
02814 KateHlManager::self()->syntax->freeGroupInfo(datasub);
02815
02816 }
02817 }
02818 i++;
02819 }
02820 }
02821
02822 KateHlManager::self()->syntax->freeGroupInfo(data);
02823
02824 if (RegionList.count()!=1)
02825 folding=true;
02826
02827 folding = folding || m_foldingIndentationSensitive;
02828
02829
02830 if (!m_additionalData[ ident ]->multiLineRegion.isEmpty()) {
02831 long commentregionid=RegionList.findIndex( m_additionalData[ ident ]->multiLineRegion );
02832 if (-1==commentregionid) {
02833 errorsAndWarnings+=i18n(
02834 "<B>%1</B>: Specified multiline comment region (%2) could not be resolved<BR>"
02835 ).arg(buildIdentifier).arg( m_additionalData[ ident ]->multiLineRegion );
02836 m_additionalData[ ident ]->multiLineRegion = QString();
02837 kdDebug(13010)<<"ERROR comment region attribute could not be resolved"<<endl;
02838
02839 } else {
02840 m_additionalData[ ident ]->multiLineRegion=QString::number(commentregionid+1);
02841 kdDebug(13010)<<"comment region resolved to:"<<m_additionalData[ ident ]->multiLineRegion<<endl;
02842 }
02843 }
02844
02845 return i;
02846 }
02847
02848 void KateHighlighting::clearAttributeArrays ()
02849 {
02850 for ( QIntDictIterator< QMemArray<KateAttribute> > it( m_attributeArrays ); it.current(); ++it )
02851 {
02852
02853 KateAttributeList defaultStyleList;
02854 defaultStyleList.setAutoDelete(true);
02855 KateHlManager::self()->getDefaults(it.currentKey(), defaultStyleList);
02856
02857 KateHlItemDataList itemDataList;
02858 getKateHlItemDataList(it.currentKey(), itemDataList);
02859
02860 uint nAttribs = itemDataList.count();
02861 QMemArray<KateAttribute> *array = it.current();
02862 array->resize (nAttribs);
02863
02864 for (uint z = 0; z < nAttribs; z++)
02865 {
02866 KateHlItemData *itemData = itemDataList.at(z);
02867 KateAttribute n = *defaultStyleList.at(itemData->defStyleNum);
02868
02869 if (itemData && itemData->isSomethingSet())
02870 n += *itemData;
02871
02872 array->at(z) = n;
02873 }
02874 }
02875 }
02876
02877 QMemArray<KateAttribute> *KateHighlighting::attributes (uint schema)
02878 {
02879 QMemArray<KateAttribute> *array;
02880
02881
02882 if ((array = m_attributeArrays[schema]))
02883 return array;
02884
02885
02886 if (!KateFactory::self()->schemaManager()->validSchema(schema))
02887 {
02888
02889 return attributes (0);
02890 }
02891
02892
02893 KateAttributeList defaultStyleList;
02894 defaultStyleList.setAutoDelete(true);
02895 KateHlManager::self()->getDefaults(schema, defaultStyleList);
02896
02897 KateHlItemDataList itemDataList;
02898 getKateHlItemDataList(schema, itemDataList);
02899
02900 uint nAttribs = itemDataList.count();
02901 array = new QMemArray<KateAttribute> (nAttribs);
02902
02903 for (uint z = 0; z < nAttribs; z++)
02904 {
02905 KateHlItemData *itemData = itemDataList.at(z);
02906 KateAttribute n = *defaultStyleList.at(itemData->defStyleNum);
02907
02908 if (itemData && itemData->isSomethingSet())
02909 n += *itemData;
02910
02911 array->at(z) = n;
02912 }
02913
02914 m_attributeArrays.insert(schema, array);
02915
02916 return array;
02917 }
02918
02919 void KateHighlighting::getKateHlItemDataListCopy (uint schema, KateHlItemDataList &outlist)
02920 {
02921 KateHlItemDataList itemDataList;
02922 getKateHlItemDataList(schema, itemDataList);
02923
02924 outlist.clear ();
02925 outlist.setAutoDelete (true);
02926 for (uint z=0; z < itemDataList.count(); z++)
02927 outlist.append (new KateHlItemData (*itemDataList.at(z)));
02928 }
02929
02930
02931
02932
02933 KateHlManager::KateHlManager()
02934 : QObject()
02935 , m_config ("katesyntaxhighlightingrc", false, false)
02936 , commonSuffixes (QStringList::split(";", ".orig;.new;~;.bak;.BAK"))
02937 , syntax (new KateSyntaxDocument())
02938 , dynamicCtxsCount(0)
02939 , forceNoDCReset(false)
02940 {
02941 hlList.setAutoDelete(true);
02942 hlDict.setAutoDelete(false);
02943
02944 KateSyntaxModeList modeList = syntax->modeList();
02945 for (uint i=0; i < modeList.count(); i++)
02946 {
02947 KateHighlighting *hl = new KateHighlighting(modeList[i]);
02948
02949 uint insert = 0;
02950 for (; insert <= hlList.count(); insert++)
02951 {
02952 if (insert == hlList.count())
02953 break;
02954
02955 if ( QString(hlList.at(insert)->section() + hlList.at(insert)->nameTranslated()).lower()
02956 > QString(hl->section() + hl->nameTranslated()).lower() )
02957 break;
02958 }
02959
02960 hlList.insert (insert, hl);
02961 hlDict.insert (hl->name(), hl);
02962 }
02963
02964
02965 KateHighlighting *hl = new KateHighlighting(0);
02966 hlList.prepend (hl);
02967 hlDict.insert (hl->name(), hl);
02968
02969 lastCtxsReset.start();
02970 }
02971
02972 KateHlManager::~KateHlManager()
02973 {
02974 delete syntax;
02975 }
02976
02977 static KStaticDeleter<KateHlManager> sdHlMan;
02978
02979 KateHlManager *KateHlManager::self()
02980 {
02981 if ( !s_self )
02982 sdHlMan.setObject(s_self, new KateHlManager ());
02983
02984 return s_self;
02985 }
02986
02987 KateHighlighting *KateHlManager::getHl(int n)
02988 {
02989 if (n < 0 || n >= (int) hlList.count())
02990 n = 0;
02991
02992 return hlList.at(n);
02993 }
02994
02995 int KateHlManager::nameFind(const QString &name)
02996 {
02997 int z (hlList.count() - 1);
02998 for (; z > 0; z--)
02999 if (hlList.at(z)->name() == name)
03000 return z;
03001
03002 return z;
03003 }
03004
03005 int KateHlManager::detectHighlighting (KateDocument *doc)
03006 {
03007 int hl = wildcardFind( doc->url().filename() );
03008 if ( hl < 0 )
03009 hl = mimeFind ( doc );
03010
03011 return hl;
03012 }
03013
03014 int KateHlManager::wildcardFind(const QString &fileName)
03015 {
03016 int result = -1;
03017 if ((result = realWildcardFind(fileName)) != -1)
03018 return result;
03019
03020 int length = fileName.length();
03021 QString backupSuffix = KateDocumentConfig::global()->backupSuffix();
03022 if (fileName.endsWith(backupSuffix)) {
03023 if ((result = realWildcardFind(fileName.left(length - backupSuffix.length()))) != -1)
03024 return result;
03025 }
03026
03027 for (QStringList::Iterator it = commonSuffixes.begin(); it != commonSuffixes.end(); ++it) {
03028 if (*it != backupSuffix && fileName.endsWith(*it)) {
03029 if ((result = realWildcardFind(fileName.left(length - (*it).length()))) != -1)
03030 return result;
03031 }
03032 }
03033
03034 return -1;
03035 }
03036
03037 int KateHlManager::realWildcardFind(const QString &fileName)
03038 {
03039 static QRegExp sep("\\s*;\\s*");
03040
03041 QPtrList<KateHighlighting> highlights;
03042
03043 for (KateHighlighting *highlight = hlList.first(); highlight != 0L; highlight = hlList.next()) {
03044 highlight->loadWildcards();
03045
03046 for (QStringList::Iterator it = highlight->getPlainExtensions().begin(); it != highlight->getPlainExtensions().end(); ++it)
03047 if (fileName.endsWith((*it)))
03048 highlights.append(highlight);
03049
03050 for (int i = 0; i < (int)highlight->getRegexpExtensions().count(); i++) {
03051 QRegExp re = highlight->getRegexpExtensions()[i];
03052 if (re.exactMatch(fileName))
03053 highlights.append(highlight);
03054 }
03055 }
03056
03057 if ( !highlights.isEmpty() )
03058 {
03059 int pri = -1;
03060 int hl = -1;
03061
03062 for (KateHighlighting *highlight = highlights.first(); highlight != 0L; highlight = highlights.next())
03063 {
03064 if (highlight->priority() > pri)
03065 {
03066 pri = highlight->priority();
03067 hl = hlList.findRef (highlight);
03068 }
03069 }
03070 return hl;
03071 }
03072
03073 return -1;
03074 }
03075
03076 int KateHlManager::mimeFind( KateDocument *doc )
03077 {
03078 static QRegExp sep("\\s*;\\s*");
03079
03080 KMimeType::Ptr mt = doc->mimeTypeForContent();
03081
03082 QPtrList<KateHighlighting> highlights;
03083
03084 for (KateHighlighting *highlight = hlList.first(); highlight != 0L; highlight = hlList.next())
03085 {
03086 QStringList l = QStringList::split( sep, highlight->getMimetypes() );
03087
03088 for( QStringList::Iterator it = l.begin(); it != l.end(); ++it )
03089 {
03090 if ( *it == mt->name() )
03091 highlights.append (highlight);
03092 }
03093 }
03094
03095 if ( !highlights.isEmpty() )
03096 {
03097 int pri = -1;
03098 int hl = -1;
03099
03100 for (KateHighlighting *highlight = highlights.first(); highlight != 0L; highlight = highlights.next())
03101 {
03102 if (highlight->priority() > pri)
03103 {
03104 pri = highlight->priority();
03105 hl = hlList.findRef (highlight);
03106 }
03107 }
03108
03109 return hl;
03110 }
03111
03112 return -1;
03113 }
03114
03115 uint KateHlManager::defaultStyles()
03116 {
03117 return 14;
03118 }
03119
03120 QString KateHlManager::defaultStyleName(int n, bool translateNames)
03121 {
03122 static QStringList names;
03123 static QStringList translatedNames;
03124
03125 if (names.isEmpty())
03126 {
03127 names << "Normal";
03128 names << "Keyword";
03129 names << "Data Type";
03130 names << "Decimal/Value";
03131 names << "Base-N Integer";
03132 names << "Floating Point";
03133 names << "Character";
03134 names << "String";
03135 names << "Comment";
03136 names << "Others";
03137 names << "Alert";
03138 names << "Function";
03139
03140 names << "Region Marker";
03141
03142 names << "Error";
03143
03144 translatedNames << i18n("Normal");
03145 translatedNames << i18n("Keyword");
03146 translatedNames << i18n("Data Type");
03147 translatedNames << i18n("Decimal/Value");
03148 translatedNames << i18n("Base-N Integer");
03149 translatedNames << i18n("Floating Point");
03150 translatedNames << i18n("Character");
03151 translatedNames << i18n("String");
03152 translatedNames << i18n("Comment");
03153 translatedNames << i18n("Others");
03154 translatedNames << i18n("Alert");
03155 translatedNames << i18n("Function");
03156
03157 translatedNames << i18n("Region Marker");
03158
03159 translatedNames << i18n("Error");
03160 }
03161
03162 return translateNames ? translatedNames[n] : names[n];
03163 }
03164
03165 void KateHlManager::getDefaults(uint schema, KateAttributeList &list)
03166 {
03167 list.setAutoDelete(true);
03168
03169 KateAttribute* normal = new KateAttribute();
03170 normal->setTextColor(Qt::black);
03171 normal->setSelectedTextColor(Qt::white);
03172 list.append(normal);
03173
03174 KateAttribute* keyword = new KateAttribute();
03175 keyword->setTextColor(Qt::black);
03176 keyword->setSelectedTextColor(Qt::white);
03177 keyword->setBold(true);
03178 list.append(keyword);
03179
03180 KateAttribute* dataType = new KateAttribute();
03181 dataType->setTextColor(Qt::darkRed);
03182 dataType->setSelectedTextColor(Qt::white);
03183 list.append(dataType);
03184
03185 KateAttribute* decimal = new KateAttribute();
03186 decimal->setTextColor(Qt::blue);
03187 decimal->setSelectedTextColor(Qt::cyan);
03188 list.append(decimal);
03189
03190 KateAttribute* basen = new KateAttribute();
03191 basen->setTextColor(Qt::darkCyan);
03192 basen->setSelectedTextColor(Qt::cyan);
03193 list.append(basen);
03194
03195 KateAttribute* floatAttribute = new KateAttribute();
03196 floatAttribute->setTextColor(Qt::darkMagenta);
03197 floatAttribute->setSelectedTextColor(Qt::cyan);
03198 list.append(floatAttribute);
03199
03200 KateAttribute* charAttribute = new KateAttribute();
03201 charAttribute->setTextColor(Qt::magenta);
03202 charAttribute->setSelectedTextColor(Qt::magenta);
03203 list.append(charAttribute);
03204
03205 KateAttribute* string = new KateAttribute();
03206 string->setTextColor(QColor::QColor("#D00"));
03207 string->setSelectedTextColor(Qt::red);
03208 list.append(string);
03209
03210 KateAttribute* comment = new KateAttribute();
03211 comment->setTextColor(Qt::darkGray);
03212 comment->setSelectedTextColor(Qt::gray);
03213 comment->setItalic(true);
03214 list.append(comment);
03215
03216 KateAttribute* others = new KateAttribute();
03217 others->setTextColor(Qt::darkGreen);
03218 others->setSelectedTextColor(Qt::green);
03219 list.append(others);
03220
03221 KateAttribute* alert = new KateAttribute();
03222 alert->setTextColor(Qt::black);
03223 alert->setSelectedTextColor( QColor::QColor("#FCC") );
03224 alert->setBold(true);
03225 alert->setBGColor( QColor::QColor("#FCC") );
03226 list.append(alert);
03227
03228 KateAttribute* functionAttribute = new KateAttribute();
03229 functionAttribute->setTextColor(Qt::darkBlue);
03230 functionAttribute->setSelectedTextColor(Qt::white);
03231 list.append(functionAttribute);
03232
03233 KateAttribute* regionmarker = new KateAttribute();
03234 regionmarker->setTextColor(Qt::white);
03235 regionmarker->setBGColor(Qt::gray);
03236 regionmarker->setSelectedTextColor(Qt::gray);
03237 list.append(regionmarker);
03238
03239 KateAttribute* error = new KateAttribute();
03240 error->setTextColor(Qt::red);
03241 error->setUnderline(true);
03242 error->setSelectedTextColor(Qt::red);
03243 list.append(error);
03244
03245 KConfig *config = KateHlManager::self()->self()->getKConfig();
03246 config->setGroup("Default Item Styles - Schema " + KateFactory::self()->schemaManager()->name(schema));
03247
03248 for (uint z = 0; z < defaultStyles(); z++)
03249 {
03250 KateAttribute *i = list.at(z);
03251 QStringList s = config->readListEntry(defaultStyleName(z));
03252 if (!s.isEmpty())
03253 {
03254 while( s.count()<8)
03255 s << "";
03256
03257 QString tmp;
03258 QRgb col;
03259
03260 tmp=s[0]; if (!tmp.isEmpty()) {
03261 col=tmp.toUInt(0,16); i->setTextColor(col); }
03262
03263 tmp=s[1]; if (!tmp.isEmpty()) {
03264 col=tmp.toUInt(0,16); i->setSelectedTextColor(col); }
03265
03266 tmp=s[2]; if (!tmp.isEmpty()) i->setBold(tmp!="0");
03267
03268 tmp=s[3]; if (!tmp.isEmpty()) i->setItalic(tmp!="0");
03269
03270 tmp=s[4]; if (!tmp.isEmpty()) i->setStrikeOut(tmp!="0");
03271
03272 tmp=s[5]; if (!tmp.isEmpty()) i->setUnderline(tmp!="0");
03273
03274 tmp=s[6]; if (!tmp.isEmpty()) {
03275 if ( tmp != "-" )
03276 {
03277 col=tmp.toUInt(0,16);
03278 i->setBGColor(col);
03279 }
03280 else
03281 i->clearAttribute(KateAttribute::BGColor);
03282 }
03283 tmp=s[7]; if (!tmp.isEmpty()) {
03284 if ( tmp != "-" )
03285 {
03286 col=tmp.toUInt(0,16);
03287 i->setSelectedBGColor(col);
03288 }
03289 else
03290 i->clearAttribute(KateAttribute::SelectedBGColor);
03291 }
03292 }
03293 }
03294 }
03295
03296 void KateHlManager::setDefaults(uint schema, KateAttributeList &list)
03297 {
03298 KConfig *config = KateHlManager::self()->self()->getKConfig();
03299 config->setGroup("Default Item Styles - Schema " + KateFactory::self()->schemaManager()->name(schema));
03300
03301 for (uint z = 0; z < defaultStyles(); z++)
03302 {
03303 QStringList settings;
03304 KateAttribute *i = list.at(z);
03305
03306 settings<<(i->itemSet(KateAttribute::TextColor)?QString::number(i->textColor().rgb(),16):"");
03307 settings<<(i->itemSet(KateAttribute::SelectedTextColor)?QString::number(i->selectedTextColor().rgb(),16):"");
03308 settings<<(i->itemSet(KateAttribute::Weight)?(i->bold()?"1":"0"):"");
03309 settings<<(i->itemSet(KateAttribute::Italic)?(i->italic()?"1":"0"):"");
03310 settings<<(i->itemSet(KateAttribute::StrikeOut)?(i->strikeOut()?"1":"0"):"");
03311 settings<<(i->itemSet(KateAttribute::Underline)?(i->underline()?"1":"0"):"");
03312 settings<<(i->itemSet(KateAttribute::BGColor)?QString::number(i->bgColor().rgb(),16):"-");
03313 settings<<(i->itemSet(KateAttribute::SelectedBGColor)?QString::number(i->selectedBGColor().rgb(),16):"-");
03314 settings<<"---";
03315
03316 config->writeEntry(defaultStyleName(z),settings);
03317 }
03318
03319 emit changed();
03320 }
03321
03322 int KateHlManager::highlights()
03323 {
03324 return (int) hlList.count();
03325 }
03326
03327 QString KateHlManager::hlName(int n)
03328 {
03329 return hlList.at(n)->name();
03330 }
03331
03332 QString KateHlManager::hlNameTranslated(int n)
03333 {
03334 return hlList.at(n)->nameTranslated();
03335 }
03336
03337 QString KateHlManager::hlSection(int n)
03338 {
03339 return hlList.at(n)->section();
03340 }
03341
03342 bool KateHlManager::hlHidden(int n)
03343 {
03344 return hlList.at(n)->hidden();
03345 }
03346
03347 QString KateHlManager::identifierForName(const QString& name)
03348 {
03349 KateHighlighting *hl = 0;
03350
03351 if ((hl = hlDict[name]))
03352 return hl->getIdentifier ();
03353
03354 return QString();
03355 }
03356
03357 bool KateHlManager::resetDynamicCtxs()
03358 {
03359 if (forceNoDCReset)
03360 return false;
03361
03362 if (lastCtxsReset.elapsed() < KATE_DYNAMIC_CONTEXTS_RESET_DELAY)
03363 return false;
03364
03365 KateHighlighting *hl;
03366 for (hl = hlList.first(); hl; hl = hlList.next())
03367 hl->dropDynamicContexts();
03368
03369 dynamicCtxsCount = 0;
03370 lastCtxsReset.start();
03371
03372 return true;
03373 }
03374
03375
03376
03377 void KateViewHighlightAction::init()
03378 {
03379 m_doc = 0;
03380 subMenus.setAutoDelete( true );
03381
03382 connect(popupMenu(),SIGNAL(aboutToShow()),this,SLOT(slotAboutToShow()));
03383 }
03384
03385 void KateViewHighlightAction::updateMenu (Kate::Document *doc)
03386 {
03387 m_doc = doc;
03388 }
03389
03390 void KateViewHighlightAction::slotAboutToShow()
03391 {
03392 Kate::Document *doc=m_doc;
03393 int count = KateHlManager::self()->highlights();
03394
03395 for (int z=0; z<count; z++)
03396 {
03397 QString hlName = KateHlManager::self()->hlNameTranslated (z);
03398 QString hlSection = KateHlManager::self()->hlSection (z);
03399
03400 if (!KateHlManager::self()->hlHidden(z))
03401 {
03402 if ( !hlSection.isEmpty() && (names.contains(hlName) < 1) )
03403 {
03404 if (subMenusName.contains(hlSection) < 1)
03405 {
03406 subMenusName << hlSection;
03407 QPopupMenu *menu = new QPopupMenu ();
03408 subMenus.append(menu);
03409 popupMenu()->insertItem ( '&' + hlSection, menu);
03410 }
03411
03412 int m = subMenusName.findIndex (hlSection);
03413 names << hlName;
03414 subMenus.at(m)->insertItem ( '&' + hlName, this, SLOT(setHl(int)), 0, z);
03415 }
03416 else if (names.contains(hlName) < 1)
03417 {
03418 names << hlName;
03419 popupMenu()->insertItem ( '&' + hlName, this, SLOT(setHl(int)), 0, z);
03420 }
03421 }
03422 }
03423
03424 if (!doc) return;
03425
03426 for (uint i=0;i<subMenus.count();i++)
03427 {
03428 for (uint i2=0;i2<subMenus.at(i)->count();i2++)
03429 {
03430 subMenus.at(i)->setItemChecked(subMenus.at(i)->idAt(i2),false);
03431 }
03432 }
03433 popupMenu()->setItemChecked (0, false);
03434
03435 int i = subMenusName.findIndex (KateHlManager::self()->hlSection(doc->hlMode()));
03436 if (i >= 0 && subMenus.at(i))
03437 subMenus.at(i)->setItemChecked (doc->hlMode(), true);
03438 else
03439 popupMenu()->setItemChecked (0, true);
03440 }
03441
03442 void KateViewHighlightAction::setHl (int mode)
03443 {
03444 Kate::Document *doc=m_doc;
03445
03446 if (doc)
03447 doc->setHlMode((uint)mode);
03448 }
03449
03450
03451