Fix harmless warning about NULL in wxStyledTextCtrl code.
[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_COMMAND_TEXT_UPDATED 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, *wxConvCurrent) )
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.GetWheelRotation(),
837 evt.GetWheelDelta(),
838 evt.GetLinesPerAction(),
839 evt.ControlDown(),
840 evt.IsPageScroll());
841 }
842
843
844 void wxStyledTextCtrl::OnChar(wxKeyEvent& evt) {
845 // On (some?) non-US PC keyboards the AltGr key is required to enter some
846 // common characters. It comes to us as both Alt and Ctrl down so we need
847 // to let the char through in that case, otherwise if only ctrl or only
848 // alt let's skip it.
849 bool ctrl = evt.ControlDown();
850 #ifdef __WXMAC__
851 // On the Mac the Alt key is just a modifier key (like Shift) so we need
852 // to allow the char events to be processed when Alt is pressed.
853 // TODO: Should we check MetaDown instead in this case?
854 bool alt = false;
855 #else
856 bool alt = evt.AltDown();
857 #endif
858 bool skip = ((ctrl || alt) && ! (ctrl && alt));
859
860 #if wxUSE_UNICODE
861 // apparently if we don't do this, Unicode keys pressed after non-char
862 // ASCII ones (e.g. Enter, Tab) are not taken into account (patch 1615989)
863 if (m_lastKeyDownConsumed && evt.GetUnicodeKey() > 255)
864 m_lastKeyDownConsumed = false;
865 #endif
866
867 if (!m_lastKeyDownConsumed && !skip) {
868 #if wxUSE_UNICODE
869 int key = evt.GetUnicodeKey();
870 bool keyOk = true;
871
872 // if the unicode key code is not really a unicode character (it may
873 // be a function key or etc., the platforms appear to always give us a
874 // small value in this case) then fallback to the ascii key code but
875 // don't do anything for function keys or etc.
876 if (key <= 127) {
877 key = evt.GetKeyCode();
878 keyOk = (key <= 127);
879 }
880 if (keyOk) {
881 m_swx->DoAddChar(key);
882 return;
883 }
884 #else
885 int key = evt.GetKeyCode();
886 if (key <= WXK_START || key > WXK_COMMAND) {
887 m_swx->DoAddChar(key);
888 return;
889 }
890 #endif
891 }
892
893 evt.Skip();
894 }
895
896
897 void wxStyledTextCtrl::OnKeyDown(wxKeyEvent& evt) {
898 int processed = m_swx->DoKeyDown(evt, &m_lastKeyDownConsumed);
899 if (!processed && !m_lastKeyDownConsumed)
900 evt.Skip();
901 }
902
903
904 void wxStyledTextCtrl::OnLoseFocus(wxFocusEvent& evt) {
905 m_swx->DoLoseFocus();
906 evt.Skip();
907 }
908
909
910 void wxStyledTextCtrl::OnGainFocus(wxFocusEvent& evt) {
911 m_swx->DoGainFocus();
912 evt.Skip();
913 }
914
915
916 void wxStyledTextCtrl::OnSysColourChanged(wxSysColourChangedEvent& WXUNUSED(evt)) {
917 m_swx->DoSysColourChange();
918 }
919
920
921 void wxStyledTextCtrl::OnEraseBackground(wxEraseEvent& WXUNUSED(evt)) {
922 // do nothing to help avoid flashing
923 }
924
925
926
927 void wxStyledTextCtrl::OnMenu(wxCommandEvent& evt) {
928 m_swx->DoCommand(evt.GetId());
929 }
930
931
932 void wxStyledTextCtrl::OnListBox(wxCommandEvent& WXUNUSED(evt)) {
933 m_swx->DoOnListBox();
934 }
935
936
937 void wxStyledTextCtrl::OnIdle(wxIdleEvent& evt) {
938 m_swx->DoOnIdle(evt);
939 }
940
941
942 wxSize wxStyledTextCtrl::DoGetBestSize() const
943 {
944 // What would be the best size for a wxSTC?
945 // Just give a reasonable minimum until something else can be figured out.
946 return wxSize(200,100);
947 }
948
949
950 //----------------------------------------------------------------------
951 // Turn notifications from Scintilla into events
952
953
954 void wxStyledTextCtrl::NotifyChange() {
955 wxStyledTextEvent evt(wxEVT_STC_CHANGE, GetId());
956 evt.SetEventObject(this);
957 GetEventHandler()->ProcessEvent(evt);
958 }
959
960
961 static void SetEventText(wxStyledTextEvent& evt, const char* text,
962 size_t length) {
963 if(!text) return;
964
965 evt.SetText(stc2wx(text, length));
966 }
967
968
969 void wxStyledTextCtrl::NotifyParent(SCNotification* _scn) {
970 SCNotification& scn = *_scn;
971 wxStyledTextEvent evt(0, GetId());
972
973 evt.SetEventObject(this);
974 evt.SetPosition(scn.position);
975 evt.SetKey(scn.ch);
976 evt.SetModifiers(scn.modifiers);
977
978 switch (scn.nmhdr.code) {
979 case SCN_STYLENEEDED:
980 evt.SetEventType(wxEVT_STC_STYLENEEDED);
981 break;
982
983 case SCN_CHARADDED:
984 evt.SetEventType(wxEVT_STC_CHARADDED);
985 break;
986
987 case SCN_SAVEPOINTREACHED:
988 evt.SetEventType(wxEVT_STC_SAVEPOINTREACHED);
989 break;
990
991 case SCN_SAVEPOINTLEFT:
992 evt.SetEventType(wxEVT_STC_SAVEPOINTLEFT);
993 break;
994
995 case SCN_MODIFYATTEMPTRO:
996 evt.SetEventType(wxEVT_STC_ROMODIFYATTEMPT);
997 break;
998
999 case SCN_KEY:
1000 evt.SetEventType(wxEVT_STC_KEY);
1001 break;
1002
1003 case SCN_DOUBLECLICK:
1004 evt.SetEventType(wxEVT_STC_DOUBLECLICK);
1005 evt.SetLine(scn.line);
1006 break;
1007
1008 case SCN_UPDATEUI:
1009 evt.SetEventType(wxEVT_STC_UPDATEUI);
1010 evt.SetUpdated(scn.updated);
1011 break;
1012
1013 case SCN_MODIFIED:
1014 evt.SetEventType(wxEVT_STC_MODIFIED);
1015 evt.SetModificationType(scn.modificationType);
1016 SetEventText(evt, scn.text, scn.length);
1017 evt.SetLength(scn.length);
1018 evt.SetLinesAdded(scn.linesAdded);
1019 evt.SetLine(scn.line);
1020 evt.SetFoldLevelNow(scn.foldLevelNow);
1021 evt.SetFoldLevelPrev(scn.foldLevelPrev);
1022 evt.SetToken(scn.token);
1023 evt.SetAnnotationLinesAdded(scn.annotationLinesAdded);
1024 break;
1025
1026 case SCN_MACRORECORD:
1027 evt.SetEventType(wxEVT_STC_MACRORECORD);
1028 evt.SetMessage(scn.message);
1029 evt.SetWParam(scn.wParam);
1030 evt.SetLParam(scn.lParam);
1031 break;
1032
1033 case SCN_MARGINCLICK:
1034 evt.SetEventType(wxEVT_STC_MARGINCLICK);
1035 evt.SetMargin(scn.margin);
1036 break;
1037
1038 case SCN_NEEDSHOWN:
1039 evt.SetEventType(wxEVT_STC_NEEDSHOWN);
1040 evt.SetLength(scn.length);
1041 break;
1042
1043 case SCN_PAINTED:
1044 evt.SetEventType(wxEVT_STC_PAINTED);
1045 break;
1046
1047 case SCN_AUTOCSELECTION:
1048 evt.SetEventType(wxEVT_STC_AUTOCOMP_SELECTION);
1049 evt.SetListType(scn.listType);
1050 SetEventText(evt, scn.text, strlen(scn.text));
1051 evt.SetPosition(scn.lParam);
1052 break;
1053
1054 case SCN_USERLISTSELECTION:
1055 evt.SetEventType(wxEVT_STC_USERLISTSELECTION);
1056 evt.SetListType(scn.listType);
1057 SetEventText(evt, scn.text, strlen(scn.text));
1058 evt.SetPosition(scn.lParam);
1059 break;
1060
1061 case SCN_URIDROPPED:
1062 evt.SetEventType(wxEVT_STC_URIDROPPED);
1063 SetEventText(evt, scn.text, strlen(scn.text));
1064 break;
1065
1066 case SCN_DWELLSTART:
1067 evt.SetEventType(wxEVT_STC_DWELLSTART);
1068 evt.SetX(scn.x);
1069 evt.SetY(scn.y);
1070 break;
1071
1072 case SCN_DWELLEND:
1073 evt.SetEventType(wxEVT_STC_DWELLEND);
1074 evt.SetX(scn.x);
1075 evt.SetY(scn.y);
1076 break;
1077
1078 case SCN_ZOOM:
1079 evt.SetEventType(wxEVT_STC_ZOOM);
1080 break;
1081
1082 case SCN_HOTSPOTCLICK:
1083 evt.SetEventType(wxEVT_STC_HOTSPOT_CLICK);
1084 break;
1085
1086 case SCN_HOTSPOTDOUBLECLICK:
1087 evt.SetEventType(wxEVT_STC_HOTSPOT_DCLICK);
1088 break;
1089
1090 case SCN_CALLTIPCLICK:
1091 evt.SetEventType(wxEVT_STC_CALLTIP_CLICK);
1092 break;
1093
1094 case SCN_INDICATORCLICK:
1095 evt.SetEventType(wxEVT_STC_INDICATOR_CLICK);
1096 break;
1097
1098 case SCN_INDICATORRELEASE:
1099 evt.SetEventType(wxEVT_STC_INDICATOR_RELEASE);
1100 break;
1101
1102 case SCN_AUTOCCANCELLED:
1103 evt.SetEventType(wxEVT_STC_AUTOCOMP_CANCELLED);
1104 break;
1105
1106 case SCN_AUTOCCHARDELETED:
1107 evt.SetEventType(wxEVT_STC_AUTOCOMP_CHAR_DELETED);
1108 break;
1109
1110 case SCN_HOTSPOTRELEASECLICK:
1111 evt.SetEventType(wxEVT_STC_HOTSPOT_RELEASE_CLICK);
1112 break;
1113
1114 default:
1115 return;
1116 }
1117
1118 GetEventHandler()->ProcessEvent(evt);
1119 }
1120
1121
1122 //----------------------------------------------------------------------
1123 //----------------------------------------------------------------------
1124 //----------------------------------------------------------------------
1125
1126 wxStyledTextEvent::wxStyledTextEvent(wxEventType commandType, int id)
1127 : wxCommandEvent(commandType, id)
1128 {
1129 m_position = 0;
1130 m_key = 0;
1131 m_modifiers = 0;
1132 m_modificationType = 0;
1133 m_length = 0;
1134 m_linesAdded = 0;
1135 m_line = 0;
1136 m_foldLevelNow = 0;
1137 m_foldLevelPrev = 0;
1138 m_margin = 0;
1139 m_message = 0;
1140 m_wParam = 0;
1141 m_lParam = 0;
1142 m_listType = 0;
1143 m_x = 0;
1144 m_y = 0;
1145 m_token = 0;
1146 m_annotationLinesAdded = 0;
1147 m_updated = 0;
1148
1149 #if wxUSE_DRAG_AND_DROP
1150 m_dragFlags = wxDrag_CopyOnly;
1151 m_dragResult = wxDragNone;
1152 #endif
1153 }
1154
1155 bool wxStyledTextEvent::GetShift() const { return (m_modifiers & SCI_SHIFT) != 0; }
1156 bool wxStyledTextEvent::GetControl() const { return (m_modifiers & SCI_CTRL) != 0; }
1157 bool wxStyledTextEvent::GetAlt() const { return (m_modifiers & SCI_ALT) != 0; }
1158
1159
1160 wxStyledTextEvent::wxStyledTextEvent(const wxStyledTextEvent& event):
1161 wxCommandEvent(event)
1162 {
1163 m_position = event.m_position;
1164 m_key = event.m_key;
1165 m_modifiers = event.m_modifiers;
1166 m_modificationType = event.m_modificationType;
1167 m_text = event.m_text;
1168 m_length = event.m_length;
1169 m_linesAdded = event.m_linesAdded;
1170 m_line = event.m_line;
1171 m_foldLevelNow = event.m_foldLevelNow;
1172 m_foldLevelPrev = event.m_foldLevelPrev;
1173
1174 m_margin = event.m_margin;
1175
1176 m_message = event.m_message;
1177 m_wParam = event.m_wParam;
1178 m_lParam = event.m_lParam;
1179
1180 m_listType = event.m_listType;
1181 m_x = event.m_x;
1182 m_y = event.m_y;
1183
1184 m_token = event.m_token;
1185 m_annotationLinesAdded = event.m_annotationLinesAdded;
1186 m_updated = event.m_updated;
1187
1188 #if wxUSE_DRAG_AND_DROP
1189 m_dragText = event.m_dragText;
1190 m_dragFlags = event.m_dragFlags;
1191 m_dragResult = event.m_dragResult;
1192 #endif
1193 }
1194
1195 //----------------------------------------------------------------------
1196 //----------------------------------------------------------------------
1197
1198 /*static*/ wxVersionInfo wxStyledTextCtrl::GetLibraryVersionInfo()
1199 {
1200 return wxVersionInfo("Scintilla", 3, 21, 0, "Scintilla 3.21");
1201 }
1202
1203 #endif // wxUSE_STC