]> git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/ScintillaBase.cxx
cae6cff15c6ead00a0250ae2864eb1fc0a0843d8
[wxWidgets.git] / src / stc / scintilla / src / ScintillaBase.cxx
1 // Scintilla source code edit control
2 /** @file ScintillaBase.cxx
3 ** An enhanced subclass of Editor with calltips, autocomplete and context menu.
4 **/
5 // Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
6 // The License.txt file describes the conditions under which this software may be distributed.
7
8 #include <stdlib.h>
9 #include <string.h>
10 #include <stdio.h>
11 #include <ctype.h>
12
13 #include "Platform.h"
14
15 #include "Scintilla.h"
16 #include "PropSet.h"
17 #include "PropSetSimple.h"
18 #ifdef SCI_LEXER
19 #include "SciLexer.h"
20 #include "Accessor.h"
21 #include "DocumentAccessor.h"
22 #include "KeyWords.h"
23 #endif
24 #include "SplitVector.h"
25 #include "Partitioning.h"
26 #include "RunStyles.h"
27 #include "ContractionState.h"
28 #include "CellBuffer.h"
29 #include "CallTip.h"
30 #include "KeyMap.h"
31 #include "Indicator.h"
32 #include "XPM.h"
33 #include "LineMarker.h"
34 #include "Style.h"
35 #include "ViewStyle.h"
36 #include "AutoComplete.h"
37 #include "CharClassify.h"
38 #include "Decoration.h"
39 #include "Document.h"
40 #include "Selection.h"
41 #include "PositionCache.h"
42 #include "Editor.h"
43 #include "ScintillaBase.h"
44
45 #ifdef SCI_NAMESPACE
46 using namespace Scintilla;
47 #endif
48
49 ScintillaBase::ScintillaBase() {
50 displayPopupMenu = true;
51 listType = 0;
52 maxListWidth = 0;
53 #ifdef SCI_LEXER
54 lexLanguage = SCLEX_CONTAINER;
55 performingStyle = false;
56 lexCurrent = 0;
57 for (int wl = 0;wl < numWordLists;wl++)
58 keyWordLists[wl] = new WordList;
59 keyWordLists[numWordLists] = 0;
60 #endif
61 }
62
63 ScintillaBase::~ScintillaBase() {
64 #ifdef SCI_LEXER
65 for (int wl = 0;wl < numWordLists;wl++)
66 delete keyWordLists[wl];
67 #endif
68 }
69
70 void ScintillaBase::Finalise() {
71 Editor::Finalise();
72 popup.Destroy();
73 }
74
75 void ScintillaBase::RefreshColourPalette(Palette &pal, bool want) {
76 Editor::RefreshColourPalette(pal, want);
77 ct.RefreshColourPalette(pal, want);
78 }
79
80 void ScintillaBase::AddCharUTF(char *s, unsigned int len, bool treatAsDBCS) {
81 bool isFillUp = ac.Active() && ac.IsFillUpChar(*s);
82 if (!isFillUp) {
83 Editor::AddCharUTF(s, len, treatAsDBCS);
84 }
85 if (ac.Active()) {
86 AutoCompleteCharacterAdded(s[0]);
87 // For fill ups add the character after the autocompletion has
88 // triggered so containers see the key so can display a calltip.
89 if (isFillUp) {
90 Editor::AddCharUTF(s, len, treatAsDBCS);
91 }
92 }
93 }
94
95 void ScintillaBase::Command(int cmdId) {
96
97 switch (cmdId) {
98
99 case idAutoComplete: // Nothing to do
100
101 break;
102
103 case idCallTip: // Nothing to do
104
105 break;
106
107 case idcmdUndo:
108 WndProc(SCI_UNDO, 0, 0);
109 break;
110
111 case idcmdRedo:
112 WndProc(SCI_REDO, 0, 0);
113 break;
114
115 case idcmdCut:
116 WndProc(SCI_CUT, 0, 0);
117 break;
118
119 case idcmdCopy:
120 WndProc(SCI_COPY, 0, 0);
121 break;
122
123 case idcmdPaste:
124 WndProc(SCI_PASTE, 0, 0);
125 break;
126
127 case idcmdDelete:
128 WndProc(SCI_CLEAR, 0, 0);
129 break;
130
131 case idcmdSelectAll:
132 WndProc(SCI_SELECTALL, 0, 0);
133 break;
134 }
135 }
136
137 int ScintillaBase::KeyCommand(unsigned int iMessage) {
138 // Most key commands cancel autocompletion mode
139 if (ac.Active()) {
140 switch (iMessage) {
141 // Except for these
142 case SCI_LINEDOWN:
143 AutoCompleteMove(1);
144 return 0;
145 case SCI_LINEUP:
146 AutoCompleteMove( -1);
147 return 0;
148 case SCI_PAGEDOWN:
149 AutoCompleteMove(5);
150 return 0;
151 case SCI_PAGEUP:
152 AutoCompleteMove( -5);
153 return 0;
154 case SCI_VCHOME:
155 AutoCompleteMove( -5000);
156 return 0;
157 case SCI_LINEEND:
158 AutoCompleteMove(5000);
159 return 0;
160 case SCI_DELETEBACK:
161 DelCharBack(true);
162 AutoCompleteCharacterDeleted();
163 EnsureCaretVisible();
164 return 0;
165 case SCI_DELETEBACKNOTLINE:
166 DelCharBack(false);
167 AutoCompleteCharacterDeleted();
168 EnsureCaretVisible();
169 return 0;
170 case SCI_TAB:
171 AutoCompleteCompleted();
172 return 0;
173 case SCI_NEWLINE:
174 AutoCompleteCompleted();
175 return 0;
176
177 default:
178 AutoCompleteCancel();
179 }
180 }
181
182 if (ct.inCallTipMode) {
183 if (
184 (iMessage != SCI_CHARLEFT) &&
185 (iMessage != SCI_CHARLEFTEXTEND) &&
186 (iMessage != SCI_CHARRIGHT) &&
187 (iMessage != SCI_CHARRIGHTEXTEND) &&
188 (iMessage != SCI_EDITTOGGLEOVERTYPE) &&
189 (iMessage != SCI_DELETEBACK) &&
190 (iMessage != SCI_DELETEBACKNOTLINE)
191 ) {
192 ct.CallTipCancel();
193 }
194 if ((iMessage == SCI_DELETEBACK) || (iMessage == SCI_DELETEBACKNOTLINE)) {
195 if (sel.MainCaret() <= ct.posStartCallTip) {
196 ct.CallTipCancel();
197 }
198 }
199 }
200 return Editor::KeyCommand(iMessage);
201 }
202
203 void ScintillaBase::AutoCompleteDoubleClick(void* p) {
204 ScintillaBase* sci = reinterpret_cast<ScintillaBase*>(p);
205 sci->AutoCompleteCompleted();
206 }
207
208 void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) {
209 //Platform::DebugPrintf("AutoComplete %s\n", list);
210 ct.CallTipCancel();
211
212 if (ac.chooseSingle && (listType == 0)) {
213 if (list && !strchr(list, ac.GetSeparator())) {
214 const char *typeSep = strchr(list, ac.GetTypesep());
215 size_t lenInsert = (typeSep) ? (typeSep-list) : strlen(list);
216 if (ac.ignoreCase) {
217 SetEmptySelection(sel.MainCaret() - lenEntered);
218 pdoc->DeleteChars(sel.MainCaret(), lenEntered);
219 SetEmptySelection(sel.MainCaret());
220 pdoc->InsertString(sel.MainCaret(), list, lenInsert);
221 SetEmptySelection(sel.MainCaret() + lenInsert);
222 } else {
223 SetEmptySelection(sel.MainCaret());
224 pdoc->InsertString(sel.MainCaret(), list + lenEntered, lenInsert - lenEntered);
225 SetEmptySelection(sel.MainCaret() + lenInsert - lenEntered);
226 }
227 return;
228 }
229 }
230 ac.Start(wMain, idAutoComplete, sel.MainCaret(), PointMainCaret(),
231 lenEntered, vs.lineHeight, IsUnicodeMode());
232
233 PRectangle rcClient = GetClientRectangle();
234 Point pt = LocationFromPosition(sel.MainCaret() - lenEntered);
235 PRectangle rcPopupBounds = wMain.GetMonitorRect(pt);
236 if (rcPopupBounds.Height() == 0)
237 rcPopupBounds = rcClient;
238
239 int heightLB = 100;
240 int widthLB = 100;
241 if (pt.x >= rcClient.right - widthLB) {
242 HorizontalScrollTo(xOffset + pt.x - rcClient.right + widthLB);
243 Redraw();
244 pt = PointMainCaret();
245 }
246 PRectangle rcac;
247 rcac.left = pt.x - ac.lb->CaretFromEdge();
248 if (pt.y >= rcPopupBounds.bottom - heightLB && // Wont fit below.
249 pt.y >= (rcPopupBounds.bottom + rcPopupBounds.top) / 2) { // and there is more room above.
250 rcac.top = pt.y - heightLB;
251 if (rcac.top < rcPopupBounds.top) {
252 heightLB -= (rcPopupBounds.top - rcac.top);
253 rcac.top = rcPopupBounds.top;
254 }
255 } else {
256 rcac.top = pt.y + vs.lineHeight;
257 }
258 rcac.right = rcac.left + widthLB;
259 rcac.bottom = Platform::Minimum(rcac.top + heightLB, rcPopupBounds.bottom);
260 ac.lb->SetPositionRelative(rcac, wMain);
261 ac.lb->SetFont(vs.styles[STYLE_DEFAULT].font);
262 unsigned int aveCharWidth = vs.styles[STYLE_DEFAULT].aveCharWidth;
263 ac.lb->SetAverageCharWidth(aveCharWidth);
264 ac.lb->SetDoubleClickAction(AutoCompleteDoubleClick, this);
265
266 ac.SetList(list);
267
268 // Fiddle the position of the list so it is right next to the target and wide enough for all its strings
269 PRectangle rcList = ac.lb->GetDesiredRect();
270 int heightAlloced = rcList.bottom - rcList.top;
271 widthLB = Platform::Maximum(widthLB, rcList.right - rcList.left);
272 if (maxListWidth != 0)
273 widthLB = Platform::Minimum(widthLB, aveCharWidth*maxListWidth);
274 // Make an allowance for large strings in list
275 rcList.left = pt.x - ac.lb->CaretFromEdge();
276 rcList.right = rcList.left + widthLB;
277 if (((pt.y + vs.lineHeight) >= (rcPopupBounds.bottom - heightAlloced)) && // Wont fit below.
278 ((pt.y + vs.lineHeight / 2) >= (rcPopupBounds.bottom + rcPopupBounds.top) / 2)) { // and there is more room above.
279 rcList.top = pt.y - heightAlloced;
280 } else {
281 rcList.top = pt.y + vs.lineHeight;
282 }
283 rcList.bottom = rcList.top + heightAlloced;
284 ac.lb->SetPositionRelative(rcList, wMain);
285 ac.Show(true);
286 if (lenEntered != 0) {
287 AutoCompleteMoveToCurrentWord();
288 }
289 }
290
291 void ScintillaBase::AutoCompleteCancel() {
292 if (ac.Active()) {
293 SCNotification scn = {0};
294 scn.nmhdr.code = SCN_AUTOCCANCELLED;
295 scn.wParam = 0;
296 scn.listType = 0;
297 NotifyParent(scn);
298 }
299 ac.Cancel();
300 }
301
302 void ScintillaBase::AutoCompleteMove(int delta) {
303 ac.Move(delta);
304 }
305
306 void ScintillaBase::AutoCompleteMoveToCurrentWord() {
307 char wordCurrent[1000];
308 int i;
309 int startWord = ac.posStart - ac.startLen;
310 for (i = startWord; i < sel.MainCaret() && i - startWord < 1000; i++)
311 wordCurrent[i - startWord] = pdoc->CharAt(i);
312 wordCurrent[Platform::Minimum(i - startWord, 999)] = '\0';
313 ac.Select(wordCurrent);
314 }
315
316 void ScintillaBase::AutoCompleteCharacterAdded(char ch) {
317 if (ac.IsFillUpChar(ch)) {
318 AutoCompleteCompleted();
319 } else if (ac.IsStopChar(ch)) {
320 AutoCompleteCancel();
321 } else {
322 AutoCompleteMoveToCurrentWord();
323 }
324 }
325
326 void ScintillaBase::AutoCompleteCharacterDeleted() {
327 if (sel.MainCaret() < ac.posStart - ac.startLen) {
328 AutoCompleteCancel();
329 } else if (ac.cancelAtStartPos && (sel.MainCaret() <= ac.posStart)) {
330 AutoCompleteCancel();
331 } else {
332 AutoCompleteMoveToCurrentWord();
333 }
334 SCNotification scn = {0};
335 scn.nmhdr.code = SCN_AUTOCCHARDELETED;
336 scn.wParam = 0;
337 scn.listType = 0;
338 NotifyParent(scn);
339 }
340
341 void ScintillaBase::AutoCompleteCompleted() {
342 int item = ac.lb->GetSelection();
343 char selected[1000];
344 selected[0] = '\0';
345 if (item != -1) {
346 ac.lb->GetValue(item, selected, sizeof(selected));
347 } else {
348 AutoCompleteCancel();
349 return;
350 }
351
352 ac.Show(false);
353
354 SCNotification scn = {0};
355 scn.nmhdr.code = listType > 0 ? SCN_USERLISTSELECTION : SCN_AUTOCSELECTION;
356 scn.message = 0;
357 scn.wParam = listType;
358 scn.listType = listType;
359 Position firstPos = ac.posStart - ac.startLen;
360 scn.lParam = firstPos;
361 scn.text = selected;
362 NotifyParent(scn);
363
364 if (!ac.Active())
365 return;
366 ac.Cancel();
367
368 if (listType > 0)
369 return;
370
371 Position endPos = sel.MainCaret();
372 if (ac.dropRestOfWord)
373 endPos = pdoc->ExtendWordSelect(endPos, 1, true);
374 if (endPos < firstPos)
375 return;
376 UndoGroup ug(pdoc);
377 if (endPos != firstPos) {
378 pdoc->DeleteChars(firstPos, endPos - firstPos);
379 }
380 SetEmptySelection(ac.posStart);
381 if (item != -1) {
382 pdoc->InsertCString(firstPos, selected);
383 SetEmptySelection(firstPos + static_cast<int>(strlen(selected)));
384 }
385 }
386
387 int ScintillaBase::AutoCompleteGetCurrent() {
388 if (!ac.Active())
389 return -1;
390 return ac.lb->GetSelection();
391 }
392
393 int ScintillaBase::AutoCompleteGetCurrentText(char *buffer) {
394 if (ac.Active()) {
395 int item = ac.lb->GetSelection();
396 char selected[1000];
397 selected[0] = '\0';
398 if (item != -1) {
399 ac.lb->GetValue(item, selected, sizeof(selected));
400 if (buffer != NULL)
401 strcpy(buffer, selected);
402 return strlen(selected);
403 }
404 }
405 if (buffer != NULL)
406 *buffer = '\0';
407 return 0;
408 }
409
410 void ScintillaBase::CallTipShow(Point pt, const char *defn) {
411 ac.Cancel();
412 pt.y += vs.lineHeight;
413 // If container knows about STYLE_CALLTIP then use it in place of the
414 // STYLE_DEFAULT for the face name, size and character set. Also use it
415 // for the foreground and background colour.
416 int ctStyle = ct.UseStyleCallTip() ? STYLE_CALLTIP : STYLE_DEFAULT;
417 if (ct.UseStyleCallTip()) {
418 ct.SetForeBack(vs.styles[STYLE_CALLTIP].fore, vs.styles[STYLE_CALLTIP].back);
419 }
420 PRectangle rc = ct.CallTipStart(sel.MainCaret(), pt,
421 defn,
422 vs.styles[ctStyle].fontName,
423 vs.styles[ctStyle].sizeZoomed,
424 CodePage(),
425 vs.styles[ctStyle].characterSet,
426 wMain);
427 // If the call-tip window would be out of the client
428 // space, adjust so it displays above the text.
429 PRectangle rcClient = GetClientRectangle();
430 if (rc.bottom > rcClient.bottom) {
431 int offset = vs.lineHeight + rc.Height();
432 rc.top -= offset;
433 rc.bottom -= offset;
434 }
435 // Now display the window.
436 CreateCallTipWindow(rc);
437 ct.wCallTip.SetPositionRelative(rc, wMain);
438 ct.wCallTip.Show();
439 }
440
441 void ScintillaBase::CallTipClick() {
442 SCNotification scn = {0};
443 scn.nmhdr.code = SCN_CALLTIPCLICK;
444 scn.position = ct.clickPlace;
445 NotifyParent(scn);
446 }
447
448 void ScintillaBase::ContextMenu(Point pt) {
449 if (displayPopupMenu) {
450 bool writable = !WndProc(SCI_GETREADONLY, 0, 0);
451 popup.CreatePopUp();
452 AddToPopUp("Undo", idcmdUndo, writable && pdoc->CanUndo());
453 AddToPopUp("Redo", idcmdRedo, writable && pdoc->CanRedo());
454 AddToPopUp("");
455 AddToPopUp("Cut", idcmdCut, writable && !sel.Empty());
456 AddToPopUp("Copy", idcmdCopy, !sel.Empty());
457 AddToPopUp("Paste", idcmdPaste, writable && WndProc(SCI_CANPASTE, 0, 0));
458 AddToPopUp("Delete", idcmdDelete, writable && !sel.Empty());
459 AddToPopUp("");
460 AddToPopUp("Select All", idcmdSelectAll);
461 popup.Show(pt, wMain);
462 }
463 }
464
465 void ScintillaBase::CancelModes() {
466 AutoCompleteCancel();
467 ct.CallTipCancel();
468 Editor::CancelModes();
469 }
470
471 void ScintillaBase::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt) {
472 CancelModes();
473 Editor::ButtonDown(pt, curTime, shift, ctrl, alt);
474 }
475
476 #ifdef SCI_LEXER
477 void ScintillaBase::SetLexer(uptr_t wParam) {
478 lexLanguage = wParam;
479 lexCurrent = LexerModule::Find(lexLanguage);
480 if (!lexCurrent)
481 lexCurrent = LexerModule::Find(SCLEX_NULL);
482 int bits = lexCurrent ? lexCurrent->GetStyleBitsNeeded() : 5;
483 vs.EnsureStyle((1 << bits) - 1);
484 }
485
486 void ScintillaBase::SetLexerLanguage(const char *languageName) {
487 lexLanguage = SCLEX_CONTAINER;
488 lexCurrent = LexerModule::Find(languageName);
489 if (!lexCurrent)
490 lexCurrent = LexerModule::Find(SCLEX_NULL);
491 if (lexCurrent)
492 lexLanguage = lexCurrent->GetLanguage();
493 int bits = lexCurrent ? lexCurrent->GetStyleBitsNeeded() : 5;
494 vs.EnsureStyle((1 << bits) - 1);
495 }
496
497 void ScintillaBase::Colourise(int start, int end) {
498 if (!performingStyle) {
499 // Protect against reentrance, which may occur, for example, when
500 // fold points are discovered while performing styling and the folding
501 // code looks for child lines which may trigger styling.
502 performingStyle = true;
503
504 int lengthDoc = pdoc->Length();
505 if (end == -1)
506 end = lengthDoc;
507 int len = end - start;
508
509 PLATFORM_ASSERT(len >= 0);
510 PLATFORM_ASSERT(start + len <= lengthDoc);
511
512 //WindowAccessor styler(wMain.GetID(), props);
513 DocumentAccessor styler(pdoc, props, wMain.GetID());
514
515 int styleStart = 0;
516 if (start > 0)
517 styleStart = styler.StyleAt(start - 1) & pdoc->stylingBitsMask;
518 styler.SetCodePage(pdoc->dbcsCodePage);
519
520 if (lexCurrent && (len > 0)) { // Should always succeed as null lexer should always be available
521 lexCurrent->Lex(start, len, styleStart, keyWordLists, styler);
522 styler.Flush();
523 if (styler.GetPropertyInt("fold")) {
524 lexCurrent->Fold(start, len, styleStart, keyWordLists, styler);
525 styler.Flush();
526 }
527 }
528
529 performingStyle = false;
530 }
531 }
532 #endif
533
534 void ScintillaBase::NotifyStyleToNeeded(int endStyleNeeded) {
535 #ifdef SCI_LEXER
536 if (lexLanguage != SCLEX_CONTAINER) {
537 int endStyled = WndProc(SCI_GETENDSTYLED, 0, 0);
538 int lineEndStyled = WndProc(SCI_LINEFROMPOSITION, endStyled, 0);
539 endStyled = WndProc(SCI_POSITIONFROMLINE, lineEndStyled, 0);
540 Colourise(endStyled, endStyleNeeded);
541 return;
542 }
543 #endif
544 Editor::NotifyStyleToNeeded(endStyleNeeded);
545 }
546
547 sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
548 switch (iMessage) {
549 case SCI_AUTOCSHOW:
550 listType = 0;
551 AutoCompleteStart(wParam, reinterpret_cast<const char *>(lParam));
552 break;
553
554 case SCI_AUTOCCANCEL:
555 ac.Cancel();
556 break;
557
558 case SCI_AUTOCACTIVE:
559 return ac.Active();
560
561 case SCI_AUTOCPOSSTART:
562 return ac.posStart;
563
564 case SCI_AUTOCCOMPLETE:
565 AutoCompleteCompleted();
566 break;
567
568 case SCI_AUTOCSETSEPARATOR:
569 ac.SetSeparator(static_cast<char>(wParam));
570 break;
571
572 case SCI_AUTOCGETSEPARATOR:
573 return ac.GetSeparator();
574
575 case SCI_AUTOCSTOPS:
576 ac.SetStopChars(reinterpret_cast<char *>(lParam));
577 break;
578
579 case SCI_AUTOCSELECT:
580 ac.Select(reinterpret_cast<char *>(lParam));
581 break;
582
583 case SCI_AUTOCGETCURRENT:
584 return AutoCompleteGetCurrent();
585
586 case SCI_AUTOCGETCURRENTTEXT:
587 return AutoCompleteGetCurrentText(reinterpret_cast<char *>(lParam));
588
589 case SCI_AUTOCSETCANCELATSTART:
590 ac.cancelAtStartPos = wParam != 0;
591 break;
592
593 case SCI_AUTOCGETCANCELATSTART:
594 return ac.cancelAtStartPos;
595
596 case SCI_AUTOCSETFILLUPS:
597 ac.SetFillUpChars(reinterpret_cast<char *>(lParam));
598 break;
599
600 case SCI_AUTOCSETCHOOSESINGLE:
601 ac.chooseSingle = wParam != 0;
602 break;
603
604 case SCI_AUTOCGETCHOOSESINGLE:
605 return ac.chooseSingle;
606
607 case SCI_AUTOCSETIGNORECASE:
608 ac.ignoreCase = wParam != 0;
609 break;
610
611 case SCI_AUTOCGETIGNORECASE:
612 return ac.ignoreCase;
613
614 case SCI_USERLISTSHOW:
615 listType = wParam;
616 AutoCompleteStart(0, reinterpret_cast<const char *>(lParam));
617 break;
618
619 case SCI_AUTOCSETAUTOHIDE:
620 ac.autoHide = wParam != 0;
621 break;
622
623 case SCI_AUTOCGETAUTOHIDE:
624 return ac.autoHide;
625
626 case SCI_AUTOCSETDROPRESTOFWORD:
627 ac.dropRestOfWord = wParam != 0;
628 break;
629
630 case SCI_AUTOCGETDROPRESTOFWORD:
631 return ac.dropRestOfWord;
632
633 case SCI_AUTOCSETMAXHEIGHT:
634 ac.lb->SetVisibleRows(wParam);
635 break;
636
637 case SCI_AUTOCGETMAXHEIGHT:
638 return ac.lb->GetVisibleRows();
639
640 case SCI_AUTOCSETMAXWIDTH:
641 maxListWidth = wParam;
642 break;
643
644 case SCI_AUTOCGETMAXWIDTH:
645 return maxListWidth;
646
647 case SCI_REGISTERIMAGE:
648 ac.lb->RegisterImage(wParam, reinterpret_cast<const char *>(lParam));
649 break;
650
651 case SCI_CLEARREGISTEREDIMAGES:
652 ac.lb->ClearRegisteredImages();
653 break;
654
655 case SCI_AUTOCSETTYPESEPARATOR:
656 ac.SetTypesep(static_cast<char>(wParam));
657 break;
658
659 case SCI_AUTOCGETTYPESEPARATOR:
660 return ac.GetTypesep();
661
662 case SCI_CALLTIPSHOW:
663 CallTipShow(LocationFromPosition(wParam),
664 reinterpret_cast<const char *>(lParam));
665 break;
666
667 case SCI_CALLTIPCANCEL:
668 ct.CallTipCancel();
669 break;
670
671 case SCI_CALLTIPACTIVE:
672 return ct.inCallTipMode;
673
674 case SCI_CALLTIPPOSSTART:
675 return ct.posStartCallTip;
676
677 case SCI_CALLTIPSETHLT:
678 ct.SetHighlight(wParam, lParam);
679 break;
680
681 case SCI_CALLTIPSETBACK:
682 ct.colourBG = ColourDesired(wParam);
683 vs.styles[STYLE_CALLTIP].back = ct.colourBG;
684 InvalidateStyleRedraw();
685 break;
686
687 case SCI_CALLTIPSETFORE:
688 ct.colourUnSel = ColourDesired(wParam);
689 vs.styles[STYLE_CALLTIP].fore = ct.colourUnSel;
690 InvalidateStyleRedraw();
691 break;
692
693 case SCI_CALLTIPSETFOREHLT:
694 ct.colourSel = ColourDesired(wParam);
695 InvalidateStyleRedraw();
696 break;
697
698 case SCI_CALLTIPUSESTYLE:
699 ct.SetTabSize((int)wParam);
700 InvalidateStyleRedraw();
701 break;
702
703 case SCI_USEPOPUP:
704 displayPopupMenu = wParam != 0;
705 break;
706
707 #ifdef SCI_LEXER
708 case SCI_SETLEXER:
709 SetLexer(wParam);
710 lexLanguage = wParam;
711 break;
712
713 case SCI_GETLEXER:
714 return lexLanguage;
715
716 case SCI_COLOURISE:
717 if (lexLanguage == SCLEX_CONTAINER) {
718 pdoc->ModifiedAt(wParam);
719 NotifyStyleToNeeded((lParam == -1) ? pdoc->Length() : lParam);
720 } else {
721 Colourise(wParam, lParam);
722 }
723 Redraw();
724 break;
725
726 case SCI_SETPROPERTY:
727 props.Set(reinterpret_cast<const char *>(wParam),
728 reinterpret_cast<const char *>(lParam));
729 break;
730
731 case SCI_GETPROPERTY:
732 return StringResult(lParam, props.Get(reinterpret_cast<const char *>(wParam)));
733
734 case SCI_GETPROPERTYEXPANDED: {
735 char *val = props.Expanded(reinterpret_cast<const char *>(wParam));
736 const int n = strlen(val);
737 if (lParam != 0) {
738 char *ptr = reinterpret_cast<char *>(lParam);
739 strcpy(ptr, val);
740 }
741 delete []val;
742 return n; // Not including NUL
743 }
744
745 case SCI_GETPROPERTYINT:
746 return props.GetInt(reinterpret_cast<const char *>(wParam), lParam);
747
748 case SCI_SETKEYWORDS:
749 if (wParam < numWordLists) {
750 keyWordLists[wParam]->Clear();
751 keyWordLists[wParam]->Set(reinterpret_cast<const char *>(lParam));
752 }
753 break;
754
755 case SCI_SETLEXERLANGUAGE:
756 SetLexerLanguage(reinterpret_cast<const char *>(lParam));
757 break;
758
759 case SCI_GETLEXERLANGUAGE:
760 return StringResult(lParam, lexCurrent ? lexCurrent->languageName : "");
761
762 case SCI_GETSTYLEBITSNEEDED:
763 return lexCurrent ? lexCurrent->GetStyleBitsNeeded() : 5;
764
765 #endif
766
767 default:
768 return Editor::WndProc(iMessage, wParam, lParam);
769 }
770 return 0l;
771 }