Finished the changes necessary to use the new event system.
[wxWidgets.git] / contrib / src / stc / stc.cpp.in
1 ////////////////////////////////////////////////////////////////////////////
2 // Name: stc.cpp
3 // Purpose: A wxWindows implementation of Scintilla. This class is the
4 // one meant to be used directly by wx applications. It does not
5 // derive directly from the Scintilla classes, but instead
6 // delegates most things to the real Scintilla class.
7 // This allows the use of Scintilla without polluting the
8 // namespace with all the classes and identifiers from Scintilla.
9 //
10 // Author: Robin Dunn
11 //
12 // Created: 13-Jan-2000
13 // RCS-ID: $Id$
14 // Copyright: (c) 2000 by Total Control Software
15 // Licence: wxWindows license
16 /////////////////////////////////////////////////////////////////////////////
17
18 #include <ctype.h>
19
20 #include "wx/stc/stc.h"
21 #include "ScintillaWX.h"
22
23 #include <wx/tokenzr.h>
24
25 // The following code forces a reference to all of the Scintilla lexers.
26 // If we don't do something like this, then the linker tends to "optimize"
27 // them away. (eric@sourcegear.com)
28
29 int wxForceScintillaLexers(void)
30 {
31 extern LexerModule lmCPP;
32 extern LexerModule lmHTML;
33 extern LexerModule lmXML;
34 extern LexerModule lmProps;
35 extern LexerModule lmErrorList;
36 extern LexerModule lmMake;
37 extern LexerModule lmBatch;
38 extern LexerModule lmPerl;
39 extern LexerModule lmPython;
40 extern LexerModule lmSQL;
41 extern LexerModule lmVB;
42
43 if (
44 &lmCPP
45 && &lmHTML
46 && &lmXML
47 && &lmProps
48 && &lmErrorList
49 && &lmMake
50 && &lmBatch
51 && &lmPerl
52 && &lmPython
53 && &lmSQL
54 && &lmVB
55 )
56 {
57 return 1;
58 }
59 else
60 {
61 return 0;
62 }
63 }
64
65 //----------------------------------------------------------------------
66
67 const wxChar* wxSTCNameStr = "stcwindow";
68
69
70 DEFINE_EVENT_TYPE( wxEVT_STC_CHANGE )
71 DEFINE_EVENT_TYPE( wxEVT_STC_STYLENEEDED )
72 DEFINE_EVENT_TYPE( wxEVT_STC_CHARADDED )
73 DEFINE_EVENT_TYPE( wxEVT_STC_UPDATEUI )
74 DEFINE_EVENT_TYPE( wxEVT_STC_SAVEPOINTREACHED )
75 DEFINE_EVENT_TYPE( wxEVT_STC_SAVEPOINTLEFT )
76 DEFINE_EVENT_TYPE( wxEVT_STC_ROMODIFYATTEMPT )
77 DEFINE_EVENT_TYPE( wxEVT_STC_DOUBLECLICK )
78 DEFINE_EVENT_TYPE( wxEVT_STC_MODIFIED )
79 DEFINE_EVENT_TYPE( wxEVT_STC_KEY )
80 DEFINE_EVENT_TYPE( wxEVT_STC_MACRORECORD )
81 DEFINE_EVENT_TYPE( wxEVT_STC_MARGINCLICK )
82 DEFINE_EVENT_TYPE( wxEVT_STC_NEEDSHOWN )
83 DEFINE_EVENT_TYPE( wxEVT_STC_POSCHANGED )
84
85
86 BEGIN_EVENT_TABLE(wxStyledTextCtrl, wxControl)
87 EVT_PAINT (wxStyledTextCtrl::OnPaint)
88 EVT_SCROLLWIN (wxStyledTextCtrl::OnScrollWin)
89 EVT_SIZE (wxStyledTextCtrl::OnSize)
90 EVT_LEFT_DOWN (wxStyledTextCtrl::OnMouseLeftDown)
91 EVT_MOTION (wxStyledTextCtrl::OnMouseMove)
92 EVT_LEFT_UP (wxStyledTextCtrl::OnMouseLeftUp)
93 EVT_RIGHT_UP (wxStyledTextCtrl::OnMouseRightUp)
94 EVT_CHAR (wxStyledTextCtrl::OnChar)
95 EVT_KEY_DOWN (wxStyledTextCtrl::OnKeyDown)
96 EVT_KILL_FOCUS (wxStyledTextCtrl::OnLoseFocus)
97 EVT_SET_FOCUS (wxStyledTextCtrl::OnGainFocus)
98 EVT_SYS_COLOUR_CHANGED (wxStyledTextCtrl::OnSysColourChanged)
99 EVT_ERASE_BACKGROUND (wxStyledTextCtrl::OnEraseBackground)
100 EVT_MENU_RANGE (-1, -1, wxStyledTextCtrl::OnMenu)
101 EVT_LISTBOX_DCLICK (-1, wxStyledTextCtrl::OnListBox)
102 END_EVENT_TABLE()
103
104
105 IMPLEMENT_CLASS(wxStyledTextCtrl, wxControl)
106 IMPLEMENT_DYNAMIC_CLASS(wxStyledTextEvent, wxCommandEvent)
107
108 //----------------------------------------------------------------------
109 // Constructor and Destructor
110
111 wxStyledTextCtrl::wxStyledTextCtrl(wxWindow *parent,
112 wxWindowID id,
113 const wxPoint& pos,
114 const wxSize& size,
115 long style,
116 const wxString& name) :
117 wxControl(parent, id, pos, size,
118 style | wxVSCROLL | wxHSCROLL | wxWANTS_CHARS | wxCLIP_CHILDREN,
119 wxDefaultValidator, name)
120 {
121 m_swx = new ScintillaWX(this);
122 m_stopWatch.Start();
123 }
124
125
126 wxStyledTextCtrl::~wxStyledTextCtrl() {
127 delete m_swx;
128 }
129
130
131 //----------------------------------------------------------------------
132
133 long wxStyledTextCtrl::SendMsg(int msg, long wp, long lp) {
134
135 return m_swx->WndProc(msg, wp, lp);
136 }
137
138
139 #ifdef MAKELONG
140 #undef MAKELONG
141 #endif
142
143 #define MAKELONG(a, b) ((a) | ((b) << 16))
144
145
146 static long wxColourAsLong(const wxColour& co) {
147 return (((long)co.Blue() << 16) |
148 ((long)co.Green() << 8) |
149 ((long)co.Red()));
150 }
151
152 static wxColour wxColourFromLong(long c) {
153 wxColour clr;
154 clr.Set(c & 0xff, (c >> 8) & 0xff, (c >> 16) & 0xff);
155 return clr;
156 }
157
158
159 static wxColour wxColourFromSpec(const wxString& spec) {
160 // spec should be #RRGGBB
161 char* junk;
162 int red = strtol(spec.Mid(1,2), &junk, 16);
163 int green = strtol(spec.Mid(3,2), &junk, 16);
164 int blue = strtol(spec.Mid(5,2), &junk, 16);
165 return wxColour(red, green, blue);
166 }
167
168
169 //----------------------------------------------------------------------
170 // BEGIN generated section. The following code is automatically generated
171 // by gen_iface.py from the contents of Scintilla.iface. Do not edit
172 // this file. Edit stc.cpp.in or gen_iface.py instead and regenerate.
173
174 %(METHOD_IMPS)s
175
176 // END of generated section
177 //----------------------------------------------------------------------
178
179
180 // Returns the line number of the line with the caret.
181 int wxStyledTextCtrl::GetCurrentLine() {
182 int line = LineFromPosition(GetCurrentPos());
183 return line;
184 }
185
186
187 // Extract style settings from a spec-string which is composed of one or
188 // more of the following comma separated elements:
189 //
190 // bold turns on bold
191 // italic turns on italics
192 // fore:#RRGGBB sets the foreground colour
193 // back:#RRGGBB sets the background colour
194 // face:[facename] sets the font face name to use
195 // size:[num] sets the font size in points
196 // eol turns on eol filling
197 // underline turns on underlining
198 //
199 void wxStyledTextCtrl::StyleSetSpec(int styleNum, const wxString& spec) {
200
201 wxStringTokenizer tkz(spec, ",");
202 while (tkz.HasMoreTokens()) {
203 wxString token = tkz.GetNextToken();
204
205 wxString option = token.BeforeFirst(':');
206 wxString val = token.AfterFirst(':');
207
208 if (option == "bold")
209 StyleSetBold(styleNum, true);
210
211 else if (option == "italic")
212 StyleSetItalic(styleNum, true);
213
214 else if (option == "underline")
215 StyleSetUnderline(styleNum, true);
216
217 else if (option == "eol")
218 StyleSetEOLFilled(styleNum, true);
219
220 else if (option == "size") {
221 long points;
222 if (val.ToLong(&points))
223 StyleSetSize(styleNum, points);
224 }
225
226 else if (option == "face")
227 StyleSetFaceName(styleNum, val);
228
229 else if (option == "fore")
230 StyleSetForeground(styleNum, wxColourFromSpec(val));
231
232 else if (option == "back")
233 StyleSetBackground(styleNum, wxColourFromSpec(val));
234 }
235 }
236
237
238 // Set style size, face, bold, italic, and underline attributes from
239 // a wxFont's attributes.
240 void wxStyledTextCtrl::StyleSetFont(int styleNum, wxFont& font) {
241 int size = font.GetPointSize();
242 wxString faceName = font.GetFaceName();
243 bool bold = font.GetWeight() == wxBOLD;
244 bool italic = font.GetStyle() != wxNORMAL;
245 bool under = font.GetUnderlined();
246
247 // TODO: add encoding/charset mapping
248 StyleSetFontAttr(styleNum, size, faceName, bold, italic, under);
249 }
250
251 // Set all font style attributes at once.
252 void wxStyledTextCtrl::StyleSetFontAttr(int styleNum, int size,
253 const wxString& faceName,
254 bool bold, bool italic,
255 bool underline) {
256 StyleSetSize(styleNum, size);
257 StyleSetFaceName(styleNum, faceName);
258 StyleSetBold(styleNum, bold);
259 StyleSetItalic(styleNum, italic);
260 StyleSetUnderline(styleNum, underline);
261
262 // TODO: add encoding/charset mapping
263 }
264
265
266 // Perform one of the operations defined by the wxSTC_CMD_* constants.
267 void wxStyledTextCtrl::CmdKeyExecute(int cmd) {
268 SendMsg(cmd);
269 }
270
271
272 // Set the left and right margin in the edit area, measured in pixels.
273 void wxStyledTextCtrl::SetMargins(int left, int right) {
274 SetMarginLeft(left);
275 SetMarginRight(right);
276 }
277
278
279 // Retrieve the start and end positions of the current selection.
280 void wxStyledTextCtrl::GetSelection(int* startPos, int* endPos) {
281 if (startPos != NULL)
282 *startPos = SendMsg(SCI_GETSELECTIONSTART);
283 if (endPos != NULL)
284 *endPos = SendMsg(SCI_GETSELECTIONEND);
285 }
286
287
288 // Retrieve the point in the window where a position is displayed.
289 wxPoint wxStyledTextCtrl::PointFromPosition(int pos) {
290 int x = SendMsg(SCI_POINTXFROMPOSITION, 0, pos);
291 int y = SendMsg(SCI_POINTYFROMPOSITION, 0, pos);
292 return wxPoint(x, y);
293 }
294
295 // Scroll enough to make the given line visible
296 void wxStyledTextCtrl::ScrollToLine(int line) {
297 m_swx->DoScrollToLine(line);
298 }
299
300
301 // Scroll enough to make the given column visible
302 void wxStyledTextCtrl::ScrollToColumn(int column) {
303 m_swx->DoScrollToColumn(column);
304 }
305
306
307
308 //----------------------------------------------------------------------
309 // Event handlers
310
311 void wxStyledTextCtrl::OnPaint(wxPaintEvent& evt) {
312 wxPaintDC dc(this);
313 wxRegion region = GetUpdateRegion();
314
315 m_swx->DoPaint(&dc, region.GetBox());
316 }
317
318 void wxStyledTextCtrl::OnScrollWin(wxScrollWinEvent& evt) {
319 if (evt.GetOrientation() == wxHORIZONTAL)
320 m_swx->DoHScroll(evt.GetEventType(), evt.GetPosition());
321 else
322 m_swx->DoVScroll(evt.GetEventType(), evt.GetPosition());
323 }
324
325 void wxStyledTextCtrl::OnSize(wxSizeEvent& evt) {
326 wxSize sz = GetClientSize();
327 m_swx->DoSize(sz.x, sz.y);
328 }
329
330 void wxStyledTextCtrl::OnMouseLeftDown(wxMouseEvent& evt) {
331 wxPoint pt = evt.GetPosition();
332 m_swx->DoButtonDown(Point(pt.x, pt.y), m_stopWatch.Time(),
333 evt.ShiftDown(), evt.ControlDown(), evt.AltDown());
334 }
335
336 void wxStyledTextCtrl::OnMouseMove(wxMouseEvent& evt) {
337 wxPoint pt = evt.GetPosition();
338 m_swx->DoButtonMove(Point(pt.x, pt.y));
339 }
340
341 void wxStyledTextCtrl::OnMouseLeftUp(wxMouseEvent& evt) {
342 wxPoint pt = evt.GetPosition();
343 m_swx->DoButtonUp(Point(pt.x, pt.y), m_stopWatch.Time(),
344 evt.ControlDown());
345 }
346
347
348 void wxStyledTextCtrl::OnMouseRightUp(wxMouseEvent& evt) {
349 wxPoint pt = evt.GetPosition();
350 m_swx->DoContextMenu(Point(pt.x, pt.y));
351 }
352
353 void wxStyledTextCtrl::OnChar(wxKeyEvent& evt) {
354 long key = evt.KeyCode();
355 if ((key > WXK_ESCAPE) &&
356 (key != WXK_DELETE) && (key < 255) &&
357 !evt.ControlDown() && !evt.AltDown()) {
358
359 m_swx->DoAddChar(key);
360 }
361 else {
362 evt.Skip();
363 }
364 }
365
366 void wxStyledTextCtrl::OnKeyDown(wxKeyEvent& evt) {
367 long key = evt.KeyCode();
368 key = toupper(key);
369 int processed = m_swx->DoKeyDown(key, evt.ShiftDown(),
370 evt.ControlDown(), evt.AltDown());
371 if (! processed)
372 evt.Skip();
373 }
374
375 void wxStyledTextCtrl::OnLoseFocus(wxFocusEvent& evt) {
376 m_swx->DoLoseFocus();
377 }
378
379 void wxStyledTextCtrl::OnGainFocus(wxFocusEvent& evt) {
380 m_swx->DoGainFocus();
381 }
382
383 void wxStyledTextCtrl::OnSysColourChanged(wxSysColourChangedEvent& evt) {
384 m_swx->DoSysColourChange();
385 }
386
387 void wxStyledTextCtrl::OnEraseBackground(wxEraseEvent& evt) {
388 // do nothing to help avoid flashing
389 }
390
391
392
393 void wxStyledTextCtrl::OnMenu(wxCommandEvent& evt) {
394 m_swx->DoCommand(evt.GetId());
395 }
396
397
398 void wxStyledTextCtrl::OnListBox(wxCommandEvent& evt) {
399 m_swx->DoOnListBox();
400 }
401
402
403 //----------------------------------------------------------------------
404 // Turn notifications from Scintilla into events
405
406
407 void wxStyledTextCtrl::NotifyChange() {
408 wxStyledTextEvent evt(wxEVT_STC_CHANGE, GetId());
409 GetEventHandler()->ProcessEvent(evt);
410 }
411
412 void wxStyledTextCtrl::NotifyParent(SCNotification* _scn) {
413 SCNotification& scn = *_scn;
414 int eventType = 0;
415 switch (scn.nmhdr.code) {
416 case SCN_STYLENEEDED:
417 eventType = wxEVT_STC_STYLENEEDED;
418 break;
419 case SCN_CHARADDED:
420 eventType = wxEVT_STC_CHARADDED;
421 break;
422 case SCN_UPDATEUI:
423 eventType = wxEVT_STC_UPDATEUI;
424 break;
425 case SCN_SAVEPOINTREACHED:
426 eventType = wxEVT_STC_SAVEPOINTREACHED;
427 break;
428 case SCN_SAVEPOINTLEFT:
429 eventType = wxEVT_STC_SAVEPOINTLEFT;
430 break;
431 case SCN_MODIFYATTEMPTRO:
432 eventType = wxEVT_STC_ROMODIFYATTEMPT;
433 break;
434 case SCN_DOUBLECLICK:
435 eventType = wxEVT_STC_DOUBLECLICK;
436 break;
437 case SCN_MODIFIED:
438 eventType = wxEVT_STC_MODIFIED;
439 break;
440 case SCN_KEY:
441 eventType = wxEVT_STC_KEY;
442 break;
443 case SCN_MACRORECORD:
444 eventType = wxEVT_STC_MACRORECORD;
445 break;
446 case SCN_MARGINCLICK:
447 eventType = wxEVT_STC_MARGINCLICK;
448 break;
449 case SCN_NEEDSHOWN:
450 eventType = wxEVT_STC_NEEDSHOWN;
451 break;
452 case SCN_POSCHANGED:
453 eventType = wxEVT_STC_POSCHANGED;
454 break;
455 }
456 if (eventType) {
457 wxStyledTextEvent evt(eventType, GetId());
458 evt.SetPosition(scn.position);
459 evt.SetKey(scn.ch);
460 evt.SetModifiers(scn.modifiers);
461 if (eventType == wxEVT_STC_MODIFIED) {
462 evt.SetModificationType(scn.modificationType);
463 if (scn.text)
464 evt.SetText(wxString(scn.text, scn.length));
465 evt.SetLength(scn.length);
466 evt.SetLinesAdded(scn.linesAdded);
467 evt.SetLine(scn.line);
468 evt.SetFoldLevelNow(scn.foldLevelNow);
469 evt.SetFoldLevelPrev(scn.foldLevelPrev);
470 }
471 if (eventType == wxEVT_STC_MARGINCLICK)
472 evt.SetMargin(scn.margin);
473 if (eventType == wxEVT_STC_MACRORECORD) {
474 evt.SetMessage(scn.message);
475 evt.SetWParam(scn.wParam);
476 evt.SetLParam(scn.lParam);
477 }
478
479 GetEventHandler()->ProcessEvent(evt);
480 }
481 }
482
483
484
485 //----------------------------------------------------------------------
486 //----------------------------------------------------------------------
487 //----------------------------------------------------------------------
488
489 wxStyledTextEvent::wxStyledTextEvent(wxEventType commandType, int id)
490 : wxCommandEvent(commandType, id)
491 {
492 m_position = 0;
493 m_key = 0;
494 m_modifiers = 0;
495 m_modificationType = 0;
496 m_length = 0;
497 m_linesAdded = 0;
498 m_line = 0;
499 m_foldLevelNow = 0;
500 m_foldLevelPrev = 0;
501 m_margin = 0;
502 m_message = 0;
503 m_wParam = 0;
504 m_lParam = 0;
505
506
507 }
508
509 bool wxStyledTextEvent::GetShift() const { return (m_modifiers & SCI_SHIFT) != 0; }
510 bool wxStyledTextEvent::GetControl() const { return (m_modifiers & SCI_CTRL) != 0; }
511 bool wxStyledTextEvent::GetAlt() const { return (m_modifiers & SCI_ALT) != 0; }
512
513 void wxStyledTextEvent::CopyObject(wxObject& obj) const {
514 wxCommandEvent::CopyObject(obj);
515
516 wxStyledTextEvent* o = (wxStyledTextEvent*)&obj;
517 o->m_position = m_position;
518 o->m_key = m_key;
519 o->m_modifiers = m_modifiers;
520 o->m_modificationType = m_modificationType;
521 o->m_text = m_text;
522 o->m_length = m_length;
523 o->m_linesAdded = m_linesAdded;
524 o->m_line = m_line;
525 o->m_foldLevelNow = m_foldLevelNow;
526 o->m_foldLevelPrev = m_foldLevelPrev;
527
528 o->m_margin = m_margin;
529
530 o->m_message = m_message;
531 o->m_wParam = m_wParam;
532 o->m_lParam = m_lParam;
533
534
535
536 }
537
538 //----------------------------------------------------------------------
539 //----------------------------------------------------------------------
540