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