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