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