]>
git.saurik.com Git - wxWidgets.git/blob - contrib/src/stc/scintilla/src/ScintillaBase.cxx
eb68904b796af4cb0fac43f0aada8f649d9d2989
1 // Scintilla source code edit control
2 // ScintillaBase.cxx - an enhanced subclass of Editor with calltips, autocomplete and context menu
3 // Copyright 1998-2000 by Neil Hodgson <neilh@scintilla.org>
4 // The License.txt file describes the conditions under which this software may be distributed.
13 #include "Scintilla.h"
20 #include "ContractionState.h"
22 #include "CellBuffer.h"
25 #include "Indicator.h"
26 #include "LineMarker.h"
28 #include "ViewStyle.h"
29 #include "AutoComplete.h"
32 #include "ScintillaBase.h"
34 ScintillaBase::ScintillaBase() {
36 lexLanguage
= SCLEX_CONTAINER
;
37 for (int wl
=0;wl
<numWordLists
;wl
++)
38 keyWordLists
[wl
] = new WordList
;
42 ScintillaBase::~ScintillaBase() {}
44 void ScintillaBase::Finalise() {
48 void ScintillaBase::RefreshColourPalette(Palette
&pal
, bool want
) {
49 Editor::RefreshColourPalette(pal
, want
);
50 ct
.RefreshColourPalette(pal
, want
);
53 void ScintillaBase::AddChar(char ch
) {
54 bool acActiveBeforeCharAdded
= ac
.Active();
56 if (acActiveBeforeCharAdded
)
57 AutoCompleteChanged(ch
);
60 void ScintillaBase::Command(int cmdId
) {
64 case idAutoComplete
: // Nothing to do
67 case idCallTip
: // Nothing to do
71 WndProc(WM_UNDO
, 0, 0);
75 WndProc(SCI_REDO
, 0, 0);
79 WndProc(WM_CUT
, 0, 0);
83 WndProc(WM_COPY
, 0, 0);
87 WndProc(WM_PASTE
, 0, 0);
91 WndProc(WM_CLEAR
, 0, 0);
95 WndProc(SCI_SELECTALL
, 0, 0);
100 int ScintillaBase::KeyCommand(UINT iMessage
) {
101 // Most key commands cancel autocompletion mode
109 AutoCompleteMove( -1);
115 AutoCompleteMove( -5);
118 AutoCompleteMove( -5000);
121 AutoCompleteMove(5000);
125 AutoCompleteChanged();
126 EnsureCaretVisible();
129 AutoCompleteCompleted();
137 if (ct
.inCallTipMode
) {
139 (iMessage
!= SCI_CHARLEFT
) &&
140 (iMessage
!= SCI_CHARLEFTEXTEND
) &&
141 (iMessage
!= SCI_CHARRIGHT
) &&
142 (iMessage
!= SCI_CHARLEFTEXTEND
) &&
143 (iMessage
!= SCI_EDITTOGGLEOVERTYPE
) &&
144 (iMessage
!= SCI_DELETEBACK
)
148 if (iMessage
== SCI_DELETEBACK
) {
149 if (currentPos
<= ct
.posStartCallTip
) {
154 return Editor::KeyCommand(iMessage
);
157 void ScintillaBase::AutoCompleteStart(int lenEntered
, const char *list
) {
158 //Platform::DebugPrintf("AutoCOmplete %s\n", list);
161 ac
.Start(wDraw
, idAutoComplete
, currentPos
, lenEntered
);
163 PRectangle rcClient
= GetClientRectangle();
164 Point pt
= LocationFromPosition(currentPos
-lenEntered
);
166 //Platform::DebugPrintf("Auto complete %x\n", lbAutoComplete);
169 if (pt
.x
>= rcClient
.right
- widthLB
) {
170 HorizontalScrollTo(xOffset
+ pt
.x
- rcClient
.right
+ widthLB
);
172 pt
= LocationFromPosition(currentPos
);
175 rcac
.left
= pt
.x
- 5;
176 if (pt
.y
>= rcClient
.bottom
- heightLB
&& // Wont fit below.
177 pt
.y
>= (rcClient
.bottom
+ rcClient
.top
) / 2) { // and there is more room above.
178 rcac
.top
= pt
.y
- heightLB
;
180 heightLB
+= rcac
.top
;
184 rcac
.top
= pt
.y
+ vs
.lineHeight
;
186 rcac
.right
= rcac
.left
+ widthLB
;
187 rcac
.bottom
= Platform::Minimum(rcac
.top
+ heightLB
, rcClient
.bottom
);
188 ac
.lb
.SetPositionRelative(rcac
, wMain
);
189 ac
.lb
.SetFont(vs
.styles
[0].font
);
191 int maxStrLen
= ac
.SetList(list
);
193 // Fiddle the position of the list so it is right next to the target and wide enough for all its strings
194 PRectangle rcList
= ac
.lb
.GetPosition();
195 int heightAlloced
= rcList
.bottom
- rcList
.top
;
196 // Make an allowance for large strings in list
197 rcList
.left
= pt
.x
- 5;
198 rcList
.right
= rcList
.left
+ Platform::Maximum(widthLB
, maxStrLen
* 8 + 16);
199 if (pt
.y
>= rcClient
.bottom
- heightLB
&& // Wont fit below.
200 pt
.y
>= (rcClient
.bottom
+ rcClient
.top
) / 2) { // and there is more room above.
201 rcList
.top
= pt
.y
- heightAlloced
;
203 rcList
.top
= pt
.y
+ vs
.lineHeight
;
205 rcList
.bottom
= rcList
.top
+ heightAlloced
;
206 ac
.lb
.SetPositionRelative(rcList
, wMain
);
207 //lbAutoComplete.SetPosition(rcList);
211 void ScintillaBase::AutoCompleteCancel() {
215 void ScintillaBase::AutoCompleteMove(int delta
) {
219 void ScintillaBase::AutoCompleteChanged(char ch
) {
220 if (currentPos
<= ac
.posStart
) {
222 } else if (ac
.IsStopChar(ch
)) {
225 char wordCurrent
[1000];
227 int startWord
= ac
.posStart
- ac
.startLen
;
228 for (i
= startWord
; i
< currentPos
; i
++)
229 wordCurrent
[i
- startWord
] = pdoc
->CharAt(i
);
230 wordCurrent
[i
- startWord
] = '\0';
231 ac
.Select(wordCurrent
);
235 void ScintillaBase::AutoCompleteCompleted() {
236 int item
= ac
.lb
.GetSelection();
239 ac
.lb
.GetValue(item
, selected
, sizeof(selected
));
242 if (currentPos
!= ac
.posStart
) {
243 pdoc
->DeleteChars(ac
.posStart
, currentPos
- ac
.posStart
);
245 SetEmptySelection(ac
.posStart
);
247 pdoc
->InsertString(currentPos
, selected
+ ac
.startLen
);
248 SetEmptySelection(currentPos
+ strlen(selected
+ ac
.startLen
));
252 void ScintillaBase::ContextMenu(Point pt
) {
254 AddToPopUp("Undo", idcmdUndo
, pdoc
->CanUndo());
255 AddToPopUp("Redo", idcmdRedo
, pdoc
->CanRedo());
257 AddToPopUp("Cut", idcmdCut
, currentPos
!= anchor
);
258 AddToPopUp("Copy", idcmdCopy
, currentPos
!= anchor
);
259 AddToPopUp("Paste", idcmdPaste
, WndProc(EM_CANPASTE
, 0, 0));
260 AddToPopUp("Delete", idcmdDelete
, currentPos
!= anchor
);
262 AddToPopUp("Select All", idcmdSelectAll
);
263 popup
.Show(pt
, wMain
);
266 void ScintillaBase::ButtonDown(Point pt
, unsigned int curTime
, bool shift
, bool ctrl
, bool alt
) {
267 AutoCompleteCancel();
269 Editor::ButtonDown(pt
, curTime
, shift
, ctrl
, alt
);
273 void ScintillaBase::Colourise(int start
, int end
) {
274 int lengthDoc
= Platform::SendScintilla(wMain
.GetID(), SCI_GETLENGTH
, 0, 0);
277 int len
= end
- start
;
281 StylingContext
styler(wMain
.GetID(), props
);
285 styleStart
= styler
.StyleAt(start
- 1);
287 ColouriseDoc(pdoc
->dbcsCodePage
, start
, len
, styleStart
, lexLanguage
, keyWordLists
, styler
);
292 void ScintillaBase::NotifyStyleNeeded(int endStyleNeeded
) {
294 if (lexLanguage
!= SCLEX_CONTAINER
) {
295 int endStyled
= Platform::SendScintilla(wMain
.GetID(), SCI_GETENDSTYLED
, 0, 0);
296 int lineEndStyled
= Platform::SendScintilla(wMain
.GetID(), EM_LINEFROMCHAR
, endStyled
, 0);
297 endStyled
= Platform::SendScintilla(wMain
.GetID(), EM_LINEINDEX
, lineEndStyled
, 0);
298 Colourise(endStyled
, endStyleNeeded
);
302 Editor::NotifyStyleNeeded(endStyleNeeded
);
305 LRESULT
ScintillaBase::WndProc(UINT iMessage
, WPARAM wParam
, LPARAM lParam
) {
308 AutoCompleteStart(wParam
, reinterpret_cast<const char *>(lParam
));
311 case SCI_AUTOCCANCEL
:
312 AutoCompleteCancel();
315 case SCI_AUTOCACTIVE
:
318 case SCI_AUTOCPOSSTART
:
321 case SCI_AUTOCCOMPLETE
:
322 AutoCompleteCompleted();
326 ac
.SetStopChars(reinterpret_cast<char *>(lParam
));
329 case SCI_CALLTIPSHOW
: {
330 AutoCompleteCancel();
331 if (!ct
.wCallTip
.Created()) {
332 PRectangle rc
= ct
.CallTipStart(currentPos
, LocationFromPosition(wParam
),
333 reinterpret_cast<char *>(lParam
),
334 vs
.styles
[0].fontName
, vs
.styles
[0].size
);
335 // If the call-tip window would be out of the client
336 // space, adjust so it displays above the text.
337 PRectangle rcClient
= GetClientRectangle();
338 if (rc
.bottom
> rcClient
.bottom
) {
339 int offset
= vs
.lineHeight
+ rc
.Height();
343 // Now display the window.
344 CreateCallTipWindow(rc
);
345 ct
.wCallTip
.SetPositionRelative(rc
, wDraw
);
351 case SCI_CALLTIPCANCEL
:
355 case SCI_CALLTIPACTIVE
:
356 return ct
.inCallTipMode
;
358 case SCI_CALLTIPPOSSTART
:
359 return ct
.posStartCallTip
;
361 case SCI_CALLTIPSETHLT
:
362 ct
.SetHighlight(wParam
, lParam
);
365 case SCI_CALLTIPSETBACK
:
366 ct
.colourBG
= Colour(wParam
);
367 InvalidateStyleRedraw();
372 lexLanguage
= wParam
;
379 Colourise(wParam
, lParam
);
382 case SCI_SETPROPERTY
:
383 props
.Set(reinterpret_cast<const char *>(wParam
),
384 reinterpret_cast<const char *>(lParam
));
387 case SCI_SETKEYWORDS
:
388 if ((wParam
>= 0) && (wParam
< numWordLists
)) {
389 keyWordLists
[wParam
]->Clear();
390 keyWordLists
[wParam
]->Set(reinterpret_cast<const char *>(lParam
));
396 return Editor::WndProc(iMessage
, wParam
, lParam
);