Update of German translation
[geany-mirror.git] / scintilla / src / ScintillaBase.cxx
blob92605d9b35fbbf8a9a5f073adab7322b7fd3396a
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>
20 #include "Platform.h"
22 #include "ILexer.h"
23 #include "Scintilla.h"
25 #ifdef SCI_LEXER
26 #include "SciLexer.h"
27 #endif
29 #include "PropSetSimple.h"
31 #ifdef SCI_LEXER
32 #include "LexerModule.h"
33 #include "Catalogue.h"
34 #endif
36 #include "Position.h"
37 #include "SplitVector.h"
38 #include "Partitioning.h"
39 #include "RunStyles.h"
40 #include "ContractionState.h"
41 #include "CellBuffer.h"
42 #include "CallTip.h"
43 #include "KeyMap.h"
44 #include "Indicator.h"
45 #include "XPM.h"
46 #include "LineMarker.h"
47 #include "Style.h"
48 #include "ViewStyle.h"
49 #include "CharClassify.h"
50 #include "Decoration.h"
51 #include "CaseFolder.h"
52 #include "Document.h"
53 #include "Selection.h"
54 #include "PositionCache.h"
55 #include "EditModel.h"
56 #include "MarginView.h"
57 #include "EditView.h"
58 #include "Editor.h"
59 #include "AutoComplete.h"
60 #include "ScintillaBase.h"
62 #ifdef SCI_NAMESPACE
63 using namespace Scintilla;
64 #endif
66 ScintillaBase::ScintillaBase() {
67 displayPopupMenu = true;
68 listType = 0;
69 maxListWidth = 0;
70 multiAutoCMode = SC_MULTIAUTOC_ONCE;
73 ScintillaBase::~ScintillaBase() {
76 void ScintillaBase::Finalise() {
77 Editor::Finalise();
78 popup.Destroy();
81 void ScintillaBase::AddCharUTF(const char *s, unsigned int len, bool treatAsDBCS) {
82 bool isFillUp = ac.Active() && ac.IsFillUpChar(*s);
83 if (!isFillUp) {
84 Editor::AddCharUTF(s, len, treatAsDBCS);
86 if (ac.Active()) {
87 AutoCompleteCharacterAdded(s[0]);
88 // For fill ups add the character after the autocompletion has
89 // triggered so containers see the key so can display a calltip.
90 if (isFillUp) {
91 Editor::AddCharUTF(s, len, treatAsDBCS);
96 void ScintillaBase::Command(int cmdId) {
98 switch (cmdId) {
100 case idAutoComplete: // Nothing to do
102 break;
104 case idCallTip: // Nothing to do
106 break;
108 case idcmdUndo:
109 WndProc(SCI_UNDO, 0, 0);
110 break;
112 case idcmdRedo:
113 WndProc(SCI_REDO, 0, 0);
114 break;
116 case idcmdCut:
117 WndProc(SCI_CUT, 0, 0);
118 break;
120 case idcmdCopy:
121 WndProc(SCI_COPY, 0, 0);
122 break;
124 case idcmdPaste:
125 WndProc(SCI_PASTE, 0, 0);
126 break;
128 case idcmdDelete:
129 WndProc(SCI_CLEAR, 0, 0);
130 break;
132 case idcmdSelectAll:
133 WndProc(SCI_SELECTALL, 0, 0);
134 break;
138 int ScintillaBase::KeyCommand(unsigned int iMessage) {
139 // Most key commands cancel autocompletion mode
140 if (ac.Active()) {
141 switch (iMessage) {
142 // Except for these
143 case SCI_LINEDOWN:
144 AutoCompleteMove(1);
145 return 0;
146 case SCI_LINEUP:
147 AutoCompleteMove(-1);
148 return 0;
149 case SCI_PAGEDOWN:
150 AutoCompleteMove(ac.lb->GetVisibleRows());
151 return 0;
152 case SCI_PAGEUP:
153 AutoCompleteMove(-ac.lb->GetVisibleRows());
154 return 0;
155 case SCI_VCHOME:
156 AutoCompleteMove(-5000);
157 return 0;
158 case SCI_LINEEND:
159 AutoCompleteMove(5000);
160 return 0;
161 case SCI_DELETEBACK:
162 DelCharBack(true);
163 AutoCompleteCharacterDeleted();
164 EnsureCaretVisible();
165 return 0;
166 case SCI_DELETEBACKNOTLINE:
167 DelCharBack(false);
168 AutoCompleteCharacterDeleted();
169 EnsureCaretVisible();
170 return 0;
171 case SCI_TAB:
172 AutoCompleteCompleted(0, SC_AC_TAB);
173 return 0;
174 case SCI_NEWLINE:
175 AutoCompleteCompleted(0, SC_AC_NEWLINE);
176 return 0;
178 default:
179 AutoCompleteCancel();
183 if (ct.inCallTipMode) {
184 if (
185 (iMessage != SCI_CHARLEFT) &&
186 (iMessage != SCI_CHARLEFTEXTEND) &&
187 (iMessage != SCI_CHARRIGHT) &&
188 (iMessage != SCI_CHARRIGHTEXTEND) &&
189 (iMessage != SCI_EDITTOGGLEOVERTYPE) &&
190 (iMessage != SCI_DELETEBACK) &&
191 (iMessage != SCI_DELETEBACKNOTLINE)
193 ct.CallTipCancel();
195 if ((iMessage == SCI_DELETEBACK) || (iMessage == SCI_DELETEBACKNOTLINE)) {
196 if (sel.MainCaret() <= ct.posStartCallTip) {
197 ct.CallTipCancel();
201 return Editor::KeyCommand(iMessage);
204 void ScintillaBase::AutoCompleteDoubleClick(void *p) {
205 ScintillaBase *sci = reinterpret_cast<ScintillaBase *>(p);
206 sci->AutoCompleteCompleted(0, SC_AC_DOUBLECLICK);
209 void ScintillaBase::AutoCompleteInsert(Position startPos, int removeLen, const char *text, int textLen) {
210 UndoGroup ug(pdoc);
211 if (multiAutoCMode == SC_MULTIAUTOC_ONCE) {
212 pdoc->DeleteChars(startPos, removeLen);
213 const int lengthInserted = pdoc->InsertString(startPos, text, textLen);
214 SetEmptySelection(startPos + lengthInserted);
215 } else {
216 // SC_MULTIAUTOC_EACH
217 for (size_t r=0; r<sel.Count(); r++) {
218 if (!RangeContainsProtected(sel.Range(r).Start().Position(),
219 sel.Range(r).End().Position())) {
220 int positionInsert = sel.Range(r).Start().Position();
221 positionInsert = RealizeVirtualSpace(positionInsert, sel.Range(r).caret.VirtualSpace());
222 if (positionInsert - removeLen >= 0) {
223 positionInsert -= removeLen;
224 pdoc->DeleteChars(positionInsert, removeLen);
226 const int lengthInserted = pdoc->InsertString(positionInsert, text, textLen);
227 if (lengthInserted > 0) {
228 sel.Range(r).caret.SetPosition(positionInsert + lengthInserted);
229 sel.Range(r).anchor.SetPosition(positionInsert + lengthInserted);
231 sel.Range(r).ClearVirtualSpace();
237 void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) {
238 //Platform::DebugPrintf("AutoComplete %s\n", list);
239 ct.CallTipCancel();
241 if (ac.chooseSingle && (listType == 0)) {
242 if (list && !strchr(list, ac.GetSeparator())) {
243 const char *typeSep = strchr(list, ac.GetTypesep());
244 int lenInsert = typeSep ?
245 static_cast<int>(typeSep-list) : static_cast<int>(strlen(list));
246 if (ac.ignoreCase) {
247 // May need to convert the case before invocation, so remove lenEntered characters
248 AutoCompleteInsert(sel.MainCaret() - lenEntered, lenEntered, list, lenInsert);
249 } else {
250 AutoCompleteInsert(sel.MainCaret(), 0, list + lenEntered, lenInsert - lenEntered);
252 ac.Cancel();
253 return;
256 ac.Start(wMain, idAutoComplete, sel.MainCaret(), PointMainCaret(),
257 lenEntered, vs.lineHeight, IsUnicodeMode(), technology);
259 PRectangle rcClient = GetClientRectangle();
260 Point pt = LocationFromPosition(sel.MainCaret() - lenEntered);
261 PRectangle rcPopupBounds = wMain.GetMonitorRect(pt);
262 if (rcPopupBounds.Height() == 0)
263 rcPopupBounds = rcClient;
265 int heightLB = ac.heightLBDefault;
266 int widthLB = ac.widthLBDefault;
267 if (pt.x >= rcClient.right - widthLB) {
268 HorizontalScrollTo(static_cast<int>(xOffset + pt.x - rcClient.right + widthLB));
269 Redraw();
270 pt = PointMainCaret();
272 if (wMargin.GetID()) {
273 Point ptOrigin = GetVisibleOriginInMain();
274 pt.x += ptOrigin.x;
275 pt.y += ptOrigin.y;
277 PRectangle rcac;
278 rcac.left = pt.x - ac.lb->CaretFromEdge();
279 if (pt.y >= rcPopupBounds.bottom - heightLB && // Won't fit below.
280 pt.y >= (rcPopupBounds.bottom + rcPopupBounds.top) / 2) { // and there is more room above.
281 rcac.top = pt.y - heightLB;
282 if (rcac.top < rcPopupBounds.top) {
283 heightLB -= static_cast<int>(rcPopupBounds.top - rcac.top);
284 rcac.top = rcPopupBounds.top;
286 } else {
287 rcac.top = pt.y + vs.lineHeight;
289 rcac.right = rcac.left + widthLB;
290 rcac.bottom = static_cast<XYPOSITION>(Platform::Minimum(static_cast<int>(rcac.top) + heightLB, static_cast<int>(rcPopupBounds.bottom)));
291 ac.lb->SetPositionRelative(rcac, wMain);
292 ac.lb->SetFont(vs.styles[STYLE_DEFAULT].font);
293 unsigned int aveCharWidth = static_cast<unsigned int>(vs.styles[STYLE_DEFAULT].aveCharWidth);
294 ac.lb->SetAverageCharWidth(aveCharWidth);
295 ac.lb->SetDoubleClickAction(AutoCompleteDoubleClick, this);
297 ac.SetList(list ? list : "");
299 // Fiddle the position of the list so it is right next to the target and wide enough for all its strings
300 PRectangle rcList = ac.lb->GetDesiredRect();
301 int heightAlloced = static_cast<int>(rcList.bottom - rcList.top);
302 widthLB = Platform::Maximum(widthLB, static_cast<int>(rcList.right - rcList.left));
303 if (maxListWidth != 0)
304 widthLB = Platform::Minimum(widthLB, aveCharWidth*maxListWidth);
305 // Make an allowance for large strings in list
306 rcList.left = pt.x - ac.lb->CaretFromEdge();
307 rcList.right = rcList.left + widthLB;
308 if (((pt.y + vs.lineHeight) >= (rcPopupBounds.bottom - heightAlloced)) && // Won't fit below.
309 ((pt.y + vs.lineHeight / 2) >= (rcPopupBounds.bottom + rcPopupBounds.top) / 2)) { // and there is more room above.
310 rcList.top = pt.y - heightAlloced;
311 } else {
312 rcList.top = pt.y + vs.lineHeight;
314 rcList.bottom = rcList.top + heightAlloced;
315 ac.lb->SetPositionRelative(rcList, wMain);
316 ac.Show(true);
317 if (lenEntered != 0) {
318 AutoCompleteMoveToCurrentWord();
322 void ScintillaBase::AutoCompleteCancel() {
323 if (ac.Active()) {
324 SCNotification scn = {};
325 scn.nmhdr.code = SCN_AUTOCCANCELLED;
326 scn.wParam = 0;
327 scn.listType = 0;
328 NotifyParent(scn);
330 ac.Cancel();
333 void ScintillaBase::AutoCompleteMove(int delta) {
334 ac.Move(delta);
337 void ScintillaBase::AutoCompleteMoveToCurrentWord() {
338 std::string wordCurrent = RangeText(ac.posStart - ac.startLen, sel.MainCaret());
339 ac.Select(wordCurrent.c_str());
342 void ScintillaBase::AutoCompleteCharacterAdded(char ch) {
343 if (ac.IsFillUpChar(ch)) {
344 AutoCompleteCompleted(ch, SC_AC_FILLUP);
345 } else if (ac.IsStopChar(ch)) {
346 AutoCompleteCancel();
347 } else {
348 AutoCompleteMoveToCurrentWord();
352 void ScintillaBase::AutoCompleteCharacterDeleted() {
353 if (sel.MainCaret() < ac.posStart - ac.startLen) {
354 AutoCompleteCancel();
355 } else if (ac.cancelAtStartPos && (sel.MainCaret() <= ac.posStart)) {
356 AutoCompleteCancel();
357 } else {
358 AutoCompleteMoveToCurrentWord();
360 SCNotification scn = {};
361 scn.nmhdr.code = SCN_AUTOCCHARDELETED;
362 scn.wParam = 0;
363 scn.listType = 0;
364 NotifyParent(scn);
367 void ScintillaBase::AutoCompleteCompleted(char ch, unsigned int completionMethod) {
368 int item = ac.GetSelection();
369 if (item == -1) {
370 AutoCompleteCancel();
371 return;
373 const std::string selected = ac.GetValue(item);
375 ac.Show(false);
377 SCNotification scn = {};
378 scn.nmhdr.code = listType > 0 ? SCN_USERLISTSELECTION : SCN_AUTOCSELECTION;
379 scn.message = 0;
380 scn.ch = ch;
381 scn.listCompletionMethod = completionMethod;
382 scn.wParam = listType;
383 scn.listType = listType;
384 Position firstPos = ac.posStart - ac.startLen;
385 scn.position = firstPos;
386 scn.lParam = firstPos;
387 scn.text = selected.c_str();
388 NotifyParent(scn);
390 if (!ac.Active())
391 return;
392 ac.Cancel();
394 if (listType > 0)
395 return;
397 Position endPos = sel.MainCaret();
398 if (ac.dropRestOfWord)
399 endPos = pdoc->ExtendWordSelect(endPos, 1, true);
400 if (endPos < firstPos)
401 return;
402 AutoCompleteInsert(firstPos, endPos - firstPos, selected.c_str(), static_cast<int>(selected.length()));
403 SetLastXChosen();
405 scn.nmhdr.code = SCN_AUTOCCOMPLETED;
406 NotifyParent(scn);
410 int ScintillaBase::AutoCompleteGetCurrent() const {
411 if (!ac.Active())
412 return -1;
413 return ac.GetSelection();
416 int ScintillaBase::AutoCompleteGetCurrentText(char *buffer) const {
417 if (ac.Active()) {
418 int item = ac.GetSelection();
419 if (item != -1) {
420 const std::string selected = ac.GetValue(item);
421 if (buffer != NULL)
422 memcpy(buffer, selected.c_str(), selected.length()+1);
423 return static_cast<int>(selected.length());
426 if (buffer != NULL)
427 *buffer = '\0';
428 return 0;
431 void ScintillaBase::CallTipShow(Point pt, const char *defn) {
432 ac.Cancel();
433 // If container knows about STYLE_CALLTIP then use it in place of the
434 // STYLE_DEFAULT for the face name, size and character set. Also use it
435 // for the foreground and background colour.
436 int ctStyle = ct.UseStyleCallTip() ? STYLE_CALLTIP : STYLE_DEFAULT;
437 if (ct.UseStyleCallTip()) {
438 ct.SetForeBack(vs.styles[STYLE_CALLTIP].fore, vs.styles[STYLE_CALLTIP].back);
440 if (wMargin.GetID()) {
441 Point ptOrigin = GetVisibleOriginInMain();
442 pt.x += ptOrigin.x;
443 pt.y += ptOrigin.y;
445 PRectangle rc = ct.CallTipStart(sel.MainCaret(), pt,
446 vs.lineHeight,
447 defn,
448 vs.styles[ctStyle].fontName,
449 vs.styles[ctStyle].sizeZoomed,
450 CodePage(),
451 vs.styles[ctStyle].characterSet,
452 vs.technology,
453 wMain);
454 // If the call-tip window would be out of the client
455 // space
456 PRectangle rcClient = GetClientRectangle();
457 int offset = vs.lineHeight + static_cast<int>(rc.Height());
458 // adjust so it displays above the text.
459 if (rc.bottom > rcClient.bottom && rc.Height() < rcClient.Height()) {
460 rc.top -= offset;
461 rc.bottom -= offset;
463 // adjust so it displays below the text.
464 if (rc.top < rcClient.top && rc.Height() < rcClient.Height()) {
465 rc.top += offset;
466 rc.bottom += offset;
468 // Now display the window.
469 CreateCallTipWindow(rc);
470 ct.wCallTip.SetPositionRelative(rc, wMain);
471 ct.wCallTip.Show();
474 void ScintillaBase::CallTipClick() {
475 SCNotification scn = {};
476 scn.nmhdr.code = SCN_CALLTIPCLICK;
477 scn.position = ct.clickPlace;
478 NotifyParent(scn);
481 void ScintillaBase::ContextMenu(Point pt) {
482 if (displayPopupMenu) {
483 bool writable = !WndProc(SCI_GETREADONLY, 0, 0);
484 popup.CreatePopUp();
485 AddToPopUp("Undo", idcmdUndo, writable && pdoc->CanUndo());
486 AddToPopUp("Redo", idcmdRedo, writable && pdoc->CanRedo());
487 AddToPopUp("");
488 AddToPopUp("Cut", idcmdCut, writable && !sel.Empty());
489 AddToPopUp("Copy", idcmdCopy, !sel.Empty());
490 AddToPopUp("Paste", idcmdPaste, writable && WndProc(SCI_CANPASTE, 0, 0));
491 AddToPopUp("Delete", idcmdDelete, writable && !sel.Empty());
492 AddToPopUp("");
493 AddToPopUp("Select All", idcmdSelectAll);
494 popup.Show(pt, wMain);
498 void ScintillaBase::CancelModes() {
499 AutoCompleteCancel();
500 ct.CallTipCancel();
501 Editor::CancelModes();
504 void ScintillaBase::ButtonDownWithModifiers(Point pt, unsigned int curTime, int modifiers) {
505 CancelModes();
506 Editor::ButtonDownWithModifiers(pt, curTime, modifiers);
509 void ScintillaBase::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt) {
510 ButtonDownWithModifiers(pt, curTime, ModifierFlags(shift, ctrl, alt));
513 #ifdef SCI_LEXER
515 #ifdef SCI_NAMESPACE
516 namespace Scintilla {
517 #endif
519 class LexState : public LexInterface {
520 const LexerModule *lexCurrent;
521 void SetLexerModule(const LexerModule *lex);
522 PropSetSimple props;
523 int interfaceVersion;
524 public:
525 int lexLanguage;
527 explicit LexState(Document *pdoc_);
528 virtual ~LexState();
529 void SetLexer(uptr_t wParam);
530 void SetLexerLanguage(const char *languageName);
531 const char *DescribeWordListSets();
532 void SetWordList(int n, const char *wl);
533 const char *GetName() const;
534 void *PrivateCall(int operation, void *pointer);
535 const char *PropertyNames();
536 int PropertyType(const char *name);
537 const char *DescribeProperty(const char *name);
538 void PropSet(const char *key, const char *val);
539 const char *PropGet(const char *key) const;
540 int PropGetInt(const char *key, int defaultValue=0) const;
541 int PropGetExpanded(const char *key, char *result) const;
543 int LineEndTypesSupported();
544 int AllocateSubStyles(int styleBase, int numberStyles);
545 int SubStylesStart(int styleBase);
546 int SubStylesLength(int styleBase);
547 int StyleFromSubStyle(int subStyle);
548 int PrimaryStyleFromStyle(int style);
549 void FreeSubStyles();
550 void SetIdentifiers(int style, const char *identifiers);
551 int DistanceToSecondaryStyles();
552 const char *GetSubStyleBases();
555 #ifdef SCI_NAMESPACE
557 #endif
559 LexState::LexState(Document *pdoc_) : LexInterface(pdoc_) {
560 lexCurrent = 0;
561 performingStyle = false;
562 interfaceVersion = lvOriginal;
563 lexLanguage = SCLEX_CONTAINER;
566 LexState::~LexState() {
567 if (instance) {
568 instance->Release();
569 instance = 0;
573 LexState *ScintillaBase::DocumentLexState() {
574 if (!pdoc->pli) {
575 pdoc->pli = new LexState(pdoc);
577 return static_cast<LexState *>(pdoc->pli);
580 void LexState::SetLexerModule(const LexerModule *lex) {
581 if (lex != lexCurrent) {
582 if (instance) {
583 instance->Release();
584 instance = 0;
586 interfaceVersion = lvOriginal;
587 lexCurrent = lex;
588 if (lexCurrent) {
589 instance = lexCurrent->Create();
590 interfaceVersion = instance->Version();
592 pdoc->LexerChanged();
596 void LexState::SetLexer(uptr_t wParam) {
597 lexLanguage = static_cast<int>(wParam);
598 if (lexLanguage == SCLEX_CONTAINER) {
599 SetLexerModule(0);
600 } else {
601 const LexerModule *lex = Catalogue::Find(lexLanguage);
602 if (!lex)
603 lex = Catalogue::Find(SCLEX_NULL);
604 SetLexerModule(lex);
608 void LexState::SetLexerLanguage(const char *languageName) {
609 const LexerModule *lex = Catalogue::Find(languageName);
610 if (!lex)
611 lex = Catalogue::Find(SCLEX_NULL);
612 if (lex)
613 lexLanguage = lex->GetLanguage();
614 SetLexerModule(lex);
617 const char *LexState::DescribeWordListSets() {
618 if (instance) {
619 return instance->DescribeWordListSets();
620 } else {
621 return 0;
625 void LexState::SetWordList(int n, const char *wl) {
626 if (instance) {
627 int firstModification = instance->WordListSet(n, wl);
628 if (firstModification >= 0) {
629 pdoc->ModifiedAt(firstModification);
634 const char *LexState::GetName() const {
635 return lexCurrent ? lexCurrent->languageName : "";
638 void *LexState::PrivateCall(int operation, void *pointer) {
639 if (pdoc && instance) {
640 return instance->PrivateCall(operation, pointer);
641 } else {
642 return 0;
646 const char *LexState::PropertyNames() {
647 if (instance) {
648 return instance->PropertyNames();
649 } else {
650 return 0;
654 int LexState::PropertyType(const char *name) {
655 if (instance) {
656 return instance->PropertyType(name);
657 } else {
658 return SC_TYPE_BOOLEAN;
662 const char *LexState::DescribeProperty(const char *name) {
663 if (instance) {
664 return instance->DescribeProperty(name);
665 } else {
666 return 0;
670 void LexState::PropSet(const char *key, const char *val) {
671 props.Set(key, val);
672 if (instance) {
673 int firstModification = instance->PropertySet(key, val);
674 if (firstModification >= 0) {
675 pdoc->ModifiedAt(firstModification);
680 const char *LexState::PropGet(const char *key) const {
681 return props.Get(key);
684 int LexState::PropGetInt(const char *key, int defaultValue) const {
685 return props.GetInt(key, defaultValue);
688 int LexState::PropGetExpanded(const char *key, char *result) const {
689 return props.GetExpanded(key, result);
692 int LexState::LineEndTypesSupported() {
693 if (instance && (interfaceVersion >= lvSubStyles)) {
694 return static_cast<ILexerWithSubStyles *>(instance)->LineEndTypesSupported();
696 return 0;
699 int LexState::AllocateSubStyles(int styleBase, int numberStyles) {
700 if (instance && (interfaceVersion >= lvSubStyles)) {
701 return static_cast<ILexerWithSubStyles *>(instance)->AllocateSubStyles(styleBase, numberStyles);
703 return -1;
706 int LexState::SubStylesStart(int styleBase) {
707 if (instance && (interfaceVersion >= lvSubStyles)) {
708 return static_cast<ILexerWithSubStyles *>(instance)->SubStylesStart(styleBase);
710 return -1;
713 int LexState::SubStylesLength(int styleBase) {
714 if (instance && (interfaceVersion >= lvSubStyles)) {
715 return static_cast<ILexerWithSubStyles *>(instance)->SubStylesLength(styleBase);
717 return 0;
720 int LexState::StyleFromSubStyle(int subStyle) {
721 if (instance && (interfaceVersion >= lvSubStyles)) {
722 return static_cast<ILexerWithSubStyles *>(instance)->StyleFromSubStyle(subStyle);
724 return 0;
727 int LexState::PrimaryStyleFromStyle(int style) {
728 if (instance && (interfaceVersion >= lvSubStyles)) {
729 return static_cast<ILexerWithSubStyles *>(instance)->PrimaryStyleFromStyle(style);
731 return 0;
734 void LexState::FreeSubStyles() {
735 if (instance && (interfaceVersion >= lvSubStyles)) {
736 static_cast<ILexerWithSubStyles *>(instance)->FreeSubStyles();
740 void LexState::SetIdentifiers(int style, const char *identifiers) {
741 if (instance && (interfaceVersion >= lvSubStyles)) {
742 static_cast<ILexerWithSubStyles *>(instance)->SetIdentifiers(style, identifiers);
743 pdoc->ModifiedAt(0);
747 int LexState::DistanceToSecondaryStyles() {
748 if (instance && (interfaceVersion >= lvSubStyles)) {
749 return static_cast<ILexerWithSubStyles *>(instance)->DistanceToSecondaryStyles();
751 return 0;
754 const char *LexState::GetSubStyleBases() {
755 if (instance && (interfaceVersion >= lvSubStyles)) {
756 return static_cast<ILexerWithSubStyles *>(instance)->GetSubStyleBases();
758 return "";
761 #endif
763 void ScintillaBase::NotifyStyleToNeeded(int endStyleNeeded) {
764 #ifdef SCI_LEXER
765 if (DocumentLexState()->lexLanguage != SCLEX_CONTAINER) {
766 int lineEndStyled = pdoc->LineFromPosition(pdoc->GetEndStyled());
767 int endStyled = pdoc->LineStart(lineEndStyled);
768 DocumentLexState()->Colourise(endStyled, endStyleNeeded);
769 return;
771 #endif
772 Editor::NotifyStyleToNeeded(endStyleNeeded);
775 void ScintillaBase::NotifyLexerChanged(Document *, void *) {
776 #ifdef SCI_LEXER
777 vs.EnsureStyle(0xff);
778 #endif
781 sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
782 switch (iMessage) {
783 case SCI_AUTOCSHOW:
784 listType = 0;
785 AutoCompleteStart(static_cast<int>(wParam), reinterpret_cast<const char *>(lParam));
786 break;
788 case SCI_AUTOCCANCEL:
789 ac.Cancel();
790 break;
792 case SCI_AUTOCACTIVE:
793 return ac.Active();
795 case SCI_AUTOCPOSSTART:
796 return ac.posStart;
798 case SCI_AUTOCCOMPLETE:
799 AutoCompleteCompleted(0, SC_AC_COMMAND);
800 break;
802 case SCI_AUTOCSETSEPARATOR:
803 ac.SetSeparator(static_cast<char>(wParam));
804 break;
806 case SCI_AUTOCGETSEPARATOR:
807 return ac.GetSeparator();
809 case SCI_AUTOCSTOPS:
810 ac.SetStopChars(reinterpret_cast<char *>(lParam));
811 break;
813 case SCI_AUTOCSELECT:
814 ac.Select(reinterpret_cast<char *>(lParam));
815 break;
817 case SCI_AUTOCGETCURRENT:
818 return AutoCompleteGetCurrent();
820 case SCI_AUTOCGETCURRENTTEXT:
821 return AutoCompleteGetCurrentText(reinterpret_cast<char *>(lParam));
823 case SCI_AUTOCSETCANCELATSTART:
824 ac.cancelAtStartPos = wParam != 0;
825 break;
827 case SCI_AUTOCGETCANCELATSTART:
828 return ac.cancelAtStartPos;
830 case SCI_AUTOCSETFILLUPS:
831 ac.SetFillUpChars(reinterpret_cast<char *>(lParam));
832 break;
834 case SCI_AUTOCSETCHOOSESINGLE:
835 ac.chooseSingle = wParam != 0;
836 break;
838 case SCI_AUTOCGETCHOOSESINGLE:
839 return ac.chooseSingle;
841 case SCI_AUTOCSETIGNORECASE:
842 ac.ignoreCase = wParam != 0;
843 break;
845 case SCI_AUTOCGETIGNORECASE:
846 return ac.ignoreCase;
848 case SCI_AUTOCSETCASEINSENSITIVEBEHAVIOUR:
849 ac.ignoreCaseBehaviour = static_cast<unsigned int>(wParam);
850 break;
852 case SCI_AUTOCGETCASEINSENSITIVEBEHAVIOUR:
853 return ac.ignoreCaseBehaviour;
855 case SCI_AUTOCSETMULTI:
856 multiAutoCMode = static_cast<int>(wParam);
857 break;
859 case SCI_AUTOCGETMULTI:
860 return multiAutoCMode;
862 case SCI_AUTOCSETORDER:
863 ac.autoSort = static_cast<int>(wParam);
864 break;
866 case SCI_AUTOCGETORDER:
867 return ac.autoSort;
869 case SCI_USERLISTSHOW:
870 listType = static_cast<int>(wParam);
871 AutoCompleteStart(0, reinterpret_cast<const char *>(lParam));
872 break;
874 case SCI_AUTOCSETAUTOHIDE:
875 ac.autoHide = wParam != 0;
876 break;
878 case SCI_AUTOCGETAUTOHIDE:
879 return ac.autoHide;
881 case SCI_AUTOCSETDROPRESTOFWORD:
882 ac.dropRestOfWord = wParam != 0;
883 break;
885 case SCI_AUTOCGETDROPRESTOFWORD:
886 return ac.dropRestOfWord;
888 case SCI_AUTOCSETMAXHEIGHT:
889 ac.lb->SetVisibleRows(static_cast<int>(wParam));
890 break;
892 case SCI_AUTOCGETMAXHEIGHT:
893 return ac.lb->GetVisibleRows();
895 case SCI_AUTOCSETMAXWIDTH:
896 maxListWidth = static_cast<int>(wParam);
897 break;
899 case SCI_AUTOCGETMAXWIDTH:
900 return maxListWidth;
902 case SCI_REGISTERIMAGE:
903 ac.lb->RegisterImage(static_cast<int>(wParam), reinterpret_cast<const char *>(lParam));
904 break;
906 case SCI_REGISTERRGBAIMAGE:
907 ac.lb->RegisterRGBAImage(static_cast<int>(wParam), static_cast<int>(sizeRGBAImage.x), static_cast<int>(sizeRGBAImage.y),
908 reinterpret_cast<unsigned char *>(lParam));
909 break;
911 case SCI_CLEARREGISTEREDIMAGES:
912 ac.lb->ClearRegisteredImages();
913 break;
915 case SCI_AUTOCSETTYPESEPARATOR:
916 ac.SetTypesep(static_cast<char>(wParam));
917 break;
919 case SCI_AUTOCGETTYPESEPARATOR:
920 return ac.GetTypesep();
922 case SCI_CALLTIPSHOW:
923 CallTipShow(LocationFromPosition(static_cast<int>(wParam)),
924 reinterpret_cast<const char *>(lParam));
925 break;
927 case SCI_CALLTIPCANCEL:
928 ct.CallTipCancel();
929 break;
931 case SCI_CALLTIPACTIVE:
932 return ct.inCallTipMode;
934 case SCI_CALLTIPPOSSTART:
935 return ct.posStartCallTip;
937 case SCI_CALLTIPSETPOSSTART:
938 ct.posStartCallTip = static_cast<int>(wParam);
939 break;
941 case SCI_CALLTIPSETHLT:
942 ct.SetHighlight(static_cast<int>(wParam), static_cast<int>(lParam));
943 break;
945 case SCI_CALLTIPSETBACK:
946 ct.colourBG = ColourDesired(static_cast<long>(wParam));
947 vs.styles[STYLE_CALLTIP].back = ct.colourBG;
948 InvalidateStyleRedraw();
949 break;
951 case SCI_CALLTIPSETFORE:
952 ct.colourUnSel = ColourDesired(static_cast<long>(wParam));
953 vs.styles[STYLE_CALLTIP].fore = ct.colourUnSel;
954 InvalidateStyleRedraw();
955 break;
957 case SCI_CALLTIPSETFOREHLT:
958 ct.colourSel = ColourDesired(static_cast<long>(wParam));
959 InvalidateStyleRedraw();
960 break;
962 case SCI_CALLTIPUSESTYLE:
963 ct.SetTabSize(static_cast<int>(wParam));
964 InvalidateStyleRedraw();
965 break;
967 case SCI_CALLTIPSETPOSITION:
968 ct.SetPosition(wParam != 0);
969 InvalidateStyleRedraw();
970 break;
972 case SCI_USEPOPUP:
973 displayPopupMenu = wParam != 0;
974 break;
976 #ifdef SCI_LEXER
977 case SCI_SETLEXER:
978 DocumentLexState()->SetLexer(static_cast<int>(wParam));
979 break;
981 case SCI_GETLEXER:
982 return DocumentLexState()->lexLanguage;
984 case SCI_COLOURISE:
985 if (DocumentLexState()->lexLanguage == SCLEX_CONTAINER) {
986 pdoc->ModifiedAt(static_cast<int>(wParam));
987 NotifyStyleToNeeded((lParam == -1) ? pdoc->Length() : static_cast<int>(lParam));
988 } else {
989 DocumentLexState()->Colourise(static_cast<int>(wParam), static_cast<int>(lParam));
991 Redraw();
992 break;
994 case SCI_SETPROPERTY:
995 DocumentLexState()->PropSet(reinterpret_cast<const char *>(wParam),
996 reinterpret_cast<const char *>(lParam));
997 break;
999 case SCI_GETPROPERTY:
1000 return StringResult(lParam, DocumentLexState()->PropGet(reinterpret_cast<const char *>(wParam)));
1002 case SCI_GETPROPERTYEXPANDED:
1003 return DocumentLexState()->PropGetExpanded(reinterpret_cast<const char *>(wParam),
1004 reinterpret_cast<char *>(lParam));
1006 case SCI_GETPROPERTYINT:
1007 return DocumentLexState()->PropGetInt(reinterpret_cast<const char *>(wParam), static_cast<int>(lParam));
1009 case SCI_SETKEYWORDS:
1010 DocumentLexState()->SetWordList(static_cast<int>(wParam), reinterpret_cast<const char *>(lParam));
1011 break;
1013 case SCI_SETLEXERLANGUAGE:
1014 DocumentLexState()->SetLexerLanguage(reinterpret_cast<const char *>(lParam));
1015 break;
1017 case SCI_GETLEXERLANGUAGE:
1018 return StringResult(lParam, DocumentLexState()->GetName());
1020 case SCI_PRIVATELEXERCALL:
1021 return reinterpret_cast<sptr_t>(
1022 DocumentLexState()->PrivateCall(static_cast<int>(wParam), reinterpret_cast<void *>(lParam)));
1024 case SCI_GETSTYLEBITSNEEDED:
1025 return 8;
1027 case SCI_PROPERTYNAMES:
1028 return StringResult(lParam, DocumentLexState()->PropertyNames());
1030 case SCI_PROPERTYTYPE:
1031 return DocumentLexState()->PropertyType(reinterpret_cast<const char *>(wParam));
1033 case SCI_DESCRIBEPROPERTY:
1034 return StringResult(lParam,
1035 DocumentLexState()->DescribeProperty(reinterpret_cast<const char *>(wParam)));
1037 case SCI_DESCRIBEKEYWORDSETS:
1038 return StringResult(lParam, DocumentLexState()->DescribeWordListSets());
1040 case SCI_GETLINEENDTYPESSUPPORTED:
1041 return DocumentLexState()->LineEndTypesSupported();
1043 case SCI_ALLOCATESUBSTYLES:
1044 return DocumentLexState()->AllocateSubStyles(static_cast<int>(wParam), static_cast<int>(lParam));
1046 case SCI_GETSUBSTYLESSTART:
1047 return DocumentLexState()->SubStylesStart(static_cast<int>(wParam));
1049 case SCI_GETSUBSTYLESLENGTH:
1050 return DocumentLexState()->SubStylesLength(static_cast<int>(wParam));
1052 case SCI_GETSTYLEFROMSUBSTYLE:
1053 return DocumentLexState()->StyleFromSubStyle(static_cast<int>(wParam));
1055 case SCI_GETPRIMARYSTYLEFROMSTYLE:
1056 return DocumentLexState()->PrimaryStyleFromStyle(static_cast<int>(wParam));
1058 case SCI_FREESUBSTYLES:
1059 DocumentLexState()->FreeSubStyles();
1060 break;
1062 case SCI_SETIDENTIFIERS:
1063 DocumentLexState()->SetIdentifiers(static_cast<int>(wParam),
1064 reinterpret_cast<const char *>(lParam));
1065 break;
1067 case SCI_DISTANCETOSECONDARYSTYLES:
1068 return DocumentLexState()->DistanceToSecondaryStyles();
1070 case SCI_GETSUBSTYLEBASES:
1071 return StringResult(lParam, DocumentLexState()->GetSubStyleBases());
1072 #endif
1074 default:
1075 return Editor::WndProc(iMessage, wParam, lParam);
1077 return 0l;