1 /**
2 ** This program is free software; you can redistribute it and/or modify
3 ** it under the terms of the GNU General Public License as published by
4 ** the Free Software Foundation; either version 2 of the License, or
5 ** (at your option) any later version.
6 **
7 ** This program is distributed in the hope that it will be useful,
8 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
9 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 ** GNU General Public License for more details.
11 **
12 ** You should have received a copy of the GNU General Public License
13 ** along with this program; if not, write to the Free Software
14 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15 **/
16
17 #include <QTextDocument>
18
19 #include "EditSyntaxHighlighter.h"
20
EditSyntaxHighlighter(QTextDocument * parent)21 EditSyntaxHighlighter::EditSyntaxHighlighter(QTextDocument *parent)
22 : QSyntaxHighlighter(parent) {
23 initLabels();
24 initKeywords();
25 initConstants();
26 initNumbers();
27 initQuotes();
28 initComments();
29 }
30
highlightBlock(const QString & text)31 void EditSyntaxHighlighter::highlightBlock(const QString &text) {
32 HighlightRule rule;
33
34 VecHighlightRules::iterator sIt = m_standardRules.begin();
35 VecHighlightRules::iterator sItEnd = m_standardRules.end();
36 while (sIt != sItEnd) {
37 rule = (*sIt);
38 QRegExp expression(rule.pattern);
39 int index = text.indexOf(expression);
40 while (index >= 0) {
41 int length = expression.matchedLength();
42 if (format(index).foreground().color() != m_quoteFmt.foreground().color()) {
43 // dont set the color if we are in quotes
44 setFormat(index, length, rule.format);
45 }
46 index = text.indexOf(expression, index + length);
47 }
48 ++sIt;
49 }
50 }
51
initKeywords()52 void EditSyntaxHighlighter::initKeywords() {
53
54 m_keywordFmt.setForeground(Qt::darkBlue);
55 m_keywordFmt.setFontWeight(QFont::Bold);
56 QStringList keywordPatterns;
57
58 keywordPatterns
59 << "\\?"
60 << "abs" //abs
61 << "acos" //acos
62 << "alert" //alert
63 << "and" //and
64 << "arc" //arc
65 << "array[ \t]*base"
66 << "asc" //asc
67 << "assigned"
68 << "asin" //asin
69 << "atan" //atan
70 << "begin[ \t]*case" //begincase or begin case
71 << "call" //call
72 << "case" //case
73 << "catch" //catch
74 << "ceil" //ceil
75 << "changedir" //changedir
76 << "chord" //chord
77 << "chr" //chr
78 << "circle" //circle
79 << "clg" //clg
80 << "clickb" //clickb
81 << "clickclear" //clickclear
82 << "clickx" //clickx
83 << "clicky" //clicky
84 << "close" //close
85 << "cls" //cls
86 << "color" //color
87 << "colour" //colour
88 << "confirm" //confirm
89 << "continue[ \t]*do" //continuedo or continue do
90 << "continue[ \t]*for" //continuefor or continue for
91 << "continue[ \t]*while" //continuewhile or continue while
92 << "cos" //cos
93 << "count" //count
94 << "countx" //countx
95 << "currentdir" //currentdir
96 << "day" //day
97 << "dbclose" //dbclose
98 << "dbcloseset" //dbcloseset
99 << "dbexecute" //dbexecute
100 << "dbfloat" //dbfloat
101 << "dbint" //dbint
102 << "dbnull" //dbnull
103 << "dbopen" //dbopen
104 << "dbopenset" //dbopenset
105 << "dbrow" //dbrow
106 << "dbstring" //dbstring
107 << "debuginfo" //debuginfo
108 << "degrees" //degrees
109 << "dim" //dim
110 << "dir" //dir
111 << "do" //do
112 << "editvisible" //editvisible
113 << "ellipse" //ellipse
114 << "else" //else
115 << "end" //end
116 << "end[ \t]*case" //endcase or end case
117 << "end[ \t]*function" //endfunction or end function
118 << "end[ \t]*if" //endif or end if
119 << "end[ \t]*subroutine" //endsubroutine or end subroutine
120 << "end[ \t]*try" //endtry or end try
121 << "end[ \t]*while" //endwhile or end while
122 << "eof" //eof
123 << "exists" //exists
124 << "exit[ \t]*do" //exitdo or exit do
125 << "exit[ \t]*for" //exitfor or exit for
126 << "exit[ \t]*while" //exitwhile or exit while
127 << "exp" //exp
128 << "explode" //explode
129 << "explodex" //explodex
130 << "fastgraphics" //fastgraphics
131 << "fill" //fill
132 << "float" //float
133 << "floor" //floor
134 << "font" //font
135 << "for" //for
136 << "for[ \t]*each"
137 << "freedb" //freedb
138 << "freedbset" //freedbset
139 << "freefile" //freefile
140 << "freenet" //freenet
141 << "frombinary" //frombinary
142 << "fromhex" //fromhex
143 << "fromoctal" //fromoctal
144 << "fromradix" //fromradix
145 << "function" //function
146 << "getarraybase"
147 << "getbrushcolor" //getbrushcolor
148 << "getclipboardimage"
149 << "getclipboardstring"
150 << "getcolor" //getcolor
151 << "getpenwidth" //getpenwidth
152 << "getsetting" //getsetting
153 << "getslice" //getslice
154 << "global" //global
155 << "gosub" //gosub
156 << "goto" //goto
157 << "graphheight" //graphheignt
158 << "graphsize" //graphsize
159 << "graphtoolbarvisible"
160 << "graphvisible" //graphvisible
161 << "graphwidth" //graphwidth
162 << "hour" //hour
163 << "if" //if
164 << "in"
165 << "imageautocrop" //imageautocrop
166 << "imagecentered" //imagecentered
167 << "imagecopy" //imagecopy
168 << "imagecrop" //imagecrop
169 << "imagedraw" //imagedraw
170 << "imageflip" //imageflip
171 << "imageheight" //imageheight
172 << "imageload" //imageload
173 << "imagenew" //imagenew
174 << "imagepixel" //imagepixel
175 << "imageresize" //imageresize
176 << "imagerotate" //imagerotate
177 << "imagesetpixel" //imagesetpixel
178 << "imagesmooth" //imagesmooth
179 << "imagetransformed" //imagetransformed
180 << "imagewidth" //imagewidth
181 << "imgload" //imgload
182 << "imgsave" //imgsave
183 << "implode" //implode
184 << "include" //include
185 << "input" //input
186 << "input[ \t]*float" //inputfloat
187 << "input[ \t]*int(eger)?" //inputint
188 << "input[ \t]*string" //inputstring
189 << "instr" //instr
190 << "instrx" //instrx
191 << "int" //int
192 << "isnumeric" //isnumeric
193 << "key" //key
194 << "keypressed" //keypressed
195 << "kill" //kill
196 << "lasterror" //lasterror
197 << "lasterrorextra" //lasterrorextra
198 << "lasterrorline" //lasterrorline
199 << "lasterrormessage" //lasterrormessage
200 << "left" //left
201 << "length" //length
202 << "let" //let
203 << "line" //line
204 << "ljust"
205 << "log" //log
206 << "log10" //log10
207 << "lower" //lower
208 << "ltrim" //ltrim
209 << "ltrim" //ltrim
210 << "maintoolbarvisible"
211 << "map"
212 << "md5" //md5
213 << "mid" //mid
214 << "midx" //midx
215 << "minute" //minute
216 << "mod"
217 << "month" //month
218 << "mouseb" //mouseb
219 << "mousex" //mousex
220 << "mousey" //mousey
221 << "msec" //msec
222 << "netaddress" //netaddress
223 << "netclose" //netclose
224 << "netconnect" //netconnect
225 << "netdata" //netdata
226 << "netlisten" //netlisten
227 << "netread" //netread
228 << "netwrite" //netwrite
229 << "next" //next
230 << "not" //not
231 << "offerror" //offerror
232 << "onerror" //onerror
233 << "open" //open
234 << "openb" //openb
235 << "openfiledialog"
236 << "openserial" //openserial
237 << "or" //or
238 << "ostype" //ostype
239 << "outputtoolbarvisible"
240 << "outputvisible" //outputvisible
241 << "pause" //pause
242 << "penwidth" //penwidth
243 << "pie" //pie
244 << "pixel" //pixel
245 << "plot" //plot
246 << "poly" //poly
247 << "portin" //portin
248 << "portout" //portout
249 << "print" //print
250 << "printer[ \t]*cancel" //printercancel or printer cancel
251 << "printer[ \t]*off" //printeroff or printer off
252 << "printer[ \t]*on" //printeron or printer on
253 << "printer[ \t]*page" //printerpage or printer page
254 << "prompt" //prompt
255 << "putslice" //putslice
256 << "radians" //radians
257 << "rand" //rand
258 << "read" //read
259 << "readbyte" //readbyte
260 << "readline" //readline
261 << "rect" //rect
262 << "redim" //redim
263 << "ref" //ref
264 << "refresh" //refresh
265 << "regexminimal" //regexminimal
266 << "replace" //replace
267 << "replacex" //replacex
268 << "reset" //reset
269 << "return" //return
270 << "rgb" //rgb
271 << "right" //right
272 << "rjust"
273 << "round"
274 << "savefiledialog"
275 << "say" //say
276 << "second" //second
277 << "seed" //seed
278 << "seek" //seek
279 << "serialize" //serialize
280 << "setclipboardimage"
281 << "setclipboardstring"
282 << "setgraph" //setgraph
283 << "setsetting" //setsetting
284 << "sin" //sin
285 << "size" //size
286 << "sound" //sound
287 << "soundenvelope" //soundenvelope
288 << "soundfade" //soundfade
289 << "soundharmonics" //soundharmonics
290 << "soundid" //soundid
291 << "soundlength" //soundlength
292 << "soundload" //soundload
293 << "soundloadraw" //soundloadraw
294 << "soundloop" //soundloop
295 << "soundpause" //soundpause
296 << "soundplay" //soundplay
297 << "soundplayer" //soundplayer
298 << "soundplayeroff" //soundplayeroff
299 << "soundposition" //soundposition
300 << "soundsamplerate" //soundsamplerate
301 << "soundseek" //soundseek
302 << "soundstate" //soundstate
303 << "soundstop" //soundstop
304 << "soundsystem" //soundsystem
305 << "soundvolume" //soundvolume
306 << "soundwait" //soundwait
307 << "soundwaveform" //soundwaveform
308 << "spritedcollide" //spritedcollide
309 << "spritedim" //spritedim
310 << "spriteh" //spriteh
311 << "spritehide" //spritehide
312 << "spriteload" //spriteload
313 << "spritemove" //spritemove
314 << "spriteo" //spriteo
315 << "spriteplace" //spriteplace
316 << "spritepoly" //spritepoly
317 << "spriter" //spriter
318 << "sprites" //sprites
319 << "spriteshow" //spriteshow
320 << "spriteslice" //spriteslice
321 << "spritev" //spritev
322 << "spritew" //spritew
323 << "spritex" //spritex
324 << "spritey" //spritey
325 << "sqr" //sqr
326 << "sqrt" //sqrt
327 << "stamp" //stamp
328 << "step" //step
329 << "string" //string
330 << "subroutine" //subroutine
331 << "system" //system
332 << "tan" //tan
333 << "text" //text
334 << "textheight" //textheight
335 << "textwidth" //textwidth
336 << "then" //then
337 << "throwerror" //throwerror
338 << "to" //to
339 << "tobinary" //tobinary
340 << "tohex" //tohex
341 << "tooctal" //tooctal
342 << "toradix" //toradix
343 << "trim" //trim
344 << "try" //try
345 << "typeof" //typeof
346 << "unassign" //unassign
347 << "unload" //unload
348 << "unserialize" //unserialize
349 << "until" //until
350 << "upper" //upper
351 << "variablewatch" //variablewatch
352 << "version" //version
353 << "volume" //volume
354 << "wavlength" //wavlength
355 << "wavpause" //wavpause
356 << "wavplay" //wavplay
357 << "wavpos" //wavpos
358 << "wavseek" //wavseek
359 << "wavstate" //wavstate
360 << "wavstop" //wavstop
361 << "wavwait" //wavwait
362 << "while" //while
363 << "write" //write
364 << "writebyte" //writebyte
365 << "writeline" //writeline
366 << "xor" //xor
367 << "year" //year
368 << "zfill"
369 ;
370 for (QStringList::iterator it = keywordPatterns.begin(); it != keywordPatterns.end(); ++it) {
371 HighlightRule *rule = new HighlightRule;
372 rule->pattern = QRegExp("\\b" + *it + "\\b", Qt::CaseInsensitive);
373 rule->format = m_keywordFmt;
374 m_standardRules.append(*rule);
375 }
376 }
377
initConstants()378 void EditSyntaxHighlighter::initConstants() {
379
380 m_constantFmt.setForeground(Qt::darkCyan);
381 QStringList constantPatterns;
382
383 constantPatterns
384 << "pi" //pi
385 << "TRUE" //TRUE
386 << "FALSE" //FALSE
387 << "clear" //clear
388 << "black" //black
389 << "white" //white
390 << "(dark){0,1}red" //red and darkred
391 << "(dark){0,1}green" //green and darkgreen
392 << "(dark){0,1}blue" //blue and darkblue
393 << "(dark){0,1}cyan" //cyan and darkcyan
394 << "(dark){0,1}purple" //purple and darkpurple
395 << "(dark){0,1}yellow" //yellow and darkyellow
396 << "(dark){0,1}orange" //orange and darkorange
397 << "(dark){0,1}gr[ea]y" //gray, grey, darkgray and darkgrey
398
399 <<"ERROR_ARGUMENTCOUNT"
400 <<"ERROR_ARRAYELEMENT"
401 <<"ERROR_ARRAYEVEN"
402 <<"ERROR_ARRAYEXPR"
403 <<"ERROR_ARRAYINDEX"
404 <<"ERROR_ARRAYINDEXMISSING"
405 <<"ERROR_ARRAYLENGTH2D"
406 <<"ERROR_ARRAYNITEMS"
407 <<"ERROR_ARRAYSIZELARGE"
408 <<"ERROR_ARRAYSIZESMALL"
409 <<"ERROR_ASINACOSRANGE"
410 <<"ERROR_BOOLEANCONV"
411 <<"ERROR_DBCOLNO"
412 <<"ERROR_DBCONNNUMBER"
413 <<"ERROR_DBNOTOPEN"
414 <<"ERROR_DBNOTSET"
415 <<"ERROR_DBNOTSETROW"
416 <<"ERROR_DBOPEN"
417 <<"ERROR_DBQUERY"
418 <<"ERROR_DBSETNUMBER"
419 <<"ERROR_DIVZERO"
420 <<"ERROR_DOWNLOAD"
421 <<"ERROR_ENVELOPEMAX"
422 <<"ERROR_ENVELOPEODD"
423 <<"ERROR_EXPECTEDARRAY"
424 <<"ERROR_EXPECTEDSOUND"
425 <<"ERROR_FILENOTOPEN"
426 <<"ERROR_FILENUMBER"
427 <<"ERROR_FILEOPEN"
428 <<"ERROR_FILEOPERATION"
429 <<"ERROR_FILERESET"
430 <<"ERROR_FILEWRITE"
431 <<"ERROR_FOLDER"
432 <<"ERROR_FREEDB"
433 <<"ERROR_FREEDBSET"
434 <<"ERROR_FREEFILE"
435 <<"ERROR_FREENET"
436 <<"ERROR_HARMONICLIST"
437 <<"ERROR_HARMONICNUMBER"
438 <<"ERROR_IMAGEFILE"
439 <<"ERROR_IMAGERESOURCE"
440 <<"ERROR_IMAGESAVETYPE"
441 <<"ERROR_IMAGESCALE"
442 <<"ERROR_INFINITY"
443 <<"ERROR_INTEGERRANGE"
444 <<"ERROR_INVALIDKEYNAME"
445 <<"ERROR_INVALIDPROGNAME"
446 <<"ERROR_INVALIDRESOURCE"
447 <<"ERROR_LOGRANGE"
448 <<"ERROR_LONGRANGE"
449 <<"ERROR_MAXRECURSE"
450 <<"ERROR_NETACCEPT"
451 <<"ERROR_NETBIND"
452 <<"ERROR_NETCONN"
453 <<"ERROR_NETHOST"
454 <<"ERROR_NETNONE"
455 <<"ERROR_NETREAD"
456 <<"ERROR_NETSOCK"
457 <<"ERROR_NETSOCKNUMBER"
458 <<"ERROR_NETSOCKOPT"
459 <<"ERROR_NETWRITE"
460 <<"ERROR_NEXTNOFOR"
461 <<"ERROR_NONE"
462 <<"ERROR_NOSUCHFUNCTION"
463 <<"ERROR_NOSUCHLABEL"
464 <<"ERROR_NOSUCHSUBROUTINE"
465 <<"ERROR_NOTARRAY"
466 <<"ERROR_NOTIMPLEMENTED"
467 <<"ERROR_NUMBERCONV"
468 <<"ERROR_NUMBEREXPR"
469 <<"ERROR_ONEDIMENSIONAL"
470 <<"ERROR_ONERRORSUB"
471 <<"ERROR_PENWIDTH"
472 <<"ERROR_PERMISSION"
473 <<"ERROR_POLYPOINTS"
474 <<"ERROR_PRINTERNOTOFF"
475 <<"ERROR_PRINTERNOTON"
476 <<"ERROR_PRINTEROPEN"
477 <<"ERROR_RADIX"
478 <<"ERROR_RADIXSTRING"
479 <<"ERROR_REFNOTASSIGNED"
480 <<"ERROR_RGB"
481 <<"ERROR_SERIALPARAMETER"
482 <<"ERROR_SETTINGMAXKEYS"
483 <<"ERROR_SETTINGMAXLEN"
484 <<"ERROR_SETTINGSGETACCESS"
485 <<"ERROR_SETTINGSSETACCESS"
486 <<"ERROR_SLICESIZE"
487 <<"ERROR_SOUNDERROR"
488 <<"ERROR_SOUNDFILE"
489 <<"ERROR_SOUNDFILEFORMAT"
490 <<"ERROR_SOUNDLENGTH"
491 <<"ERROR_SOUNDNOTSEEKABLE"
492 <<"ERROR_SOUNDRESOURCE"
493 <<"ERROR_SPRITENA"
494 <<"ERROR_SPRITENUMBER"
495 <<"ERROR_SPRITESLICE"
496 <<"ERROR_SQRRANGE"
497 <<"ERROR_STACKUNDERFLOW"
498 <<"ERROR_STRING2NOTE"
499 <<"ERROR_STRINGCONV"
500 <<"ERROR_STRINGEXPR"
501 <<"ERROR_STRINGMAXLEN"
502 <<"ERROR_STRSTART"
503 <<"ERROR_TOOMANYSOUNDS"
504 <<"ERROR_UNEXPECTEDRETURN"
505 <<"ERROR_UNSERIALIZEFORMAT"
506 <<"ERROR_VARCIRCULAR"
507 <<"ERROR_VARNOTASSIGNED"
508 <<"ERROR_VARNULL"
509 <<"ERROR_WAVEFORMLOGICAL"
510 <<"ERROR_WAVOBSOLETE"
511 <<"WARNING_ARRAYELEMENT"
512 <<"WARNING_BOOLEANCONV"
513 <<"WARNING_INTEGERRANGE"
514 <<"WARNING_LONGRANGE"
515 <<"WARNING_NUMBERCONV"
516 <<"WARNING_REFNOTASSIGNED"
517 <<"WARNING_SOUNDERROR"
518 <<"WARNING_SOUNDFILEFORMAT"
519 <<"WARNING_SOUNDLENGTH"
520 <<"WARNING_SOUNDNOTSEEKABLE"
521 <<"WARNING_START"
522 <<"WARNING_STRING2NOTE"
523 <<"WARNING_STRINGCONV"
524 <<"WARNING_WAVOBSOLETE"
525 <<"WARNING_VARNOTASSIGNED"
526
527 << "TYPE_ARRAY"
528 << "TYPE_FLOAT"
529 << "TYPE_INT"
530 << "TYPE_MAP"
531 << "TYPE_STRING"
532 << "TYPE_UNASSIGNED"
533 << "MOUSEBUTTON_CENTER"
534 << "MOUSEBUTTON_LEFT"
535 << "MOUSEBUTTON_NONE"
536 << "MOUSEBUTTON_RIGHT"
537 << "MOUSEBUTTON_DOUBLECLICK"
538 << "IMAGETYPE_BMP"
539 << "IMAGETYPE_JPG"
540 << "IMAGETYPE_PNG"
541 << "OSTYPE_ANDROID"
542 << "OSTYPE_LINUX"
543 << "OSTYPE_MACINTOSH"
544 << "OSTYPE_WINDOWS"
545 << "SLICE_ALL"
546 << "SLICE_PAINT"
547 << "SLICE_SPRITE"
548 ;
549 for (QStringList::iterator it = constantPatterns.begin(); it != constantPatterns.end(); ++it ) {
550 HighlightRule *rule = new HighlightRule;
551 rule->pattern = QRegExp("\\b" + *it + "\\b", Qt::CaseInsensitive);
552 rule->format = m_constantFmt;
553 m_standardRules.append(*rule);
554 }
555 }
556
initQuotes()557 void EditSyntaxHighlighter::initQuotes() {
558 m_quoteFmt.setForeground(Qt::magenta);
559
560 HighlightRule *rule = new HighlightRule;
561 rule->pattern = QRegExp("(\"[^\"]*\")|(\'[^\']*\')");
562 rule->format = m_quoteFmt;
563 m_standardRules.append(*rule);
564 }
565
initLabels()566 void EditSyntaxHighlighter::initLabels() {
567 m_labelFmt.setForeground(Qt::blue);
568
569 HighlightRule *rule = new HighlightRule;
570 rule->pattern = QRegExp("(?:^\\s*)([a-z0-9]+):", Qt::CaseInsensitive);
571 rule->format = m_labelFmt;
572 m_standardRules.append(*rule);
573 }
574
initNumbers()575 void EditSyntaxHighlighter::initNumbers() {
576 m_numberFmt.setForeground(Qt::darkMagenta);
577
578 HighlightRule *rule = new HighlightRule;
579 rule->pattern = QRegExp("(\\b([0-9]*\\.?[0-9]+(e[-+]?[0-9]+)?)\\b)|(\\b0x[0-9a-f]+\\b)|(\\b0b[0-1]+\\b)|(\\b0o[0-7]+\\b)", Qt::CaseInsensitive);
580 rule->format = m_numberFmt;
581 m_standardRules.append(*rule);
582 }
583
initComments()584 void EditSyntaxHighlighter::initComments() {
585 m_commentFmt.setForeground(Qt::darkGreen);
586 m_commentFmt.setFontItalic(true);
587
588 HighlightRule *rule;
589 rule = new HighlightRule;
590 rule->pattern = QRegExp("(\\bREM\\b.*$)|(#.*$)", Qt::CaseInsensitive);
591 rule->format = m_commentFmt;
592 m_standardRules.append(*rule);
593 }
594