]> git.saurik.com Git - wxWidgets.git/blob - src/stc/stc.cpp.in
Add wxAnyScrollHelperBase to reduce code duplication in wxVarScrollHelperBase.
[wxWidgets.git] / src / stc / stc.cpp.in
1 ////////////////////////////////////////////////////////////////////////////
2 // Name: stc.cpp
3 // Purpose: A wxWidgets 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 // Copyright: (c) 2000 by Total Control Software
14 // Licence: wxWindows licence
15 /////////////////////////////////////////////////////////////////////////////
16
17 /*
18 IMPORTANT: src/stc/stc.cpp is generated by src/stc/gen_iface.py from
19 src/stc/stc.cpp.in, don't edit stc.cpp file as your changes will be
20 lost after the next regeneration, edit stc.cpp.in and rerun the
21 gen_iface.py script instead!
22
23 Parts of this file generated by the script are found in between
24 the special "{{{" and "}}}" markers, the rest of it is copied
25 verbatim from src.h.in.
26 */
27
28 // For compilers that support precompilation, includes "wx.h".
29 #include "wx/wxprec.h"
30
31 #ifdef __BORLANDC__
32 #pragma hdrstop
33 #endif
34
35 #if wxUSE_STC
36
37 #include "wx/stc/stc.h"
38 #include "wx/stc/private.h"
39
40 #ifndef WX_PRECOMP
41 #include "wx/wx.h"
42 #endif // WX_PRECOMP
43
44 #include <ctype.h>
45
46 #include "wx/tokenzr.h"
47 #include "wx/mstream.h"
48 #include "wx/image.h"
49 #if wxUSE_FFILE
50 #include "wx/ffile.h"
51 #elif wxUSE_FILE
52 #include "wx/file.h"
53 #endif
54
55 #ifdef __WXGTK__
56 #include "wx/dcbuffer.h"
57 #endif
58
59 #include "ScintillaWX.h"
60
61 //----------------------------------------------------------------------
62
63 const char wxSTCNameStr[] = "stcwindow";
64
65 #ifdef MAKELONG
66 #undef MAKELONG
67 #endif
68
69 #define MAKELONG(a, b) ((a) | ((b) << 16))
70
71
72 static long wxColourAsLong(const wxColour& co) {
73 return (((long)co.Blue() << 16) |
74 ((long)co.Green() << 8) |
75 ((long)co.Red()));
76 }
77
78 static wxColour wxColourFromLong(long c) {
79 wxColour clr;
80 clr.Set((unsigned char)(c & 0xff),
81 (unsigned char)((c >> 8) & 0xff),
82 (unsigned char)((c >> 16) & 0xff));
83 return clr;
84 }
85
86
87 static wxColour wxColourFromSpec(const wxString& spec) {
88 // spec should be a colour name or "#RRGGBB"
89 if (spec.GetChar(0) == wxT('#')) {
90
91 long red, green, blue;
92 red = green = blue = 0;
93 spec.Mid(1,2).ToLong(&red, 16);
94 spec.Mid(3,2).ToLong(&green, 16);
95 spec.Mid(5,2).ToLong(&blue, 16);
96 return wxColour((unsigned char)red,
97 (unsigned char)green,
98 (unsigned char)blue);
99 }
100 else
101 return wxColour(spec);
102 }
103
104 //----------------------------------------------------------------------
105
106 wxDEFINE_EVENT( wxEVT_STC_CHANGE, wxStyledTextEvent );
107 wxDEFINE_EVENT( wxEVT_STC_STYLENEEDED, wxStyledTextEvent );
108 wxDEFINE_EVENT( wxEVT_STC_CHARADDED, wxStyledTextEvent );
109 wxDEFINE_EVENT( wxEVT_STC_SAVEPOINTREACHED, wxStyledTextEvent );
110 wxDEFINE_EVENT( wxEVT_STC_SAVEPOINTLEFT, wxStyledTextEvent );
111 wxDEFINE_EVENT( wxEVT_STC_ROMODIFYATTEMPT, wxStyledTextEvent );
112 wxDEFINE_EVENT( wxEVT_STC_KEY, wxStyledTextEvent );
113 wxDEFINE_EVENT( wxEVT_STC_DOUBLECLICK, wxStyledTextEvent );
114 wxDEFINE_EVENT( wxEVT_STC_UPDATEUI, wxStyledTextEvent );
115 wxDEFINE_EVENT( wxEVT_STC_MODIFIED, wxStyledTextEvent );
116 wxDEFINE_EVENT( wxEVT_STC_MACRORECORD, wxStyledTextEvent );
117 wxDEFINE_EVENT( wxEVT_STC_MARGINCLICK, wxStyledTextEvent );
118 wxDEFINE_EVENT( wxEVT_STC_NEEDSHOWN, wxStyledTextEvent );
119 wxDEFINE_EVENT( wxEVT_STC_PAINTED, wxStyledTextEvent );
120 wxDEFINE_EVENT( wxEVT_STC_USERLISTSELECTION, wxStyledTextEvent );
121 wxDEFINE_EVENT( wxEVT_STC_URIDROPPED, wxStyledTextEvent );
122 wxDEFINE_EVENT( wxEVT_STC_DWELLSTART, wxStyledTextEvent );
123 wxDEFINE_EVENT( wxEVT_STC_DWELLEND, wxStyledTextEvent );
124 wxDEFINE_EVENT( wxEVT_STC_START_DRAG, wxStyledTextEvent );
125 wxDEFINE_EVENT( wxEVT_STC_DRAG_OVER, wxStyledTextEvent );
126 wxDEFINE_EVENT( wxEVT_STC_DO_DROP, wxStyledTextEvent );
127 wxDEFINE_EVENT( wxEVT_STC_ZOOM, wxStyledTextEvent );
128 wxDEFINE_EVENT( wxEVT_STC_HOTSPOT_CLICK, wxStyledTextEvent );
129 wxDEFINE_EVENT( wxEVT_STC_HOTSPOT_DCLICK, wxStyledTextEvent );
130 wxDEFINE_EVENT( wxEVT_STC_CALLTIP_CLICK, wxStyledTextEvent );
131 wxDEFINE_EVENT( wxEVT_STC_AUTOCOMP_SELECTION, wxStyledTextEvent );
132 wxDEFINE_EVENT( wxEVT_STC_INDICATOR_CLICK, wxStyledTextEvent );
133 wxDEFINE_EVENT( wxEVT_STC_INDICATOR_RELEASE, wxStyledTextEvent );
134 wxDEFINE_EVENT( wxEVT_STC_AUTOCOMP_CANCELLED, wxStyledTextEvent );
135 wxDEFINE_EVENT( wxEVT_STC_AUTOCOMP_CHAR_DELETED, wxStyledTextEvent );
136 wxDEFINE_EVENT( wxEVT_STC_HOTSPOT_RELEASE_CLICK, wxStyledTextEvent );
137
138
139
140 BEGIN_EVENT_TABLE(wxStyledTextCtrl, wxControl)
141 EVT_PAINT (wxStyledTextCtrl::OnPaint)
142 EVT_SCROLLWIN (wxStyledTextCtrl::OnScrollWin)
143 EVT_SCROLL (wxStyledTextCtrl::OnScroll)
144 EVT_SIZE (wxStyledTextCtrl::OnSize)
145 EVT_LEFT_DOWN (wxStyledTextCtrl::OnMouseLeftDown)
146 // Let Scintilla see the double click as a second click
147 EVT_LEFT_DCLICK (wxStyledTextCtrl::OnMouseLeftDown)
148 EVT_MOTION (wxStyledTextCtrl::OnMouseMove)
149 EVT_LEFT_UP (wxStyledTextCtrl::OnMouseLeftUp)
150 #if defined(__WXGTK__) || defined(__WXMAC__)
151 EVT_RIGHT_UP (wxStyledTextCtrl::OnMouseRightUp)
152 #else
153 EVT_CONTEXT_MENU (wxStyledTextCtrl::OnContextMenu)
154 #endif
155 EVT_MOUSEWHEEL (wxStyledTextCtrl::OnMouseWheel)
156 EVT_MIDDLE_UP (wxStyledTextCtrl::OnMouseMiddleUp)
157 EVT_CHAR (wxStyledTextCtrl::OnChar)
158 EVT_KEY_DOWN (wxStyledTextCtrl::OnKeyDown)
159 EVT_KILL_FOCUS (wxStyledTextCtrl::OnLoseFocus)
160 EVT_SET_FOCUS (wxStyledTextCtrl::OnGainFocus)
161 EVT_SYS_COLOUR_CHANGED (wxStyledTextCtrl::OnSysColourChanged)
162 EVT_ERASE_BACKGROUND (wxStyledTextCtrl::OnEraseBackground)
163 EVT_MENU_RANGE (10, 16, wxStyledTextCtrl::OnMenu)
164 EVT_LISTBOX_DCLICK (wxID_ANY, wxStyledTextCtrl::OnListBox)
165 END_EVENT_TABLE()
166
167
168 IMPLEMENT_CLASS(wxStyledTextCtrl, wxControl)
169 IMPLEMENT_DYNAMIC_CLASS(wxStyledTextEvent, wxCommandEvent)
170
171 #ifdef LINK_LEXERS
172 // forces the linking of the lexer modules
173 int Scintilla_LinkLexers();
174 #endif
175
176 //----------------------------------------------------------------------
177 // Constructor and Destructor
178
179 wxStyledTextCtrl::wxStyledTextCtrl(wxWindow *parent,
180 wxWindowID id,
181 const wxPoint& pos,
182 const wxSize& size,
183 long style,
184 const wxString& name)
185 {
186 m_swx = NULL;
187 Create(parent, id, pos, size, style, name);
188 }
189
190
191 bool wxStyledTextCtrl::Create(wxWindow *parent,
192 wxWindowID id,
193 const wxPoint& pos,
194 const wxSize& size,
195 long style,
196 const wxString& name)
197 {
198 style |= wxVSCROLL | wxHSCROLL;
199 if (!wxControl::Create(parent, id, pos, size,
200 style | wxWANTS_CHARS | wxCLIP_CHILDREN,
201 wxDefaultValidator, name))
202 return false;
203
204 #ifdef LINK_LEXERS
205 Scintilla_LinkLexers();
206 #endif
207 m_swx = new ScintillaWX(this);
208 m_stopWatch.Start();
209 m_lastKeyDownConsumed = false;
210 m_vScrollBar = NULL;
211 m_hScrollBar = NULL;
212 #if wxUSE_UNICODE
213 // Put Scintilla into unicode (UTF-8) mode
214 SetCodePage(wxSTC_CP_UTF8);
215 #endif
216
217 SetInitialSize(size);
218
219 // Reduces flicker on GTK+/X11
220 SetBackgroundStyle(wxBG_STYLE_PAINT);
221
222 // Make sure it can take the focus
223 SetCanFocus(true);
224
225 return true;
226 }
227
228
229 wxStyledTextCtrl::~wxStyledTextCtrl() {
230 delete m_swx;
231 }
232
233
234 //----------------------------------------------------------------------
235
236 wxIntPtr wxStyledTextCtrl::SendMsg(int msg, wxUIntPtr wp, wxIntPtr lp) const
237 {
238 return m_swx->WndProc(msg, wp, lp);
239 }
240
241 //----------------------------------------------------------------------
242
243 // Set the vertical scrollbar to use instead of the ont that's built-in.
244 void wxStyledTextCtrl::SetVScrollBar(wxScrollBar* bar) {
245 m_vScrollBar = bar;
246 if (bar != NULL) {
247 // ensure that the built-in scrollbar is not visible
248 SetScrollbar(wxVERTICAL, 0, 0, 0);
249 }
250 }
251
252
253 // Set the horizontal scrollbar to use instead of the ont that's built-in.
254 void wxStyledTextCtrl::SetHScrollBar(wxScrollBar* bar) {
255 m_hScrollBar = bar;
256 if (bar != NULL) {
257 // ensure that the built-in scrollbar is not visible
258 SetScrollbar(wxHORIZONTAL, 0, 0, 0);
259 }
260 }
261
262 //----------------------------------------------------------------------
263 // Generated methods implementation section {{{
264
265 %(METHOD_IMPS)s
266
267 //}}}
268 //----------------------------------------------------------------------
269
270
271 // Returns the line number of the line with the caret.
272 int wxStyledTextCtrl::GetCurrentLine() {
273 int line = LineFromPosition(GetCurrentPos());
274 return line;
275 }
276
277
278 // Extract style settings from a spec-string which is composed of one or
279 // more of the following comma separated elements:
280 //
281 // bold turns on bold
282 // italic turns on italics
283 // fore:[name or #RRGGBB] sets the foreground colour
284 // back:[name or #RRGGBB] sets the background colour
285 // face:[facename] sets the font face name to use
286 // size:[num] sets the font size in points
287 // eol turns on eol filling
288 // underline turns on underlining
289 //
290 void wxStyledTextCtrl::StyleSetSpec(int styleNum, const wxString& spec) {
291
292 wxStringTokenizer tkz(spec, wxT(","));
293 while (tkz.HasMoreTokens()) {
294 wxString token = tkz.GetNextToken();
295
296 wxString option = token.BeforeFirst(':');
297 wxString val = token.AfterFirst(':');
298
299 if (option == wxT("bold"))
300 StyleSetBold(styleNum, true);
301
302 else if (option == wxT("italic"))
303 StyleSetItalic(styleNum, true);
304
305 else if (option == wxT("underline"))
306 StyleSetUnderline(styleNum, true);
307
308 else if (option == wxT("eol"))
309 StyleSetEOLFilled(styleNum, true);
310
311 else if (option == wxT("size")) {
312 long points;
313 if (val.ToLong(&points))
314 StyleSetSize(styleNum, points);
315 }
316
317 else if (option == wxT("face"))
318 StyleSetFaceName(styleNum, val);
319
320 else if (option == wxT("fore"))
321 StyleSetForeground(styleNum, wxColourFromSpec(val));
322
323 else if (option == wxT("back"))
324 StyleSetBackground(styleNum, wxColourFromSpec(val));
325 }
326 }
327
328
329 // Get the font of a style
330 wxFont wxStyledTextCtrl::StyleGetFont(int style) {
331 wxFont font;
332 font.SetPointSize(StyleGetSize(style));
333 font.SetFaceName(StyleGetFaceName(style));
334 if( StyleGetBold(style) )
335 font.SetWeight(wxFONTWEIGHT_BOLD);
336 else
337 font.SetWeight(wxFONTWEIGHT_NORMAL);
338
339 if( StyleGetItalic(style) )
340 font.SetStyle(wxFONTSTYLE_ITALIC);
341 else
342 font.SetStyle(wxFONTSTYLE_NORMAL);
343
344 return font;
345 }
346
347
348 // Set style size, face, bold, italic, and underline attributes from
349 // a wxFont's attributes.
350 void wxStyledTextCtrl::StyleSetFont(int styleNum, wxFont& font) {
351 #ifdef __WXGTK__
352 // Ensure that the native font is initialized
353 int x, y;
354 GetTextExtent(wxT("X"), &x, &y, NULL, NULL, &font);
355 #endif
356 int size = font.GetPointSize();
357 wxString faceName = font.GetFaceName();
358 bool bold = font.GetWeight() == wxBOLD;
359 bool italic = font.GetStyle() != wxNORMAL;
360 bool under = font.GetUnderlined();
361 wxFontEncoding encoding = font.GetEncoding();
362
363 StyleSetFontAttr(styleNum, size, faceName, bold, italic, under, encoding);
364 }
365
366 // Set all font style attributes at once.
367 void wxStyledTextCtrl::StyleSetFontAttr(int styleNum, int size,
368 const wxString& faceName,
369 bool bold, bool italic,
370 bool underline,
371 wxFontEncoding encoding) {
372 StyleSetSize(styleNum, size);
373 StyleSetFaceName(styleNum, faceName);
374 StyleSetBold(styleNum, bold);
375 StyleSetItalic(styleNum, italic);
376 StyleSetUnderline(styleNum, underline);
377 StyleSetFontEncoding(styleNum, encoding);
378 }
379
380
381 // Set the character set of the font in a style. Converts the Scintilla
382 // character set values to a wxFontEncoding.
383 void wxStyledTextCtrl::StyleSetCharacterSet(int style, int characterSet)
384 {
385 wxFontEncoding encoding;
386
387 // Translate the Scintilla characterSet to a wxFontEncoding
388 switch (characterSet) {
389 default:
390 case wxSTC_CHARSET_ANSI:
391 case wxSTC_CHARSET_DEFAULT:
392 encoding = wxFONTENCODING_DEFAULT;
393 break;
394
395 case wxSTC_CHARSET_BALTIC:
396 encoding = wxFONTENCODING_ISO8859_13;
397 break;
398
399 case wxSTC_CHARSET_CHINESEBIG5:
400 encoding = wxFONTENCODING_CP950;
401 break;
402
403 case wxSTC_CHARSET_EASTEUROPE:
404 encoding = wxFONTENCODING_ISO8859_2;
405 break;
406
407 case wxSTC_CHARSET_GB2312:
408 encoding = wxFONTENCODING_CP936;
409 break;
410
411 case wxSTC_CHARSET_GREEK:
412 encoding = wxFONTENCODING_ISO8859_7;
413 break;
414
415 case wxSTC_CHARSET_HANGUL:
416 encoding = wxFONTENCODING_CP949;
417 break;
418
419 case wxSTC_CHARSET_MAC:
420 encoding = wxFONTENCODING_DEFAULT;
421 break;
422
423 case wxSTC_CHARSET_OEM:
424 encoding = wxFONTENCODING_DEFAULT;
425 break;
426
427 case wxSTC_CHARSET_RUSSIAN:
428 encoding = wxFONTENCODING_KOI8;
429 break;
430
431 case wxSTC_CHARSET_SHIFTJIS:
432 encoding = wxFONTENCODING_CP932;
433 break;
434
435 case wxSTC_CHARSET_SYMBOL:
436 encoding = wxFONTENCODING_DEFAULT;
437 break;
438
439 case wxSTC_CHARSET_TURKISH:
440 encoding = wxFONTENCODING_ISO8859_9;
441 break;
442
443 case wxSTC_CHARSET_JOHAB:
444 encoding = wxFONTENCODING_DEFAULT;
445 break;
446
447 case wxSTC_CHARSET_HEBREW:
448 encoding = wxFONTENCODING_ISO8859_8;
449 break;
450
451 case wxSTC_CHARSET_ARABIC:
452 encoding = wxFONTENCODING_ISO8859_6;
453 break;
454
455 case wxSTC_CHARSET_VIETNAMESE:
456 encoding = wxFONTENCODING_DEFAULT;
457 break;
458
459 case wxSTC_CHARSET_THAI:
460 encoding = wxFONTENCODING_ISO8859_11;
461 break;
462
463 case wxSTC_CHARSET_CYRILLIC:
464 encoding = wxFONTENCODING_ISO8859_5;
465 break;
466
467 case wxSTC_CHARSET_8859_15:
468 encoding = wxFONTENCODING_ISO8859_15;;
469 break;
470 }
471
472 // We just have Scintilla track the wxFontEncoding for us. It gets used
473 // in Font::Create in PlatWX.cpp. We add one to the value so that the
474 // effective wxFONENCODING_DEFAULT == SC_SHARSET_DEFAULT and so when
475 // Scintilla internally uses SC_CHARSET_DEFAULT we will translate it back
476 // to wxFONENCODING_DEFAULT in Font::Create.
477 SendMsg(SCI_STYLESETCHARACTERSET, style, encoding+1);
478 }
479
480
481 // Set the font encoding to be used by a style.
482 void wxStyledTextCtrl::StyleSetFontEncoding(int style, wxFontEncoding encoding)
483 {
484 SendMsg(SCI_STYLESETCHARACTERSET, style, encoding+1);
485 }
486
487
488 // Perform one of the operations defined by the wxSTC_CMD_* constants.
489 void wxStyledTextCtrl::CmdKeyExecute(int cmd) {
490 SendMsg(cmd);
491 }
492
493
494 // Set the left and right margin in the edit area, measured in pixels.
495 void wxStyledTextCtrl::SetMargins(int left, int right) {
496 SetMarginLeft(left);
497 SetMarginRight(right);
498 }
499
500
501 // Retrieve the point in the window where a position is displayed.
502 wxPoint wxStyledTextCtrl::PointFromPosition(int pos) {
503 int x = SendMsg(SCI_POINTXFROMPOSITION, 0, pos);
504 int y = SendMsg(SCI_POINTYFROMPOSITION, 0, pos);
505 return wxPoint(x, y);
506 }
507
508 // Scroll enough to make the given line visible
509 void wxStyledTextCtrl::ScrollToLine(int line) {
510 m_swx->DoScrollToLine(line);
511 }
512
513
514 // Scroll enough to make the given column visible
515 void wxStyledTextCtrl::ScrollToColumn(int column) {
516 m_swx->DoScrollToColumn(column);
517 }
518
519
520 void wxStyledTextCtrl::DoSetValue(const wxString& value, int flags)
521 {
522 if ( flags & SetValue_SelectionOnly )
523 ReplaceSelection(value);
524 else
525 SetText(value);
526
527 // We don't send wxEVT_TEXT anyhow, so ignore the
528 // SetValue_SendEvent bit of the flags
529 }
530
531 bool
532 wxStyledTextCtrl::DoSaveFile(const wxString& filename, int WXUNUSED(fileType))
533 {
534 #if wxUSE_FFILE || wxUSE_FILE
535
536 #if wxUSE_FFILE
537 // Take care to use "b" to ensure that possibly non-native EOLs in the file
538 // contents are not mangled when saving it.
539 wxFFile file(filename, wxS("wb"));
540 #elif wxUSE_FILE
541 wxFile file(filename, wxFile::write);
542 #endif
543
544 if ( file.IsOpened() && file.Write(GetValue(), *wxConvCurrent) )
545 {
546 SetSavePoint();
547
548 return true;
549 }
550
551 #endif // !wxUSE_FFILE && !wxUSE_FILE
552
553 return false;
554 }
555
556 bool
557 wxStyledTextCtrl::DoLoadFile(const wxString& filename, int WXUNUSED(fileType))
558 {
559 #if wxUSE_FFILE || wxUSE_FILE
560
561 #if wxUSE_FFILE
562 // As above, we want to read the real EOLs from the file, e.g. without
563 // translating them to just LFs under Windows, so that the original CR LF
564 // are preserved when it's written back.
565 wxFFile file(filename, wxS("rb"));
566 #else
567 wxFile file(filename);
568 #endif
569
570 if ( file.IsOpened() )
571 {
572 wxString text;
573 if ( file.ReadAll(&text, wxConvAuto()) )
574 {
575 // Detect the EOL: we use just the first line because there is not
576 // much we can do if the file uses inconsistent EOLs anyhow, we'd
577 // need to ask the user about the one we should really use and we
578 // don't currently provide a way to do it.
579 //
580 // We also only check for Unix and DOS EOLs but not classic Mac
581 // CR-only one as it's obsolete by now.
582 const wxString::size_type posLF = text.find('\n');
583 if ( posLF != wxString::npos )
584 {
585 // Set EOL mode to ensure that the new lines inserted into the
586 // text use the same EOLs as the existing ones.
587 if ( posLF > 0 && text[posLF - 1] == '\r' )
588 SetEOLMode(wxSTC_EOL_CRLF);
589 else
590 SetEOLMode(wxSTC_EOL_LF);
591 }
592 //else: Use the default EOL for the current platform.
593
594 SetValue(text);
595 EmptyUndoBuffer();
596 SetSavePoint();
597
598 return true;
599 }
600 }
601 #endif // !wxUSE_FFILE && !wxUSE_FILE
602
603 return false;
604 }
605
606 // If we don't derive from wxTextAreaBase, we need to implement these methods
607 // ourselves, otherwise we already inherit them.
608 #if !wxUSE_TEXTCTRL
609
610 bool wxStyledTextCtrl::SaveFile(const wxString& filename)
611 {
612 if ( filename.empty() )
613 return false;
614
615 return DoSaveFile(filename, wxTEXT_TYPE_ANY);
616 }
617
618 bool wxStyledTextCtrl::LoadFile(const wxString& filename)
619 {
620 if ( filename.empty() )
621 return false;
622
623 return DoLoadFile(filename, wxTEXT_TYPE_ANY);
624 }
625
626 #endif // !wxUSE_TEXTCTRL
627
628 #if wxUSE_DRAG_AND_DROP
629 wxDragResult wxStyledTextCtrl::DoDragOver(wxCoord x, wxCoord y, wxDragResult def) {
630 return m_swx->DoDragOver(x, y, def);
631 }
632
633
634 bool wxStyledTextCtrl::DoDropText(long x, long y, const wxString& data) {
635 return m_swx->DoDropText(x, y, data);
636 }
637 #endif
638
639
640 void wxStyledTextCtrl::SetUseAntiAliasing(bool useAA) {
641 m_swx->SetUseAntiAliasing(useAA);
642 }
643
644 bool wxStyledTextCtrl::GetUseAntiAliasing() {
645 return m_swx->GetUseAntiAliasing();
646 }
647
648 void wxStyledTextCtrl::AnnotationClearLine(int line) {
649 SendMsg(SCI_ANNOTATIONSETTEXT, line, (sptr_t)NULL);
650 }
651
652
653
654
655 void wxStyledTextCtrl::AddTextRaw(const char* text, int length)
656 {
657 if (length == -1)
658 length = strlen(text);
659 SendMsg(SCI_ADDTEXT, length, (sptr_t)text);
660 }
661
662 void wxStyledTextCtrl::InsertTextRaw(int pos, const char* text)
663 {
664 SendMsg(SCI_INSERTTEXT, pos, (sptr_t)text);
665 }
666
667 wxCharBuffer wxStyledTextCtrl::GetCurLineRaw(int* linePos)
668 {
669 int len = LineLength(GetCurrentLine());
670 if (!len) {
671 if (linePos) *linePos = 0;
672 wxCharBuffer empty;
673 return empty;
674 }
675
676 wxCharBuffer buf(len);
677 int pos = SendMsg(SCI_GETCURLINE, len, (sptr_t)buf.data());
678 if (linePos) *linePos = pos;
679 return buf;
680 }
681
682 wxCharBuffer wxStyledTextCtrl::GetLineRaw(int line)
683 {
684 int len = LineLength(line);
685 if (!len) {
686 wxCharBuffer empty;
687 return empty;
688 }
689
690 wxCharBuffer buf(len);
691 SendMsg(SCI_GETLINE, line, (sptr_t)buf.data());
692 return buf;
693 }
694
695 wxCharBuffer wxStyledTextCtrl::GetSelectedTextRaw()
696 {
697 // Calculate the length needed first.
698 const int len = SendMsg(SCI_GETSELTEXT, 0, (sptr_t)0);
699
700 // And then really get the data.
701 wxCharBuffer buf(len);
702 SendMsg(SCI_GETSELTEXT, 0, (sptr_t)buf.data());
703 return buf;
704 }
705
706 wxCharBuffer wxStyledTextCtrl::GetTextRangeRaw(int startPos, int endPos)
707 {
708 if (endPos < startPos) {
709 int temp = startPos;
710 startPos = endPos;
711 endPos = temp;
712 }
713 int len = endPos - startPos;
714 if (!len) {
715 wxCharBuffer empty;
716 return empty;
717 }
718
719 wxCharBuffer buf(len);
720 TextRange tr;
721 tr.lpstrText = buf.data();
722 tr.chrg.cpMin = startPos;
723 tr.chrg.cpMax = endPos;
724 SendMsg(SCI_GETTEXTRANGE, 0, (sptr_t)&tr);
725 return buf;
726 }
727
728 void wxStyledTextCtrl::SetTextRaw(const char* text)
729 {
730 SendMsg(SCI_SETTEXT, 0, (sptr_t)text);
731 }
732
733 wxCharBuffer wxStyledTextCtrl::GetTextRaw()
734 {
735 int len = GetTextLength();
736 wxCharBuffer buf(len); // adds 1 for NUL automatically
737 SendMsg(SCI_GETTEXT, len + 1, (sptr_t)buf.data());
738 return buf;
739 }
740
741 void wxStyledTextCtrl::AppendTextRaw(const char* text, int length)
742 {
743 if (length == -1)
744 length = strlen(text);
745 SendMsg(SCI_APPENDTEXT, length, (sptr_t)text);
746 }
747
748
749
750
751
752 //----------------------------------------------------------------------
753 // Event handlers
754
755 void wxStyledTextCtrl::OnPaint(wxPaintEvent& WXUNUSED(evt)) {
756 #ifdef __WXGTK__
757 wxBufferedPaintDC dc(this);
758 #else
759 wxPaintDC dc(this);
760 #endif
761 m_swx->DoPaint(&dc, GetUpdateRegion().GetBox());
762 }
763
764 void wxStyledTextCtrl::OnScrollWin(wxScrollWinEvent& evt) {
765 if (evt.GetOrientation() == wxHORIZONTAL)
766 m_swx->DoHScroll(evt.GetEventType(), evt.GetPosition());
767 else
768 m_swx->DoVScroll(evt.GetEventType(), evt.GetPosition());
769 }
770
771 void wxStyledTextCtrl::OnScroll(wxScrollEvent& evt) {
772 wxScrollBar* sb = wxDynamicCast(evt.GetEventObject(), wxScrollBar);
773 if (sb) {
774 if (sb->IsVertical())
775 m_swx->DoVScroll(evt.GetEventType(), evt.GetPosition());
776 else
777 m_swx->DoHScroll(evt.GetEventType(), evt.GetPosition());
778 }
779 }
780
781 void wxStyledTextCtrl::OnSize(wxSizeEvent& WXUNUSED(evt)) {
782 if (m_swx) {
783 wxSize sz = GetClientSize();
784 m_swx->DoSize(sz.x, sz.y);
785 }
786 }
787
788 void wxStyledTextCtrl::OnMouseLeftDown(wxMouseEvent& evt) {
789 SetFocus();
790 wxPoint pt = evt.GetPosition();
791 m_swx->DoLeftButtonDown(Point(pt.x, pt.y), m_stopWatch.Time(),
792 evt.ShiftDown(), evt.ControlDown(), evt.AltDown());
793 }
794
795 void wxStyledTextCtrl::OnMouseMove(wxMouseEvent& evt) {
796 wxPoint pt = evt.GetPosition();
797 m_swx->DoLeftButtonMove(Point(pt.x, pt.y));
798 }
799
800 void wxStyledTextCtrl::OnMouseLeftUp(wxMouseEvent& evt) {
801 wxPoint pt = evt.GetPosition();
802 m_swx->DoLeftButtonUp(Point(pt.x, pt.y), m_stopWatch.Time(),
803 evt.ControlDown());
804 }
805
806
807 void wxStyledTextCtrl::OnMouseRightUp(wxMouseEvent& evt) {
808 wxPoint pt = evt.GetPosition();
809 m_swx->DoContextMenu(Point(pt.x, pt.y));
810 }
811
812
813 void wxStyledTextCtrl::OnMouseMiddleUp(wxMouseEvent& evt) {
814 wxPoint pt = evt.GetPosition();
815 m_swx->DoMiddleButtonUp(Point(pt.x, pt.y));
816 }
817
818 void wxStyledTextCtrl::OnContextMenu(wxContextMenuEvent& evt) {
819 wxPoint pt = evt.GetPosition();
820 ScreenToClient(&pt.x, &pt.y);
821 /*
822 Show context menu at event point if it's within the window,
823 or at caret location if not
824 */
825 wxHitTest ht = this->HitTest(pt);
826 if (ht != wxHT_WINDOW_INSIDE) {
827 pt = this->PointFromPosition(this->GetCurrentPos());
828 }
829 m_swx->DoContextMenu(Point(pt.x, pt.y));
830 }
831
832
833 void wxStyledTextCtrl::OnMouseWheel(wxMouseEvent& evt)
834 {
835 m_swx->DoMouseWheel(evt.GetWheelAxis(),
836 evt.GetWheelRotation(),
837 evt.GetWheelDelta(),
838 evt.GetLinesPerAction(),
839 evt.GetColumnsPerAction(),
840 evt.ControlDown(),
841 evt.IsPageScroll());
842 }
843
844
845 void wxStyledTextCtrl::OnChar(wxKeyEvent& evt) {
846 // On (some?) non-US PC keyboards the AltGr key is required to enter some
847 // common characters. It comes to us as both Alt and Ctrl down so we need
848 // to let the char through in that case, otherwise if only ctrl or only
849 // alt let's skip it.
850 bool ctrl = evt.ControlDown();
851 #ifdef __WXMAC__
852 // On the Mac the Alt key is just a modifier key (like Shift) so we need
853 // to allow the char events to be processed when Alt is pressed.
854 // TODO: Should we check MetaDown instead in this case?
855 bool alt = false;
856 #else
857 bool alt = evt.AltDown();
858 #endif
859 bool skip = ((ctrl || alt) && ! (ctrl && alt));
860
861 #if wxUSE_UNICODE
862 // apparently if we don't do this, Unicode keys pressed after non-char
863 // ASCII ones (e.g. Enter, Tab) are not taken into account (patch 1615989)
864 if (m_lastKeyDownConsumed && evt.GetUnicodeKey() > 255)
865 m_lastKeyDownConsumed = false;
866 #endif
867
868 if (!m_lastKeyDownConsumed && !skip) {
869 #if wxUSE_UNICODE
870 int key = evt.GetUnicodeKey();
871 bool keyOk = true;
872
873 // if the unicode key code is not really a unicode character (it may
874 // be a function key or etc., the platforms appear to always give us a
875 // small value in this case) then fallback to the ascii key code but
876 // don't do anything for function keys or etc.
877 if (key <= 127) {
878 key = evt.GetKeyCode();
879 keyOk = (key <= 127);
880 }
881 if (keyOk) {
882 m_swx->DoAddChar(key);
883 return;
884 }
885 #else
886 int key = evt.GetKeyCode();
887 if (key <= WXK_START || key > WXK_COMMAND) {
888 m_swx->DoAddChar(key);
889 return;
890 }
891 #endif
892 }
893
894 evt.Skip();
895 }
896
897
898 void wxStyledTextCtrl::OnKeyDown(wxKeyEvent& evt) {
899 int processed = m_swx->DoKeyDown(evt, &m_lastKeyDownConsumed);
900 if (!processed && !m_lastKeyDownConsumed)
901 evt.Skip();
902 }
903
904
905 void wxStyledTextCtrl::OnLoseFocus(wxFocusEvent& evt) {
906 m_swx->DoLoseFocus();
907 evt.Skip();
908 }
909
910
911 void wxStyledTextCtrl::OnGainFocus(wxFocusEvent& evt) {
912 m_swx->DoGainFocus();
913 evt.Skip();
914 }
915
916
917 void wxStyledTextCtrl::OnSysColourChanged(wxSysColourChangedEvent& WXUNUSED(evt)) {
918 m_swx->DoSysColourChange();
919 }
920
921
922 void wxStyledTextCtrl::OnEraseBackground(wxEraseEvent& WXUNUSED(evt)) {
923 // do nothing to help avoid flashing
924 }
925
926
927
928 void wxStyledTextCtrl::OnMenu(wxCommandEvent& evt) {
929 m_swx->DoCommand(evt.GetId());
930 }
931
932
933 void wxStyledTextCtrl::OnListBox(wxCommandEvent& WXUNUSED(evt)) {
934 m_swx->DoOnListBox();
935 }
936
937
938 void wxStyledTextCtrl::OnIdle(wxIdleEvent& evt) {
939 m_swx->DoOnIdle(evt);
940 }
941
942
943 wxSize wxStyledTextCtrl::DoGetBestSize() const
944 {
945 // What would be the best size for a wxSTC?
946 // Just give a reasonable minimum until something else can be figured out.
947 return wxSize(200,100);
948 }
949
950
951 //----------------------------------------------------------------------
952 // Turn notifications from Scintilla into events
953
954
955 void wxStyledTextCtrl::NotifyChange() {
956 wxStyledTextEvent evt(wxEVT_STC_CHANGE, GetId());
957 evt.SetEventObject(this);
958 GetEventHandler()->ProcessEvent(evt);
959 }
960
961
962 static void SetEventText(wxStyledTextEvent& evt, const char* text,
963 size_t length) {
964 if(!text) return;
965
966 evt.SetText(stc2wx(text, length));
967 }
968
969
970 void wxStyledTextCtrl::NotifyParent(SCNotification* _scn) {
971 SCNotification& scn = *_scn;
972 wxStyledTextEvent evt(0, GetId());
973
974 evt.SetEventObject(this);
975 evt.SetPosition(scn.position);
976 evt.SetKey(scn.ch);
977 evt.SetModifiers(scn.modifiers);
978
979 switch (scn.nmhdr.code) {
980 case SCN_STYLENEEDED:
981 evt.SetEventType(wxEVT_STC_STYLENEEDED);
982 break;
983
984 case SCN_CHARADDED:
985 evt.SetEventType(wxEVT_STC_CHARADDED);
986 break;
987
988 case SCN_SAVEPOINTREACHED:
989 evt.SetEventType(wxEVT_STC_SAVEPOINTREACHED);
990 break;
991
992 case SCN_SAVEPOINTLEFT:
993 evt.SetEventType(wxEVT_STC_SAVEPOINTLEFT);
994 break;
995
996 case SCN_MODIFYATTEMPTRO:
997 evt.SetEventType(wxEVT_STC_ROMODIFYATTEMPT);
998 break;
999
1000 case SCN_KEY:
1001 evt.SetEventType(wxEVT_STC_KEY);
1002 break;
1003
1004 case SCN_DOUBLECLICK:
1005 evt.SetEventType(wxEVT_STC_DOUBLECLICK);
1006 evt.SetLine(scn.line);
1007 break;
1008
1009 case SCN_UPDATEUI:
1010 evt.SetEventType(wxEVT_STC_UPDATEUI);
1011 evt.SetUpdated(scn.updated);
1012 break;
1013
1014 case SCN_MODIFIED:
1015 evt.SetEventType(wxEVT_STC_MODIFIED);
1016 evt.SetModificationType(scn.modificationType);
1017 SetEventText(evt, scn.text, scn.length);
1018 evt.SetLength(scn.length);
1019 evt.SetLinesAdded(scn.linesAdded);
1020 evt.SetLine(scn.line);
1021 evt.SetFoldLevelNow(scn.foldLevelNow);
1022 evt.SetFoldLevelPrev(scn.foldLevelPrev);
1023 evt.SetToken(scn.token);
1024 evt.SetAnnotationLinesAdded(scn.annotationLinesAdded);
1025 break;
1026
1027 case SCN_MACRORECORD:
1028 evt.SetEventType(wxEVT_STC_MACRORECORD);
1029 evt.SetMessage(scn.message);
1030 evt.SetWParam(scn.wParam);
1031 evt.SetLParam(scn.lParam);
1032 break;
1033
1034 case SCN_MARGINCLICK:
1035 evt.SetEventType(wxEVT_STC_MARGINCLICK);
1036 evt.SetMargin(scn.margin);
1037 break;
1038
1039 case SCN_NEEDSHOWN:
1040 evt.SetEventType(wxEVT_STC_NEEDSHOWN);
1041 evt.SetLength(scn.length);
1042 break;
1043
1044 case SCN_PAINTED:
1045 evt.SetEventType(wxEVT_STC_PAINTED);
1046 break;
1047
1048 case SCN_AUTOCSELECTION:
1049 evt.SetEventType(wxEVT_STC_AUTOCOMP_SELECTION);
1050 evt.SetListType(scn.listType);
1051 SetEventText(evt, scn.text, strlen(scn.text));
1052 evt.SetPosition(scn.lParam);
1053 break;
1054
1055 case SCN_USERLISTSELECTION:
1056 evt.SetEventType(wxEVT_STC_USERLISTSELECTION);
1057 evt.SetListType(scn.listType);
1058 SetEventText(evt, scn.text, strlen(scn.text));
1059 evt.SetPosition(scn.lParam);
1060 break;
1061
1062 case SCN_URIDROPPED:
1063 evt.SetEventType(wxEVT_STC_URIDROPPED);
1064 SetEventText(evt, scn.text, strlen(scn.text));
1065 break;
1066
1067 case SCN_DWELLSTART:
1068 evt.SetEventType(wxEVT_STC_DWELLSTART);
1069 evt.SetX(scn.x);
1070 evt.SetY(scn.y);
1071 break;
1072
1073 case SCN_DWELLEND:
1074 evt.SetEventType(wxEVT_STC_DWELLEND);
1075 evt.SetX(scn.x);
1076 evt.SetY(scn.y);
1077 break;
1078
1079 case SCN_ZOOM:
1080 evt.SetEventType(wxEVT_STC_ZOOM);
1081 break;
1082
1083 case SCN_HOTSPOTCLICK:
1084 evt.SetEventType(wxEVT_STC_HOTSPOT_CLICK);
1085 break;
1086
1087 case SCN_HOTSPOTDOUBLECLICK:
1088 evt.SetEventType(wxEVT_STC_HOTSPOT_DCLICK);
1089 break;
1090
1091 case SCN_CALLTIPCLICK:
1092 evt.SetEventType(wxEVT_STC_CALLTIP_CLICK);
1093 break;
1094
1095 case SCN_INDICATORCLICK:
1096 evt.SetEventType(wxEVT_STC_INDICATOR_CLICK);
1097 break;
1098
1099 case SCN_INDICATORRELEASE:
1100 evt.SetEventType(wxEVT_STC_INDICATOR_RELEASE);
1101 break;
1102
1103 case SCN_AUTOCCANCELLED:
1104 evt.SetEventType(wxEVT_STC_AUTOCOMP_CANCELLED);
1105 break;
1106
1107 case SCN_AUTOCCHARDELETED:
1108 evt.SetEventType(wxEVT_STC_AUTOCOMP_CHAR_DELETED);
1109 break;
1110
1111 case SCN_HOTSPOTRELEASECLICK:
1112 evt.SetEventType(wxEVT_STC_HOTSPOT_RELEASE_CLICK);
1113 break;
1114
1115 default:
1116 return;
1117 }
1118
1119 GetEventHandler()->ProcessEvent(evt);
1120 }
1121
1122
1123 //----------------------------------------------------------------------
1124 //----------------------------------------------------------------------
1125 //----------------------------------------------------------------------
1126
1127 wxStyledTextEvent::wxStyledTextEvent(wxEventType commandType, int id)
1128 : wxCommandEvent(commandType, id)
1129 {
1130 m_position = 0;
1131 m_key = 0;
1132 m_modifiers = 0;
1133 m_modificationType = 0;
1134 m_length = 0;
1135 m_linesAdded = 0;
1136 m_line = 0;
1137 m_foldLevelNow = 0;
1138 m_foldLevelPrev = 0;
1139 m_margin = 0;
1140 m_message = 0;
1141 m_wParam = 0;
1142 m_lParam = 0;
1143 m_listType = 0;
1144 m_x = 0;
1145 m_y = 0;
1146 m_token = 0;
1147 m_annotationLinesAdded = 0;
1148 m_updated = 0;
1149
1150 #if wxUSE_DRAG_AND_DROP
1151 m_dragFlags = wxDrag_CopyOnly;
1152 m_dragResult = wxDragNone;
1153 #endif
1154 }
1155
1156 bool wxStyledTextEvent::GetShift() const { return (m_modifiers & SCI_SHIFT) != 0; }
1157 bool wxStyledTextEvent::GetControl() const { return (m_modifiers & SCI_CTRL) != 0; }
1158 bool wxStyledTextEvent::GetAlt() const { return (m_modifiers & SCI_ALT) != 0; }
1159
1160
1161 wxStyledTextEvent::wxStyledTextEvent(const wxStyledTextEvent& event):
1162 wxCommandEvent(event)
1163 {
1164 m_position = event.m_position;
1165 m_key = event.m_key;
1166 m_modifiers = event.m_modifiers;
1167 m_modificationType = event.m_modificationType;
1168 m_text = event.m_text;
1169 m_length = event.m_length;
1170 m_linesAdded = event.m_linesAdded;
1171 m_line = event.m_line;
1172 m_foldLevelNow = event.m_foldLevelNow;
1173 m_foldLevelPrev = event.m_foldLevelPrev;
1174
1175 m_margin = event.m_margin;
1176
1177 m_message = event.m_message;
1178 m_wParam = event.m_wParam;
1179 m_lParam = event.m_lParam;
1180
1181 m_listType = event.m_listType;
1182 m_x = event.m_x;
1183 m_y = event.m_y;
1184
1185 m_token = event.m_token;
1186 m_annotationLinesAdded = event.m_annotationLinesAdded;
1187 m_updated = event.m_updated;
1188
1189 #if wxUSE_DRAG_AND_DROP
1190 m_dragText = event.m_dragText;
1191 m_dragFlags = event.m_dragFlags;
1192 m_dragResult = event.m_dragResult;
1193 #endif
1194 }
1195
1196 //----------------------------------------------------------------------
1197 //----------------------------------------------------------------------
1198
1199 /*static*/ wxVersionInfo wxStyledTextCtrl::GetLibraryVersionInfo()
1200 {
1201 return wxVersionInfo("Scintilla", 3, 21, 0, "Scintilla 3.21");
1202 }
1203
1204 #endif // wxUSE_STC