Fix action icons in the log dialog being clipped on High-DPI displays
[TortoiseGit.git] / ext / scintilla / src / ScintillaBase.cxx
blob901df79713d0faaa750f21c103f8f35719ad0b40
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 <assert.h>
12 #include <ctype.h>
14 #include <stdexcept>
15 #include <string>
16 #include <vector>
17 #include <map>
18 #include <algorithm>
19 #include <memory>
21 #include "Platform.h"
23 #include "ILexer.h"
24 #include "Scintilla.h"
26 #ifdef SCI_LEXER
27 #include "SciLexer.h"
28 #endif
30 #include "PropSetSimple.h"
32 #ifdef SCI_LEXER
33 #include "LexerModule.h"
34 #include "Catalogue.h"
35 #endif
37 #include "Position.h"
38 #include "SplitVector.h"
39 #include "Partitioning.h"
40 #include "RunStyles.h"
41 #include "ContractionState.h"
42 #include "CellBuffer.h"
43 #include "CallTip.h"
44 #include "KeyMap.h"
45 #include "Indicator.h"
46 #include "XPM.h"
47 #include "LineMarker.h"
48 #include "Style.h"
49 #include "ViewStyle.h"
50 #include "CharClassify.h"
51 #include "Decoration.h"
52 #include "CaseFolder.h"
53 #include "Document.h"
54 #include "Selection.h"
55 #include "PositionCache.h"
56 #include "EditModel.h"
57 #include "MarginView.h"
58 #include "EditView.h"
59 #include "Editor.h"
60 #include "AutoComplete.h"
61 #include "ScintillaBase.h"
63 #ifdef SCI_NAMESPACE
64 using namespace Scintilla;
65 #endif
67 ScintillaBase::ScintillaBase() {
68 displayPopupMenu = SC_POPUP_ALL;
69 listType = 0;
70 maxListWidth = 0;
71 multiAutoCMode = SC_MULTIAUTOC_ONCE;
74 ScintillaBase::~ScintillaBase() {
77 void ScintillaBase::Finalise() {
78 Editor::Finalise();
79 popup.Destroy();
82 void ScintillaBase::AddCharUTF(const 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(ac.lb->GetVisibleRows());
152 return 0;
153 case SCI_PAGEUP:
154 AutoCompleteMove(-ac.lb->GetVisibleRows());
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(0, SC_AC_TAB);
174 return 0;
175 case SCI_NEWLINE:
176 AutoCompleteCompleted(0, SC_AC_NEWLINE);
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 = static_cast<ScintillaBase *>(p);
207 sci->AutoCompleteCompleted(0, SC_AC_DOUBLECLICK);
210 void ScintillaBase::AutoCompleteInsert(Position startPos, int removeLen, const char *text, int textLen) {
211 UndoGroup ug(pdoc);
212 if (multiAutoCMode == SC_MULTIAUTOC_ONCE) {
213 pdoc->DeleteChars(startPos, removeLen);
214 const int lengthInserted = pdoc->InsertString(startPos, text, textLen);
215 SetEmptySelection(startPos + lengthInserted);
216 } else {
217 // SC_MULTIAUTOC_EACH
218 for (size_t r=0; r<sel.Count(); r++) {
219 if (!RangeContainsProtected(sel.Range(r).Start().Position(),
220 sel.Range(r).End().Position())) {
221 int positionInsert = sel.Range(r).Start().Position();
222 positionInsert = RealizeVirtualSpace(positionInsert, sel.Range(r).caret.VirtualSpace());
223 if (positionInsert - removeLen >= 0) {
224 positionInsert -= removeLen;
225 pdoc->DeleteChars(positionInsert, removeLen);
227 const int lengthInserted = pdoc->InsertString(positionInsert, text, textLen);
228 if (lengthInserted > 0) {
229 sel.Range(r).caret.SetPosition(positionInsert + lengthInserted);
230 sel.Range(r).anchor.SetPosition(positionInsert + lengthInserted);
232 sel.Range(r).ClearVirtualSpace();
238 void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) {
239 //Platform::DebugPrintf("AutoComplete %s\n", list);
240 ct.CallTipCancel();
242 if (ac.chooseSingle && (listType == 0)) {
243 if (list && !strchr(list, ac.GetSeparator())) {
244 const char *typeSep = strchr(list, ac.GetTypesep());
245 int lenInsert = typeSep ?
246 static_cast<int>(typeSep-list) : static_cast<int>(strlen(list));
247 if (ac.ignoreCase) {
248 // May need to convert the case before invocation, so remove lenEntered characters
249 AutoCompleteInsert(sel.MainCaret() - lenEntered, lenEntered, list, lenInsert);
250 } else {
251 AutoCompleteInsert(sel.MainCaret(), 0, list + lenEntered, lenInsert - lenEntered);
253 ac.Cancel();
254 return;
257 ac.Start(wMain, idAutoComplete, sel.MainCaret(), PointMainCaret(),
258 lenEntered, vs.lineHeight, IsUnicodeMode(), technology);
260 PRectangle rcClient = GetClientRectangle();
261 Point pt = LocationFromPosition(sel.MainCaret() - lenEntered);
262 PRectangle rcPopupBounds = wMain.GetMonitorRect(pt);
263 if (rcPopupBounds.Height() == 0)
264 rcPopupBounds = rcClient;
266 int heightLB = ac.heightLBDefault;
267 int widthLB = ac.widthLBDefault;
268 if (pt.x >= rcClient.right - widthLB) {
269 HorizontalScrollTo(static_cast<int>(xOffset + pt.x - rcClient.right + widthLB));
270 Redraw();
271 pt = PointMainCaret();
273 if (wMargin.GetID()) {
274 Point ptOrigin = GetVisibleOriginInMain();
275 pt.x += ptOrigin.x;
276 pt.y += ptOrigin.y;
278 PRectangle rcac;
279 rcac.left = pt.x - ac.lb->CaretFromEdge();
280 if (pt.y >= rcPopupBounds.bottom - heightLB && // Won't fit below.
281 pt.y >= (rcPopupBounds.bottom + rcPopupBounds.top) / 2) { // and there is more room above.
282 rcac.top = pt.y - heightLB;
283 if (rcac.top < rcPopupBounds.top) {
284 heightLB -= static_cast<int>(rcPopupBounds.top - rcac.top);
285 rcac.top = rcPopupBounds.top;
287 } else {
288 rcac.top = pt.y + vs.lineHeight;
290 rcac.right = rcac.left + widthLB;
291 rcac.bottom = static_cast<XYPOSITION>(Platform::Minimum(static_cast<int>(rcac.top) + heightLB, static_cast<int>(rcPopupBounds.bottom)));
292 ac.lb->SetPositionRelative(rcac, wMain);
293 ac.lb->SetFont(vs.styles[STYLE_DEFAULT].font);
294 unsigned int aveCharWidth = static_cast<unsigned int>(vs.styles[STYLE_DEFAULT].aveCharWidth);
295 ac.lb->SetAverageCharWidth(aveCharWidth);
296 ac.lb->SetDoubleClickAction(AutoCompleteDoubleClick, this);
298 ac.SetList(list ? list : "");
300 // Fiddle the position of the list so it is right next to the target and wide enough for all its strings
301 PRectangle rcList = ac.lb->GetDesiredRect();
302 int heightAlloced = static_cast<int>(rcList.bottom - rcList.top);
303 widthLB = Platform::Maximum(widthLB, static_cast<int>(rcList.right - rcList.left));
304 if (maxListWidth != 0)
305 widthLB = Platform::Minimum(widthLB, aveCharWidth*maxListWidth);
306 // Make an allowance for large strings in list
307 rcList.left = pt.x - ac.lb->CaretFromEdge();
308 rcList.right = rcList.left + widthLB;
309 if (((pt.y + vs.lineHeight) >= (rcPopupBounds.bottom - heightAlloced)) && // Won't fit below.
310 ((pt.y + vs.lineHeight / 2) >= (rcPopupBounds.bottom + rcPopupBounds.top) / 2)) { // and there is more room above.
311 rcList.top = pt.y - heightAlloced;
312 } else {
313 rcList.top = pt.y + vs.lineHeight;
315 rcList.bottom = rcList.top + heightAlloced;
316 ac.lb->SetPositionRelative(rcList, wMain);
317 ac.Show(true);
318 if (lenEntered != 0) {
319 AutoCompleteMoveToCurrentWord();
323 void ScintillaBase::AutoCompleteCancel() {
324 if (ac.Active()) {
325 SCNotification scn = {};
326 scn.nmhdr.code = SCN_AUTOCCANCELLED;
327 scn.wParam = 0;
328 scn.listType = 0;
329 NotifyParent(scn);
331 ac.Cancel();
334 void ScintillaBase::AutoCompleteMove(int delta) {
335 ac.Move(delta);
338 void ScintillaBase::AutoCompleteMoveToCurrentWord() {
339 std::string wordCurrent = RangeText(ac.posStart - ac.startLen, sel.MainCaret());
340 ac.Select(wordCurrent.c_str());
343 void ScintillaBase::AutoCompleteCharacterAdded(char ch) {
344 if (ac.IsFillUpChar(ch)) {
345 AutoCompleteCompleted(ch, SC_AC_FILLUP);
346 } else if (ac.IsStopChar(ch)) {
347 AutoCompleteCancel();
348 } else {
349 AutoCompleteMoveToCurrentWord();
353 void ScintillaBase::AutoCompleteCharacterDeleted() {
354 if (sel.MainCaret() < ac.posStart - ac.startLen) {
355 AutoCompleteCancel();
356 } else if (ac.cancelAtStartPos && (sel.MainCaret() <= ac.posStart)) {
357 AutoCompleteCancel();
358 } else {
359 AutoCompleteMoveToCurrentWord();
361 SCNotification scn = {};
362 scn.nmhdr.code = SCN_AUTOCCHARDELETED;
363 scn.wParam = 0;
364 scn.listType = 0;
365 NotifyParent(scn);
368 void ScintillaBase::AutoCompleteCompleted(char ch, unsigned int completionMethod) {
369 int item = ac.GetSelection();
370 if (item == -1) {
371 AutoCompleteCancel();
372 return;
374 const std::string selected = ac.GetValue(item);
376 ac.Show(false);
378 SCNotification scn = {};
379 scn.nmhdr.code = listType > 0 ? SCN_USERLISTSELECTION : SCN_AUTOCSELECTION;
380 scn.message = 0;
381 scn.ch = ch;
382 scn.listCompletionMethod = completionMethod;
383 scn.wParam = listType;
384 scn.listType = listType;
385 Position firstPos = ac.posStart - ac.startLen;
386 scn.position = firstPos;
387 scn.lParam = firstPos;
388 scn.text = selected.c_str();
389 NotifyParent(scn);
391 if (!ac.Active())
392 return;
393 ac.Cancel();
395 if (listType > 0)
396 return;
398 Position endPos = sel.MainCaret();
399 if (ac.dropRestOfWord)
400 endPos = pdoc->ExtendWordSelect(endPos, 1, true);
401 if (endPos < firstPos)
402 return;
403 AutoCompleteInsert(firstPos, endPos - firstPos, selected.c_str(), static_cast<int>(selected.length()));
404 SetLastXChosen();
406 scn.nmhdr.code = SCN_AUTOCCOMPLETED;
407 NotifyParent(scn);
411 int ScintillaBase::AutoCompleteGetCurrent() const {
412 if (!ac.Active())
413 return -1;
414 return ac.GetSelection();
417 int ScintillaBase::AutoCompleteGetCurrentText(char *buffer) const {
418 if (ac.Active()) {
419 int item = ac.GetSelection();
420 if (item != -1) {
421 const std::string selected = ac.GetValue(item);
422 if (buffer != NULL)
423 memcpy(buffer, selected.c_str(), selected.length()+1);
424 return static_cast<int>(selected.length());
427 if (buffer != NULL)
428 *buffer = '\0';
429 return 0;
432 void ScintillaBase::CallTipShow(Point pt, const char *defn) {
433 ac.Cancel();
434 // If container knows about STYLE_CALLTIP then use it in place of the
435 // STYLE_DEFAULT for the face name, size and character set. Also use it
436 // for the foreground and background colour.
437 int ctStyle = ct.UseStyleCallTip() ? STYLE_CALLTIP : STYLE_DEFAULT;
438 if (ct.UseStyleCallTip()) {
439 ct.SetForeBack(vs.styles[STYLE_CALLTIP].fore, vs.styles[STYLE_CALLTIP].back);
441 if (wMargin.GetID()) {
442 Point ptOrigin = GetVisibleOriginInMain();
443 pt.x += ptOrigin.x;
444 pt.y += ptOrigin.y;
446 PRectangle rc = ct.CallTipStart(sel.MainCaret(), pt,
447 vs.lineHeight,
448 defn,
449 vs.styles[ctStyle].fontName,
450 vs.styles[ctStyle].sizeZoomed,
451 CodePage(),
452 vs.styles[ctStyle].characterSet,
453 vs.technology,
454 wMain);
455 // If the call-tip window would be out of the client
456 // space
457 PRectangle rcClient = GetClientRectangle();
458 int offset = vs.lineHeight + static_cast<int>(rc.Height());
459 // adjust so it displays above the text.
460 if (rc.bottom > rcClient.bottom && rc.Height() < rcClient.Height()) {
461 rc.top -= offset;
462 rc.bottom -= offset;
464 // adjust so it displays below the text.
465 if (rc.top < rcClient.top && rc.Height() < rcClient.Height()) {
466 rc.top += offset;
467 rc.bottom += offset;
469 // Now display the window.
470 CreateCallTipWindow(rc);
471 ct.wCallTip.SetPositionRelative(rc, wMain);
472 ct.wCallTip.Show();
475 void ScintillaBase::CallTipClick() {
476 SCNotification scn = {};
477 scn.nmhdr.code = SCN_CALLTIPCLICK;
478 scn.position = ct.clickPlace;
479 NotifyParent(scn);
482 bool ScintillaBase::ShouldDisplayPopup(Point ptInWindowCoordinates) const {
483 return (displayPopupMenu == SC_POPUP_ALL ||
484 (displayPopupMenu == SC_POPUP_TEXT && !PointInSelMargin(ptInWindowCoordinates)));
487 void ScintillaBase::ContextMenu(Point pt) {
488 if (displayPopupMenu) {
489 bool writable = !WndProc(SCI_GETREADONLY, 0, 0);
490 popup.CreatePopUp();
491 AddToPopUp("Undo", idcmdUndo, writable && pdoc->CanUndo());
492 AddToPopUp("Redo", idcmdRedo, writable && pdoc->CanRedo());
493 AddToPopUp("");
494 AddToPopUp("Cut", idcmdCut, writable && !sel.Empty());
495 AddToPopUp("Copy", idcmdCopy, !sel.Empty());
496 AddToPopUp("Paste", idcmdPaste, writable && WndProc(SCI_CANPASTE, 0, 0));
497 AddToPopUp("Delete", idcmdDelete, writable && !sel.Empty());
498 AddToPopUp("");
499 AddToPopUp("Select All", idcmdSelectAll);
500 popup.Show(pt, wMain);
504 void ScintillaBase::CancelModes() {
505 AutoCompleteCancel();
506 ct.CallTipCancel();
507 Editor::CancelModes();
510 void ScintillaBase::ButtonDownWithModifiers(Point pt, unsigned int curTime, int modifiers) {
511 CancelModes();
512 Editor::ButtonDownWithModifiers(pt, curTime, modifiers);
515 void ScintillaBase::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt) {
516 ButtonDownWithModifiers(pt, curTime, ModifierFlags(shift, ctrl, alt));
519 void ScintillaBase::RightButtonDownWithModifiers(Point pt, unsigned int curTime, int modifiers) {
520 CancelModes();
521 Editor::RightButtonDownWithModifiers(pt, curTime, modifiers);
524 #ifdef SCI_LEXER
526 #ifdef SCI_NAMESPACE
527 namespace Scintilla {
528 #endif
530 class LexState : public LexInterface {
531 const LexerModule *lexCurrent;
532 void SetLexerModule(const LexerModule *lex);
533 PropSetSimple props;
534 int interfaceVersion;
535 public:
536 int lexLanguage;
538 explicit LexState(Document *pdoc_);
539 ~LexState() override;
540 void SetLexer(uptr_t wParam);
541 void SetLexerLanguage(const char *languageName);
542 const char *DescribeWordListSets();
543 void SetWordList(int n, const char *wl);
544 const char *GetName() const;
545 void *PrivateCall(int operation, void *pointer);
546 const char *PropertyNames();
547 int PropertyType(const char *name);
548 const char *DescribeProperty(const char *name);
549 void PropSet(const char *key, const char *val);
550 const char *PropGet(const char *key) const;
551 int PropGetInt(const char *key, int defaultValue=0) const;
552 int PropGetExpanded(const char *key, char *result) const;
554 int LineEndTypesSupported();
555 int AllocateSubStyles(int styleBase, int numberStyles);
556 int SubStylesStart(int styleBase);
557 int SubStylesLength(int styleBase);
558 int StyleFromSubStyle(int subStyle);
559 int PrimaryStyleFromStyle(int style);
560 void FreeSubStyles();
561 void SetIdentifiers(int style, const char *identifiers);
562 int DistanceToSecondaryStyles();
563 const char *GetSubStyleBases();
566 #ifdef SCI_NAMESPACE
568 #endif
570 LexState::LexState(Document *pdoc_) : LexInterface(pdoc_) {
571 lexCurrent = 0;
572 performingStyle = false;
573 interfaceVersion = lvOriginal;
574 lexLanguage = SCLEX_CONTAINER;
577 LexState::~LexState() {
578 if (instance) {
579 instance->Release();
580 instance = 0;
584 LexState *ScintillaBase::DocumentLexState() {
585 if (!pdoc->pli) {
586 pdoc->pli = new LexState(pdoc);
588 return static_cast<LexState *>(pdoc->pli);
591 void LexState::SetLexerModule(const LexerModule *lex) {
592 if (lex != lexCurrent) {
593 if (instance) {
594 instance->Release();
595 instance = 0;
597 interfaceVersion = lvOriginal;
598 lexCurrent = lex;
599 if (lexCurrent) {
600 instance = lexCurrent->Create();
601 interfaceVersion = instance->Version();
603 pdoc->LexerChanged();
607 void LexState::SetLexer(uptr_t wParam) {
608 lexLanguage = static_cast<int>(wParam);
609 if (lexLanguage == SCLEX_CONTAINER) {
610 SetLexerModule(0);
611 } else {
612 const LexerModule *lex = Catalogue::Find(lexLanguage);
613 if (!lex)
614 lex = Catalogue::Find(SCLEX_NULL);
615 SetLexerModule(lex);
619 void LexState::SetLexerLanguage(const char *languageName) {
620 const LexerModule *lex = Catalogue::Find(languageName);
621 if (!lex)
622 lex = Catalogue::Find(SCLEX_NULL);
623 if (lex)
624 lexLanguage = lex->GetLanguage();
625 SetLexerModule(lex);
628 const char *LexState::DescribeWordListSets() {
629 if (instance) {
630 return instance->DescribeWordListSets();
631 } else {
632 return 0;
636 void LexState::SetWordList(int n, const char *wl) {
637 if (instance) {
638 int firstModification = instance->WordListSet(n, wl);
639 if (firstModification >= 0) {
640 pdoc->ModifiedAt(firstModification);
645 const char *LexState::GetName() const {
646 return lexCurrent ? lexCurrent->languageName : "";
649 void *LexState::PrivateCall(int operation, void *pointer) {
650 if (pdoc && instance) {
651 return instance->PrivateCall(operation, pointer);
652 } else {
653 return 0;
657 const char *LexState::PropertyNames() {
658 if (instance) {
659 return instance->PropertyNames();
660 } else {
661 return 0;
665 int LexState::PropertyType(const char *name) {
666 if (instance) {
667 return instance->PropertyType(name);
668 } else {
669 return SC_TYPE_BOOLEAN;
673 const char *LexState::DescribeProperty(const char *name) {
674 if (instance) {
675 return instance->DescribeProperty(name);
676 } else {
677 return 0;
681 void LexState::PropSet(const char *key, const char *val) {
682 props.Set(key, val);
683 if (instance) {
684 int firstModification = instance->PropertySet(key, val);
685 if (firstModification >= 0) {
686 pdoc->ModifiedAt(firstModification);
691 const char *LexState::PropGet(const char *key) const {
692 return props.Get(key);
695 int LexState::PropGetInt(const char *key, int defaultValue) const {
696 return props.GetInt(key, defaultValue);
699 int LexState::PropGetExpanded(const char *key, char *result) const {
700 return props.GetExpanded(key, result);
703 int LexState::LineEndTypesSupported() {
704 if (instance && (interfaceVersion >= lvSubStyles)) {
705 return static_cast<ILexerWithSubStyles *>(instance)->LineEndTypesSupported();
707 return 0;
710 int LexState::AllocateSubStyles(int styleBase, int numberStyles) {
711 if (instance && (interfaceVersion >= lvSubStyles)) {
712 return static_cast<ILexerWithSubStyles *>(instance)->AllocateSubStyles(styleBase, numberStyles);
714 return -1;
717 int LexState::SubStylesStart(int styleBase) {
718 if (instance && (interfaceVersion >= lvSubStyles)) {
719 return static_cast<ILexerWithSubStyles *>(instance)->SubStylesStart(styleBase);
721 return -1;
724 int LexState::SubStylesLength(int styleBase) {
725 if (instance && (interfaceVersion >= lvSubStyles)) {
726 return static_cast<ILexerWithSubStyles *>(instance)->SubStylesLength(styleBase);
728 return 0;
731 int LexState::StyleFromSubStyle(int subStyle) {
732 if (instance && (interfaceVersion >= lvSubStyles)) {
733 return static_cast<ILexerWithSubStyles *>(instance)->StyleFromSubStyle(subStyle);
735 return 0;
738 int LexState::PrimaryStyleFromStyle(int style) {
739 if (instance && (interfaceVersion >= lvSubStyles)) {
740 return static_cast<ILexerWithSubStyles *>(instance)->PrimaryStyleFromStyle(style);
742 return 0;
745 void LexState::FreeSubStyles() {
746 if (instance && (interfaceVersion >= lvSubStyles)) {
747 static_cast<ILexerWithSubStyles *>(instance)->FreeSubStyles();
751 void LexState::SetIdentifiers(int style, const char *identifiers) {
752 if (instance && (interfaceVersion >= lvSubStyles)) {
753 static_cast<ILexerWithSubStyles *>(instance)->SetIdentifiers(style, identifiers);
754 pdoc->ModifiedAt(0);
758 int LexState::DistanceToSecondaryStyles() {
759 if (instance && (interfaceVersion >= lvSubStyles)) {
760 return static_cast<ILexerWithSubStyles *>(instance)->DistanceToSecondaryStyles();
762 return 0;
765 const char *LexState::GetSubStyleBases() {
766 if (instance && (interfaceVersion >= lvSubStyles)) {
767 return static_cast<ILexerWithSubStyles *>(instance)->GetSubStyleBases();
769 return "";
772 #endif
774 void ScintillaBase::NotifyStyleToNeeded(int endStyleNeeded) {
775 #ifdef SCI_LEXER
776 if (DocumentLexState()->lexLanguage != SCLEX_CONTAINER) {
777 int lineEndStyled = pdoc->LineFromPosition(pdoc->GetEndStyled());
778 int endStyled = pdoc->LineStart(lineEndStyled);
779 DocumentLexState()->Colourise(endStyled, endStyleNeeded);
780 return;
782 #endif
783 Editor::NotifyStyleToNeeded(endStyleNeeded);
786 void ScintillaBase::NotifyLexerChanged(Document *, void *) {
787 #ifdef SCI_LEXER
788 vs.EnsureStyle(0xff);
789 #endif
792 sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
793 switch (iMessage) {
794 case SCI_AUTOCSHOW:
795 listType = 0;
796 AutoCompleteStart(static_cast<int>(wParam), reinterpret_cast<const char *>(lParam));
797 break;
799 case SCI_AUTOCCANCEL:
800 ac.Cancel();
801 break;
803 case SCI_AUTOCACTIVE:
804 return ac.Active();
806 case SCI_AUTOCPOSSTART:
807 return ac.posStart;
809 case SCI_AUTOCCOMPLETE:
810 AutoCompleteCompleted(0, SC_AC_COMMAND);
811 break;
813 case SCI_AUTOCSETSEPARATOR:
814 ac.SetSeparator(static_cast<char>(wParam));
815 break;
817 case SCI_AUTOCGETSEPARATOR:
818 return ac.GetSeparator();
820 case SCI_AUTOCSTOPS:
821 ac.SetStopChars(reinterpret_cast<char *>(lParam));
822 break;
824 case SCI_AUTOCSELECT:
825 ac.Select(reinterpret_cast<char *>(lParam));
826 break;
828 case SCI_AUTOCGETCURRENT:
829 return AutoCompleteGetCurrent();
831 case SCI_AUTOCGETCURRENTTEXT:
832 return AutoCompleteGetCurrentText(reinterpret_cast<char *>(lParam));
834 case SCI_AUTOCSETCANCELATSTART:
835 ac.cancelAtStartPos = wParam != 0;
836 break;
838 case SCI_AUTOCGETCANCELATSTART:
839 return ac.cancelAtStartPos;
841 case SCI_AUTOCSETFILLUPS:
842 ac.SetFillUpChars(reinterpret_cast<char *>(lParam));
843 break;
845 case SCI_AUTOCSETCHOOSESINGLE:
846 ac.chooseSingle = wParam != 0;
847 break;
849 case SCI_AUTOCGETCHOOSESINGLE:
850 return ac.chooseSingle;
852 case SCI_AUTOCSETIGNORECASE:
853 ac.ignoreCase = wParam != 0;
854 break;
856 case SCI_AUTOCGETIGNORECASE:
857 return ac.ignoreCase;
859 case SCI_AUTOCSETCASEINSENSITIVEBEHAVIOUR:
860 ac.ignoreCaseBehaviour = static_cast<unsigned int>(wParam);
861 break;
863 case SCI_AUTOCGETCASEINSENSITIVEBEHAVIOUR:
864 return ac.ignoreCaseBehaviour;
866 case SCI_AUTOCSETMULTI:
867 multiAutoCMode = static_cast<int>(wParam);
868 break;
870 case SCI_AUTOCGETMULTI:
871 return multiAutoCMode;
873 case SCI_AUTOCSETORDER:
874 ac.autoSort = static_cast<int>(wParam);
875 break;
877 case SCI_AUTOCGETORDER:
878 return ac.autoSort;
880 case SCI_USERLISTSHOW:
881 listType = static_cast<int>(wParam);
882 AutoCompleteStart(0, reinterpret_cast<const char *>(lParam));
883 break;
885 case SCI_AUTOCSETAUTOHIDE:
886 ac.autoHide = wParam != 0;
887 break;
889 case SCI_AUTOCGETAUTOHIDE:
890 return ac.autoHide;
892 case SCI_AUTOCSETDROPRESTOFWORD:
893 ac.dropRestOfWord = wParam != 0;
894 break;
896 case SCI_AUTOCGETDROPRESTOFWORD:
897 return ac.dropRestOfWord;
899 case SCI_AUTOCSETMAXHEIGHT:
900 ac.lb->SetVisibleRows(static_cast<int>(wParam));
901 break;
903 case SCI_AUTOCGETMAXHEIGHT:
904 return ac.lb->GetVisibleRows();
906 case SCI_AUTOCSETMAXWIDTH:
907 maxListWidth = static_cast<int>(wParam);
908 break;
910 case SCI_AUTOCGETMAXWIDTH:
911 return maxListWidth;
913 case SCI_REGISTERIMAGE:
914 ac.lb->RegisterImage(static_cast<int>(wParam), reinterpret_cast<const char *>(lParam));
915 break;
917 case SCI_REGISTERRGBAIMAGE:
918 ac.lb->RegisterRGBAImage(static_cast<int>(wParam), static_cast<int>(sizeRGBAImage.x), static_cast<int>(sizeRGBAImage.y),
919 reinterpret_cast<unsigned char *>(lParam));
920 break;
922 case SCI_CLEARREGISTEREDIMAGES:
923 ac.lb->ClearRegisteredImages();
924 break;
926 case SCI_AUTOCSETTYPESEPARATOR:
927 ac.SetTypesep(static_cast<char>(wParam));
928 break;
930 case SCI_AUTOCGETTYPESEPARATOR:
931 return ac.GetTypesep();
933 case SCI_CALLTIPSHOW:
934 CallTipShow(LocationFromPosition(static_cast<int>(wParam)),
935 reinterpret_cast<const char *>(lParam));
936 break;
938 case SCI_CALLTIPCANCEL:
939 ct.CallTipCancel();
940 break;
942 case SCI_CALLTIPACTIVE:
943 return ct.inCallTipMode;
945 case SCI_CALLTIPPOSSTART:
946 return ct.posStartCallTip;
948 case SCI_CALLTIPSETPOSSTART:
949 ct.posStartCallTip = static_cast<int>(wParam);
950 break;
952 case SCI_CALLTIPSETHLT:
953 ct.SetHighlight(static_cast<int>(wParam), static_cast<int>(lParam));
954 break;
956 case SCI_CALLTIPSETBACK:
957 ct.colourBG = ColourDesired(static_cast<long>(wParam));
958 vs.styles[STYLE_CALLTIP].back = ct.colourBG;
959 InvalidateStyleRedraw();
960 break;
962 case SCI_CALLTIPSETFORE:
963 ct.colourUnSel = ColourDesired(static_cast<long>(wParam));
964 vs.styles[STYLE_CALLTIP].fore = ct.colourUnSel;
965 InvalidateStyleRedraw();
966 break;
968 case SCI_CALLTIPSETFOREHLT:
969 ct.colourSel = ColourDesired(static_cast<long>(wParam));
970 InvalidateStyleRedraw();
971 break;
973 case SCI_CALLTIPUSESTYLE:
974 ct.SetTabSize(static_cast<int>(wParam));
975 InvalidateStyleRedraw();
976 break;
978 case SCI_CALLTIPSETPOSITION:
979 ct.SetPosition(wParam != 0);
980 InvalidateStyleRedraw();
981 break;
983 case SCI_USEPOPUP:
984 displayPopupMenu = static_cast<int>(wParam);
985 break;
987 #ifdef SCI_LEXER
988 case SCI_SETLEXER:
989 DocumentLexState()->SetLexer(static_cast<int>(wParam));
990 break;
992 case SCI_GETLEXER:
993 return DocumentLexState()->lexLanguage;
995 case SCI_COLOURISE:
996 if (DocumentLexState()->lexLanguage == SCLEX_CONTAINER) {
997 pdoc->ModifiedAt(static_cast<int>(wParam));
998 NotifyStyleToNeeded((lParam == -1) ? pdoc->Length() : static_cast<int>(lParam));
999 } else {
1000 DocumentLexState()->Colourise(static_cast<int>(wParam), static_cast<int>(lParam));
1002 Redraw();
1003 break;
1005 case SCI_SETPROPERTY:
1006 DocumentLexState()->PropSet(reinterpret_cast<const char *>(wParam),
1007 reinterpret_cast<const char *>(lParam));
1008 break;
1010 case SCI_GETPROPERTY:
1011 return StringResult(lParam, DocumentLexState()->PropGet(reinterpret_cast<const char *>(wParam)));
1013 case SCI_GETPROPERTYEXPANDED:
1014 return DocumentLexState()->PropGetExpanded(reinterpret_cast<const char *>(wParam),
1015 reinterpret_cast<char *>(lParam));
1017 case SCI_GETPROPERTYINT:
1018 return DocumentLexState()->PropGetInt(reinterpret_cast<const char *>(wParam), static_cast<int>(lParam));
1020 case SCI_SETKEYWORDS:
1021 DocumentLexState()->SetWordList(static_cast<int>(wParam), reinterpret_cast<const char *>(lParam));
1022 break;
1024 case SCI_SETLEXERLANGUAGE:
1025 DocumentLexState()->SetLexerLanguage(reinterpret_cast<const char *>(lParam));
1026 break;
1028 case SCI_GETLEXERLANGUAGE:
1029 return StringResult(lParam, DocumentLexState()->GetName());
1031 case SCI_PRIVATELEXERCALL:
1032 return reinterpret_cast<sptr_t>(
1033 DocumentLexState()->PrivateCall(static_cast<int>(wParam), reinterpret_cast<void *>(lParam)));
1035 case SCI_GETSTYLEBITSNEEDED:
1036 return 8;
1038 case SCI_PROPERTYNAMES:
1039 return StringResult(lParam, DocumentLexState()->PropertyNames());
1041 case SCI_PROPERTYTYPE:
1042 return DocumentLexState()->PropertyType(reinterpret_cast<const char *>(wParam));
1044 case SCI_DESCRIBEPROPERTY:
1045 return StringResult(lParam,
1046 DocumentLexState()->DescribeProperty(reinterpret_cast<const char *>(wParam)));
1048 case SCI_DESCRIBEKEYWORDSETS:
1049 return StringResult(lParam, DocumentLexState()->DescribeWordListSets());
1051 case SCI_GETLINEENDTYPESSUPPORTED:
1052 return DocumentLexState()->LineEndTypesSupported();
1054 case SCI_ALLOCATESUBSTYLES:
1055 return DocumentLexState()->AllocateSubStyles(static_cast<int>(wParam), static_cast<int>(lParam));
1057 case SCI_GETSUBSTYLESSTART:
1058 return DocumentLexState()->SubStylesStart(static_cast<int>(wParam));
1060 case SCI_GETSUBSTYLESLENGTH:
1061 return DocumentLexState()->SubStylesLength(static_cast<int>(wParam));
1063 case SCI_GETSTYLEFROMSUBSTYLE:
1064 return DocumentLexState()->StyleFromSubStyle(static_cast<int>(wParam));
1066 case SCI_GETPRIMARYSTYLEFROMSTYLE:
1067 return DocumentLexState()->PrimaryStyleFromStyle(static_cast<int>(wParam));
1069 case SCI_FREESUBSTYLES:
1070 DocumentLexState()->FreeSubStyles();
1071 break;
1073 case SCI_SETIDENTIFIERS:
1074 DocumentLexState()->SetIdentifiers(static_cast<int>(wParam),
1075 reinterpret_cast<const char *>(lParam));
1076 break;
1078 case SCI_DISTANCETOSECONDARYSTYLES:
1079 return DocumentLexState()->DistanceToSecondaryStyles();
1081 case SCI_GETSUBSTYLEBASES:
1082 return StringResult(lParam, DocumentLexState()->GetSubStyleBases());
1083 #endif
1085 default:
1086 return Editor::WndProc(iMessage, wParam, lParam);
1088 return 0l;