Fix catalan translation
[geany-mirror.git] / scintilla / src / ScintillaBase.cxx
blobb52fb9a043f6614d7b92c6bd8df5ddc4ad02dbfd
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 "SplitVector.h"
37 #include "Partitioning.h"
38 #include "RunStyles.h"
39 #include "ContractionState.h"
40 #include "CellBuffer.h"
41 #include "CallTip.h"
42 #include "KeyMap.h"
43 #include "Indicator.h"
44 #include "XPM.h"
45 #include "LineMarker.h"
46 #include "Style.h"
47 #include "ViewStyle.h"
48 #include "CharClassify.h"
49 #include "Decoration.h"
50 #include "CaseFolder.h"
51 #include "Document.h"
52 #include "Selection.h"
53 #include "PositionCache.h"
54 #include "EditModel.h"
55 #include "MarginView.h"
56 #include "EditView.h"
57 #include "Editor.h"
58 #include "AutoComplete.h"
59 #include "ScintillaBase.h"
61 #ifdef SCI_NAMESPACE
62 using namespace Scintilla;
63 #endif
65 ScintillaBase::ScintillaBase() {
66 displayPopupMenu = true;
67 listType = 0;
68 maxListWidth = 0;
69 multiAutoCMode = SC_MULTIAUTOC_ONCE;
72 ScintillaBase::~ScintillaBase() {
75 void ScintillaBase::Finalise() {
76 Editor::Finalise();
77 popup.Destroy();
80 void ScintillaBase::AddCharUTF(const char *s, unsigned int len, bool treatAsDBCS) {
81 bool isFillUp = ac.Active() && ac.IsFillUpChar(*s);
82 if (!isFillUp) {
83 Editor::AddCharUTF(s, len, treatAsDBCS);
85 if (ac.Active()) {
86 AutoCompleteCharacterAdded(s[0]);
87 // For fill ups add the character after the autocompletion has
88 // triggered so containers see the key so can display a calltip.
89 if (isFillUp) {
90 Editor::AddCharUTF(s, len, treatAsDBCS);
95 void ScintillaBase::Command(int cmdId) {
97 switch (cmdId) {
99 case idAutoComplete: // Nothing to do
101 break;
103 case idCallTip: // Nothing to do
105 break;
107 case idcmdUndo:
108 WndProc(SCI_UNDO, 0, 0);
109 break;
111 case idcmdRedo:
112 WndProc(SCI_REDO, 0, 0);
113 break;
115 case idcmdCut:
116 WndProc(SCI_CUT, 0, 0);
117 break;
119 case idcmdCopy:
120 WndProc(SCI_COPY, 0, 0);
121 break;
123 case idcmdPaste:
124 WndProc(SCI_PASTE, 0, 0);
125 break;
127 case idcmdDelete:
128 WndProc(SCI_CLEAR, 0, 0);
129 break;
131 case idcmdSelectAll:
132 WndProc(SCI_SELECTALL, 0, 0);
133 break;
137 int ScintillaBase::KeyCommand(unsigned int iMessage) {
138 // Most key commands cancel autocompletion mode
139 if (ac.Active()) {
140 switch (iMessage) {
141 // Except for these
142 case SCI_LINEDOWN:
143 AutoCompleteMove(1);
144 return 0;
145 case SCI_LINEUP:
146 AutoCompleteMove(-1);
147 return 0;
148 case SCI_PAGEDOWN:
149 AutoCompleteMove(ac.lb->GetVisibleRows());
150 return 0;
151 case SCI_PAGEUP:
152 AutoCompleteMove(-ac.lb->GetVisibleRows());
153 return 0;
154 case SCI_VCHOME:
155 AutoCompleteMove(-5000);
156 return 0;
157 case SCI_LINEEND:
158 AutoCompleteMove(5000);
159 return 0;
160 case SCI_DELETEBACK:
161 DelCharBack(true);
162 AutoCompleteCharacterDeleted();
163 EnsureCaretVisible();
164 return 0;
165 case SCI_DELETEBACKNOTLINE:
166 DelCharBack(false);
167 AutoCompleteCharacterDeleted();
168 EnsureCaretVisible();
169 return 0;
170 case SCI_TAB:
171 AutoCompleteCompleted();
172 return 0;
173 case SCI_NEWLINE:
174 AutoCompleteCompleted();
175 return 0;
177 default:
178 AutoCompleteCancel();
182 if (ct.inCallTipMode) {
183 if (
184 (iMessage != SCI_CHARLEFT) &&
185 (iMessage != SCI_CHARLEFTEXTEND) &&
186 (iMessage != SCI_CHARRIGHT) &&
187 (iMessage != SCI_CHARRIGHTEXTEND) &&
188 (iMessage != SCI_EDITTOGGLEOVERTYPE) &&
189 (iMessage != SCI_DELETEBACK) &&
190 (iMessage != SCI_DELETEBACKNOTLINE)
192 ct.CallTipCancel();
194 if ((iMessage == SCI_DELETEBACK) || (iMessage == SCI_DELETEBACKNOTLINE)) {
195 if (sel.MainCaret() <= ct.posStartCallTip) {
196 ct.CallTipCancel();
200 return Editor::KeyCommand(iMessage);
203 void ScintillaBase::AutoCompleteDoubleClick(void *p) {
204 ScintillaBase *sci = reinterpret_cast<ScintillaBase *>(p);
205 sci->AutoCompleteCompleted();
208 void ScintillaBase::AutoCompleteInsert(Position startPos, int removeLen, const char *text, int textLen) {
209 UndoGroup ug(pdoc);
210 if (multiAutoCMode == SC_MULTIAUTOC_ONCE) {
211 pdoc->DeleteChars(startPos, removeLen);
212 const int lengthInserted = pdoc->InsertString(startPos, text, textLen);
213 SetEmptySelection(startPos + lengthInserted);
214 } else {
215 // SC_MULTIAUTOC_EACH
216 for (size_t r=0; r<sel.Count(); r++) {
217 if (!RangeContainsProtected(sel.Range(r).Start().Position(),
218 sel.Range(r).End().Position())) {
219 int positionInsert = sel.Range(r).Start().Position();
220 positionInsert = InsertSpace(positionInsert, sel.Range(r).caret.VirtualSpace());
221 if (positionInsert - removeLen >= 0) {
222 positionInsert -= removeLen;
223 pdoc->DeleteChars(positionInsert, removeLen);
225 const int lengthInserted = pdoc->InsertString(positionInsert, text, textLen);
226 if (lengthInserted > 0) {
227 sel.Range(r).caret.SetPosition(positionInsert + lengthInserted);
228 sel.Range(r).anchor.SetPosition(positionInsert + lengthInserted);
230 sel.Range(r).ClearVirtualSpace();
236 void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) {
237 //Platform::DebugPrintf("AutoComplete %s\n", list);
238 ct.CallTipCancel();
240 if (ac.chooseSingle && (listType == 0)) {
241 if (list && !strchr(list, ac.GetSeparator())) {
242 const char *typeSep = strchr(list, ac.GetTypesep());
243 int lenInsert = typeSep ?
244 static_cast<int>(typeSep-list) : static_cast<int>(strlen(list));
245 if (ac.ignoreCase) {
246 // May need to convert the case before invocation, so remove lenEntered characters
247 AutoCompleteInsert(sel.MainCaret() - lenEntered, lenEntered, list, lenInsert);
248 } else {
249 AutoCompleteInsert(sel.MainCaret(), 0, list + lenEntered, lenInsert - lenEntered);
251 ac.Cancel();
252 return;
255 ac.Start(wMain, idAutoComplete, sel.MainCaret(), PointMainCaret(),
256 lenEntered, vs.lineHeight, IsUnicodeMode(), technology);
258 PRectangle rcClient = GetClientRectangle();
259 Point pt = LocationFromPosition(sel.MainCaret() - lenEntered);
260 PRectangle rcPopupBounds = wMain.GetMonitorRect(pt);
261 if (rcPopupBounds.Height() == 0)
262 rcPopupBounds = rcClient;
264 int heightLB = ac.heightLBDefault;
265 int widthLB = ac.widthLBDefault;
266 if (pt.x >= rcClient.right - widthLB) {
267 HorizontalScrollTo(static_cast<int>(xOffset + pt.x - rcClient.right + widthLB));
268 Redraw();
269 pt = PointMainCaret();
271 if (wMargin.GetID()) {
272 Point ptOrigin = GetVisibleOriginInMain();
273 pt.x += ptOrigin.x;
274 pt.y += ptOrigin.y;
276 PRectangle rcac;
277 rcac.left = pt.x - ac.lb->CaretFromEdge();
278 if (pt.y >= rcPopupBounds.bottom - heightLB && // Wont fit below.
279 pt.y >= (rcPopupBounds.bottom + rcPopupBounds.top) / 2) { // and there is more room above.
280 rcac.top = pt.y - heightLB;
281 if (rcac.top < rcPopupBounds.top) {
282 heightLB -= static_cast<int>(rcPopupBounds.top - rcac.top);
283 rcac.top = rcPopupBounds.top;
285 } else {
286 rcac.top = pt.y + vs.lineHeight;
288 rcac.right = rcac.left + widthLB;
289 rcac.bottom = static_cast<XYPOSITION>(Platform::Minimum(static_cast<int>(rcac.top) + heightLB, static_cast<int>(rcPopupBounds.bottom)));
290 ac.lb->SetPositionRelative(rcac, wMain);
291 ac.lb->SetFont(vs.styles[STYLE_DEFAULT].font);
292 unsigned int aveCharWidth = static_cast<unsigned int>(vs.styles[STYLE_DEFAULT].aveCharWidth);
293 ac.lb->SetAverageCharWidth(aveCharWidth);
294 ac.lb->SetDoubleClickAction(AutoCompleteDoubleClick, this);
296 ac.SetList(list ? list : "");
298 // Fiddle the position of the list so it is right next to the target and wide enough for all its strings
299 PRectangle rcList = ac.lb->GetDesiredRect();
300 int heightAlloced = static_cast<int>(rcList.bottom - rcList.top);
301 widthLB = Platform::Maximum(widthLB, static_cast<int>(rcList.right - rcList.left));
302 if (maxListWidth != 0)
303 widthLB = Platform::Minimum(widthLB, aveCharWidth*maxListWidth);
304 // Make an allowance for large strings in list
305 rcList.left = pt.x - ac.lb->CaretFromEdge();
306 rcList.right = rcList.left + widthLB;
307 if (((pt.y + vs.lineHeight) >= (rcPopupBounds.bottom - heightAlloced)) && // Wont fit below.
308 ((pt.y + vs.lineHeight / 2) >= (rcPopupBounds.bottom + rcPopupBounds.top) / 2)) { // and there is more room above.
309 rcList.top = pt.y - heightAlloced;
310 } else {
311 rcList.top = pt.y + vs.lineHeight;
313 rcList.bottom = rcList.top + heightAlloced;
314 ac.lb->SetPositionRelative(rcList, wMain);
315 ac.Show(true);
316 if (lenEntered != 0) {
317 AutoCompleteMoveToCurrentWord();
321 void ScintillaBase::AutoCompleteCancel() {
322 if (ac.Active()) {
323 SCNotification scn = {};
324 scn.nmhdr.code = SCN_AUTOCCANCELLED;
325 scn.wParam = 0;
326 scn.listType = 0;
327 NotifyParent(scn);
329 ac.Cancel();
332 void ScintillaBase::AutoCompleteMove(int delta) {
333 ac.Move(delta);
336 void ScintillaBase::AutoCompleteMoveToCurrentWord() {
337 std::string wordCurrent = RangeText(ac.posStart - ac.startLen, sel.MainCaret());
338 ac.Select(wordCurrent.c_str());
341 void ScintillaBase::AutoCompleteCharacterAdded(char ch) {
342 if (ac.IsFillUpChar(ch)) {
343 AutoCompleteCompleted();
344 } else if (ac.IsStopChar(ch)) {
345 AutoCompleteCancel();
346 } else {
347 AutoCompleteMoveToCurrentWord();
351 void ScintillaBase::AutoCompleteCharacterDeleted() {
352 if (sel.MainCaret() < ac.posStart - ac.startLen) {
353 AutoCompleteCancel();
354 } else if (ac.cancelAtStartPos && (sel.MainCaret() <= ac.posStart)) {
355 AutoCompleteCancel();
356 } else {
357 AutoCompleteMoveToCurrentWord();
359 SCNotification scn = {};
360 scn.nmhdr.code = SCN_AUTOCCHARDELETED;
361 scn.wParam = 0;
362 scn.listType = 0;
363 NotifyParent(scn);
366 void ScintillaBase::AutoCompleteCompleted() {
367 int item = ac.GetSelection();
368 if (item == -1) {
369 AutoCompleteCancel();
370 return;
372 const std::string selected = ac.GetValue(item);
374 ac.Show(false);
376 SCNotification scn = {};
377 scn.nmhdr.code = listType > 0 ? SCN_USERLISTSELECTION : SCN_AUTOCSELECTION;
378 scn.message = 0;
379 scn.wParam = listType;
380 scn.listType = listType;
381 Position firstPos = ac.posStart - ac.startLen;
382 scn.position = firstPos;
383 scn.lParam = firstPos;
384 scn.text = selected.c_str();
385 NotifyParent(scn);
387 if (!ac.Active())
388 return;
389 ac.Cancel();
391 if (listType > 0)
392 return;
394 Position endPos = sel.MainCaret();
395 if (ac.dropRestOfWord)
396 endPos = pdoc->ExtendWordSelect(endPos, 1, true);
397 if (endPos < firstPos)
398 return;
399 AutoCompleteInsert(firstPos, endPos - firstPos, selected.c_str(), static_cast<int>(selected.length()));
400 SetLastXChosen();
403 int ScintillaBase::AutoCompleteGetCurrent() const {
404 if (!ac.Active())
405 return -1;
406 return ac.GetSelection();
409 int ScintillaBase::AutoCompleteGetCurrentText(char *buffer) const {
410 if (ac.Active()) {
411 int item = ac.GetSelection();
412 if (item != -1) {
413 const std::string selected = ac.GetValue(item);
414 if (buffer != NULL)
415 memcpy(buffer, selected.c_str(), selected.length()+1);
416 return static_cast<int>(selected.length());
419 if (buffer != NULL)
420 *buffer = '\0';
421 return 0;
424 void ScintillaBase::CallTipShow(Point pt, const char *defn) {
425 ac.Cancel();
426 // If container knows about STYLE_CALLTIP then use it in place of the
427 // STYLE_DEFAULT for the face name, size and character set. Also use it
428 // for the foreground and background colour.
429 int ctStyle = ct.UseStyleCallTip() ? STYLE_CALLTIP : STYLE_DEFAULT;
430 if (ct.UseStyleCallTip()) {
431 ct.SetForeBack(vs.styles[STYLE_CALLTIP].fore, vs.styles[STYLE_CALLTIP].back);
433 if (wMargin.GetID()) {
434 Point ptOrigin = GetVisibleOriginInMain();
435 pt.x += ptOrigin.x;
436 pt.y += ptOrigin.y;
438 PRectangle rc = ct.CallTipStart(sel.MainCaret(), pt,
439 vs.lineHeight,
440 defn,
441 vs.styles[ctStyle].fontName,
442 vs.styles[ctStyle].sizeZoomed,
443 CodePage(),
444 vs.styles[ctStyle].characterSet,
445 vs.technology,
446 wMain);
447 // If the call-tip window would be out of the client
448 // space
449 PRectangle rcClient = GetClientRectangle();
450 int offset = vs.lineHeight + static_cast<int>(rc.Height());
451 // adjust so it displays above the text.
452 if (rc.bottom > rcClient.bottom && rc.Height() < rcClient.Height()) {
453 rc.top -= offset;
454 rc.bottom -= offset;
456 // adjust so it displays below the text.
457 if (rc.top < rcClient.top && rc.Height() < rcClient.Height()) {
458 rc.top += offset;
459 rc.bottom += offset;
461 // Now display the window.
462 CreateCallTipWindow(rc);
463 ct.wCallTip.SetPositionRelative(rc, wMain);
464 ct.wCallTip.Show();
467 void ScintillaBase::CallTipClick() {
468 SCNotification scn = {};
469 scn.nmhdr.code = SCN_CALLTIPCLICK;
470 scn.position = ct.clickPlace;
471 NotifyParent(scn);
474 void ScintillaBase::ContextMenu(Point pt) {
475 if (displayPopupMenu) {
476 bool writable = !WndProc(SCI_GETREADONLY, 0, 0);
477 popup.CreatePopUp();
478 AddToPopUp("Undo", idcmdUndo, writable && pdoc->CanUndo());
479 AddToPopUp("Redo", idcmdRedo, writable && pdoc->CanRedo());
480 AddToPopUp("");
481 AddToPopUp("Cut", idcmdCut, writable && !sel.Empty());
482 AddToPopUp("Copy", idcmdCopy, !sel.Empty());
483 AddToPopUp("Paste", idcmdPaste, writable && WndProc(SCI_CANPASTE, 0, 0));
484 AddToPopUp("Delete", idcmdDelete, writable && !sel.Empty());
485 AddToPopUp("");
486 AddToPopUp("Select All", idcmdSelectAll);
487 popup.Show(pt, wMain);
491 void ScintillaBase::CancelModes() {
492 AutoCompleteCancel();
493 ct.CallTipCancel();
494 Editor::CancelModes();
497 void ScintillaBase::ButtonDownWithModifiers(Point pt, unsigned int curTime, int modifiers) {
498 CancelModes();
499 Editor::ButtonDownWithModifiers(pt, curTime, modifiers);
502 void ScintillaBase::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt) {
503 ButtonDownWithModifiers(pt, curTime, ModifierFlags(shift, ctrl, alt));
506 #ifdef SCI_LEXER
508 #ifdef SCI_NAMESPACE
509 namespace Scintilla {
510 #endif
512 class LexState : public LexInterface {
513 const LexerModule *lexCurrent;
514 void SetLexerModule(const LexerModule *lex);
515 PropSetSimple props;
516 int interfaceVersion;
517 public:
518 int lexLanguage;
520 explicit LexState(Document *pdoc_);
521 virtual ~LexState();
522 void SetLexer(uptr_t wParam);
523 void SetLexerLanguage(const char *languageName);
524 const char *DescribeWordListSets();
525 void SetWordList(int n, const char *wl);
526 const char *GetName() const;
527 void *PrivateCall(int operation, void *pointer);
528 const char *PropertyNames();
529 int PropertyType(const char *name);
530 const char *DescribeProperty(const char *name);
531 void PropSet(const char *key, const char *val);
532 const char *PropGet(const char *key) const;
533 int PropGetInt(const char *key, int defaultValue=0) const;
534 int PropGetExpanded(const char *key, char *result) const;
536 int LineEndTypesSupported();
537 int AllocateSubStyles(int styleBase, int numberStyles);
538 int SubStylesStart(int styleBase);
539 int SubStylesLength(int styleBase);
540 int StyleFromSubStyle(int subStyle);
541 int PrimaryStyleFromStyle(int style);
542 void FreeSubStyles();
543 void SetIdentifiers(int style, const char *identifiers);
544 int DistanceToSecondaryStyles();
545 const char *GetSubStyleBases();
548 #ifdef SCI_NAMESPACE
550 #endif
552 LexState::LexState(Document *pdoc_) : LexInterface(pdoc_) {
553 lexCurrent = 0;
554 performingStyle = false;
555 interfaceVersion = lvOriginal;
556 lexLanguage = SCLEX_CONTAINER;
559 LexState::~LexState() {
560 if (instance) {
561 instance->Release();
562 instance = 0;
566 LexState *ScintillaBase::DocumentLexState() {
567 if (!pdoc->pli) {
568 pdoc->pli = new LexState(pdoc);
570 return static_cast<LexState *>(pdoc->pli);
573 void LexState::SetLexerModule(const LexerModule *lex) {
574 if (lex != lexCurrent) {
575 if (instance) {
576 instance->Release();
577 instance = 0;
579 interfaceVersion = lvOriginal;
580 lexCurrent = lex;
581 if (lexCurrent) {
582 instance = lexCurrent->Create();
583 interfaceVersion = instance->Version();
585 pdoc->LexerChanged();
589 void LexState::SetLexer(uptr_t wParam) {
590 lexLanguage = static_cast<int>(wParam);
591 if (lexLanguage == SCLEX_CONTAINER) {
592 SetLexerModule(0);
593 } else {
594 const LexerModule *lex = Catalogue::Find(lexLanguage);
595 if (!lex)
596 lex = Catalogue::Find(SCLEX_NULL);
597 SetLexerModule(lex);
601 void LexState::SetLexerLanguage(const char *languageName) {
602 const LexerModule *lex = Catalogue::Find(languageName);
603 if (!lex)
604 lex = Catalogue::Find(SCLEX_NULL);
605 if (lex)
606 lexLanguage = lex->GetLanguage();
607 SetLexerModule(lex);
610 const char *LexState::DescribeWordListSets() {
611 if (instance) {
612 return instance->DescribeWordListSets();
613 } else {
614 return 0;
618 void LexState::SetWordList(int n, const char *wl) {
619 if (instance) {
620 int firstModification = instance->WordListSet(n, wl);
621 if (firstModification >= 0) {
622 pdoc->ModifiedAt(firstModification);
627 const char *LexState::GetName() const {
628 return lexCurrent ? lexCurrent->languageName : "";
631 void *LexState::PrivateCall(int operation, void *pointer) {
632 if (pdoc && instance) {
633 return instance->PrivateCall(operation, pointer);
634 } else {
635 return 0;
639 const char *LexState::PropertyNames() {
640 if (instance) {
641 return instance->PropertyNames();
642 } else {
643 return 0;
647 int LexState::PropertyType(const char *name) {
648 if (instance) {
649 return instance->PropertyType(name);
650 } else {
651 return SC_TYPE_BOOLEAN;
655 const char *LexState::DescribeProperty(const char *name) {
656 if (instance) {
657 return instance->DescribeProperty(name);
658 } else {
659 return 0;
663 void LexState::PropSet(const char *key, const char *val) {
664 props.Set(key, val);
665 if (instance) {
666 int firstModification = instance->PropertySet(key, val);
667 if (firstModification >= 0) {
668 pdoc->ModifiedAt(firstModification);
673 const char *LexState::PropGet(const char *key) const {
674 return props.Get(key);
677 int LexState::PropGetInt(const char *key, int defaultValue) const {
678 return props.GetInt(key, defaultValue);
681 int LexState::PropGetExpanded(const char *key, char *result) const {
682 return props.GetExpanded(key, result);
685 int LexState::LineEndTypesSupported() {
686 if (instance && (interfaceVersion >= lvSubStyles)) {
687 return static_cast<ILexerWithSubStyles *>(instance)->LineEndTypesSupported();
689 return 0;
692 int LexState::AllocateSubStyles(int styleBase, int numberStyles) {
693 if (instance && (interfaceVersion >= lvSubStyles)) {
694 return static_cast<ILexerWithSubStyles *>(instance)->AllocateSubStyles(styleBase, numberStyles);
696 return -1;
699 int LexState::SubStylesStart(int styleBase) {
700 if (instance && (interfaceVersion >= lvSubStyles)) {
701 return static_cast<ILexerWithSubStyles *>(instance)->SubStylesStart(styleBase);
703 return -1;
706 int LexState::SubStylesLength(int styleBase) {
707 if (instance && (interfaceVersion >= lvSubStyles)) {
708 return static_cast<ILexerWithSubStyles *>(instance)->SubStylesLength(styleBase);
710 return 0;
713 int LexState::StyleFromSubStyle(int subStyle) {
714 if (instance && (interfaceVersion >= lvSubStyles)) {
715 return static_cast<ILexerWithSubStyles *>(instance)->StyleFromSubStyle(subStyle);
717 return 0;
720 int LexState::PrimaryStyleFromStyle(int style) {
721 if (instance && (interfaceVersion >= lvSubStyles)) {
722 return static_cast<ILexerWithSubStyles *>(instance)->PrimaryStyleFromStyle(style);
724 return 0;
727 void LexState::FreeSubStyles() {
728 if (instance && (interfaceVersion >= lvSubStyles)) {
729 static_cast<ILexerWithSubStyles *>(instance)->FreeSubStyles();
733 void LexState::SetIdentifiers(int style, const char *identifiers) {
734 if (instance && (interfaceVersion >= lvSubStyles)) {
735 static_cast<ILexerWithSubStyles *>(instance)->SetIdentifiers(style, identifiers);
739 int LexState::DistanceToSecondaryStyles() {
740 if (instance && (interfaceVersion >= lvSubStyles)) {
741 return static_cast<ILexerWithSubStyles *>(instance)->DistanceToSecondaryStyles();
743 return 0;
746 const char *LexState::GetSubStyleBases() {
747 if (instance && (interfaceVersion >= lvSubStyles)) {
748 return static_cast<ILexerWithSubStyles *>(instance)->GetSubStyleBases();
750 return "";
753 #endif
755 void ScintillaBase::NotifyStyleToNeeded(int endStyleNeeded) {
756 #ifdef SCI_LEXER
757 if (DocumentLexState()->lexLanguage != SCLEX_CONTAINER) {
758 int lineEndStyled = pdoc->LineFromPosition(pdoc->GetEndStyled());
759 int endStyled = pdoc->LineStart(lineEndStyled);
760 DocumentLexState()->Colourise(endStyled, endStyleNeeded);
761 return;
763 #endif
764 Editor::NotifyStyleToNeeded(endStyleNeeded);
767 void ScintillaBase::NotifyLexerChanged(Document *, void *) {
768 #ifdef SCI_LEXER
769 vs.EnsureStyle(0xff);
770 #endif
773 sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
774 switch (iMessage) {
775 case SCI_AUTOCSHOW:
776 listType = 0;
777 AutoCompleteStart(static_cast<int>(wParam), reinterpret_cast<const char *>(lParam));
778 break;
780 case SCI_AUTOCCANCEL:
781 ac.Cancel();
782 break;
784 case SCI_AUTOCACTIVE:
785 return ac.Active();
787 case SCI_AUTOCPOSSTART:
788 return ac.posStart;
790 case SCI_AUTOCCOMPLETE:
791 AutoCompleteCompleted();
792 break;
794 case SCI_AUTOCSETSEPARATOR:
795 ac.SetSeparator(static_cast<char>(wParam));
796 break;
798 case SCI_AUTOCGETSEPARATOR:
799 return ac.GetSeparator();
801 case SCI_AUTOCSTOPS:
802 ac.SetStopChars(reinterpret_cast<char *>(lParam));
803 break;
805 case SCI_AUTOCSELECT:
806 ac.Select(reinterpret_cast<char *>(lParam));
807 break;
809 case SCI_AUTOCGETCURRENT:
810 return AutoCompleteGetCurrent();
812 case SCI_AUTOCGETCURRENTTEXT:
813 return AutoCompleteGetCurrentText(reinterpret_cast<char *>(lParam));
815 case SCI_AUTOCSETCANCELATSTART:
816 ac.cancelAtStartPos = wParam != 0;
817 break;
819 case SCI_AUTOCGETCANCELATSTART:
820 return ac.cancelAtStartPos;
822 case SCI_AUTOCSETFILLUPS:
823 ac.SetFillUpChars(reinterpret_cast<char *>(lParam));
824 break;
826 case SCI_AUTOCSETCHOOSESINGLE:
827 ac.chooseSingle = wParam != 0;
828 break;
830 case SCI_AUTOCGETCHOOSESINGLE:
831 return ac.chooseSingle;
833 case SCI_AUTOCSETIGNORECASE:
834 ac.ignoreCase = wParam != 0;
835 break;
837 case SCI_AUTOCGETIGNORECASE:
838 return ac.ignoreCase;
840 case SCI_AUTOCSETCASEINSENSITIVEBEHAVIOUR:
841 ac.ignoreCaseBehaviour = static_cast<unsigned int>(wParam);
842 break;
844 case SCI_AUTOCGETCASEINSENSITIVEBEHAVIOUR:
845 return ac.ignoreCaseBehaviour;
847 case SCI_AUTOCSETMULTI:
848 multiAutoCMode = static_cast<int>(wParam);
849 break;
851 case SCI_AUTOCGETMULTI:
852 return multiAutoCMode;
854 case SCI_AUTOCSETORDER:
855 ac.autoSort = static_cast<int>(wParam);
856 break;
858 case SCI_AUTOCGETORDER:
859 return ac.autoSort;
861 case SCI_USERLISTSHOW:
862 listType = static_cast<int>(wParam);
863 AutoCompleteStart(0, reinterpret_cast<const char *>(lParam));
864 break;
866 case SCI_AUTOCSETAUTOHIDE:
867 ac.autoHide = wParam != 0;
868 break;
870 case SCI_AUTOCGETAUTOHIDE:
871 return ac.autoHide;
873 case SCI_AUTOCSETDROPRESTOFWORD:
874 ac.dropRestOfWord = wParam != 0;
875 break;
877 case SCI_AUTOCGETDROPRESTOFWORD:
878 return ac.dropRestOfWord;
880 case SCI_AUTOCSETMAXHEIGHT:
881 ac.lb->SetVisibleRows(static_cast<int>(wParam));
882 break;
884 case SCI_AUTOCGETMAXHEIGHT:
885 return ac.lb->GetVisibleRows();
887 case SCI_AUTOCSETMAXWIDTH:
888 maxListWidth = static_cast<int>(wParam);
889 break;
891 case SCI_AUTOCGETMAXWIDTH:
892 return maxListWidth;
894 case SCI_REGISTERIMAGE:
895 ac.lb->RegisterImage(static_cast<int>(wParam), reinterpret_cast<const char *>(lParam));
896 break;
898 case SCI_REGISTERRGBAIMAGE:
899 ac.lb->RegisterRGBAImage(static_cast<int>(wParam), static_cast<int>(sizeRGBAImage.x), static_cast<int>(sizeRGBAImage.y),
900 reinterpret_cast<unsigned char *>(lParam));
901 break;
903 case SCI_CLEARREGISTEREDIMAGES:
904 ac.lb->ClearRegisteredImages();
905 break;
907 case SCI_AUTOCSETTYPESEPARATOR:
908 ac.SetTypesep(static_cast<char>(wParam));
909 break;
911 case SCI_AUTOCGETTYPESEPARATOR:
912 return ac.GetTypesep();
914 case SCI_CALLTIPSHOW:
915 CallTipShow(LocationFromPosition(static_cast<int>(wParam)),
916 reinterpret_cast<const char *>(lParam));
917 break;
919 case SCI_CALLTIPCANCEL:
920 ct.CallTipCancel();
921 break;
923 case SCI_CALLTIPACTIVE:
924 return ct.inCallTipMode;
926 case SCI_CALLTIPPOSSTART:
927 return ct.posStartCallTip;
929 case SCI_CALLTIPSETPOSSTART:
930 ct.posStartCallTip = static_cast<int>(wParam);
931 break;
933 case SCI_CALLTIPSETHLT:
934 ct.SetHighlight(static_cast<int>(wParam), static_cast<int>(lParam));
935 break;
937 case SCI_CALLTIPSETBACK:
938 ct.colourBG = ColourDesired(static_cast<long>(wParam));
939 vs.styles[STYLE_CALLTIP].back = ct.colourBG;
940 InvalidateStyleRedraw();
941 break;
943 case SCI_CALLTIPSETFORE:
944 ct.colourUnSel = ColourDesired(static_cast<long>(wParam));
945 vs.styles[STYLE_CALLTIP].fore = ct.colourUnSel;
946 InvalidateStyleRedraw();
947 break;
949 case SCI_CALLTIPSETFOREHLT:
950 ct.colourSel = ColourDesired(static_cast<long>(wParam));
951 InvalidateStyleRedraw();
952 break;
954 case SCI_CALLTIPUSESTYLE:
955 ct.SetTabSize(static_cast<int>(wParam));
956 InvalidateStyleRedraw();
957 break;
959 case SCI_CALLTIPSETPOSITION:
960 ct.SetPosition(wParam != 0);
961 InvalidateStyleRedraw();
962 break;
964 case SCI_USEPOPUP:
965 displayPopupMenu = wParam != 0;
966 break;
968 #ifdef SCI_LEXER
969 case SCI_SETLEXER:
970 DocumentLexState()->SetLexer(static_cast<int>(wParam));
971 break;
973 case SCI_GETLEXER:
974 return DocumentLexState()->lexLanguage;
976 case SCI_COLOURISE:
977 if (DocumentLexState()->lexLanguage == SCLEX_CONTAINER) {
978 pdoc->ModifiedAt(static_cast<int>(wParam));
979 NotifyStyleToNeeded((lParam == -1) ? pdoc->Length() : static_cast<int>(lParam));
980 } else {
981 DocumentLexState()->Colourise(static_cast<int>(wParam), static_cast<int>(lParam));
983 Redraw();
984 break;
986 case SCI_SETPROPERTY:
987 DocumentLexState()->PropSet(reinterpret_cast<const char *>(wParam),
988 reinterpret_cast<const char *>(lParam));
989 break;
991 case SCI_GETPROPERTY:
992 return StringResult(lParam, DocumentLexState()->PropGet(reinterpret_cast<const char *>(wParam)));
994 case SCI_GETPROPERTYEXPANDED:
995 return DocumentLexState()->PropGetExpanded(reinterpret_cast<const char *>(wParam),
996 reinterpret_cast<char *>(lParam));
998 case SCI_GETPROPERTYINT:
999 return DocumentLexState()->PropGetInt(reinterpret_cast<const char *>(wParam), static_cast<int>(lParam));
1001 case SCI_SETKEYWORDS:
1002 DocumentLexState()->SetWordList(static_cast<int>(wParam), reinterpret_cast<const char *>(lParam));
1003 break;
1005 case SCI_SETLEXERLANGUAGE:
1006 DocumentLexState()->SetLexerLanguage(reinterpret_cast<const char *>(lParam));
1007 break;
1009 case SCI_GETLEXERLANGUAGE:
1010 return StringResult(lParam, DocumentLexState()->GetName());
1012 case SCI_PRIVATELEXERCALL:
1013 return reinterpret_cast<sptr_t>(
1014 DocumentLexState()->PrivateCall(static_cast<int>(wParam), reinterpret_cast<void *>(lParam)));
1016 case SCI_GETSTYLEBITSNEEDED:
1017 return 8;
1019 case SCI_PROPERTYNAMES:
1020 return StringResult(lParam, DocumentLexState()->PropertyNames());
1022 case SCI_PROPERTYTYPE:
1023 return DocumentLexState()->PropertyType(reinterpret_cast<const char *>(wParam));
1025 case SCI_DESCRIBEPROPERTY:
1026 return StringResult(lParam,
1027 DocumentLexState()->DescribeProperty(reinterpret_cast<const char *>(wParam)));
1029 case SCI_DESCRIBEKEYWORDSETS:
1030 return StringResult(lParam, DocumentLexState()->DescribeWordListSets());
1032 case SCI_GETLINEENDTYPESSUPPORTED:
1033 return DocumentLexState()->LineEndTypesSupported();
1035 case SCI_ALLOCATESUBSTYLES:
1036 return DocumentLexState()->AllocateSubStyles(static_cast<int>(wParam), static_cast<int>(lParam));
1038 case SCI_GETSUBSTYLESSTART:
1039 return DocumentLexState()->SubStylesStart(static_cast<int>(wParam));
1041 case SCI_GETSUBSTYLESLENGTH:
1042 return DocumentLexState()->SubStylesLength(static_cast<int>(wParam));
1044 case SCI_GETSTYLEFROMSUBSTYLE:
1045 return DocumentLexState()->StyleFromSubStyle(static_cast<int>(wParam));
1047 case SCI_GETPRIMARYSTYLEFROMSTYLE:
1048 return DocumentLexState()->PrimaryStyleFromStyle(static_cast<int>(wParam));
1050 case SCI_FREESUBSTYLES:
1051 DocumentLexState()->FreeSubStyles();
1052 break;
1054 case SCI_SETIDENTIFIERS:
1055 DocumentLexState()->SetIdentifiers(static_cast<int>(wParam),
1056 reinterpret_cast<const char *>(lParam));
1057 break;
1059 case SCI_DISTANCETOSECONDARYSTYLES:
1060 return DocumentLexState()->DistanceToSecondaryStyles();
1062 case SCI_GETSUBSTYLEBASES:
1063 return StringResult(lParam, DocumentLexState()->GetSubStyleBases());
1064 #endif
1066 default:
1067 return Editor::WndProc(iMessage, wParam, lParam);
1069 return 0l;