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