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