• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • kate
 

kate

  • kate
  • part
katehighlight.cpp
1 /* This file is part of the KDE libraries
2  Copyright (C) 2003, 2004 Anders Lund <anders@alweb.dk>
3  Copyright (C) 2003 Hamish Rodda <rodda@kde.org>
4  Copyright (C) 2001,2002 Joseph Wenninger <jowenn@kde.org>
5  Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
6  Copyright (C) 1999 Jochen Wilhelmy <digisnap@cs.tu-berlin.de>
7 
8  This library is free software; you can redistribute it and/or
9  modify it under the terms of the GNU Library General Public
10  License version 2 as published by the Free Software Foundation.
11 
12  This library is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  Library General Public License for more details.
16 
17  You should have received a copy of the GNU Library General Public License
18  along with this library; see the file COPYING.LIB. If not, write to
19  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  Boston, MA 02110-1301, USA.
21 */
22 
23 //BEGIN INCLUDES
24 #include "katehighlight.h"
25 #include "katehighlight.moc"
26 
27 #include "katetextline.h"
28 #include "katedocument.h"
29 #include "katesyntaxdocument.h"
30 #include "katerenderer.h"
31 #include "katefactory.h"
32 #include "kateschema.h"
33 #include "kateconfig.h"
34 
35 #include <kconfig.h>
36 #include <kglobal.h>
37 #include <kinstance.h>
38 #include <kmimetype.h>
39 #include <klocale.h>
40 #include <kregexp.h>
41 #include <kpopupmenu.h>
42 #include <kglobalsettings.h>
43 #include <kdebug.h>
44 #include <kstandarddirs.h>
45 #include <kmessagebox.h>
46 #include <kstaticdeleter.h>
47 #include <kapplication.h>
48 
49 #include <tqstringlist.h>
50 #include <tqtextstream.h>
51 //END
52 
53 //BEGIN defines
54 // same as in kmimemagic, no need to feed more data
55 #define KATE_HL_HOWMANY 1024
56 
57 // min. x seconds between two dynamic contexts reset
58 static const int KATE_DYNAMIC_CONTEXTS_RESET_DELAY = 30 * 1000;
59 
60 // x is a TQString. if x is "true" or "1" this expression returns "true"
61 #define IS_TRUE(x) x.lower() == TQString("true") || x.toInt() == 1
62 //END defines
63 
64 //BEGIN Prviate HL classes
65 
66 inline bool kateInsideString (const TQString &str, TQChar ch)
67 {
68  const TQChar *unicode = str.unicode();
69  const uint len = str.length();
70  for (uint i=0; i < len; i++)
71  if (unicode[i] == ch)
72  return true;
73 
74  return false;
75 }
76 
77 class KateHlItem
78 {
79  public:
80  KateHlItem(int attribute, int context,signed char regionId, signed char regionId2);
81  virtual ~KateHlItem();
82 
83  public:
84  // caller must keep in mind: LEN > 0 is a must !!!!!!!!!!!!!!!!!!!!!1
85  // Now, the function returns the offset detected, or 0 if no match is found.
86  // bool linestart isn't needed, this is equivalent to offset == 0.
87  virtual int checkHgl(const TQString& text, int offset, int len) = 0;
88 
89  virtual bool lineContinue(){return false;}
90 
91  virtual TQStringList *capturedTexts() {return 0;}
92  virtual KateHlItem *clone(const TQStringList *) {return this;}
93 
94  static void dynamicSubstitute(TQString& str, const TQStringList *args);
95 
96  TQMemArray<KateHlItem*> subItems;
97  int attr;
98  int ctx;
99  signed char region;
100  signed char region2;
101 
102  bool lookAhead;
103 
104  bool dynamic;
105  bool dynamicChild;
106  bool firstNonSpace;
107  bool onlyConsume;
108  int column;
109 
110  // start enable flags, nicer than the virtual methodes
111  // saves function calls
112  bool alwaysStartEnable;
113  bool customStartEnable;
114 };
115 
116 class KateHlContext
117 {
118  public:
119  KateHlContext(const TQString &_hlId, int attribute, int lineEndContext,int _lineBeginContext,
120  bool _fallthrough, int _fallthroughContext, bool _dynamic,bool _noIndentationBasedFolding);
121  virtual ~KateHlContext();
122  KateHlContext *clone(const TQStringList *args);
123 
124  TQValueVector<KateHlItem*> items;
125  TQString hlId;
126  int attr;
127  int ctx;
128  int lineBeginContext;
134  bool fallthrough;
135  int ftctx; // where to go after no rules matched
136 
137  bool dynamic;
138  bool dynamicChild;
139  bool noIndentationBasedFolding;
140 };
141 
142 class KateEmbeddedHlInfo
143 {
144  public:
145  KateEmbeddedHlInfo() {loaded=false;context0=-1;}
146  KateEmbeddedHlInfo(bool l, int ctx0) {loaded=l;context0=ctx0;}
147 
148  public:
149  bool loaded;
150  int context0;
151 };
152 
153 class KateHlIncludeRule
154 {
155  public:
156  KateHlIncludeRule(int ctx_=0, uint pos_=0, const TQString &incCtxN_="", bool incAttrib=false)
157  : ctx(ctx_)
158  , pos( pos_)
159  , incCtxN( incCtxN_ )
160  , includeAttrib( incAttrib )
161  {
162  incCtx=-1;
163  }
164  //KateHlIncludeRule(int ctx_, uint pos_, bool incAttrib) {ctx=ctx_;pos=pos_;incCtx=-1;incCtxN="";includeAttrib=incAttrib}
165 
166  public:
167  int ctx;
168  uint pos;
169  int incCtx;
170  TQString incCtxN;
171  bool includeAttrib;
172 };
173 
174 class KateHlCharDetect : public KateHlItem
175 {
176  public:
177  KateHlCharDetect(int attribute, int context,signed char regionId,signed char regionId2, TQChar);
178 
179  virtual int checkHgl(const TQString& text, int offset, int len);
180  virtual KateHlItem *clone(const TQStringList *args);
181 
182  private:
183  TQChar sChar;
184 };
185 
186 class KateHl2CharDetect : public KateHlItem
187 {
188  public:
189  KateHl2CharDetect(int attribute, int context, signed char regionId,signed char regionId2, TQChar ch1, TQChar ch2);
190  KateHl2CharDetect(int attribute, int context,signed char regionId,signed char regionId2, const TQChar *ch);
191 
192  virtual int checkHgl(const TQString& text, int offset, int len);
193  virtual KateHlItem *clone(const TQStringList *args);
194 
195  private:
196  TQChar sChar1;
197  TQChar sChar2;
198 };
199 
200 class KateHlStringDetect : public KateHlItem
201 {
202  public:
203  KateHlStringDetect(int attribute, int context, signed char regionId,signed char regionId2, const TQString &, bool inSensitive=false);
204 
205  virtual int checkHgl(const TQString& text, int offset, int len);
206  virtual KateHlItem *clone(const TQStringList *args);
207 
208  private:
209  const TQString str;
210  const int strLen;
211  const bool _inSensitive;
212 };
213 
214 class KateHlRangeDetect : public KateHlItem
215 {
216  public:
217  KateHlRangeDetect(int attribute, int context, signed char regionId,signed char regionId2, TQChar ch1, TQChar ch2);
218 
219  virtual int checkHgl(const TQString& text, int offset, int len);
220 
221  private:
222  TQChar sChar1;
223  TQChar sChar2;
224 };
225 
226 class KateHlKeyword : public KateHlItem
227 {
228  public:
229  KateHlKeyword(int attribute, int context,signed char regionId,signed char regionId2, bool insensitive, const TQString& delims);
230  virtual ~KateHlKeyword ();
231 
232  void addList(const TQStringList &);
233  virtual int checkHgl(const TQString& text, int offset, int len);
234 
235  private:
236  TQMemArray< TQDict<bool>* > dict;
237  bool _insensitive;
238  const TQString& deliminators;
239  int minLen;
240  int maxLen;
241 };
242 
243 class KateHlInt : public KateHlItem
244 {
245  public:
246  KateHlInt(int attribute, int context, signed char regionId,signed char regionId2);
247 
248  virtual int checkHgl(const TQString& text, int offset, int len);
249 };
250 
251 class KateHlFloat : public KateHlItem
252 {
253  public:
254  KateHlFloat(int attribute, int context, signed char regionId,signed char regionId2);
255  virtual ~KateHlFloat () {}
256 
257  virtual int checkHgl(const TQString& text, int offset, int len);
258 };
259 
260 class KateHlCFloat : public KateHlFloat
261 {
262  public:
263  KateHlCFloat(int attribute, int context, signed char regionId,signed char regionId2);
264 
265  virtual int checkHgl(const TQString& text, int offset, int len);
266  int checkIntHgl(const TQString& text, int offset, int len);
267 };
268 
269 class KateHlCOct : public KateHlItem
270 {
271  public:
272  KateHlCOct(int attribute, int context, signed char regionId,signed char regionId2);
273 
274  virtual int checkHgl(const TQString& text, int offset, int len);
275 };
276 
277 class KateHlCHex : public KateHlItem
278 {
279  public:
280  KateHlCHex(int attribute, int context, signed char regionId,signed char regionId2);
281 
282  virtual int checkHgl(const TQString& text, int offset, int len);
283 };
284 
285 class KateHlLineContinue : public KateHlItem
286 {
287  public:
288  KateHlLineContinue(int attribute, int context, signed char regionId,signed char regionId2);
289 
290  virtual bool endEnable(TQChar c) {return c == '\0';}
291  virtual int checkHgl(const TQString& text, int offset, int len);
292  virtual bool lineContinue(){return true;}
293 };
294 
295 class KateHlCStringChar : public KateHlItem
296 {
297  public:
298  KateHlCStringChar(int attribute, int context, signed char regionId,signed char regionId2);
299 
300  virtual int checkHgl(const TQString& text, int offset, int len);
301 };
302 
303 class KateHlCChar : public KateHlItem
304 {
305  public:
306  KateHlCChar(int attribute, int context,signed char regionId,signed char regionId2);
307 
308  virtual int checkHgl(const TQString& text, int offset, int len);
309 };
310 
311 class KateHlAnyChar : public KateHlItem
312 {
313  public:
314  KateHlAnyChar(int attribute, int context, signed char regionId,signed char regionId2, const TQString& charList);
315 
316  virtual int checkHgl(const TQString& text, int offset, int len);
317 
318  private:
319  const TQString _charList;
320 };
321 
322 class KateHlRegExpr : public KateHlItem
323 {
324  public:
325  KateHlRegExpr(int attribute, int context,signed char regionId,signed char regionId2 ,TQString expr, bool insensitive, bool minimal);
326  ~KateHlRegExpr() { delete Expr; };
327 
328  virtual int checkHgl(const TQString& text, int offset, int len);
329  virtual TQStringList *capturedTexts();
330  virtual KateHlItem *clone(const TQStringList *args);
331 
332  private:
333  TQRegExp *Expr;
334  bool handlesLinestart;
335  TQString _regexp;
336  bool _insensitive;
337  bool _minimal;
338 };
339 
340 class KateHlDetectSpaces : public KateHlItem
341 {
342  public:
343  KateHlDetectSpaces (int attribute, int context,signed char regionId,signed char regionId2)
344  : KateHlItem(attribute,context,regionId,regionId2) {}
345 
346  virtual int checkHgl(const TQString& text, int offset, int len)
347  {
348  int len2 = offset + len;
349  while ((offset < len2) && text[offset].isSpace()) offset++;
350  return offset;
351  }
352 };
353 
354 class KateHlDetectIdentifier : public KateHlItem
355 {
356  public:
357  KateHlDetectIdentifier (int attribute, int context,signed char regionId,signed char regionId2)
358  : KateHlItem(attribute,context,regionId,regionId2) { alwaysStartEnable = false; }
359 
360  virtual int checkHgl(const TQString& text, int offset, int len)
361  {
362  // first char should be a letter or underscore
363  if ( text[offset].isLetter() || text[offset] == TQChar ('_') )
364  {
365  // memorize length
366  int len2 = offset+len;
367 
368  // one char seen
369  offset++;
370 
371  // now loop for all other thingies
372  while (
373  (offset < len2)
374  && (text[offset].isLetterOrNumber() || (text[offset] == TQChar ('_')))
375  )
376  offset++;
377 
378  return offset;
379  }
380 
381  return 0;
382  }
383 };
384 
385 //END
386 
387 //BEGIN STATICS
388 KateHlManager *KateHlManager::s_self = 0;
389 
390 static const bool trueBool = true;
391 static const TQString stdDeliminator = TQString (" \t.():!+,-<=>%&*/;?[]^{|}~\\");
392 //END
393 
394 //BEGIN NON MEMBER FUNCTIONS
395 static KateHlItemData::ItemStyles getDefStyleNum(TQString name)
396 {
397  if (name=="dsNormal") return KateHlItemData::dsNormal;
398  else if (name=="dsKeyword") return KateHlItemData::dsKeyword;
399  else if (name=="dsDataType") return KateHlItemData::dsDataType;
400  else if (name=="dsDecVal") return KateHlItemData::dsDecVal;
401  else if (name=="dsBaseN") return KateHlItemData::dsBaseN;
402  else if (name=="dsFloat") return KateHlItemData::dsFloat;
403  else if (name=="dsChar") return KateHlItemData::dsChar;
404  else if (name=="dsString") return KateHlItemData::dsString;
405  else if (name=="dsComment") return KateHlItemData::dsComment;
406  else if (name=="dsOthers") return KateHlItemData::dsOthers;
407  else if (name=="dsAlert") return KateHlItemData::dsAlert;
408  else if (name=="dsFunction") return KateHlItemData::dsFunction;
409  else if (name=="dsRegionMarker") return KateHlItemData::dsRegionMarker;
410  else if (name=="dsError") return KateHlItemData::dsError;
411 
412  return KateHlItemData::dsNormal;
413 }
414 //END
415 
416 //BEGIN KateHlItem
417 KateHlItem::KateHlItem(int attribute, int context,signed char regionId,signed char regionId2)
418  : attr(attribute),
419  ctx(context),
420  region(regionId),
421  region2(regionId2),
422  lookAhead(false),
423  dynamic(false),
424  dynamicChild(false),
425  firstNonSpace(false),
426  onlyConsume(false),
427  column (-1),
428  alwaysStartEnable (true),
429  customStartEnable (false)
430 {
431 }
432 
433 KateHlItem::~KateHlItem()
434 {
435  //kdDebug(13010)<<"In hlItem::~KateHlItem()"<<endl;
436  for (uint i=0; i < subItems.size(); i++)
437  delete subItems[i];
438 }
439 
440 void KateHlItem::dynamicSubstitute(TQString &str, const TQStringList *args)
441 {
442  uint strLength = str.length();
443  if (strLength > 0) {
444  for (uint i = 0; i < strLength - 1; ++i) {
445  if (str[i] == '%') {
446  char c = str[i + 1].latin1();
447  if (c == '%') {
448  str.replace(i, 1, "");
449  }
450  else if (c >= '0' && c <= '9') {
451  if ((uint)(c - '0') < args->size()) {
452  str.replace(i, 2, (*args)[c - '0']);
453  i += ((*args)[c - '0']).length() - 1;
454  }
455  else {
456  str.replace(i, 2, "");
457  --i;
458  }
459  }
460  }
461  }
462  }
463 }
464 //END
465 
466 //BEGIN KateHlCharDetect
467 KateHlCharDetect::KateHlCharDetect(int attribute, int context, signed char regionId,signed char regionId2, TQChar c)
468  : KateHlItem(attribute,context,regionId,regionId2)
469  , sChar(c)
470 {
471 }
472 
473 int KateHlCharDetect::checkHgl(const TQString& text, int offset, int /*len*/)
474 {
475  if (text[offset] == sChar)
476  return offset + 1;
477 
478  return 0;
479 }
480 
481 KateHlItem *KateHlCharDetect::clone(const TQStringList *args)
482 {
483  char c = sChar.latin1();
484 
485  if (c < '0' || c > '9' || (unsigned)(c - '0') >= args->size())
486  return this;
487 
488  KateHlCharDetect *ret = new KateHlCharDetect(attr, ctx, region, region2, (*args)[c - '0'][0]);
489  ret->dynamicChild = true;
490  return ret;
491 }
492 //END
493 
494 //BEGIN KateHl2CharDetect
495 KateHl2CharDetect::KateHl2CharDetect(int attribute, int context, signed char regionId,signed char regionId2, TQChar ch1, TQChar ch2)
496  : KateHlItem(attribute,context,regionId,regionId2)
497  , sChar1 (ch1)
498  , sChar2 (ch2)
499 {
500 }
501 
502 int KateHl2CharDetect::checkHgl(const TQString& text, int offset, int len)
503 {
504  if ((len >= 2) && text[offset++] == sChar1 && text[offset++] == sChar2)
505  return offset;
506 
507  return 0;
508 }
509 
510 KateHlItem *KateHl2CharDetect::clone(const TQStringList *args)
511 {
512  char c1 = sChar1.latin1();
513  char c2 = sChar2.latin1();
514 
515  if (c1 < '0' || c1 > '9' || (unsigned)(c1 - '0') >= args->size())
516  return this;
517 
518  if (c2 < '0' || c2 > '9' || (unsigned)(c2 - '0') >= args->size())
519  return this;
520 
521  KateHl2CharDetect *ret = new KateHl2CharDetect(attr, ctx, region, region2, (*args)[c1 - '0'][0], (*args)[c2 - '0'][0]);
522  ret->dynamicChild = true;
523  return ret;
524 }
525 //END
526 
527 //BEGIN KateHlStringDetect
528 KateHlStringDetect::KateHlStringDetect(int attribute, int context, signed char regionId,signed char regionId2,const TQString &s, bool inSensitive)
529  : KateHlItem(attribute, context,regionId,regionId2)
530  , str(inSensitive ? s.upper() : s)
531  , strLen (str.length())
532  , _inSensitive(inSensitive)
533 {
534 }
535 
536 int KateHlStringDetect::checkHgl(const TQString& text, int offset, int len)
537 {
538  if (len < strLen)
539  return 0;
540 
541  if (_inSensitive)
542  {
543  for (int i=0; i < strLen; i++)
544  if (text[offset++].upper() != str[i])
545  return 0;
546 
547  return offset;
548  }
549  else
550  {
551  for (int i=0; i < strLen; i++)
552  if (text[offset++] != str[i])
553  return 0;
554 
555  return offset;
556  }
557 
558  return 0;
559 }
560 
561 KateHlItem *KateHlStringDetect::clone(const TQStringList *args)
562 {
563  TQString newstr = str;
564 
565  dynamicSubstitute(newstr, args);
566 
567  if (newstr == str)
568  return this;
569 
570  KateHlStringDetect *ret = new KateHlStringDetect(attr, ctx, region, region2, newstr, _inSensitive);
571  ret->dynamicChild = true;
572  return ret;
573 }
574 //END
575 
576 //BEGIN KateHlRangeDetect
577 KateHlRangeDetect::KateHlRangeDetect(int attribute, int context, signed char regionId,signed char regionId2, TQChar ch1, TQChar ch2)
578  : KateHlItem(attribute,context,regionId,regionId2)
579  , sChar1 (ch1)
580  , sChar2 (ch2)
581 {
582 }
583 
584 int KateHlRangeDetect::checkHgl(const TQString& text, int offset, int len)
585 {
586  if (text[offset] == sChar1)
587  {
588  do
589  {
590  offset++;
591  len--;
592  if (len < 1) return 0;
593  }
594  while (text[offset] != sChar2);
595 
596  return offset + 1;
597  }
598  return 0;
599 }
600 //END
601 
602 //BEGIN KateHlKeyword
603 KateHlKeyword::KateHlKeyword (int attribute, int context, signed char regionId,signed char regionId2, bool insensitive, const TQString& delims)
604  : KateHlItem(attribute,context,regionId,regionId2)
605  , _insensitive(insensitive)
606  , deliminators(delims)
607  , minLen (0xFFFFFF)
608  , maxLen (0)
609 {
610  alwaysStartEnable = false;
611  customStartEnable = true;
612 }
613 
614 KateHlKeyword::~KateHlKeyword ()
615 {
616  for (uint i=0; i < dict.size(); ++i)
617  delete dict[i];
618 }
619 
620 void KateHlKeyword::addList(const TQStringList& list)
621 {
622  for(uint i=0; i < list.count(); ++i)
623  {
624  int len = list[i].length();
625 
626  if (minLen > len)
627  minLen = len;
628 
629  if (maxLen < len)
630  maxLen = len;
631 
632  if ((uint)len >= dict.size())
633  {
634  uint oldSize = dict.size();
635  dict.resize (len+1);
636 
637  for (uint m=oldSize; m < dict.size(); ++m)
638  dict[m] = 0;
639  }
640 
641  if (!dict[len])
642  dict[len] = new TQDict<bool> (17, !_insensitive);
643 
644  dict[len]->insert(list[i], &trueBool);
645  }
646 }
647 
648 int KateHlKeyword::checkHgl(const TQString& text, int offset, int len)
649 {
650  int offset2 = offset;
651  int wordLen = 0;
652 
653  while ((len > wordLen) && !kateInsideString (deliminators, text[offset2]))
654  {
655  offset2++;
656  wordLen++;
657 
658  if (wordLen > maxLen) return 0;
659  }
660 
661  if (wordLen < minLen) return 0;
662 
663  if ( dict[wordLen] && dict[wordLen]->find(TQConstString(text.unicode() + offset, wordLen).string()) )
664  return offset2;
665 
666  return 0;
667 }
668 //END
669 
670 //BEGIN KateHlInt
671 KateHlInt::KateHlInt(int attribute, int context, signed char regionId,signed char regionId2)
672  : KateHlItem(attribute,context,regionId,regionId2)
673 {
674  alwaysStartEnable = false;
675 }
676 
677 int KateHlInt::checkHgl(const TQString& text, int offset, int len)
678 {
679  int offset2 = offset;
680 
681  while ((len > 0) && text[offset2].isDigit())
682  {
683  offset2++;
684  len--;
685  }
686 
687  if (offset2 > offset)
688  {
689  if (len > 0)
690  {
691  for (uint i=0; i < subItems.size(); i++)
692  {
693  if ( (offset = subItems[i]->checkHgl(text, offset2, len)) )
694  return offset;
695  }
696  }
697 
698  return offset2;
699  }
700 
701  return 0;
702 }
703 //END
704 
705 //BEGIN KateHlFloat
706 KateHlFloat::KateHlFloat(int attribute, int context, signed char regionId,signed char regionId2)
707  : KateHlItem(attribute,context, regionId,regionId2)
708 {
709  alwaysStartEnable = false;
710 }
711 
712 int KateHlFloat::checkHgl(const TQString& text, int offset, int len)
713 {
714  bool b = false;
715  bool p = false;
716 
717  while ((len > 0) && text[offset].isDigit())
718  {
719  offset++;
720  len--;
721  b = true;
722  }
723 
724  if ((len > 0) && (p = (text[offset] == '.')))
725  {
726  offset++;
727  len--;
728 
729  while ((len > 0) && text[offset].isDigit())
730  {
731  offset++;
732  len--;
733  b = true;
734  }
735  }
736 
737  if (!b)
738  return 0;
739 
740  if ((len > 0) && ((text[offset] & 0xdf) == 'E'))
741  {
742  offset++;
743  len--;
744  }
745  else
746  {
747  if (!p)
748  return 0;
749  else
750  {
751  if (len > 0)
752  {
753  for (uint i=0; i < subItems.size(); i++)
754  {
755  int offset2 = subItems[i]->checkHgl(text, offset, len);
756 
757  if (offset2)
758  return offset2;
759  }
760  }
761 
762  return offset;
763  }
764  }
765 
766  if ((len > 0) && (text[offset] == '-' || text[offset] =='+'))
767  {
768  offset++;
769  len--;
770  }
771 
772  b = false;
773 
774  while ((len > 0) && text[offset].isDigit())
775  {
776  offset++;
777  len--;
778  b = true;
779  }
780 
781  if (b)
782  {
783  if (len > 0)
784  {
785  for (uint i=0; i < subItems.size(); i++)
786  {
787  int offset2 = subItems[i]->checkHgl(text, offset, len);
788 
789  if (offset2)
790  return offset2;
791  }
792  }
793 
794  return offset;
795  }
796 
797  return 0;
798 }
799 //END
800 
801 //BEGIN KateHlCOct
802 KateHlCOct::KateHlCOct(int attribute, int context, signed char regionId,signed char regionId2)
803  : KateHlItem(attribute,context,regionId,regionId2)
804 {
805  alwaysStartEnable = false;
806 }
807 
808 int KateHlCOct::checkHgl(const TQString& text, int offset, int len)
809 {
810  if (text[offset] == '0')
811  {
812  offset++;
813  len--;
814 
815  int offset2 = offset;
816 
817  while ((len > 0) && (text.at(offset2) >= TQChar('0') && text.at(offset2) <= TQChar('7')))
818  {
819  offset2++;
820  len--;
821  }
822 
823  if (offset2 > offset)
824  {
825  if ((len > 0) && ((text[offset2] & 0xdf) == 'L' || (text[offset] & 0xdf) == 'U' ))
826  offset2++;
827 
828  return offset2;
829  }
830  }
831 
832  return 0;
833 }
834 //END
835 
836 //BEGIN KateHlCHex
837 KateHlCHex::KateHlCHex(int attribute, int context,signed char regionId,signed char regionId2)
838  : KateHlItem(attribute,context,regionId,regionId2)
839 {
840  alwaysStartEnable = false;
841 }
842 
843 int KateHlCHex::checkHgl(const TQString& text, int offset, int len)
844 {
845  if ((len > 1) && (text[offset++] == '0') && ((text[offset++] & 0xdf) == 'X' ))
846  {
847  len -= 2;
848 
849  int offset2 = offset;
850 
851  while ((len > 0) && (text[offset2].isDigit() || ((text[offset2] & 0xdf) >= 'A' && (text[offset2] & 0xdf) <= 'F')))
852  {
853  offset2++;
854  len--;
855  }
856 
857  if (offset2 > offset)
858  {
859  if ((len > 0) && ((text[offset2] & 0xdf) == 'L' || (text[offset2] & 0xdf) == 'U' ))
860  offset2++;
861 
862  return offset2;
863  }
864  }
865 
866  return 0;
867 }
868 //END
869 
870 //BEGIN KateHlCFloat
871 KateHlCFloat::KateHlCFloat(int attribute, int context, signed char regionId,signed char regionId2)
872  : KateHlFloat(attribute,context,regionId,regionId2)
873 {
874  alwaysStartEnable = false;
875 }
876 
877 int KateHlCFloat::checkIntHgl(const TQString& text, int offset, int len)
878 {
879  int offset2 = offset;
880 
881  while ((len > 0) && text[offset].isDigit()) {
882  offset2++;
883  len--;
884  }
885 
886  if (offset2 > offset)
887  return offset2;
888 
889  return 0;
890 }
891 
892 int KateHlCFloat::checkHgl(const TQString& text, int offset, int len)
893 {
894  int offset2 = KateHlFloat::checkHgl(text, offset, len);
895 
896  if (offset2)
897  {
898  if ((text[offset2] & 0xdf) == 'F' )
899  offset2++;
900 
901  return offset2;
902  }
903  else
904  {
905  offset2 = checkIntHgl(text, offset, len);
906 
907  if (offset2 && ((text[offset2] & 0xdf) == 'F' ))
908  return ++offset2;
909  else
910  return 0;
911  }
912 }
913 //END
914 
915 //BEGIN KateHlAnyChar
916 KateHlAnyChar::KateHlAnyChar(int attribute, int context, signed char regionId,signed char regionId2, const TQString& charList)
917  : KateHlItem(attribute, context,regionId,regionId2)
918  , _charList(charList)
919 {
920 }
921 
922 int KateHlAnyChar::checkHgl(const TQString& text, int offset, int)
923 {
924  if (kateInsideString (_charList, text[offset]))
925  return ++offset;
926 
927  return 0;
928 }
929 //END
930 
931 //BEGIN KateHlRegExpr
932 KateHlRegExpr::KateHlRegExpr( int attribute, int context, signed char regionId,signed char regionId2, TQString regexp, bool insensitive, bool minimal)
933  : KateHlItem(attribute, context, regionId,regionId2)
934  , handlesLinestart (regexp.startsWith("^"))
935  , _regexp(regexp)
936  , _insensitive(insensitive)
937  , _minimal(minimal)
938 {
939  if (!handlesLinestart)
940  regexp.prepend("^");
941 
942  Expr = new TQRegExp(regexp, !_insensitive);
943  Expr->setMinimal(_minimal);
944 }
945 
946 int KateHlRegExpr::checkHgl(const TQString& text, int offset, int /*len*/)
947 {
948  if (offset && handlesLinestart)
949  return 0;
950 
951  int offset2 = Expr->search( text, offset, TQRegExp::CaretAtOffset );
952 
953  if (offset2 == -1) return 0;
954 
955  return (offset + Expr->matchedLength());
956 }
957 
958 TQStringList *KateHlRegExpr::capturedTexts()
959 {
960  return new TQStringList(Expr->capturedTexts());
961 }
962 
963 KateHlItem *KateHlRegExpr::clone(const TQStringList *args)
964 {
965  TQString regexp = _regexp;
966  TQStringList escArgs = *args;
967 
968  for (TQStringList::Iterator it = escArgs.begin(); it != escArgs.end(); ++it)
969  {
970  (*it).replace(TQRegExp("(\\W)"), "\\\\1");
971  }
972 
973  dynamicSubstitute(regexp, &escArgs);
974 
975  if (regexp == _regexp)
976  return this;
977 
978  // kdDebug (13010) << "clone regexp: " << regexp << endl;
979 
980  KateHlRegExpr *ret = new KateHlRegExpr(attr, ctx, region, region2, regexp, _insensitive, _minimal);
981  ret->dynamicChild = true;
982  return ret;
983 }
984 //END
985 
986 //BEGIN KateHlLineContinue
987 KateHlLineContinue::KateHlLineContinue(int attribute, int context, signed char regionId,signed char regionId2)
988  : KateHlItem(attribute,context,regionId,regionId2) {
989 }
990 
991 int KateHlLineContinue::checkHgl(const TQString& text, int offset, int len)
992 {
993  if ((len == 1) && (text[offset] == '\\'))
994  return ++offset;
995 
996  return 0;
997 }
998 //END
999 
1000 //BEGIN KateHlCStringChar
1001 KateHlCStringChar::KateHlCStringChar(int attribute, int context,signed char regionId,signed char regionId2)
1002  : KateHlItem(attribute,context,regionId,regionId2) {
1003 }
1004 
1005 // checks for C escaped chars \n and escaped hex/octal chars
1006 static int checkEscapedChar(const TQString& text, int offset, int& len)
1007 {
1008  int i;
1009  if (text[offset] == '\\' && len > 1)
1010  {
1011  offset++;
1012  len--;
1013 
1014  switch(text[offset])
1015  {
1016  case 'a': // checks for control chars
1017  case 'b': // we want to fall through
1018  case 'e':
1019  case 'f':
1020 
1021  case 'n':
1022  case 'r':
1023  case 't':
1024  case 'v':
1025  case '\'':
1026  case '\"':
1027  case '?' : // added ? ANSI C classifies this as an escaped char
1028  case '\\':
1029  offset++;
1030  len--;
1031  break;
1032 
1033  case 'x': // if it's like \xff
1034  offset++; // eat the x
1035  len--;
1036  // these for loops can probably be
1037  // replaced with something else but
1038  // for right now they work
1039  // check for hexdigits
1040  for (i = 0; (len > 0) && (i < 2) && (((static_cast<const char>(text.at(offset)) >= '0') && (static_cast<const char>(text.at(offset)) <= '9')) || ((text[offset] & 0xdf) >= 'A' && (text[offset] & 0xdf) <= 'F')); i++)
1041  {
1042  offset++;
1043  len--;
1044  }
1045 
1046  if (i == 0)
1047  return 0; // takes care of case '\x'
1048 
1049  break;
1050 
1051  case '0': case '1': case '2': case '3' :
1052  case '4': case '5': case '6': case '7' :
1053  for (i = 0; (len > 0) && (i < 3) && (static_cast<const char>(text.at(offset)) >= '0' && static_cast<const char>(text.at(offset)) <= '7'); i++)
1054  {
1055  offset++;
1056  len--;
1057  }
1058  break;
1059 
1060  default:
1061  return 0;
1062  }
1063 
1064  return offset;
1065  }
1066 
1067  return 0;
1068 }
1069 
1070 int KateHlCStringChar::checkHgl(const TQString& text, int offset, int len)
1071 {
1072  return checkEscapedChar(text, offset, len);
1073 }
1074 //END
1075 
1076 //BEGIN KateHlCChar
1077 KateHlCChar::KateHlCChar(int attribute, int context,signed char regionId,signed char regionId2)
1078  : KateHlItem(attribute,context,regionId,regionId2) {
1079 }
1080 
1081 int KateHlCChar::checkHgl(const TQString& text, int offset, int len)
1082 {
1083  if ((len > 1) && (text[offset] == '\'') && (text[offset+1] != '\''))
1084  {
1085  int oldl;
1086  oldl = len;
1087 
1088  len--;
1089 
1090  int offset2 = checkEscapedChar(text, offset + 1, len);
1091 
1092  if (!offset2)
1093  {
1094  if (oldl > 2)
1095  {
1096  offset2 = offset + 2;
1097  len = oldl - 2;
1098  }
1099  else
1100  {
1101  return 0;
1102  }
1103  }
1104 
1105  if ((len > 0) && (text[offset2] == '\''))
1106  return ++offset2;
1107  }
1108 
1109  return 0;
1110 }
1111 //END
1112 
1113 //BEGIN KateHl2CharDetect
1114 KateHl2CharDetect::KateHl2CharDetect(int attribute, int context, signed char regionId,signed char regionId2, const TQChar *s)
1115  : KateHlItem(attribute,context,regionId,regionId2) {
1116  sChar1 = s[0];
1117  sChar2 = s[1];
1118  }
1119 //END KateHl2CharDetect
1120 
1121 KateHlItemData::KateHlItemData(const TQString name, int defStyleNum)
1122  : name(name), defStyleNum(defStyleNum) {
1123 }
1124 
1125 KateHlData::KateHlData(const TQString &wildcards, const TQString &mimetypes, const TQString &identifier, int priority)
1126  : wildcards(wildcards), mimetypes(mimetypes), identifier(identifier), priority(priority)
1127 {
1128 }
1129 
1130 //BEGIN KateHlContext
1131 KateHlContext::KateHlContext (const TQString &_hlId, int attribute, int lineEndContext, int _lineBeginContext, bool _fallthrough,
1132  int _fallthroughContext, bool _dynamic, bool _noIndentationBasedFolding)
1133 {
1134  hlId = _hlId;
1135  attr = attribute;
1136  ctx = lineEndContext;
1137  lineBeginContext = _lineBeginContext;
1138  fallthrough = _fallthrough;
1139  ftctx = _fallthroughContext;
1140  dynamic = _dynamic;
1141  dynamicChild = false;
1142  noIndentationBasedFolding=_noIndentationBasedFolding;
1143  if (_noIndentationBasedFolding) kdDebug(13010)<<TQString("**********************_noIndentationBasedFolding is TRUE*****************")<<endl;
1144 
1145 }
1146 
1147 KateHlContext *KateHlContext::clone(const TQStringList *args)
1148 {
1149  KateHlContext *ret = new KateHlContext(hlId, attr, ctx, lineBeginContext, fallthrough, ftctx, false,noIndentationBasedFolding);
1150 
1151  for (uint n=0; n < items.size(); ++n)
1152  {
1153  KateHlItem *item = items[n];
1154  KateHlItem *i = (item->dynamic ? item->clone(args) : item);
1155  ret->items.append(i);
1156  }
1157 
1158  ret->dynamicChild = true;
1159 
1160  return ret;
1161 }
1162 
1163 KateHlContext::~KateHlContext()
1164 {
1165  if (dynamicChild)
1166  {
1167  for (uint n=0; n < items.size(); ++n)
1168  {
1169  if (items[n]->dynamicChild)
1170  delete items[n];
1171  }
1172  }
1173 }
1174 //END
1175 
1176 //BEGIN KateHighlighting
1177 KateHighlighting::KateHighlighting(const KateSyntaxModeListItem *def) : refCount(0)
1178 {
1179  m_attributeArrays.setAutoDelete (true);
1180 
1181  errorsAndWarnings = "";
1182  building=false;
1183  noHl = false;
1184  m_foldingIndentationSensitive = false;
1185  folding=false;
1186  internalIDList.setAutoDelete(true);
1187 
1188  if (def == 0)
1189  {
1190  noHl = true;
1191  iName = "None"; // not translated internal name (for config and more)
1192  iNameTranslated = i18n("None"); // user visible name
1193  iSection = "";
1194  m_priority = 0;
1195  iHidden = false;
1196  m_additionalData.insert( "none", new HighlightPropertyBag );
1197  m_additionalData["none"]->deliminator = stdDeliminator;
1198  m_additionalData["none"]->wordWrapDeliminator = stdDeliminator;
1199  m_hlIndex[0] = "none";
1200  }
1201  else
1202  {
1203  iName = def->name;
1204  iNameTranslated = def->nameTranslated;
1205  iSection = def->section;
1206  iHidden = def->hidden;
1207  iWildcards = def->extension;
1208  iMimetypes = def->mimetype;
1209  identifier = def->identifier;
1210  iVersion=def->version;
1211  iAuthor=def->author;
1212  iLicense=def->license;
1213  m_priority=def->priority.toInt();
1214  }
1215 
1216  deliminator = stdDeliminator;
1217 }
1218 
1219 KateHighlighting::~KateHighlighting()
1220 {
1221  // cu contexts
1222  for (uint i=0; i < m_contexts.size(); ++i)
1223  delete m_contexts[i];
1224  m_contexts.clear ();
1225 }
1226 
1227 void KateHighlighting::generateContextStack(int *ctxNum, int ctx, TQMemArray<short>* ctxs, int *prevLine)
1228 {
1229  //kdDebug(13010)<<TQString("Entering generateContextStack with %1").arg(ctx)<<endl;
1230  while (true)
1231  {
1232  if (ctx >= 0)
1233  {
1234  (*ctxNum) = ctx;
1235 
1236  ctxs->resize (ctxs->size()+1, TQGArray::SpeedOptim);
1237  (*ctxs)[ctxs->size()-1]=(*ctxNum);
1238 
1239  return;
1240  }
1241  else
1242  {
1243  if (ctx == -1)
1244  {
1245  (*ctxNum)=( (ctxs->isEmpty() ) ? 0 : (*ctxs)[ctxs->size()-1]);
1246  }
1247  else
1248  {
1249  int size = ctxs->size() + ctx + 1;
1250 
1251  if (size > 0)
1252  {
1253  ctxs->resize (size, TQGArray::SpeedOptim);
1254  (*ctxNum)=(*ctxs)[size-1];
1255  }
1256  else
1257  {
1258  ctxs->resize (0, TQGArray::SpeedOptim);
1259  (*ctxNum)=0;
1260  }
1261 
1262  ctx = 0;
1263 
1264  if ((*prevLine) >= (int)(ctxs->size()-1))
1265  {
1266  *prevLine=ctxs->size()-1;
1267 
1268  if ( ctxs->isEmpty() )
1269  return;
1270 
1271  KateHlContext *c = contextNum((*ctxs)[ctxs->size()-1]);
1272  if (c && (c->ctx != -1))
1273  {
1274  //kdDebug(13010)<<"PrevLine > size()-1 and ctx!=-1)"<<endl;
1275  ctx = c->ctx;
1276 
1277  continue;
1278  }
1279  }
1280  }
1281 
1282  return;
1283  }
1284  }
1285 }
1286 
1290 int KateHighlighting::makeDynamicContext(KateHlContext *model, const TQStringList *args)
1291 {
1292  QPair<KateHlContext *, TQString> key(model, args->front());
1293  short value;
1294 
1295  if (dynamicCtxs.contains(key))
1296  value = dynamicCtxs[key];
1297  else
1298  {
1299  kdDebug(13010) << "new stuff: " << startctx << endl;
1300 
1301  KateHlContext *newctx = model->clone(args);
1302 
1303  m_contexts.push_back (newctx);
1304 
1305  value = startctx++;
1306  dynamicCtxs[key] = value;
1307  KateHlManager::self()->incDynamicCtxs();
1308  }
1309 
1310  // kdDebug(13010) << "Dynamic context: using context #" << value << " (for model " << model << " with args " << *args << ")" << endl;
1311 
1312  return value;
1313 }
1314 
1319 void KateHighlighting::dropDynamicContexts()
1320 {
1321  for (uint i=base_startctx; i < m_contexts.size(); ++i)
1322  delete m_contexts[i];
1323 
1324  m_contexts.resize (base_startctx);
1325 
1326  dynamicCtxs.clear();
1327  startctx = base_startctx;
1328 }
1329 
1338 void KateHighlighting::doHighlight ( KateTextLine *prevLine,
1339  KateTextLine *textLine,
1340  TQMemArray<uint>* foldingList,
1341  bool *ctxChanged )
1342 {
1343  if (!textLine)
1344  return;
1345 
1346  if (noHl)
1347  {
1348  if (textLine->length() > 0)
1349  memset (textLine->attributes(), 0, textLine->length());
1350 
1351  return;
1352  }
1353 
1354  // duplicate the ctx stack, only once !
1355  TQMemArray<short> ctx;
1356  ctx.duplicate (prevLine->ctxArray());
1357 
1358  int ctxNum = 0;
1359  int previousLine = -1;
1360  KateHlContext *context;
1361 
1362  if (ctx.isEmpty())
1363  {
1364  // If the stack is empty, we assume to be in Context 0 (Normal)
1365  context = contextNum(ctxNum);
1366  }
1367  else
1368  {
1369  // There does an old context stack exist -> find the context at the line start
1370  ctxNum = ctx[ctx.size()-1]; //context ID of the last character in the previous line
1371 
1372  //kdDebug(13010) << "\t\tctxNum = " << ctxNum << " contextList[ctxNum] = " << contextList[ctxNum] << endl; // ellis
1373 
1374  //if (lineContinue) kdDebug(13010)<<TQString("The old context should be %1").arg((int)ctxNum)<<endl;
1375 
1376  if (!(context = contextNum(ctxNum)))
1377  context = contextNum(0);
1378 
1379  //kdDebug(13010)<<"test1-2-1-text2"<<endl;
1380 
1381  previousLine=ctx.size()-1; //position of the last context ID of th previous line within the stack
1382 
1383  // hl continue set or not ???
1384  if (prevLine->hlLineContinue())
1385  {
1386  prevLine--;
1387  }
1388  else
1389  {
1390  generateContextStack(&ctxNum, context->ctx, &ctx, &previousLine); //get stack ID to use
1391 
1392  if (!(context = contextNum(ctxNum)))
1393  context = contextNum(0);
1394  }
1395 
1396  //kdDebug(13010)<<"test1-2-1-text4"<<endl;
1397 
1398  //if (lineContinue) kdDebug(13010)<<TQString("The new context is %1").arg((int)ctxNum)<<endl;
1399  }
1400 
1401  // text, for programming convenience :)
1402  TQChar lastChar = ' ';
1403  const TQString& text = textLine->string();
1404  const int len = textLine->length();
1405 
1406  // calc at which char the first char occurs, set it to length of line if never
1407  const int firstChar = textLine->firstChar();
1408  const int startNonSpace = (firstChar == -1) ? len : firstChar;
1409 
1410  // last found item
1411  KateHlItem *item = 0;
1412 
1413  // loop over the line, offset gives current offset
1414  int offset = 0;
1415  while (offset < len)
1416  {
1417  bool anItemMatched = false;
1418  bool standardStartEnableDetermined = false;
1419  bool customStartEnableDetermined = false;
1420 
1421  uint index = 0;
1422  for (item = context->items.empty() ? 0 : context->items[0]; item; item = (++index < context->items.size()) ? context->items[index] : 0 )
1423  {
1424  // does we only match if we are firstNonSpace?
1425  if (item->firstNonSpace && (offset > startNonSpace))
1426  continue;
1427 
1428  // have we a column specified? if yes, only match at this column
1429  if ((item->column != -1) && (item->column != offset))
1430  continue;
1431 
1432  if (!item->alwaysStartEnable)
1433  {
1434  if (item->customStartEnable)
1435  {
1436  if (customStartEnableDetermined || kateInsideString (m_additionalData[context->hlId]->deliminator, lastChar))
1437  customStartEnableDetermined = true;
1438  else
1439  continue;
1440  }
1441  else
1442  {
1443  if (standardStartEnableDetermined || kateInsideString (stdDeliminator, lastChar))
1444  standardStartEnableDetermined = true;
1445  else
1446  continue;
1447  }
1448  }
1449 
1450  int offset2 = item->checkHgl(text, offset, len-offset);
1451 
1452  if (offset2 <= offset)
1453  continue;
1454  // BUG 144599: Ignore a context change that would push the same context
1455  // without eating anything... this would be an infinite loop!
1456  if ( item->lookAhead && item->ctx == ctxNum )
1457  continue;
1458 
1459  if (item->region2)
1460  {
1461  // kdDebug(13010)<<TQString("Region mark 2 detected: %1").arg(item->region2)<<endl;
1462  if ( !foldingList->isEmpty() && ((item->region2 < 0) && ((int)((*foldingList)[foldingList->size()-2]) == -item->region2) ) )
1463  {
1464  foldingList->resize (foldingList->size()-2, TQGArray::SpeedOptim);
1465  }
1466  else
1467  {
1468  foldingList->resize (foldingList->size()+2, TQGArray::SpeedOptim);
1469  (*foldingList)[foldingList->size()-2] = (uint)item->region2;
1470  if (item->region2<0) //check not really needed yet
1471  (*foldingList)[foldingList->size()-1] = offset2;
1472  else
1473  (*foldingList)[foldingList->size()-1] = offset;
1474  }
1475 
1476  }
1477 
1478  if (item->region)
1479  {
1480  // kdDebug(13010)<<TQString("Region mark detected: %1").arg(item->region)<<endl;
1481 
1482  /* if ( !foldingList->isEmpty() && ((item->region < 0) && (*foldingList)[foldingList->size()-1] == -item->region ) )
1483  {
1484  foldingList->resize (foldingList->size()-1, TQGArray::SpeedOptim);
1485  }
1486  else*/
1487  {
1488  foldingList->resize (foldingList->size()+2, TQGArray::SpeedOptim);
1489  (*foldingList)[foldingList->size()-2] = item->region;
1490  if (item->region<0) //check not really needed yet
1491  (*foldingList)[foldingList->size()-1] = offset2;
1492  else
1493  (*foldingList)[foldingList->size()-1] = offset;
1494  }
1495 
1496  }
1497 
1498  // regenerate context stack if needed
1499  if (item->ctx != -1)
1500  {
1501  generateContextStack (&ctxNum, item->ctx, &ctx, &previousLine);
1502  context = contextNum(ctxNum);
1503  }
1504 
1505  // dynamic context: substitute the model with an 'instance'
1506  if (context->dynamic)
1507  {
1508  TQStringList *lst = item->capturedTexts();
1509  if (lst != 0)
1510  {
1511  // Replace the top of the stack and the current context
1512  int newctx = makeDynamicContext(context, lst);
1513  if (ctx.size() > 0)
1514  ctx[ctx.size() - 1] = newctx;
1515  ctxNum = newctx;
1516  context = contextNum(ctxNum);
1517  }
1518  delete lst;
1519  }
1520 
1521  // dominik: look ahead w/o changing offset?
1522  if (!item->lookAhead)
1523  {
1524  if (offset2 > len)
1525  offset2 = len;
1526 
1527  // even set attributes ;)
1528  memset ( textLine->attributes()+offset
1529  , item->onlyConsume ? context->attr : item->attr
1530  , offset2-offset);
1531 
1532  offset = offset2;
1533  lastChar = text[offset-1];
1534  }
1535 
1536  anItemMatched = true;
1537  break;
1538  }
1539 
1540  // something matched, continue loop
1541  if (anItemMatched)
1542  continue;
1543 
1544  // nothing found: set attribute of one char
1545  // anders: unless this context does not want that!
1546  if ( context->fallthrough )
1547  {
1548  // set context to context->ftctx.
1549  generateContextStack(&ctxNum, context->ftctx, &ctx, &previousLine); //regenerate context stack
1550  context=contextNum(ctxNum);
1551  //kdDebug(13010)<<"context num after fallthrough at col "<<z<<": "<<ctxNum<<endl;
1552  // the next is nessecary, as otherwise keyword (or anything using the std delimitor check)
1553  // immediately after fallthrough fails. Is it bad?
1554  // jowenn, can you come up with a nicer way to do this?
1555  /* if (offset)
1556  lastChar = text[offset - 1];
1557  else
1558  lastChar = '\\';*/
1559  continue;
1560  }
1561  else
1562  {
1563  *(textLine->attributes() + offset) = context->attr;
1564  lastChar = text[offset];
1565  offset++;
1566  }
1567  }
1568 
1569  // has the context stack changed ?
1570  if (ctx == textLine->ctxArray())
1571  {
1572  if (ctxChanged)
1573  (*ctxChanged) = false;
1574  }
1575  else
1576  {
1577  if (ctxChanged)
1578  (*ctxChanged) = true;
1579 
1580  // assign ctx stack !
1581  textLine->setContext(ctx);
1582  }
1583 
1584  // write hl continue flag
1585  textLine->setHlLineContinue (item && item->lineContinue());
1586 
1587  if (m_foldingIndentationSensitive) {
1588  bool noindent=false;
1589  for(int i=ctx.size()-1; i>=0; --i) {
1590  if (contextNum(ctx[i])->noIndentationBasedFolding) {
1591  noindent=true;
1592  break;
1593  }
1594  }
1595  textLine->setNoIndentBasedFolding(noindent);
1596  }
1597 }
1598 
1599 void KateHighlighting::loadWildcards()
1600 {
1601  KConfig *config = KateHlManager::self()->getKConfig();
1602  config->setGroup("Highlighting " + iName);
1603 
1604  TQString extensionString = config->readEntry("Wildcards", iWildcards);
1605 
1606  if (extensionSource != extensionString) {
1607  regexpExtensions.clear();
1608  plainExtensions.clear();
1609 
1610  extensionSource = extensionString;
1611 
1612  static TQRegExp sep("\\s*;\\s*");
1613 
1614  TQStringList l = TQStringList::split( sep, extensionSource );
1615 
1616  static TQRegExp boringExpression("\\*\\.[\\d\\w]+");
1617 
1618  for( TQStringList::Iterator it = l.begin(); it != l.end(); ++it )
1619  if (boringExpression.exactMatch(*it))
1620  plainExtensions.append((*it).mid(1));
1621  else
1622  regexpExtensions.append(TQRegExp((*it), true, true));
1623  }
1624 }
1625 
1626 TQValueList<TQRegExp>& KateHighlighting::getRegexpExtensions()
1627 {
1628  return regexpExtensions;
1629 }
1630 
1631 TQStringList& KateHighlighting::getPlainExtensions()
1632 {
1633  return plainExtensions;
1634 }
1635 
1636 TQString KateHighlighting::getMimetypes()
1637 {
1638  KConfig *config = KateHlManager::self()->getKConfig();
1639  config->setGroup("Highlighting " + iName);
1640 
1641  return config->readEntry("Mimetypes", iMimetypes);
1642 }
1643 
1644 int KateHighlighting::priority()
1645 {
1646  KConfig *config = KateHlManager::self()->getKConfig();
1647  config->setGroup("Highlighting " + iName);
1648 
1649  return config->readNumEntry("Priority", m_priority);
1650 }
1651 
1652 KateHlData *KateHighlighting::getData()
1653 {
1654  KConfig *config = KateHlManager::self()->getKConfig();
1655  config->setGroup("Highlighting " + iName);
1656 
1657  KateHlData *hlData = new KateHlData(
1658  config->readEntry("Wildcards", iWildcards),
1659  config->readEntry("Mimetypes", iMimetypes),
1660  config->readEntry("Identifier", identifier),
1661  config->readNumEntry("Priority", m_priority));
1662 
1663  return hlData;
1664 }
1665 
1666 void KateHighlighting::setData(KateHlData *hlData)
1667 {
1668  KConfig *config = KateHlManager::self()->getKConfig();
1669  config->setGroup("Highlighting " + iName);
1670 
1671  config->writeEntry("Wildcards",hlData->wildcards);
1672  config->writeEntry("Mimetypes",hlData->mimetypes);
1673  config->writeEntry("Priority",hlData->priority);
1674 }
1675 
1676 void KateHighlighting::getKateHlItemDataList (uint schema, KateHlItemDataList &list)
1677 {
1678  KConfig *config = KateHlManager::self()->getKConfig();
1679  config->setGroup("Highlighting " + iName + " - Schema " + KateFactory::self()->schemaManager()->name(schema));
1680 
1681  list.clear();
1682  createKateHlItemData(list);
1683 
1684  for (KateHlItemData *p = list.first(); p != 0L; p = list.next())
1685  {
1686  TQStringList s = config->readListEntry(p->name);
1687 
1688 // kdDebug(13010)<<p->name<<s.count()<<endl;
1689  if (s.count()>0)
1690  {
1691 
1692  while(s.count()<9) s<<"";
1693  p->clear();
1694 
1695  TQString tmp=s[0]; if (!tmp.isEmpty()) p->defStyleNum=tmp.toInt();
1696 
1697  QRgb col;
1698 
1699  tmp=s[1]; if (!tmp.isEmpty()) {
1700  col=tmp.toUInt(0,16); p->setTextColor(col); }
1701 
1702  tmp=s[2]; if (!tmp.isEmpty()) {
1703  col=tmp.toUInt(0,16); p->setSelectedTextColor(col); }
1704 
1705  tmp=s[3]; if (!tmp.isEmpty()) p->setBold(tmp!="0");
1706 
1707  tmp=s[4]; if (!tmp.isEmpty()) p->setItalic(tmp!="0");
1708 
1709  tmp=s[5]; if (!tmp.isEmpty()) p->setStrikeOut(tmp!="0");
1710 
1711  tmp=s[6]; if (!tmp.isEmpty()) p->setUnderline(tmp!="0");
1712 
1713  tmp=s[7]; if (!tmp.isEmpty()) {
1714  col=tmp.toUInt(0,16); p->setBGColor(col); }
1715 
1716  tmp=s[8]; if (!tmp.isEmpty()) {
1717  col=tmp.toUInt(0,16); p->setSelectedBGColor(col); }
1718 
1719  }
1720  }
1721 }
1722 
1729 void KateHighlighting::setKateHlItemDataList(uint schema, KateHlItemDataList &list)
1730 {
1731  KConfig *config = KateHlManager::self()->getKConfig();
1732  config->setGroup("Highlighting " + iName + " - Schema "
1733  + KateFactory::self()->schemaManager()->name(schema));
1734 
1735  TQStringList settings;
1736 
1737  for (KateHlItemData *p = list.first(); p != 0L; p = list.next())
1738  {
1739  settings.clear();
1740  settings<<TQString::number(p->defStyleNum,10);
1741  settings<<(p->itemSet(KateAttribute::TextColor)?TQString::number(p->textColor().rgb(),16):"");
1742  settings<<(p->itemSet(KateAttribute::SelectedTextColor)?TQString::number(p->selectedTextColor().rgb(),16):"");
1743  settings<<(p->itemSet(KateAttribute::Weight)?(p->bold()?"1":"0"):"");
1744  settings<<(p->itemSet(KateAttribute::Italic)?(p->italic()?"1":"0"):"");
1745  settings<<(p->itemSet(KateAttribute::StrikeOut)?(p->strikeOut()?"1":"0"):"");
1746  settings<<(p->itemSet(KateAttribute::Underline)?(p->underline()?"1":"0"):"");
1747  settings<<(p->itemSet(KateAttribute::BGColor)?TQString::number(p->bgColor().rgb(),16):"");
1748  settings<<(p->itemSet(KateAttribute::SelectedBGColor)?TQString::number(p->selectedBGColor().rgb(),16):"");
1749  settings<<"---";
1750  config->writeEntry(p->name,settings);
1751  }
1752 }
1753 
1757 void KateHighlighting::use()
1758 {
1759  if (refCount == 0)
1760  init();
1761 
1762  refCount++;
1763 }
1764 
1768 void KateHighlighting::release()
1769 {
1770  refCount--;
1771 
1772  if (refCount == 0)
1773  done();
1774 }
1775 
1780 void KateHighlighting::init()
1781 {
1782  if (noHl)
1783  return;
1784 
1785  // cu contexts
1786  for (uint i=0; i < m_contexts.size(); ++i)
1787  delete m_contexts[i];
1788  m_contexts.clear ();
1789 
1790  makeContextList();
1791 }
1792 
1793 
1798 void KateHighlighting::done()
1799 {
1800  if (noHl)
1801  return;
1802 
1803  // cu contexts
1804  for (uint i=0; i < m_contexts.size(); ++i)
1805  delete m_contexts[i];
1806  m_contexts.clear ();
1807 
1808  internalIDList.clear();
1809 }
1810 
1818 void KateHighlighting::createKateHlItemData(KateHlItemDataList &list)
1819 {
1820  // If no highlighting is selected we need only one default.
1821  if (noHl)
1822  {
1823  list.append(new KateHlItemData(i18n("Normal Text"), KateHlItemData::dsNormal));
1824  return;
1825  }
1826 
1827  // If the internal list isn't already available read the config file
1828  if (internalIDList.isEmpty())
1829  makeContextList();
1830 
1831  list=internalIDList;
1832 }
1833 
1837 void KateHighlighting::addToKateHlItemDataList()
1838 {
1839  //Tell the syntax document class which file we want to parse and which data group
1840  KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
1841  KateSyntaxContextData *data = KateHlManager::self()->syntax->getGroupInfo("highlighting","itemData");
1842 
1843  //begin with the real parsing
1844  while (KateHlManager::self()->syntax->nextGroup(data))
1845  {
1846  // read all attributes
1847  TQString color = KateHlManager::self()->syntax->groupData(data,TQString("color"));
1848  TQString selColor = KateHlManager::self()->syntax->groupData(data,TQString("selColor"));
1849  TQString bold = KateHlManager::self()->syntax->groupData(data,TQString("bold"));
1850  TQString italic = KateHlManager::self()->syntax->groupData(data,TQString("italic"));
1851  TQString underline = KateHlManager::self()->syntax->groupData(data,TQString("underline"));
1852  TQString strikeOut = KateHlManager::self()->syntax->groupData(data,TQString("strikeOut"));
1853  TQString bgColor = KateHlManager::self()->syntax->groupData(data,TQString("backgroundColor"));
1854  TQString selBgColor = KateHlManager::self()->syntax->groupData(data,TQString("selBackgroundColor"));
1855 
1856  KateHlItemData* newData = new KateHlItemData(
1857  buildPrefix+KateHlManager::self()->syntax->groupData(data,TQString("name")).simplifyWhiteSpace(),
1858  getDefStyleNum(KateHlManager::self()->syntax->groupData(data,TQString("defStyleNum"))));
1859 
1860  /* here the custom style overrides are specified, if needed */
1861  if (!color.isEmpty()) newData->setTextColor(TQColor(color));
1862  if (!selColor.isEmpty()) newData->setSelectedTextColor(TQColor(selColor));
1863  if (!bold.isEmpty()) newData->setBold( IS_TRUE(bold) );
1864  if (!italic.isEmpty()) newData->setItalic( IS_TRUE(italic) );
1865  // new attributes for the new rendering view
1866  if (!underline.isEmpty()) newData->setUnderline( IS_TRUE(underline) );
1867  if (!strikeOut.isEmpty()) newData->setStrikeOut( IS_TRUE(strikeOut) );
1868  if (!bgColor.isEmpty()) newData->setBGColor(TQColor(bgColor));
1869  if (!selBgColor.isEmpty()) newData->setSelectedBGColor(TQColor(selBgColor));
1870 
1871  internalIDList.append(newData);
1872  }
1873 
1874  //clean up
1875  if (data)
1876  KateHlManager::self()->syntax->freeGroupInfo(data);
1877 }
1878 
1889 int KateHighlighting::lookupAttrName(const TQString& name, KateHlItemDataList &iDl)
1890 {
1891  for (uint i = 0; i < iDl.count(); i++)
1892  if (iDl.at(i)->name == buildPrefix+name)
1893  return i;
1894 
1895  kdDebug(13010)<<"Couldn't resolve itemDataName:"<<name<<endl;
1896  return 0;
1897 }
1898 
1912 KateHlItem *KateHighlighting::createKateHlItem(KateSyntaxContextData *data,
1913  KateHlItemDataList &iDl,
1914  TQStringList *RegionList,
1915  TQStringList *ContextNameList)
1916 {
1917  // No highlighting -> exit
1918  if (noHl)
1919  return 0;
1920 
1921  // get the (tagname) itemd type
1922  TQString dataname=KateHlManager::self()->syntax->groupItemData(data,TQString(""));
1923 
1924  // code folding region handling:
1925  TQString beginRegionStr=KateHlManager::self()->syntax->groupItemData(data,TQString("beginRegion"));
1926  TQString endRegionStr=KateHlManager::self()->syntax->groupItemData(data,TQString("endRegion"));
1927 
1928  signed char regionId=0;
1929  signed char regionId2=0;
1930 
1931  if (!beginRegionStr.isEmpty())
1932  {
1933  regionId = RegionList->findIndex(beginRegionStr);
1934 
1935  if (regionId==-1) // if the region name doesn't already exist, add it to the list
1936  {
1937  (*RegionList)<<beginRegionStr;
1938  regionId = RegionList->findIndex(beginRegionStr);
1939  }
1940 
1941  regionId++;
1942 
1943  kdDebug(13010) << "########### BEG REG: " << beginRegionStr << " NUM: " << regionId << endl;
1944  }
1945 
1946  if (!endRegionStr.isEmpty())
1947  {
1948  regionId2 = RegionList->findIndex(endRegionStr);
1949 
1950  if (regionId2==-1) // if the region name doesn't already exist, add it to the list
1951  {
1952  (*RegionList)<<endRegionStr;
1953  regionId2 = RegionList->findIndex(endRegionStr);
1954  }
1955 
1956  regionId2 = -regionId2 - 1;
1957 
1958  kdDebug(13010) << "########### END REG: " << endRegionStr << " NUM: " << regionId2 << endl;
1959  }
1960 
1961  int attr = 0;
1962  TQString tmpAttr=KateHlManager::self()->syntax->groupItemData(data,TQString("attribute")).simplifyWhiteSpace();
1963  bool onlyConsume = tmpAttr.isEmpty();
1964 
1965  // only relevant for non consumer
1966  if (!onlyConsume)
1967  {
1968  if (TQString("%1").arg(tmpAttr.toInt())==tmpAttr)
1969  {
1970  errorsAndWarnings+=i18n(
1971  "<B>%1</B>: Deprecated syntax. Attribute (%2) not addressed by symbolic name<BR>").
1972  arg(buildIdentifier).arg(tmpAttr);
1973  attr=tmpAttr.toInt();
1974  }
1975  else
1976  attr=lookupAttrName(tmpAttr,iDl);
1977  }
1978 
1979  // Info about context switch
1980  int context = -1;
1981  TQString unresolvedContext;
1982  TQString tmpcontext=KateHlManager::self()->syntax->groupItemData(data,TQString("context"));
1983  if (!tmpcontext.isEmpty())
1984  context=getIdFromString(ContextNameList, tmpcontext,unresolvedContext);
1985 
1986  // Get the char parameter (eg DetectChar)
1987  char chr;
1988  if (! KateHlManager::self()->syntax->groupItemData(data,TQString("char")).isEmpty())
1989  chr= (KateHlManager::self()->syntax->groupItemData(data,TQString("char")).latin1())[0];
1990  else
1991  chr=0;
1992 
1993  // Get the String parameter (eg. StringDetect)
1994  TQString stringdata=KateHlManager::self()->syntax->groupItemData(data,TQString("String"));
1995 
1996  // Get a second char parameter (char1) (eg Detect2Chars)
1997  char chr1;
1998  if (! KateHlManager::self()->syntax->groupItemData(data,TQString("char1")).isEmpty())
1999  chr1= (KateHlManager::self()->syntax->groupItemData(data,TQString("char1")).latin1())[0];
2000  else
2001  chr1=0;
2002 
2003  // Will be removed eventually. Atm used for StringDetect, keyword and RegExp
2004  const TQString & insensitive_str = KateHlManager::self()->syntax->groupItemData(data,TQString("insensitive"));
2005  bool insensitive = IS_TRUE( insensitive_str );
2006 
2007  // for regexp only
2008  bool minimal = IS_TRUE( KateHlManager::self()->syntax->groupItemData(data,TQString("minimal")) );
2009 
2010  // dominik: look ahead and do not change offset. so we can change contexts w/o changing offset1.
2011  bool lookAhead = IS_TRUE( KateHlManager::self()->syntax->groupItemData(data,TQString("lookAhead")) );
2012 
2013  bool dynamic= IS_TRUE(KateHlManager::self()->syntax->groupItemData(data,TQString("dynamic")) );
2014 
2015  bool firstNonSpace = IS_TRUE(KateHlManager::self()->syntax->groupItemData(data,TQString("firstNonSpace")) );
2016 
2017  int column = -1;
2018  TQString colStr = KateHlManager::self()->syntax->groupItemData(data,TQString("column"));
2019  if (!colStr.isEmpty())
2020  column = colStr.toInt();
2021 
2022  //Create the item corresponding to it's type and set it's parameters
2023  KateHlItem *tmpItem;
2024 
2025  if (dataname=="keyword")
2026  {
2027  bool keywordInsensitive = insensitive_str.isEmpty() ? !casesensitive : insensitive;
2028  KateHlKeyword *keyword=new KateHlKeyword(attr,context,regionId,regionId2,keywordInsensitive,
2029  m_additionalData[ buildIdentifier ]->deliminator);
2030 
2031  //Get the entries for the keyword lookup list
2032  keyword->addList(KateHlManager::self()->syntax->finddata("highlighting",stringdata));
2033  tmpItem=keyword;
2034  }
2035  else if (dataname=="Float") tmpItem= (new KateHlFloat(attr,context,regionId,regionId2));
2036  else if (dataname=="Int") tmpItem=(new KateHlInt(attr,context,regionId,regionId2));
2037  else if (dataname=="DetectChar") tmpItem=(new KateHlCharDetect(attr,context,regionId,regionId2,chr));
2038  else if (dataname=="Detect2Chars") tmpItem=(new KateHl2CharDetect(attr,context,regionId,regionId2,chr,chr1));
2039  else if (dataname=="RangeDetect") tmpItem=(new KateHlRangeDetect(attr,context,regionId,regionId2, chr, chr1));
2040  else if (dataname=="LineContinue") tmpItem=(new KateHlLineContinue(attr,context,regionId,regionId2));
2041  else if (dataname=="StringDetect") tmpItem=(new KateHlStringDetect(attr,context,regionId,regionId2,stringdata,insensitive));
2042  else if (dataname=="AnyChar") tmpItem=(new KateHlAnyChar(attr,context,regionId,regionId2,stringdata));
2043  else if (dataname=="RegExpr") tmpItem=(new KateHlRegExpr(attr,context,regionId,regionId2,stringdata, insensitive, minimal));
2044  else if (dataname=="HlCChar") tmpItem= ( new KateHlCChar(attr,context,regionId,regionId2));
2045  else if (dataname=="HlCHex") tmpItem= (new KateHlCHex(attr,context,regionId,regionId2));
2046  else if (dataname=="HlCOct") tmpItem= (new KateHlCOct(attr,context,regionId,regionId2));
2047  else if (dataname=="HlCFloat") tmpItem= (new KateHlCFloat(attr,context,regionId,regionId2));
2048  else if (dataname=="HlCStringChar") tmpItem= (new KateHlCStringChar(attr,context,regionId,regionId2));
2049  else if (dataname=="DetectSpaces") tmpItem= (new KateHlDetectSpaces(attr,context,regionId,regionId2));
2050  else if (dataname=="DetectIdentifier") tmpItem= (new KateHlDetectIdentifier(attr,context,regionId,regionId2));
2051  else
2052  {
2053  // oops, unknown type. Perhaps a spelling error in the xml file
2054  return 0;
2055  }
2056 
2057  // set lookAhead & dynamic properties
2058  tmpItem->lookAhead = lookAhead;
2059  tmpItem->dynamic = dynamic;
2060  tmpItem->firstNonSpace = firstNonSpace;
2061  tmpItem->column = column;
2062  tmpItem->onlyConsume = onlyConsume;
2063 
2064  if (!unresolvedContext.isEmpty())
2065  {
2066  unresolvedContextReferences.insert(&(tmpItem->ctx),unresolvedContext);
2067  }
2068 
2069  return tmpItem;
2070 }
2071 
2072 TQString KateHighlighting::hlKeyForAttrib( int i ) const
2073 {
2074  // find entry. This is faster than TQMap::find. m_hlIndex always has an entry
2075  // for key '0' (it is "none"), so the result is always valid.
2076  int k = 0;
2077  TQMap<int,TQString>::const_iterator it = m_hlIndex.constEnd();
2078  while ( it != m_hlIndex.constBegin() )
2079  {
2080  --it;
2081  k = it.key();
2082  if ( i >= k )
2083  break;
2084  }
2085  return it.data();
2086 }
2087 
2088 bool KateHighlighting::isInWord( TQChar c, int attrib ) const
2089 {
2090  return m_additionalData[ hlKeyForAttrib( attrib ) ]->deliminator.find(c) < 0
2091  && !c.isSpace() && c != '"' && c != '\'';
2092 }
2093 
2094 bool KateHighlighting::canBreakAt( TQChar c, int attrib ) const
2095 {
2096  static const TQString& sq = KGlobal::staticQString("\"'");
2097  return (m_additionalData[ hlKeyForAttrib( attrib ) ]->wordWrapDeliminator.find(c) != -1) && (sq.find(c) == -1);
2098 }
2099 
2100 signed char KateHighlighting::commentRegion(int attr) const {
2101  TQString commentRegion=m_additionalData[ hlKeyForAttrib( attr ) ]->multiLineRegion;
2102  return (commentRegion.isEmpty()?0:(commentRegion.toShort()));
2103 }
2104 
2105 bool KateHighlighting::canComment( int startAttrib, int endAttrib ) const
2106 {
2107  TQString k = hlKeyForAttrib( startAttrib );
2108  return ( k == hlKeyForAttrib( endAttrib ) &&
2109  ( ( !m_additionalData[k]->multiLineCommentStart.isEmpty() && !m_additionalData[k]->multiLineCommentEnd.isEmpty() ) ||
2110  ! m_additionalData[k]->singleLineCommentMarker.isEmpty() ) );
2111 }
2112 
2113 TQString KateHighlighting::getCommentStart( int attrib ) const
2114 {
2115  return m_additionalData[ hlKeyForAttrib( attrib) ]->multiLineCommentStart;
2116 }
2117 
2118 TQString KateHighlighting::getCommentEnd( int attrib ) const
2119 {
2120  return m_additionalData[ hlKeyForAttrib( attrib ) ]->multiLineCommentEnd;
2121 }
2122 
2123 TQString KateHighlighting::getCommentSingleLineStart( int attrib ) const
2124 {
2125  return m_additionalData[ hlKeyForAttrib( attrib) ]->singleLineCommentMarker;
2126 }
2127 
2128 KateHighlighting::CSLPos KateHighlighting::getCommentSingleLinePosition( int attrib ) const
2129 {
2130  return m_additionalData[ hlKeyForAttrib( attrib) ]->singleLineCommentPosition;
2131 }
2132 
2133 
2138 void KateHighlighting::readCommentConfig()
2139 {
2140  KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
2141  KateSyntaxContextData *data=KateHlManager::self()->syntax->getGroupInfo("general","comment");
2142 
2143  TQString cmlStart="", cmlEnd="", cmlRegion="", cslStart="";
2144  CSLPos cslPosition=CSLPosColumn0;
2145 
2146  if (data)
2147  {
2148  while (KateHlManager::self()->syntax->nextGroup(data))
2149  {
2150  if (KateHlManager::self()->syntax->groupData(data,"name")=="singleLine")
2151  {
2152  cslStart=KateHlManager::self()->syntax->groupData(data,"start");
2153  TQString cslpos=KateHlManager::self()->syntax->groupData(data,"position");
2154  if (cslpos=="afterwhitespace")
2155  cslPosition=CSLPosAfterWhitespace;
2156  else
2157  cslPosition=CSLPosColumn0;
2158  }
2159  else if (KateHlManager::self()->syntax->groupData(data,"name")=="multiLine")
2160  {
2161  cmlStart=KateHlManager::self()->syntax->groupData(data,"start");
2162  cmlEnd=KateHlManager::self()->syntax->groupData(data,"end");
2163  cmlRegion=KateHlManager::self()->syntax->groupData(data,"region");
2164  }
2165  }
2166 
2167  KateHlManager::self()->syntax->freeGroupInfo(data);
2168  }
2169 
2170  m_additionalData[buildIdentifier]->singleLineCommentMarker = cslStart;
2171  m_additionalData[buildIdentifier]->singleLineCommentPosition = cslPosition;
2172  m_additionalData[buildIdentifier]->multiLineCommentStart = cmlStart;
2173  m_additionalData[buildIdentifier]->multiLineCommentEnd = cmlEnd;
2174  m_additionalData[buildIdentifier]->multiLineRegion = cmlRegion;
2175 }
2176 
2182 void KateHighlighting::readGlobalKeywordConfig()
2183 {
2184  deliminator = stdDeliminator;
2185  // Tell the syntax document class which file we want to parse
2186  kdDebug(13010)<<"readGlobalKeywordConfig:BEGIN"<<endl;
2187 
2188  KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
2189  KateSyntaxContextData *data = KateHlManager::self()->syntax->getConfig("general","keywords");
2190 
2191  if (data)
2192  {
2193  kdDebug(13010)<<"Found global keyword config"<<endl;
2194 
2195  if ( IS_TRUE( KateHlManager::self()->syntax->groupItemData(data,TQString("casesensitive")) ) )
2196  casesensitive=true;
2197  else
2198  casesensitive=false;
2199 
2200  //get the weak deliminators
2201  weakDeliminator=(KateHlManager::self()->syntax->groupItemData(data,TQString("weakDeliminator")));
2202 
2203  kdDebug(13010)<<"weak delimiters are: "<<weakDeliminator<<endl;
2204 
2205  // remove any weakDelimitars (if any) from the default list and store this list.
2206  for (uint s=0; s < weakDeliminator.length(); s++)
2207  {
2208  int f = deliminator.find (weakDeliminator[s]);
2209 
2210  if (f > -1)
2211  deliminator.remove (f, 1);
2212  }
2213 
2214  TQString addDelim = (KateHlManager::self()->syntax->groupItemData(data,TQString("additionalDeliminator")));
2215 
2216  if (!addDelim.isEmpty())
2217  deliminator=deliminator+addDelim;
2218 
2219  KateHlManager::self()->syntax->freeGroupInfo(data);
2220  }
2221  else
2222  {
2223  //Default values
2224  casesensitive=true;
2225  weakDeliminator=TQString("");
2226  }
2227 
2228  kdDebug(13010)<<"readGlobalKeywordConfig:END"<<endl;
2229 
2230  kdDebug(13010)<<"delimiterCharacters are: "<<deliminator<<endl;
2231 
2232  m_additionalData[buildIdentifier]->deliminator = deliminator;
2233 }
2234 
2245 void KateHighlighting::readWordWrapConfig()
2246 {
2247  // Tell the syntax document class which file we want to parse
2248  kdDebug(13010)<<"readWordWrapConfig:BEGIN"<<endl;
2249 
2250  KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
2251  KateSyntaxContextData *data = KateHlManager::self()->syntax->getConfig("general","keywords");
2252 
2253  TQString wordWrapDeliminator = stdDeliminator;
2254  if (data)
2255  {
2256  kdDebug(13010)<<"Found global keyword config"<<endl;
2257 
2258  wordWrapDeliminator = (KateHlManager::self()->syntax->groupItemData(data,TQString("wordWrapDeliminator")));
2259  //when no wordWrapDeliminator is defined use the deliminator list
2260  if ( wordWrapDeliminator.length() == 0 ) wordWrapDeliminator = deliminator;
2261 
2262  kdDebug(13010) << "word wrap deliminators are " << wordWrapDeliminator << endl;
2263 
2264  KateHlManager::self()->syntax->freeGroupInfo(data);
2265  }
2266 
2267  kdDebug(13010)<<"readWordWrapConfig:END"<<endl;
2268 
2269  m_additionalData[buildIdentifier]->wordWrapDeliminator = wordWrapDeliminator;
2270 }
2271 
2272 void KateHighlighting::readIndentationConfig()
2273 {
2274  m_indentation = "";
2275 
2276  KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
2277  KateSyntaxContextData *data = KateHlManager::self()->syntax->getConfig("general","indentation");
2278 
2279  if (data)
2280  {
2281  m_indentation = (KateHlManager::self()->syntax->groupItemData(data,TQString("mode")));
2282 
2283  KateHlManager::self()->syntax->freeGroupInfo(data);
2284  }
2285 }
2286 
2287 void KateHighlighting::readFoldingConfig()
2288 {
2289  // Tell the syntax document class which file we want to parse
2290  kdDebug(13010)<<"readfoldignConfig:BEGIN"<<endl;
2291 
2292  KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
2293  KateSyntaxContextData *data = KateHlManager::self()->syntax->getConfig("general","folding");
2294 
2295  if (data)
2296  {
2297  kdDebug(13010)<<"Found global keyword config"<<endl;
2298 
2299  if ( IS_TRUE( KateHlManager::self()->syntax->groupItemData(data,TQString("indentationsensitive")) ) )
2300  m_foldingIndentationSensitive=true;
2301  else
2302  m_foldingIndentationSensitive=false;
2303 
2304  KateHlManager::self()->syntax->freeGroupInfo(data);
2305  }
2306  else
2307  {
2308  //Default values
2309  m_foldingIndentationSensitive = false;
2310  }
2311 
2312  kdDebug(13010)<<"readfoldingConfig:END"<<endl;
2313 
2314  kdDebug(13010)<<"############################ use indent for fold are: "<<m_foldingIndentationSensitive<<endl;
2315 }
2316 
2317 void KateHighlighting::createContextNameList(TQStringList *ContextNameList,int ctx0)
2318 {
2319  kdDebug(13010)<<"creatingContextNameList:BEGIN"<<endl;
2320 
2321  if (ctx0 == 0)
2322  ContextNameList->clear();
2323 
2324  KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
2325 
2326  KateSyntaxContextData *data=KateHlManager::self()->syntax->getGroupInfo("highlighting","context");
2327 
2328  int id=ctx0;
2329 
2330  if (data)
2331  {
2332  while (KateHlManager::self()->syntax->nextGroup(data))
2333  {
2334  TQString tmpAttr=KateHlManager::self()->syntax->groupData(data,TQString("name")).simplifyWhiteSpace();
2335  if (tmpAttr.isEmpty())
2336  {
2337  tmpAttr=TQString("!KATE_INTERNAL_DUMMY! %1").arg(id);
2338  errorsAndWarnings +=i18n("<B>%1</B>: Deprecated syntax. Context %2 has no symbolic name<BR>").arg(buildIdentifier).arg(id-ctx0);
2339  }
2340  else tmpAttr=buildPrefix+tmpAttr;
2341  (*ContextNameList)<<tmpAttr;
2342  id++;
2343  }
2344  KateHlManager::self()->syntax->freeGroupInfo(data);
2345  }
2346  kdDebug(13010)<<"creatingContextNameList:END"<<endl;
2347 
2348 }
2349 
2350 int KateHighlighting::getIdFromString(TQStringList *ContextNameList, TQString tmpLineEndContext, /*NO CONST*/ TQString &unres)
2351 {
2352  unres="";
2353  int context;
2354  if ((tmpLineEndContext=="#stay") || (tmpLineEndContext.simplifyWhiteSpace().isEmpty()))
2355  context=-1;
2356 
2357  else if (tmpLineEndContext.startsWith("#pop"))
2358  {
2359  context=-1;
2360  for(;tmpLineEndContext.startsWith("#pop");context--)
2361  {
2362  tmpLineEndContext.remove(0,4);
2363  kdDebug(13010)<<"#pop found"<<endl;
2364  }
2365  }
2366 
2367  else if ( tmpLineEndContext.contains("##"))
2368  {
2369  int o = tmpLineEndContext.find("##");
2370  // FIXME at least with 'foo##bar'-style contexts the rules are picked up
2371  // but the default attribute is not
2372  TQString tmp=tmpLineEndContext.mid(o+2);
2373  if (!embeddedHls.contains(tmp)) embeddedHls.insert(tmp,KateEmbeddedHlInfo());
2374  unres=tmp+':'+tmpLineEndContext.left(o);
2375  context=0;
2376  }
2377 
2378  else
2379  {
2380  context=ContextNameList->findIndex(buildPrefix+tmpLineEndContext);
2381  if (context==-1)
2382  {
2383  context=tmpLineEndContext.toInt();
2384  errorsAndWarnings+=i18n(
2385  "<B>%1</B>:Deprecated syntax. Context %2 not addressed by a symbolic name"
2386  ).arg(buildIdentifier).arg(tmpLineEndContext);
2387  }
2388 //#warning restructure this the name list storage.
2389 // context=context+buildContext0Offset;
2390  }
2391  return context;
2392 }
2393 
2399 void KateHighlighting::makeContextList()
2400 {
2401  if (noHl) // if this a highlighting for "normal texts" only, tere is no need for a context list creation
2402  return;
2403 
2404  embeddedHls.clear();
2405  unresolvedContextReferences.clear();
2406  RegionList.clear();
2407  ContextNameList.clear();
2408 
2409  // prepare list creation. To reuse as much code as possible handle this
2410  // highlighting the same way as embedded onces
2411  embeddedHls.insert(iName,KateEmbeddedHlInfo());
2412 
2413  bool something_changed;
2414  // the context "0" id is 0 for this hl, all embedded context "0"s have offsets
2415  startctx=base_startctx=0;
2416  // inform everybody that we are building the highlighting contexts and itemlists
2417  building=true;
2418 
2419  do
2420  {
2421  kdDebug(13010)<<"**************** Outer loop in make ContextList"<<endl;
2422  kdDebug(13010)<<"**************** Hl List count:"<<embeddedHls.count()<<endl;
2423  something_changed=false; //assume all "embedded" hls have already been loaded
2424  for (KateEmbeddedHlInfos::const_iterator it=embeddedHls.begin(); it!=embeddedHls.end();++it)
2425  {
2426  if (!it.data().loaded) // we found one, we still have to load
2427  {
2428  kdDebug(13010)<<"**************** Inner loop in make ContextList"<<endl;
2429  TQString identifierToUse;
2430  kdDebug(13010)<<"Trying to open highlighting definition file: "<< it.key()<<endl;
2431  if (iName==it.key()) // the own identifier is known
2432  identifierToUse=identifier;
2433  else // all others have to be looked up
2434  identifierToUse=KateHlManager::self()->identifierForName(it.key());
2435 
2436  kdDebug(13010)<<"Location is:"<< identifierToUse<<endl;
2437 
2438  buildPrefix=it.key()+':'; // attribute names get prefixed by the names
2439  // of the highlighting definitions they belong to
2440 
2441  if (identifierToUse.isEmpty() )
2442  kdDebug(13010)<<"OHOH, unknown highlighting description referenced"<<endl;
2443 
2444  kdDebug(13010)<<"setting ("<<it.key()<<") to loaded"<<endl;
2445 
2446  //mark hl as loaded
2447  it=embeddedHls.insert(it.key(),KateEmbeddedHlInfo(true,startctx));
2448  //set class member for context 0 offset, so we don't need to pass it around
2449  buildContext0Offset=startctx;
2450  //parse one hl definition file
2451  startctx=addToContextList(identifierToUse,startctx);
2452 
2453  if (noHl) return; // an error occurred
2454 
2455  base_startctx = startctx;
2456  something_changed=true; // something has been loaded
2457  }
2458  }
2459  } while (something_changed); // as long as there has been another file parsed
2460  // repeat everything, there could be newly added embedded hls.
2461 
2462 
2463  // at this point all needed highlighing (sub)definitions are loaded. It's time
2464  // to resolve cross file references (if there are any)
2465  kdDebug(13010)<<"Unresolved contexts, which need attention: "<<unresolvedContextReferences.count()<<endl;
2466 
2467  //optimize this a littlebit
2468  for (KateHlUnresolvedCtxRefs::iterator unresIt=unresolvedContextReferences.begin();
2469  unresIt!=unresolvedContextReferences.end();++unresIt)
2470  {
2471  TQString incCtx = unresIt.data();
2472  kdDebug(13010)<<"Context "<<incCtx<<" is unresolved"<<endl;
2473  // only resolve '##Name' contexts here; handleKateHlIncludeRules() can figure
2474  // out 'Name##Name'-style inclusions, but we screw it up
2475  if (incCtx.endsWith(":")) {
2476  kdDebug(13010)<<"Looking up context0 for ruleset "<<incCtx<<endl;
2477  incCtx = incCtx.left(incCtx.length()-1);
2478  //try to find the context0 id for a given unresolvedReference
2479  KateEmbeddedHlInfos::const_iterator hlIt=embeddedHls.find(incCtx);
2480  if (hlIt!=embeddedHls.end())
2481  *(unresIt.key())=hlIt.data().context0;
2482  }
2483  }
2484 
2485  // eventually handle KateHlIncludeRules items, if they exist.
2486  // This has to be done after the cross file references, because it is allowed
2487  // to include the context0 from a different definition, than the one the rule
2488  // belongs to
2489  handleKateHlIncludeRules();
2490 
2491  embeddedHls.clear(); //save some memory.
2492  unresolvedContextReferences.clear(); //save some memory
2493  RegionList.clear(); // I think you get the idea ;)
2494  ContextNameList.clear();
2495 
2496 
2497  // if there have been errors show them
2498  if (!errorsAndWarnings.isEmpty())
2499  KMessageBox::detailedSorry(0L,i18n(
2500  "There were warning(s) and/or error(s) while parsing the syntax "
2501  "highlighting configuration."),
2502  errorsAndWarnings, i18n("Kate Syntax Highlighting Parser"));
2503 
2504  // we have finished
2505  building=false;
2506 }
2507 
2508 void KateHighlighting::handleKateHlIncludeRules()
2509 {
2510  // if there are noe include rules to take care of, just return
2511  kdDebug(13010)<<"KateHlIncludeRules, which need attention: " <<includeRules.count()<<endl;
2512  if (includeRules.isEmpty()) return;
2513 
2514  buildPrefix="";
2515  TQString dummy;
2516 
2517  // By now the context0 references are resolved, now more or less only inner
2518  // file references are resolved. If we decide that arbitrary inclusion is
2519  // needed, this doesn't need to be changed, only the addToContextList
2520  // method.
2521 
2522  //resolove context names
2523  for (KateHlIncludeRules::iterator it=includeRules.begin();it!=includeRules.end();)
2524  {
2525  if ((*it)->incCtx==-1) // context unresolved ?
2526  {
2527 
2528  if ((*it)->incCtxN.isEmpty())
2529  {
2530  // no context name given, and no valid context id set, so this item is
2531  // going to be removed
2532  KateHlIncludeRules::iterator it1=it;
2533  ++it1;
2534  delete (*it);
2535  includeRules.remove(it);
2536  it=it1;
2537  }
2538  else
2539  {
2540  // resolve name to id
2541  (*it)->incCtx=getIdFromString(&ContextNameList,(*it)->incCtxN,dummy);
2542  kdDebug(13010)<<"Resolved "<<(*it)->incCtxN<< " to "<<(*it)->incCtx<<" for include rule"<<endl;
2543  // It would be good to look here somehow, if the result is valid
2544  }
2545  }
2546  else ++it; //nothing to do, already resolved (by the cross defintion reference resolver)
2547  }
2548 
2549  // now that all KateHlIncludeRule items should be valid and completely resolved,
2550  // do the real inclusion of the rules.
2551  // recursiveness is needed, because context 0 could include context 1, which
2552  // itself includes context 2 and so on.
2553  // In that case we have to handle context 2 first, then 1, 0
2554  //TODO: catch circular references: eg 0->1->2->3->1
2555  while (!includeRules.isEmpty())
2556  handleKateHlIncludeRulesRecursive(includeRules.begin(),&includeRules);
2557 }
2558 
2559 void KateHighlighting::handleKateHlIncludeRulesRecursive(KateHlIncludeRules::iterator it, KateHlIncludeRules *list)
2560 {
2561  if (it==list->end()) return; //invalid iterator, shouldn't happen, but better have a rule prepared ;)
2562 
2563  KateHlIncludeRules::iterator it1=it;
2564  int ctx=(*it1)->ctx;
2565 
2566  // find the last entry for the given context in the KateHlIncludeRules list
2567  // this is need if one context includes more than one. This saves us from
2568  // updating all insert positions:
2569  // eg: context 0:
2570  // pos 3 - include context 2
2571  // pos 5 - include context 3
2572  // During the building of the includeRules list the items are inserted in
2573  // ascending order, now we need it descending to make our life easier.
2574  while ((it!=list->end()) && ((*it)->ctx==ctx))
2575  {
2576  it1=it;
2577  ++it;
2578  }
2579 
2580  // iterate over each include rule for the context the function has been called for.
2581  while ((it1!=list->end()) && ((*it1)->ctx==ctx))
2582  {
2583  int ctx1=(*it1)->incCtx;
2584 
2585  //let's see, if the the included context includes other contexts
2586  for (KateHlIncludeRules::iterator it2=list->begin();it2!=list->end();++it2)
2587  {
2588  if ((*it2)->ctx==ctx1)
2589  {
2590  //yes it does, so first handle that include rules, since we want to
2591  // include those subincludes too
2592  handleKateHlIncludeRulesRecursive(it2,list);
2593  break;
2594  }
2595  }
2596 
2597  // if the context we want to include had sub includes, they are already inserted there.
2598  KateHlContext *dest=m_contexts[ctx];
2599  KateHlContext *src=m_contexts[ctx1];
2600 // kdDebug(3010)<<"linking included rules from "<<ctx<<" to "<<ctx1<<endl;
2601 
2602  // If so desired, change the dest attribute to the one of the src.
2603  // Required to make commenting work, if text matched by the included context
2604  // is a different highlight than the host context.
2605  if ( (*it1)->includeAttrib )
2606  dest->attr = src->attr;
2607 
2608  // insert the included context's rules starting at position p
2609  int p=(*it1)->pos;
2610 
2611  // remember some stuff
2612  int oldLen = dest->items.size();
2613  uint itemsToInsert = src->items.size();
2614 
2615  // resize target
2616  dest->items.resize (oldLen + itemsToInsert);
2617 
2618  // move old elements
2619  for (int i=oldLen-1; i >= p; --i)
2620  dest->items[i+itemsToInsert] = dest->items[i];
2621 
2622  // insert new stuff
2623  for (uint i=0; i < itemsToInsert; ++i )
2624  dest->items[p+i] = src->items[i];
2625 
2626  it=it1; //backup the iterator
2627  --it1; //move to the next entry, which has to be take care of
2628  delete (*it); //free the already handled data structure
2629  list->remove(it); // remove it from the list
2630  }
2631 }
2632 
2638 int KateHighlighting::addToContextList(const TQString &ident, int ctx0)
2639 {
2640  kdDebug(13010)<<"=== Adding hl with ident '"<<ident<<"'"<<endl;
2641 
2642  buildIdentifier=ident;
2643  KateSyntaxContextData *data, *datasub;
2644  KateHlItem *c;
2645 
2646  TQString dummy;
2647 
2648  // Let the syntax document class know, which file we'd like to parse
2649  if (!KateHlManager::self()->syntax->setIdentifier(ident))
2650  {
2651  noHl=true;
2652  KMessageBox::information(0L,i18n(
2653  "Since there has been an error parsing the highlighting description, "
2654  "this highlighting will be disabled"));
2655  return 0;
2656  }
2657 
2658  // only read for the own stuff
2659  if (identifier == ident)
2660  {
2661  readIndentationConfig ();
2662  }
2663 
2664  RegionList<<"!KateInternal_TopLevel!";
2665 
2666  m_hlIndex[internalIDList.count()] = ident;
2667  m_additionalData.insert( ident, new HighlightPropertyBag );
2668 
2669  // fill out the propertybag
2670  readCommentConfig();
2671  readGlobalKeywordConfig();
2672  readWordWrapConfig();
2673 
2674  readFoldingConfig ();
2675 
2676  TQString ctxName;
2677 
2678  // This list is needed for the translation of the attribute parameter,
2679  // if the itemData name is given instead of the index
2680  addToKateHlItemDataList();
2681  KateHlItemDataList iDl = internalIDList;
2682 
2683  createContextNameList(&ContextNameList,ctx0);
2684 
2685 
2686  kdDebug(13010)<<"Parsing Context structure"<<endl;
2687  //start the real work
2688  data=KateHlManager::self()->syntax->getGroupInfo("highlighting","context");
2689  uint i=buildContext0Offset;
2690  if (data)
2691  {
2692  while (KateHlManager::self()->syntax->nextGroup(data))
2693  {
2694  kdDebug(13010)<<"Found a context in file, building structure now"<<endl;
2695  //BEGIN - Translation of the attribute parameter
2696  TQString tmpAttr=KateHlManager::self()->syntax->groupData(data,TQString("attribute")).simplifyWhiteSpace();
2697  int attr;
2698  if (TQString("%1").arg(tmpAttr.toInt())==tmpAttr)
2699  attr=tmpAttr.toInt();
2700  else
2701  attr=lookupAttrName(tmpAttr,iDl);
2702  //END - Translation of the attribute parameter
2703 
2704  ctxName=buildPrefix+KateHlManager::self()->syntax->groupData(data,TQString("lineEndContext")).simplifyWhiteSpace();
2705 
2706  TQString tmpLineEndContext=KateHlManager::self()->syntax->groupData(data,TQString("lineEndContext")).simplifyWhiteSpace();
2707  int context;
2708 
2709  context=getIdFromString(&ContextNameList, tmpLineEndContext,dummy);
2710 
2711  TQString tmpNIBF = KateHlManager::self()->syntax->groupData(data, TQString("noIndentationBasedFolding") );
2712  bool noIndentationBasedFolding=IS_TRUE(tmpNIBF);
2713 
2714  //BEGIN get fallthrough props
2715  bool ft = false;
2716  int ftc = 0; // fallthrough context
2717  if ( i > 0 ) // fallthrough is not smart in context 0
2718  {
2719  TQString tmpFt = KateHlManager::self()->syntax->groupData(data, TQString("fallthrough") );
2720  if ( IS_TRUE(tmpFt) )
2721  ft = true;
2722  if ( ft )
2723  {
2724  TQString tmpFtc = KateHlManager::self()->syntax->groupData( data, TQString("fallthroughContext") );
2725 
2726  ftc=getIdFromString(&ContextNameList, tmpFtc,dummy);
2727  if (ftc == -1) ftc =0;
2728 
2729  kdDebug(13010)<<"Setting fall through context (context "<<i<<"): "<<ftc<<endl;
2730  }
2731  }
2732  //END falltrhough props
2733 
2734  bool dynamic = false;
2735  TQString tmpDynamic = KateHlManager::self()->syntax->groupData(data, TQString("dynamic") );
2736  if ( tmpDynamic.lower() == "true" || tmpDynamic.toInt() == 1 )
2737  dynamic = true;
2738 
2739  KateHlContext *ctxNew = new KateHlContext (
2740  ident,
2741  attr,
2742  context,
2743  (KateHlManager::self()->syntax->groupData(data,TQString("lineBeginContext"))).isEmpty()?-1:
2744  (KateHlManager::self()->syntax->groupData(data,TQString("lineBeginContext"))).toInt(),
2745  ft, ftc, dynamic,noIndentationBasedFolding);
2746 
2747  m_contexts.push_back (ctxNew);
2748 
2749  kdDebug(13010) << "INDEX: " << i << " LENGTH " << m_contexts.size()-1 << endl;
2750 
2751  //Let's create all items for the context
2752  while (KateHlManager::self()->syntax->nextItem(data))
2753  {
2754 // kdDebug(13010)<< "In make Contextlist: Item:"<<endl;
2755 
2756  // KateHlIncludeRules : add a pointer to each item in that context
2757  // TODO add a attrib includeAttrib
2758  TQString tag = KateHlManager::self()->syntax->groupItemData(data,TQString(""));
2759  if ( tag == "IncludeRules" ) //if the new item is an Include rule, we have to take special care
2760  {
2761  TQString incCtx = KateHlManager::self()->syntax->groupItemData( data, TQString("context"));
2762  TQString incAttrib = KateHlManager::self()->syntax->groupItemData( data, TQString("includeAttrib"));
2763  bool includeAttrib = IS_TRUE( incAttrib );
2764  // only context refernces of type Name, ##Name, and Subname##Name are allowed
2765  if (incCtx.startsWith("##") || (!incCtx.startsWith("#")))
2766  {
2767  int incCtxi = incCtx.find("##");
2768  //#stay, #pop is not interesting here
2769  if (incCtxi >= 0)
2770  {
2771  TQString incSet = incCtx.mid(incCtxi + 2);
2772  TQString incCtxN = incSet + ":" + incCtx.left(incCtxi);
2773 
2774  //a cross highlighting reference
2775  kdDebug(13010)<<"Cross highlight reference <IncludeRules>, context "<<incCtxN<<endl;
2776  KateHlIncludeRule *ir=new KateHlIncludeRule(i,m_contexts[i]->items.count(),incCtxN,includeAttrib);
2777 
2778  //use the same way to determine cross hl file references as other items do
2779  if (!embeddedHls.contains(incSet))
2780  embeddedHls.insert(incSet,KateEmbeddedHlInfo());
2781  else
2782  kdDebug(13010)<<"Skipping embeddedHls.insert for "<<incCtxN<<endl;
2783 
2784  unresolvedContextReferences.insert(&(ir->incCtx), incCtxN);
2785 
2786  includeRules.append(ir);
2787  }
2788  else
2789  {
2790  // a local reference -> just initialize the include rule structure
2791  incCtx=buildPrefix+incCtx.simplifyWhiteSpace();
2792  includeRules.append(new KateHlIncludeRule(i,m_contexts[i]->items.count(),incCtx, includeAttrib));
2793  }
2794  }
2795 
2796  continue;
2797  }
2798  // TODO -- can we remove the block below??
2799 #if 0
2800  TQString tag = KateHlManager::self()->syntax->groupKateHlItemData(data,TQString(""));
2801  if ( tag == "IncludeRules" ) {
2802  // attrib context: the index (jowenn, i think using names here
2803  // would be a cool feat, goes for mentioning the context in
2804  // any item. a map or dict?)
2805  int ctxId = getIdFromString(&ContextNameList,
2806  KateHlManager::self()->syntax->groupKateHlItemData( data, TQString("context")),dummy); // the index is *required*
2807  if ( ctxId > -1) { // we can even reuse rules of 0 if we want to:)
2808  kdDebug(13010)<<"makeContextList["<<i<<"]: including all items of context "<<ctxId<<endl;
2809  if ( ctxId < (int) i ) { // must be defined
2810  for ( c = m_contexts[ctxId]->items.first(); c; c = m_contexts[ctxId]->items.next() )
2811  m_contexts[i]->items.append(c);
2812  }
2813  else
2814  kdDebug(13010)<<"Context "<<ctxId<<"not defined. You can not include the rules of an undefined context"<<endl;
2815  }
2816  continue; // while nextItem
2817  }
2818 #endif
2819  c=createKateHlItem(data,iDl,&RegionList,&ContextNameList);
2820  if (c)
2821  {
2822  m_contexts[i]->items.append(c);
2823 
2824  // Not supported completely atm and only one level. Subitems.(all have
2825  // to be matched to at once)
2826  datasub=KateHlManager::self()->syntax->getSubItems(data);
2827  bool tmpbool;
2828  if ((tmpbool = KateHlManager::self()->syntax->nextItem(datasub)))
2829  {
2830  for (;tmpbool;tmpbool=KateHlManager::self()->syntax->nextItem(datasub))
2831  {
2832  c->subItems.resize (c->subItems.size()+1);
2833  c->subItems[c->subItems.size()-1] = createKateHlItem(datasub,iDl,&RegionList,&ContextNameList);
2834  } }
2835  KateHlManager::self()->syntax->freeGroupInfo(datasub);
2836  // end of sublevel
2837  }
2838  }
2839  i++;
2840  }
2841  }
2842 
2843  KateHlManager::self()->syntax->freeGroupInfo(data);
2844 
2845  if (RegionList.count()!=1)
2846  folding=true;
2847 
2848  folding = folding || m_foldingIndentationSensitive;
2849 
2850  //BEGIN Resolve multiline region if possible
2851  if (!m_additionalData[ ident ]->multiLineRegion.isEmpty()) {
2852  long commentregionid=RegionList.findIndex( m_additionalData[ ident ]->multiLineRegion );
2853  if (-1==commentregionid) {
2854  errorsAndWarnings+=i18n(
2855  "<B>%1</B>: Specified multiline comment region (%2) could not be resolved<BR>"
2856  ).arg(buildIdentifier).arg( m_additionalData[ ident ]->multiLineRegion );
2857  m_additionalData[ ident ]->multiLineRegion = TQString();
2858  kdDebug(13010)<<"ERROR comment region attribute could not be resolved"<<endl;
2859 
2860  } else {
2861  m_additionalData[ ident ]->multiLineRegion=TQString::number(commentregionid+1);
2862  kdDebug(13010)<<"comment region resolved to:"<<m_additionalData[ ident ]->multiLineRegion<<endl;
2863  }
2864  }
2865  //END Resolve multiline region if possible
2866  return i;
2867 }
2868 
2869 void KateHighlighting::clearAttributeArrays ()
2870 {
2871  for ( TQIntDictIterator< TQMemArray<KateAttribute> > it( m_attributeArrays ); it.current(); ++it )
2872  {
2873  // k, schema correct, let create the data
2874  KateAttributeList defaultStyleList;
2875  defaultStyleList.setAutoDelete(true);
2876  KateHlManager::self()->getDefaults(it.currentKey(), defaultStyleList);
2877 
2878  KateHlItemDataList itemDataList;
2879  getKateHlItemDataList(it.currentKey(), itemDataList);
2880 
2881  uint nAttribs = itemDataList.count();
2882  TQMemArray<KateAttribute> *array = it.current();
2883  array->resize (nAttribs);
2884 
2885  for (uint z = 0; z < nAttribs; z++)
2886  {
2887  KateHlItemData *itemData = itemDataList.at(z);
2888  KateAttribute n = *defaultStyleList.at(itemData->defStyleNum);
2889 
2890  if (itemData && itemData->isSomethingSet())
2891  n += *itemData;
2892 
2893  array->at(z) = n;
2894  }
2895  }
2896 }
2897 
2898 TQMemArray<KateAttribute> *KateHighlighting::attributes (uint schema)
2899 {
2900  TQMemArray<KateAttribute> *array;
2901 
2902  // found it, allready floating around
2903  if ((array = m_attributeArrays[schema]))
2904  return array;
2905 
2906  // ohh, not found, check if valid schema number
2907  if (!KateFactory::self()->schemaManager()->validSchema(schema))
2908  {
2909  // uhh, not valid :/, stick with normal default schema, it's always there !
2910  return attributes (0);
2911  }
2912 
2913  // k, schema correct, let create the data
2914  KateAttributeList defaultStyleList;
2915  defaultStyleList.setAutoDelete(true);
2916  KateHlManager::self()->getDefaults(schema, defaultStyleList);
2917 
2918  KateHlItemDataList itemDataList;
2919  getKateHlItemDataList(schema, itemDataList);
2920 
2921  uint nAttribs = itemDataList.count();
2922  array = new TQMemArray<KateAttribute> (nAttribs);
2923 
2924  for (uint z = 0; z < nAttribs; z++)
2925  {
2926  KateHlItemData *itemData = itemDataList.at(z);
2927  KateAttribute n = *defaultStyleList.at(itemData->defStyleNum);
2928 
2929  if (itemData && itemData->isSomethingSet())
2930  n += *itemData;
2931 
2932  array->at(z) = n;
2933  }
2934 
2935  m_attributeArrays.insert(schema, array);
2936 
2937  return array;
2938 }
2939 
2940 void KateHighlighting::getKateHlItemDataListCopy (uint schema, KateHlItemDataList &outlist)
2941 {
2942  KateHlItemDataList itemDataList;
2943  getKateHlItemDataList(schema, itemDataList);
2944 
2945  outlist.clear ();
2946  outlist.setAutoDelete (true);
2947  for (uint z=0; z < itemDataList.count(); z++)
2948  outlist.append (new KateHlItemData (*itemDataList.at(z)));
2949 }
2950 
2951 //END
2952 
2953 //BEGIN KateHlManager
2954 KateHlManager::KateHlManager()
2955  : TQObject()
2956  , m_config ("katesyntaxhighlightingrc", false, false)
2957  , commonSuffixes (TQStringList::split(";", ".orig;.new;~;.bak;.BAK"))
2958  , syntax (new KateSyntaxDocument())
2959  , dynamicCtxsCount(0)
2960  , forceNoDCReset(false)
2961 {
2962  hlList.setAutoDelete(true);
2963  hlDict.setAutoDelete(false);
2964 
2965  KateSyntaxModeList modeList = syntax->modeList();
2966  for (uint i=0; i < modeList.count(); i++)
2967  {
2968  KateHighlighting *hl = new KateHighlighting(modeList[i]);
2969 
2970  uint insert = 0;
2971  for (; insert <= hlList.count(); insert++)
2972  {
2973  if (insert == hlList.count())
2974  break;
2975 
2976  if ( TQString(hlList.at(insert)->section() + hlList.at(insert)->nameTranslated()).lower()
2977  > TQString(hl->section() + hl->nameTranslated()).lower() )
2978  break;
2979  }
2980 
2981  hlList.insert (insert, hl);
2982  hlDict.insert (hl->name(), hl);
2983  }
2984 
2985  // Normal HL
2986  KateHighlighting *hl = new KateHighlighting(0);
2987  hlList.prepend (hl);
2988  hlDict.insert (hl->name(), hl);
2989 
2990  lastCtxsReset.start();
2991 }
2992 
2993 KateHlManager::~KateHlManager()
2994 {
2995  delete syntax;
2996 }
2997 
2998 static KStaticDeleter<KateHlManager> sdHlMan;
2999 
3000 KateHlManager *KateHlManager::self()
3001 {
3002  if ( !s_self )
3003  sdHlMan.setObject(s_self, new KateHlManager ());
3004 
3005  return s_self;
3006 }
3007 
3008 KateHighlighting *KateHlManager::getHl(int n)
3009 {
3010  if (n < 0 || n >= (int) hlList.count())
3011  n = 0;
3012 
3013  return hlList.at(n);
3014 }
3015 
3016 int KateHlManager::nameFind(const TQString &name)
3017 {
3018  int z (hlList.count() - 1);
3019  for (; z > 0; z--)
3020  if (hlList.at(z)->name() == name)
3021  return z;
3022 
3023  return z;
3024 }
3025 
3026 int KateHlManager::detectHighlighting (KateDocument *doc)
3027 {
3028  int hl = wildcardFind( doc->url().filename() );
3029  if ( hl < 0 )
3030  hl = mimeFind ( doc );
3031 
3032  return hl;
3033 }
3034 
3035 int KateHlManager::wildcardFind(const TQString &fileName)
3036 {
3037  int result = -1;
3038  if ((result = realWildcardFind(fileName)) != -1)
3039  return result;
3040 
3041  int length = fileName.length();
3042  TQString backupSuffix = KateDocumentConfig::global()->backupSuffix();
3043  if (fileName.endsWith(backupSuffix)) {
3044  if ((result = realWildcardFind(fileName.left(length - backupSuffix.length()))) != -1)
3045  return result;
3046  }
3047 
3048  for (TQStringList::Iterator it = commonSuffixes.begin(); it != commonSuffixes.end(); ++it) {
3049  if (*it != backupSuffix && fileName.endsWith(*it)) {
3050  if ((result = realWildcardFind(fileName.left(length - (*it).length()))) != -1)
3051  return result;
3052  }
3053  }
3054 
3055  return -1;
3056 }
3057 
3058 int KateHlManager::realWildcardFind(const TQString &fileName)
3059 {
3060  static TQRegExp sep("\\s*;\\s*");
3061 
3062  TQPtrList<KateHighlighting> highlights;
3063 
3064  for (KateHighlighting *highlight = hlList.first(); highlight != 0L; highlight = hlList.next()) {
3065  highlight->loadWildcards();
3066 
3067  for (TQStringList::Iterator it = highlight->getPlainExtensions().begin(); it != highlight->getPlainExtensions().end(); ++it)
3068  if (fileName.endsWith((*it)))
3069  highlights.append(highlight);
3070 
3071  for (int i = 0; i < (int)highlight->getRegexpExtensions().count(); i++) {
3072  TQRegExp re = highlight->getRegexpExtensions()[i];
3073  if (re.exactMatch(fileName))
3074  highlights.append(highlight);
3075  }
3076  }
3077 
3078  if ( !highlights.isEmpty() )
3079  {
3080  int pri = -1;
3081  int hl = -1;
3082 
3083  for (KateHighlighting *highlight = highlights.first(); highlight != 0L; highlight = highlights.next())
3084  {
3085  if (highlight->priority() > pri)
3086  {
3087  pri = highlight->priority();
3088  hl = hlList.findRef (highlight);
3089  }
3090  }
3091  return hl;
3092  }
3093 
3094  return -1;
3095 }
3096 
3097 int KateHlManager::mimeFind( KateDocument *doc )
3098 {
3099  static TQRegExp sep("\\s*;\\s*");
3100 
3101  KMimeType::Ptr mt = doc->mimeTypeForContent();
3102 
3103  TQPtrList<KateHighlighting> highlights;
3104 
3105  for (KateHighlighting *highlight = hlList.first(); highlight != 0L; highlight = hlList.next())
3106  {
3107  TQStringList l = TQStringList::split( sep, highlight->getMimetypes() );
3108 
3109  for( TQStringList::Iterator it = l.begin(); it != l.end(); ++it )
3110  {
3111  if ( *it == mt->name() ) // faster than a regexp i guess?
3112  highlights.append (highlight);
3113  }
3114  }
3115 
3116  if ( !highlights.isEmpty() )
3117  {
3118  int pri = -1;
3119  int hl = -1;
3120 
3121  for (KateHighlighting *highlight = highlights.first(); highlight != 0L; highlight = highlights.next())
3122  {
3123  if (highlight->priority() > pri)
3124  {
3125  pri = highlight->priority();
3126  hl = hlList.findRef (highlight);
3127  }
3128  }
3129 
3130  return hl;
3131  }
3132 
3133  return -1;
3134 }
3135 
3136 uint KateHlManager::defaultStyles()
3137 {
3138  return 14;
3139 }
3140 
3141 TQString KateHlManager::defaultStyleName(int n, bool translateNames)
3142 {
3143  static TQStringList names;
3144  static TQStringList translatedNames;
3145 
3146  if (names.isEmpty())
3147  {
3148  names << "Normal";
3149  names << "Keyword";
3150  names << "Data Type";
3151  names << "Decimal/Value";
3152  names << "Base-N Integer";
3153  names << "Floating Point";
3154  names << "Character";
3155  names << "String";
3156  names << "Comment";
3157  names << "Others";
3158  names << "Alert";
3159  names << "Function";
3160  // this next one is for denoting the beginning/end of a user defined folding region
3161  names << "Region Marker";
3162  // this one is for marking invalid input
3163  names << "Error";
3164 
3165  translatedNames << i18n("Normal");
3166  translatedNames << i18n("Keyword");
3167  translatedNames << i18n("Data Type");
3168  translatedNames << i18n("Decimal/Value");
3169  translatedNames << i18n("Base-N Integer");
3170  translatedNames << i18n("Floating Point");
3171  translatedNames << i18n("Character");
3172  translatedNames << i18n("String");
3173  translatedNames << i18n("Comment");
3174  translatedNames << i18n("Others");
3175  translatedNames << i18n("Alert");
3176  translatedNames << i18n("Function");
3177  // this next one is for denoting the beginning/end of a user defined folding region
3178  translatedNames << i18n("Region Marker");
3179  // this one is for marking invalid input
3180  translatedNames << i18n("Error");
3181  }
3182 
3183  return translateNames ? translatedNames[n] : names[n];
3184 }
3185 
3186 void KateHlManager::getDefaults(uint schema, KateAttributeList &list)
3187 {
3188  list.setAutoDelete(true);
3189 
3190  KateAttribute* normal = new KateAttribute();
3191  normal->setTextColor(Qt::black);
3192  normal->setSelectedTextColor(Qt::white);
3193  list.append(normal);
3194 
3195  KateAttribute* keyword = new KateAttribute();
3196  keyword->setTextColor(Qt::black);
3197  keyword->setSelectedTextColor(Qt::white);
3198  keyword->setBold(true);
3199  list.append(keyword);
3200 
3201  KateAttribute* dataType = new KateAttribute();
3202  dataType->setTextColor(Qt::darkRed);
3203  dataType->setSelectedTextColor(Qt::white);
3204  list.append(dataType);
3205 
3206  KateAttribute* decimal = new KateAttribute();
3207  decimal->setTextColor(Qt::blue);
3208  decimal->setSelectedTextColor(Qt::cyan);
3209  list.append(decimal);
3210 
3211  KateAttribute* basen = new KateAttribute();
3212  basen->setTextColor(Qt::darkCyan);
3213  basen->setSelectedTextColor(Qt::cyan);
3214  list.append(basen);
3215 
3216  KateAttribute* floatAttribute = new KateAttribute();
3217  floatAttribute->setTextColor(Qt::darkMagenta);
3218  floatAttribute->setSelectedTextColor(Qt::cyan);
3219  list.append(floatAttribute);
3220 
3221  KateAttribute* charAttribute = new KateAttribute();
3222  charAttribute->setTextColor(Qt::magenta);
3223  charAttribute->setSelectedTextColor(Qt::magenta);
3224  list.append(charAttribute);
3225 
3226  KateAttribute* string = new KateAttribute();
3227  string->setTextColor(TQColor("#D00"));
3228  string->setSelectedTextColor(Qt::red);
3229  list.append(string);
3230 
3231  KateAttribute* comment = new KateAttribute();
3232  comment->setTextColor(Qt::darkGray);
3233  comment->setSelectedTextColor(Qt::gray);
3234  comment->setItalic(true);
3235  list.append(comment);
3236 
3237  KateAttribute* others = new KateAttribute();
3238  others->setTextColor(Qt::darkGreen);
3239  others->setSelectedTextColor(Qt::green);
3240  list.append(others);
3241 
3242  KateAttribute* alert = new KateAttribute();
3243  alert->setTextColor(Qt::black);
3244  alert->setSelectedTextColor( TQColor("#FCC") );
3245  alert->setBold(true);
3246  alert->setBGColor( TQColor("#FCC") );
3247  list.append(alert);
3248 
3249  KateAttribute* functionAttribute = new KateAttribute();
3250  functionAttribute->setTextColor(Qt::darkBlue);
3251  functionAttribute->setSelectedTextColor(Qt::white);
3252  list.append(functionAttribute);
3253 
3254  KateAttribute* regionmarker = new KateAttribute();
3255  regionmarker->setTextColor(Qt::white);
3256  regionmarker->setBGColor(Qt::gray);
3257  regionmarker->setSelectedTextColor(Qt::gray);
3258  list.append(regionmarker);
3259 
3260  KateAttribute* error = new KateAttribute();
3261  error->setTextColor(Qt::red);
3262  error->setUnderline(true);
3263  error->setSelectedTextColor(Qt::red);
3264  list.append(error);
3265 
3266  KConfig *config = KateHlManager::self()->self()->getKConfig();
3267  config->setGroup("Default Item Styles - Schema " + KateFactory::self()->schemaManager()->name(schema));
3268 
3269  for (uint z = 0; z < defaultStyles(); z++)
3270  {
3271  KateAttribute *i = list.at(z);
3272  TQStringList s = config->readListEntry(defaultStyleName(z));
3273  if (!s.isEmpty())
3274  {
3275  while( s.count()<8)
3276  s << "";
3277 
3278  TQString tmp;
3279  QRgb col;
3280 
3281  tmp=s[0]; if (!tmp.isEmpty()) {
3282  col=tmp.toUInt(0,16); i->setTextColor(col); }
3283 
3284  tmp=s[1]; if (!tmp.isEmpty()) {
3285  col=tmp.toUInt(0,16); i->setSelectedTextColor(col); }
3286 
3287  tmp=s[2]; if (!tmp.isEmpty()) i->setBold(tmp!="0");
3288 
3289  tmp=s[3]; if (!tmp.isEmpty()) i->setItalic(tmp!="0");
3290 
3291  tmp=s[4]; if (!tmp.isEmpty()) i->setStrikeOut(tmp!="0");
3292 
3293  tmp=s[5]; if (!tmp.isEmpty()) i->setUnderline(tmp!="0");
3294 
3295  tmp=s[6]; if (!tmp.isEmpty()) {
3296  if ( tmp != "-" )
3297  {
3298  col=tmp.toUInt(0,16);
3299  i->setBGColor(col);
3300  }
3301  else
3302  i->clearAttribute(KateAttribute::BGColor);
3303  }
3304  tmp=s[7]; if (!tmp.isEmpty()) {
3305  if ( tmp != "-" )
3306  {
3307  col=tmp.toUInt(0,16);
3308  i->setSelectedBGColor(col);
3309  }
3310  else
3311  i->clearAttribute(KateAttribute::SelectedBGColor);
3312  }
3313  }
3314  }
3315 }
3316 
3317 void KateHlManager::setDefaults(uint schema, KateAttributeList &list)
3318 {
3319  KConfig *config = KateHlManager::self()->self()->getKConfig();
3320  config->setGroup("Default Item Styles - Schema " + KateFactory::self()->schemaManager()->name(schema));
3321 
3322  for (uint z = 0; z < defaultStyles(); z++)
3323  {
3324  TQStringList settings;
3325  KateAttribute *i = list.at(z);
3326 
3327  settings<<(i->itemSet(KateAttribute::TextColor)?TQString::number(i->textColor().rgb(),16):"");
3328  settings<<(i->itemSet(KateAttribute::SelectedTextColor)?TQString::number(i->selectedTextColor().rgb(),16):"");
3329  settings<<(i->itemSet(KateAttribute::Weight)?(i->bold()?"1":"0"):"");
3330  settings<<(i->itemSet(KateAttribute::Italic)?(i->italic()?"1":"0"):"");
3331  settings<<(i->itemSet(KateAttribute::StrikeOut)?(i->strikeOut()?"1":"0"):"");
3332  settings<<(i->itemSet(KateAttribute::Underline)?(i->underline()?"1":"0"):"");
3333  settings<<(i->itemSet(KateAttribute::BGColor)?TQString::number(i->bgColor().rgb(),16):"-");
3334  settings<<(i->itemSet(KateAttribute::SelectedBGColor)?TQString::number(i->selectedBGColor().rgb(),16):"-");
3335  settings<<"---";
3336 
3337  config->writeEntry(defaultStyleName(z),settings);
3338  }
3339 
3340  emit changed();
3341 }
3342 
3343 int KateHlManager::highlights()
3344 {
3345  return (int) hlList.count();
3346 }
3347 
3348 TQString KateHlManager::hlName(int n)
3349 {
3350  return hlList.at(n)->name();
3351 }
3352 
3353 TQString KateHlManager::hlNameTranslated(int n)
3354 {
3355  return hlList.at(n)->nameTranslated();
3356 }
3357 
3358 TQString KateHlManager::hlSection(int n)
3359 {
3360  return hlList.at(n)->section();
3361 }
3362 
3363 bool KateHlManager::hlHidden(int n)
3364 {
3365  return hlList.at(n)->hidden();
3366 }
3367 
3368 TQString KateHlManager::identifierForName(const TQString& name)
3369 {
3370  KateHighlighting *hl = 0;
3371 
3372  if ((hl = hlDict[name]))
3373  return hl->getIdentifier ();
3374 
3375  return TQString();
3376 }
3377 
3378 bool KateHlManager::resetDynamicCtxs()
3379 {
3380  if (forceNoDCReset)
3381  return false;
3382 
3383  if (lastCtxsReset.elapsed() < KATE_DYNAMIC_CONTEXTS_RESET_DELAY)
3384  return false;
3385 
3386  KateHighlighting *hl;
3387  for (hl = hlList.first(); hl; hl = hlList.next())
3388  hl->dropDynamicContexts();
3389 
3390  dynamicCtxsCount = 0;
3391  lastCtxsReset.start();
3392 
3393  return true;
3394 }
3395 //END
3396 
3397 //BEGIN KateHighlightAction
3398 void KateViewHighlightAction::init()
3399 {
3400  m_doc = 0;
3401  subMenus.setAutoDelete( true );
3402 
3403  connect(popupMenu(),TQT_SIGNAL(aboutToShow()),this,TQT_SLOT(slotAboutToShow()));
3404 }
3405 
3406 void KateViewHighlightAction::updateMenu (Kate::Document *doc)
3407 {
3408  m_doc = doc;
3409 }
3410 
3411 void KateViewHighlightAction::slotAboutToShow()
3412 {
3413  Kate::Document *doc=m_doc;
3414  int count = KateHlManager::self()->highlights();
3415 
3416  for (int z=0; z<count; z++)
3417  {
3418  TQString hlName = KateHlManager::self()->hlNameTranslated (z);
3419  TQString hlSection = KateHlManager::self()->hlSection (z);
3420 
3421  if (!KateHlManager::self()->hlHidden(z))
3422  {
3423  if ( !hlSection.isEmpty() && (names.contains(hlName) < 1) )
3424  {
3425  if (subMenusName.contains(hlSection) < 1)
3426  {
3427  subMenusName << hlSection;
3428  TQPopupMenu *menu = new TQPopupMenu ();
3429  subMenus.append(menu);
3430  popupMenu()->insertItem ( '&' + hlSection, menu);
3431  }
3432 
3433  int m = subMenusName.findIndex (hlSection);
3434  names << hlName;
3435  subMenus.at(m)->insertItem ( '&' + hlName, this, TQT_SLOT(setHl(int)), 0, z);
3436  }
3437  else if (names.contains(hlName) < 1)
3438  {
3439  names << hlName;
3440  popupMenu()->insertItem ( '&' + hlName, this, TQT_SLOT(setHl(int)), 0, z);
3441  }
3442  }
3443  }
3444 
3445  if (!doc) return;
3446 
3447  for (uint i=0;i<subMenus.count();i++)
3448  {
3449  for (uint i2=0;i2<subMenus.at(i)->count();i2++)
3450  {
3451  subMenus.at(i)->setItemChecked(subMenus.at(i)->idAt(i2),false);
3452  }
3453  }
3454  popupMenu()->setItemChecked (0, false);
3455 
3456  int i = subMenusName.findIndex (KateHlManager::self()->hlSection(doc->hlMode()));
3457  if (i >= 0 && subMenus.at(i))
3458  subMenus.at(i)->setItemChecked (doc->hlMode(), true);
3459  else
3460  popupMenu()->setItemChecked (0, true);
3461 }
3462 
3463 void KateViewHighlightAction::setHl (int mode)
3464 {
3465  Kate::Document *doc=m_doc;
3466 
3467  if (doc)
3468  doc->setHlMode((uint)mode);
3469 }
3470 //END KateViewHighlightAction
3471 
3472 // kate: space-indent on; indent-width 2; replace-tabs on;

kate

Skip menu "kate"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kate

Skip menu "kate"
  • arts
  • dcop
  • dnssd
  • interfaces
  •     interface
  •     library
  •   kspeech
  •   ktexteditor
  • kabc
  • kate
  • kcmshell
  • kdecore
  • kded
  • kdefx
  • kdeprint
  • kdesu
  • kdeui
  • kdoctools
  • khtml
  • kimgio
  • kinit
  • kio
  •   bookmarks
  •   httpfilter
  •   kfile
  •   kio
  •   kioexec
  •   kpasswdserver
  •   kssl
  • kioslave
  •   http
  • kjs
  • kmdi
  •   kmdi
  • knewstuff
  • kparts
  • krandr
  • kresources
  • kspell2
  • kunittest
  • kutils
  • kwallet
  • libkmid
  • libkscreensaver
Generated for kate by doxygen 1.8.3.1
This website is maintained by Timothy Pearson.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. |