You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
727 lines
18 KiB
727 lines
18 KiB
// Scintilla source code edit control |
|
/** @file ScintillaBase.cxx |
|
** An enhanced subclass of Editor with calltips, autocomplete and context menu. |
|
**/ |
|
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org> |
|
// The License.txt file describes the conditions under which this software may be distributed. |
|
|
|
#include <stdlib.h> |
|
#include <string.h> |
|
#include <stdio.h> |
|
#include <ctype.h> |
|
|
|
#include "Platform.h" |
|
|
|
#include "Scintilla.h" |
|
#include "PropSet.h" |
|
#ifdef SCI_LEXER |
|
#include "SciLexer.h" |
|
#include "Accessor.h" |
|
#include "DocumentAccessor.h" |
|
#include "KeyWords.h" |
|
#endif |
|
#include "ContractionState.h" |
|
#include "SVector.h" |
|
#include "CellBuffer.h" |
|
#include "CallTip.h" |
|
#include "KeyMap.h" |
|
#include "Indicator.h" |
|
#include "XPM.h" |
|
#include "LineMarker.h" |
|
#include "Style.h" |
|
#include "ViewStyle.h" |
|
#include "AutoComplete.h" |
|
#include "CharClassify.h" |
|
#include "Document.h" |
|
#include "Editor.h" |
|
#include "ScintillaBase.h" |
|
|
|
ScintillaBase::ScintillaBase() { |
|
displayPopupMenu = true; |
|
listType = 0; |
|
maxListWidth = 0; |
|
#ifdef SCI_LEXER |
|
lexLanguage = SCLEX_CONTAINER; |
|
performingStyle = false; |
|
lexCurrent = 0; |
|
for (int wl = 0;wl < numWordLists;wl++) |
|
keyWordLists[wl] = new WordList; |
|
keyWordLists[numWordLists] = 0; |
|
#endif |
|
} |
|
|
|
ScintillaBase::~ScintillaBase() { |
|
#ifdef SCI_LEXER |
|
for (int wl = 0;wl < numWordLists;wl++) |
|
delete keyWordLists[wl]; |
|
#endif |
|
} |
|
|
|
void ScintillaBase::Finalise() { |
|
Editor::Finalise(); |
|
popup.Destroy(); |
|
} |
|
|
|
void ScintillaBase::RefreshColourPalette(Palette &pal, bool want) { |
|
Editor::RefreshColourPalette(pal, want); |
|
ct.RefreshColourPalette(pal, want); |
|
} |
|
|
|
void ScintillaBase::AddCharUTF(char *s, unsigned int len, bool treatAsDBCS) { |
|
bool isFillUp = ac.Active() && ac.IsFillUpChar(*s); |
|
if (!isFillUp) { |
|
Editor::AddCharUTF(s, len, treatAsDBCS); |
|
} |
|
if (ac.Active()) { |
|
AutoCompleteCharacterAdded(s[0]); |
|
// For fill ups add the character after the autocompletion has |
|
// triggered so containers see the key so can display a calltip. |
|
if (isFillUp) { |
|
Editor::AddCharUTF(s, len, treatAsDBCS); |
|
} |
|
} |
|
} |
|
|
|
void ScintillaBase::Command(int cmdId) { |
|
|
|
switch (cmdId) { |
|
|
|
case idAutoComplete: // Nothing to do |
|
|
|
break; |
|
|
|
case idCallTip: // Nothing to do |
|
|
|
break; |
|
|
|
case idcmdUndo: |
|
WndProc(SCI_UNDO, 0, 0); |
|
break; |
|
|
|
case idcmdRedo: |
|
WndProc(SCI_REDO, 0, 0); |
|
break; |
|
|
|
case idcmdCut: |
|
WndProc(SCI_CUT, 0, 0); |
|
break; |
|
|
|
case idcmdCopy: |
|
WndProc(SCI_COPY, 0, 0); |
|
break; |
|
|
|
case idcmdPaste: |
|
WndProc(SCI_PASTE, 0, 0); |
|
break; |
|
|
|
case idcmdDelete: |
|
WndProc(SCI_CLEAR, 0, 0); |
|
break; |
|
|
|
case idcmdSelectAll: |
|
WndProc(SCI_SELECTALL, 0, 0); |
|
break; |
|
} |
|
} |
|
|
|
int ScintillaBase::KeyCommand(unsigned int iMessage) { |
|
// Most key commands cancel autocompletion mode |
|
if (ac.Active()) { |
|
switch (iMessage) { |
|
// Except for these |
|
case SCI_LINEDOWN: |
|
AutoCompleteMove(1); |
|
return 0; |
|
case SCI_LINEUP: |
|
AutoCompleteMove( -1); |
|
return 0; |
|
case SCI_PAGEDOWN: |
|
AutoCompleteMove(5); |
|
return 0; |
|
case SCI_PAGEUP: |
|
AutoCompleteMove( -5); |
|
return 0; |
|
case SCI_VCHOME: |
|
AutoCompleteMove( -5000); |
|
return 0; |
|
case SCI_LINEEND: |
|
AutoCompleteMove(5000); |
|
return 0; |
|
case SCI_DELETEBACK: |
|
DelCharBack(true); |
|
AutoCompleteCharacterDeleted(); |
|
EnsureCaretVisible(); |
|
return 0; |
|
case SCI_DELETEBACKNOTLINE: |
|
DelCharBack(false); |
|
AutoCompleteCharacterDeleted(); |
|
EnsureCaretVisible(); |
|
return 0; |
|
case SCI_TAB: |
|
AutoCompleteCompleted(); |
|
return 0; |
|
case SCI_NEWLINE: |
|
AutoCompleteCompleted(); |
|
return 0; |
|
|
|
default: |
|
ac.Cancel(); |
|
} |
|
} |
|
|
|
if (ct.inCallTipMode) { |
|
if ( |
|
(iMessage != SCI_CHARLEFT) && |
|
(iMessage != SCI_CHARLEFTEXTEND) && |
|
(iMessage != SCI_CHARRIGHT) && |
|
(iMessage != SCI_CHARLEFTEXTEND) && |
|
(iMessage != SCI_EDITTOGGLEOVERTYPE) && |
|
(iMessage != SCI_DELETEBACK) && |
|
(iMessage != SCI_DELETEBACKNOTLINE) |
|
) { |
|
ct.CallTipCancel(); |
|
} |
|
if ((iMessage == SCI_DELETEBACK) || (iMessage == SCI_DELETEBACKNOTLINE)) { |
|
if (currentPos <= ct.posStartCallTip) { |
|
ct.CallTipCancel(); |
|
} |
|
} |
|
} |
|
return Editor::KeyCommand(iMessage); |
|
} |
|
|
|
void ScintillaBase::AutoCompleteDoubleClick(void* p) { |
|
ScintillaBase* sci = reinterpret_cast<ScintillaBase*>(p); |
|
sci->AutoCompleteCompleted(); |
|
} |
|
|
|
void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) { |
|
//Platform::DebugPrintf("AutoComplete %s\n", list); |
|
ct.CallTipCancel(); |
|
|
|
if (ac.chooseSingle && (listType == 0)) { |
|
if (list && !strchr(list, ac.GetSeparator())) { |
|
const char *typeSep = strchr(list, ac.GetTypesep()); |
|
size_t lenInsert = (typeSep) ? (typeSep-list) : strlen(list); |
|
if (ac.ignoreCase) { |
|
SetEmptySelection(currentPos - lenEntered); |
|
pdoc->DeleteChars(currentPos, lenEntered); |
|
SetEmptySelection(currentPos); |
|
pdoc->InsertString(currentPos, list, lenInsert); |
|
SetEmptySelection(currentPos + lenInsert); |
|
} else { |
|
SetEmptySelection(currentPos); |
|
pdoc->InsertString(currentPos, list + lenEntered, lenInsert - lenEntered); |
|
SetEmptySelection(currentPos + lenInsert - lenEntered); |
|
} |
|
return; |
|
} |
|
} |
|
ac.Start(wMain, idAutoComplete, currentPos, LocationFromPosition(currentPos), |
|
lenEntered, vs.lineHeight, IsUnicodeMode()); |
|
|
|
PRectangle rcClient = GetClientRectangle(); |
|
Point pt = LocationFromPosition(currentPos - lenEntered); |
|
|
|
int heightLB = 100; |
|
int widthLB = 100; |
|
if (pt.x >= rcClient.right - widthLB) { |
|
HorizontalScrollTo(xOffset + pt.x - rcClient.right + widthLB); |
|
Redraw(); |
|
pt = LocationFromPosition(currentPos); |
|
} |
|
PRectangle rcac; |
|
rcac.left = pt.x - ac.lb->CaretFromEdge(); |
|
if (pt.y >= rcClient.bottom - heightLB && // Wont fit below. |
|
pt.y >= (rcClient.bottom + rcClient.top) / 2) { // and there is more room above. |
|
rcac.top = pt.y - heightLB; |
|
if (rcac.top < 0) { |
|
heightLB += rcac.top; |
|
rcac.top = 0; |
|
} |
|
} else { |
|
rcac.top = pt.y + vs.lineHeight; |
|
} |
|
rcac.right = rcac.left + widthLB; |
|
rcac.bottom = Platform::Minimum(rcac.top + heightLB, rcClient.bottom); |
|
ac.lb->SetPositionRelative(rcac, wMain); |
|
ac.lb->SetFont(vs.styles[STYLE_DEFAULT].font); |
|
unsigned int aveCharWidth = vs.styles[STYLE_DEFAULT].aveCharWidth; |
|
ac.lb->SetAverageCharWidth(aveCharWidth); |
|
ac.lb->SetDoubleClickAction(AutoCompleteDoubleClick, this); |
|
|
|
ac.SetList(list); |
|
|
|
// Fiddle the position of the list so it is right next to the target and wide enough for all its strings |
|
PRectangle rcList = ac.lb->GetDesiredRect(); |
|
int heightAlloced = rcList.bottom - rcList.top; |
|
widthLB = Platform::Maximum(widthLB, rcList.right - rcList.left); |
|
if (maxListWidth != 0) |
|
widthLB = Platform::Minimum(widthLB, aveCharWidth*maxListWidth); |
|
// Make an allowance for large strings in list |
|
rcList.left = pt.x - ac.lb->CaretFromEdge(); |
|
rcList.right = rcList.left + widthLB; |
|
if (((pt.y + vs.lineHeight) >= (rcClient.bottom - heightAlloced)) && // Wont fit below. |
|
((pt.y + vs.lineHeight / 2) >= (rcClient.bottom + rcClient.top) / 2)) { // and there is more room above. |
|
rcList.top = pt.y - heightAlloced; |
|
} else { |
|
rcList.top = pt.y + vs.lineHeight; |
|
} |
|
rcList.bottom = rcList.top + heightAlloced; |
|
ac.lb->SetPositionRelative(rcList, wMain); |
|
ac.Show(true); |
|
if (lenEntered != 0) { |
|
AutoCompleteMoveToCurrentWord(); |
|
} |
|
} |
|
|
|
void ScintillaBase::AutoCompleteCancel() { |
|
ac.Cancel(); |
|
} |
|
|
|
void ScintillaBase::AutoCompleteMove(int delta) { |
|
ac.Move(delta); |
|
} |
|
|
|
void ScintillaBase::AutoCompleteMoveToCurrentWord() { |
|
char wordCurrent[1000]; |
|
int i; |
|
int startWord = ac.posStart - ac.startLen; |
|
for (i = startWord; i < currentPos && i - startWord < 1000; i++) |
|
wordCurrent[i - startWord] = pdoc->CharAt(i); |
|
wordCurrent[Platform::Minimum(i - startWord, 999)] = '\0'; |
|
ac.Select(wordCurrent); |
|
} |
|
|
|
void ScintillaBase::AutoCompleteCharacterAdded(char ch) { |
|
if (ac.IsFillUpChar(ch)) { |
|
AutoCompleteCompleted(); |
|
} else if (ac.IsStopChar(ch)) { |
|
ac.Cancel(); |
|
} else { |
|
AutoCompleteMoveToCurrentWord(); |
|
} |
|
} |
|
|
|
void ScintillaBase::AutoCompleteCharacterDeleted() { |
|
if (currentPos < ac.posStart - ac.startLen) { |
|
ac.Cancel(); |
|
} else if (ac.cancelAtStartPos && (currentPos <= ac.posStart)) { |
|
ac.Cancel(); |
|
} else { |
|
AutoCompleteMoveToCurrentWord(); |
|
} |
|
} |
|
|
|
void ScintillaBase::AutoCompleteCompleted() { |
|
int item = ac.lb->GetSelection(); |
|
char selected[1000]; |
|
selected[0] = '\0'; |
|
if (item != -1) { |
|
ac.lb->GetValue(item, selected, sizeof(selected)); |
|
} else { |
|
ac.Cancel(); |
|
return; |
|
} |
|
|
|
ac.Show(false); |
|
|
|
listSelected = selected; |
|
SCNotification scn = {0}; |
|
scn.nmhdr.code = listType > 0 ? SCN_USERLISTSELECTION : SCN_AUTOCSELECTION; |
|
scn.message = 0; |
|
scn.wParam = listType; |
|
scn.listType = listType; |
|
Position firstPos = ac.posStart - ac.startLen; |
|
scn.lParam = firstPos; |
|
scn.text = listSelected.c_str(); |
|
NotifyParent(scn); |
|
|
|
if (!ac.Active()) |
|
return; |
|
ac.Cancel(); |
|
|
|
if (listType > 0) |
|
return; |
|
|
|
Position endPos = currentPos; |
|
if (ac.dropRestOfWord) |
|
endPos = pdoc->ExtendWordSelect(endPos, 1, true); |
|
if (endPos < firstPos) |
|
return; |
|
pdoc->BeginUndoAction(); |
|
if (endPos != firstPos) { |
|
pdoc->DeleteChars(firstPos, endPos - firstPos); |
|
} |
|
SetEmptySelection(ac.posStart); |
|
if (item != -1) { |
|
SString piece = selected; |
|
pdoc->InsertString(firstPos, piece.c_str()); |
|
SetEmptySelection(firstPos + static_cast<int>(piece.length())); |
|
} |
|
pdoc->EndUndoAction(); |
|
} |
|
|
|
int ScintillaBase::AutoCompleteGetCurrent() { |
|
return ac.lb->GetSelection(); |
|
} |
|
|
|
void ScintillaBase::CallTipShow(Point pt, const char *defn) { |
|
AutoCompleteCancel(); |
|
pt.y += vs.lineHeight; |
|
// If container knows about STYLE_CALLTIP then use it in place of the |
|
// STYLE_DEFAULT for the face name, size and character set. Also use it |
|
// for the foreground and background colour. |
|
int ctStyle = ct.UseStyleCallTip() ? STYLE_CALLTIP : STYLE_DEFAULT; |
|
if (ct.UseStyleCallTip()) { |
|
ct.SetForeBack(vs.styles[STYLE_CALLTIP].fore, vs.styles[STYLE_CALLTIP].back); |
|
} |
|
PRectangle rc = ct.CallTipStart(currentPos, pt, |
|
defn, |
|
vs.styles[ctStyle].fontName, |
|
vs.styles[ctStyle].sizeZoomed, |
|
CodePage(), |
|
vs.styles[ctStyle].characterSet, |
|
wMain); |
|
// If the call-tip window would be out of the client |
|
// space, adjust so it displays above the text. |
|
PRectangle rcClient = GetClientRectangle(); |
|
if (rc.bottom > rcClient.bottom) { |
|
int offset = vs.lineHeight + rc.Height(); |
|
rc.top -= offset; |
|
rc.bottom -= offset; |
|
} |
|
// Now display the window. |
|
CreateCallTipWindow(rc); |
|
ct.wCallTip.SetPositionRelative(rc, wMain); |
|
ct.wCallTip.Show(); |
|
} |
|
|
|
void ScintillaBase::CallTipClick() { |
|
SCNotification scn = {0}; |
|
scn.nmhdr.code = SCN_CALLTIPCLICK; |
|
scn.position = ct.clickPlace; |
|
NotifyParent(scn); |
|
} |
|
|
|
void ScintillaBase::ContextMenu(Point pt) { |
|
if (displayPopupMenu) { |
|
bool writable = !WndProc(SCI_GETREADONLY, 0, 0); |
|
popup.CreatePopUp(); |
|
AddToPopUp("Undo", idcmdUndo, writable && pdoc->CanUndo()); |
|
AddToPopUp("Redo", idcmdRedo, writable && pdoc->CanRedo()); |
|
AddToPopUp(""); |
|
AddToPopUp("Cut", idcmdCut, writable && currentPos != anchor); |
|
AddToPopUp("Copy", idcmdCopy, currentPos != anchor); |
|
AddToPopUp("Paste", idcmdPaste, writable && WndProc(SCI_CANPASTE, 0, 0)); |
|
AddToPopUp("Delete", idcmdDelete, writable && currentPos != anchor); |
|
AddToPopUp(""); |
|
AddToPopUp("Select All", idcmdSelectAll); |
|
popup.Show(pt, wMain); |
|
} |
|
} |
|
|
|
void ScintillaBase::CancelModes() { |
|
AutoCompleteCancel(); |
|
ct.CallTipCancel(); |
|
Editor::CancelModes(); |
|
} |
|
|
|
void ScintillaBase::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt) { |
|
CancelModes(); |
|
Editor::ButtonDown(pt, curTime, shift, ctrl, alt); |
|
} |
|
|
|
#ifdef SCI_LEXER |
|
void ScintillaBase::SetLexer(uptr_t wParam) { |
|
lexLanguage = wParam; |
|
lexCurrent = LexerModule::Find(lexLanguage); |
|
if (!lexCurrent) |
|
lexCurrent = LexerModule::Find(SCLEX_NULL); |
|
} |
|
|
|
void ScintillaBase::SetLexerLanguage(const char *languageName) { |
|
lexLanguage = SCLEX_CONTAINER; |
|
lexCurrent = LexerModule::Find(languageName); |
|
if (!lexCurrent) |
|
lexCurrent = LexerModule::Find(SCLEX_NULL); |
|
if (lexCurrent) |
|
lexLanguage = lexCurrent->GetLanguage(); |
|
} |
|
|
|
void ScintillaBase::Colourise(int start, int end) { |
|
if (!performingStyle) { |
|
// Protect against reentrance, which may occur, for example, when |
|
// fold points are discovered while performing styling and the folding |
|
// code looks for child lines which may trigger styling. |
|
performingStyle = true; |
|
|
|
int lengthDoc = pdoc->Length(); |
|
if (end == -1) |
|
end = lengthDoc; |
|
int len = end - start; |
|
|
|
PLATFORM_ASSERT(len >= 0); |
|
PLATFORM_ASSERT(start + len <= lengthDoc); |
|
|
|
//WindowAccessor styler(wMain.GetID(), props); |
|
DocumentAccessor styler(pdoc, props, wMain.GetID()); |
|
|
|
int styleStart = 0; |
|
if (start > 0) |
|
styleStart = styler.StyleAt(start - 1) & pdoc->stylingBitsMask; |
|
styler.SetCodePage(pdoc->dbcsCodePage); |
|
|
|
if (lexCurrent && (len > 0)) { // Should always succeed as null lexer should always be available |
|
lexCurrent->Lex(start, len, styleStart, keyWordLists, styler); |
|
styler.Flush(); |
|
if (styler.GetPropertyInt("fold")) { |
|
lexCurrent->Fold(start, len, styleStart, keyWordLists, styler); |
|
styler.Flush(); |
|
} |
|
} |
|
|
|
performingStyle = false; |
|
} |
|
} |
|
#endif |
|
|
|
void ScintillaBase::NotifyStyleToNeeded(int endStyleNeeded) { |
|
#ifdef SCI_LEXER |
|
if (lexLanguage != SCLEX_CONTAINER) { |
|
int endStyled = WndProc(SCI_GETENDSTYLED, 0, 0); |
|
int lineEndStyled = WndProc(SCI_LINEFROMPOSITION, endStyled, 0); |
|
endStyled = WndProc(SCI_POSITIONFROMLINE, lineEndStyled, 0); |
|
Colourise(endStyled, endStyleNeeded); |
|
return; |
|
} |
|
#endif |
|
Editor::NotifyStyleToNeeded(endStyleNeeded); |
|
} |
|
|
|
sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { |
|
switch (iMessage) { |
|
case SCI_AUTOCSHOW: |
|
listType = 0; |
|
AutoCompleteStart(wParam, reinterpret_cast<const char *>(lParam)); |
|
break; |
|
|
|
case SCI_AUTOCCANCEL: |
|
AutoCompleteCancel(); |
|
break; |
|
|
|
case SCI_AUTOCACTIVE: |
|
return ac.Active(); |
|
|
|
case SCI_AUTOCPOSSTART: |
|
return ac.posStart; |
|
|
|
case SCI_AUTOCCOMPLETE: |
|
AutoCompleteCompleted(); |
|
break; |
|
|
|
case SCI_AUTOCSETSEPARATOR: |
|
ac.SetSeparator(static_cast<char>(wParam)); |
|
break; |
|
|
|
case SCI_AUTOCGETSEPARATOR: |
|
return ac.GetSeparator(); |
|
|
|
case SCI_AUTOCSTOPS: |
|
ac.SetStopChars(reinterpret_cast<char *>(lParam)); |
|
break; |
|
|
|
case SCI_AUTOCSELECT: |
|
ac.Select(reinterpret_cast<char *>(lParam)); |
|
break; |
|
|
|
case SCI_AUTOCGETCURRENT: |
|
return AutoCompleteGetCurrent(); |
|
|
|
case SCI_AUTOCSETCANCELATSTART: |
|
ac.cancelAtStartPos = wParam != 0; |
|
break; |
|
|
|
case SCI_AUTOCGETCANCELATSTART: |
|
return ac.cancelAtStartPos; |
|
|
|
case SCI_AUTOCSETFILLUPS: |
|
ac.SetFillUpChars(reinterpret_cast<char *>(lParam)); |
|
break; |
|
|
|
case SCI_AUTOCSETCHOOSESINGLE: |
|
ac.chooseSingle = wParam != 0; |
|
break; |
|
|
|
case SCI_AUTOCGETCHOOSESINGLE: |
|
return ac.chooseSingle; |
|
|
|
case SCI_AUTOCSETIGNORECASE: |
|
ac.ignoreCase = wParam != 0; |
|
break; |
|
|
|
case SCI_AUTOCGETIGNORECASE: |
|
return ac.ignoreCase; |
|
|
|
case SCI_USERLISTSHOW: |
|
listType = wParam; |
|
AutoCompleteStart(0, reinterpret_cast<const char *>(lParam)); |
|
break; |
|
|
|
case SCI_AUTOCSETAUTOHIDE: |
|
ac.autoHide = wParam != 0; |
|
break; |
|
|
|
case SCI_AUTOCGETAUTOHIDE: |
|
return ac.autoHide; |
|
|
|
case SCI_AUTOCSETDROPRESTOFWORD: |
|
ac.dropRestOfWord = wParam != 0; |
|
break; |
|
|
|
case SCI_AUTOCGETDROPRESTOFWORD: |
|
return ac.dropRestOfWord; |
|
|
|
case SCI_AUTOCSETMAXHEIGHT: |
|
ac.lb->SetVisibleRows(wParam); |
|
break; |
|
|
|
case SCI_AUTOCGETMAXHEIGHT: |
|
return ac.lb->GetVisibleRows(); |
|
|
|
case SCI_AUTOCSETMAXWIDTH: |
|
maxListWidth = wParam; |
|
break; |
|
|
|
case SCI_AUTOCGETMAXWIDTH: |
|
return maxListWidth; |
|
|
|
case SCI_REGISTERIMAGE: |
|
ac.lb->RegisterImage(wParam, reinterpret_cast<const char *>(lParam)); |
|
break; |
|
|
|
case SCI_CLEARREGISTEREDIMAGES: |
|
ac.lb->ClearRegisteredImages(); |
|
break; |
|
|
|
case SCI_AUTOCSETTYPESEPARATOR: |
|
ac.SetTypesep(static_cast<char>(wParam)); |
|
break; |
|
|
|
case SCI_AUTOCGETTYPESEPARATOR: |
|
return ac.GetTypesep(); |
|
|
|
case SCI_CALLTIPSHOW: |
|
CallTipShow(LocationFromPosition(wParam), |
|
reinterpret_cast<const char *>(lParam)); |
|
break; |
|
|
|
case SCI_CALLTIPCANCEL: |
|
ct.CallTipCancel(); |
|
break; |
|
|
|
case SCI_CALLTIPACTIVE: |
|
return ct.inCallTipMode; |
|
|
|
case SCI_CALLTIPPOSSTART: |
|
return ct.posStartCallTip; |
|
|
|
case SCI_CALLTIPSETHLT: |
|
ct.SetHighlight(wParam, lParam); |
|
break; |
|
|
|
case SCI_CALLTIPSETBACK: |
|
ct.colourBG = ColourDesired(wParam); |
|
vs.styles[STYLE_CALLTIP].fore = ct.colourBG; |
|
InvalidateStyleRedraw(); |
|
break; |
|
|
|
case SCI_CALLTIPSETFORE: |
|
ct.colourUnSel = ColourDesired(wParam); |
|
vs.styles[STYLE_CALLTIP].fore = ct.colourUnSel; |
|
InvalidateStyleRedraw(); |
|
break; |
|
|
|
case SCI_CALLTIPSETFOREHLT: |
|
ct.colourSel = ColourDesired(wParam); |
|
InvalidateStyleRedraw(); |
|
break; |
|
|
|
case SCI_CALLTIPUSESTYLE: |
|
ct.SetTabSize((int)wParam); |
|
InvalidateStyleRedraw(); |
|
break; |
|
|
|
case SCI_USEPOPUP: |
|
displayPopupMenu = wParam != 0; |
|
break; |
|
|
|
#ifdef SCI_LEXER |
|
case SCI_SETLEXER: |
|
SetLexer(wParam); |
|
lexLanguage = wParam; |
|
break; |
|
|
|
case SCI_GETLEXER: |
|
return lexLanguage; |
|
|
|
case SCI_COLOURISE: |
|
if (lexLanguage == SCLEX_CONTAINER) { |
|
pdoc->ModifiedAt(wParam); |
|
NotifyStyleToNeeded((lParam == -1) ? pdoc->Length() : lParam); |
|
} else { |
|
Colourise(wParam, lParam); |
|
} |
|
Redraw(); |
|
break; |
|
|
|
case SCI_SETPROPERTY: |
|
props.Set(reinterpret_cast<const char *>(wParam), |
|
reinterpret_cast<const char *>(lParam)); |
|
break; |
|
|
|
case SCI_GETPROPERTY: { |
|
SString val = props.Get(reinterpret_cast<const char *>(wParam)); |
|
const int n = val.length(); |
|
if (lParam != 0) { |
|
char *ptr = reinterpret_cast<char *>(lParam); |
|
memcpy(ptr, val.c_str(), n); |
|
ptr[n] = '\0'; // terminate |
|
} |
|
return n; // Not including NUL |
|
} |
|
|
|
case SCI_GETPROPERTYEXPANDED: { |
|
SString val = props.GetExpanded(reinterpret_cast<const char *>(wParam)); |
|
const int n = val.length(); |
|
if (lParam != 0) { |
|
char *ptr = reinterpret_cast<char *>(lParam); |
|
memcpy(ptr, val.c_str(), n); |
|
ptr[n] = '\0'; // terminate |
|
} |
|
return n; // Not including NUL |
|
} |
|
|
|
case SCI_GETPROPERTYINT: |
|
return props.GetInt(reinterpret_cast<const char *>(wParam), lParam); |
|
|
|
case SCI_SETKEYWORDS: |
|
if (wParam < numWordLists) { |
|
keyWordLists[wParam]->Clear(); |
|
keyWordLists[wParam]->Set(reinterpret_cast<const char *>(lParam)); |
|
} |
|
break; |
|
|
|
case SCI_SETLEXERLANGUAGE: |
|
SetLexerLanguage(reinterpret_cast<const char *>(lParam)); |
|
break; |
|
|
|
case SCI_GETSTYLEBITSNEEDED: |
|
return lexCurrent ? lexCurrent->GetStyleBitsNeeded() : 5; |
|
#endif |
|
|
|
default: |
|
return Editor::WndProc(iMessage, wParam, lParam); |
|
} |
|
return 0l; |
|
}
|
|
|