]> git.saurik.com Git - wxWidgets.git/blame - src/stc/stc.cpp.in
Use the black pen for the border on Windows now too.
[wxWidgets.git] / src / stc / stc.cpp.in
CommitLineData
f97d84a6
RD
1////////////////////////////////////////////////////////////////////////////
2// Name: stc.cpp
3// Purpose: A wxWindows 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#include <ctype.h>
19
20#include "wx/stc/stc.h"
21#include "ScintillaWX.h"
22
23#include <wx/tokenzr.h>
24
25// The following code forces a reference to all of the Scintilla lexers.
26// If we don't do something like this, then the linker tends to "optimize"
27// them away. (eric@sourcegear.com)
28
29int wxForceScintillaLexers(void)
30{
65ec6247
RD
31 extern LexerModule lmAda;
32 extern LexerModule lmAVE;
33 extern LexerModule lmConf;
f97d84a6 34 extern LexerModule lmCPP;
b8b0e402 35 extern LexerModule lmNncrontab;
65ec6247 36 extern LexerModule lmEiffel;
f97d84a6 37 extern LexerModule lmHTML;
65ec6247
RD
38 extern LexerModule lmLISP;
39 extern LexerModule lmLua;
40 extern LexerModule lmBatch; // In LexOthers.cxx
41 extern LexerModule lmPascal;
f97d84a6
RD
42 extern LexerModule lmPerl;
43 extern LexerModule lmPython;
65ec6247 44 extern LexerModule lmRuby;
f97d84a6
RD
45 extern LexerModule lmSQL;
46 extern LexerModule lmVB;
47
65ec6247
RD
48 if ( &lmAda
49 && &lmAVE
50 && &lmConf
51 && &lmCPP
b8b0e402 52 && &lmNncrontab
65ec6247
RD
53 && &lmEiffel
54 && &lmHTML
55 && &lmLISP
56 && &lmLua
57 && &lmBatch
58 && &lmPascal
59 && &lmPerl
60 && &lmPython
61 && &lmRuby
62 && &lmSQL
63 && &lmVB )
f97d84a6
RD
64 {
65 return 1;
66 }
67 else
68 {
69 return 0;
70 }
71}
72
73//----------------------------------------------------------------------
74
75const wxChar* wxSTCNameStr = "stcwindow";
76
d25f5fbb
RD
77DEFINE_EVENT_TYPE( wxEVT_STC_CHANGE )
78DEFINE_EVENT_TYPE( wxEVT_STC_STYLENEEDED )
79DEFINE_EVENT_TYPE( wxEVT_STC_CHARADDED )
d25f5fbb
RD
80DEFINE_EVENT_TYPE( wxEVT_STC_SAVEPOINTREACHED )
81DEFINE_EVENT_TYPE( wxEVT_STC_SAVEPOINTLEFT )
82DEFINE_EVENT_TYPE( wxEVT_STC_ROMODIFYATTEMPT )
65ec6247 83DEFINE_EVENT_TYPE( wxEVT_STC_KEY )
d25f5fbb 84DEFINE_EVENT_TYPE( wxEVT_STC_DOUBLECLICK )
65ec6247 85DEFINE_EVENT_TYPE( wxEVT_STC_UPDATEUI )
d25f5fbb 86DEFINE_EVENT_TYPE( wxEVT_STC_MODIFIED )
d25f5fbb
RD
87DEFINE_EVENT_TYPE( wxEVT_STC_MACRORECORD )
88DEFINE_EVENT_TYPE( wxEVT_STC_MARGINCLICK )
89DEFINE_EVENT_TYPE( wxEVT_STC_NEEDSHOWN )
90DEFINE_EVENT_TYPE( wxEVT_STC_POSCHANGED )
65ec6247
RD
91DEFINE_EVENT_TYPE( wxEVT_STC_PAINTED )
92DEFINE_EVENT_TYPE( wxEVT_STC_USERLISTSELECTION )
93DEFINE_EVENT_TYPE( wxEVT_STC_URIDROPPED )
94DEFINE_EVENT_TYPE( wxEVT_STC_DWELLSTART )
95DEFINE_EVENT_TYPE( wxEVT_STC_DWELLEND )
96
97
d25f5fbb
RD
98
99
f97d84a6
RD
100BEGIN_EVENT_TABLE(wxStyledTextCtrl, wxControl)
101 EVT_PAINT (wxStyledTextCtrl::OnPaint)
102 EVT_SCROLLWIN (wxStyledTextCtrl::OnScrollWin)
103 EVT_SIZE (wxStyledTextCtrl::OnSize)
104 EVT_LEFT_DOWN (wxStyledTextCtrl::OnMouseLeftDown)
4ceb1196
RD
105#ifdef __WXMSW__
106 // Let Scintilla see the double click as a second click
107 EVT_LEFT_DCLICK (wxStyledTextCtrl::OnMouseLeftDown)
108#endif
f97d84a6
RD
109 EVT_MOTION (wxStyledTextCtrl::OnMouseMove)
110 EVT_LEFT_UP (wxStyledTextCtrl::OnMouseLeftUp)
65ec6247 111 EVT_CONTEXT_MENU (wxStyledTextCtrl::OnContextMenu)
37d62433 112 EVT_MOUSEWHEEL (wxStyledTextCtrl::OnMouseWheel)
f97d84a6
RD
113 EVT_CHAR (wxStyledTextCtrl::OnChar)
114 EVT_KEY_DOWN (wxStyledTextCtrl::OnKeyDown)
115 EVT_KILL_FOCUS (wxStyledTextCtrl::OnLoseFocus)
116 EVT_SET_FOCUS (wxStyledTextCtrl::OnGainFocus)
117 EVT_SYS_COLOUR_CHANGED (wxStyledTextCtrl::OnSysColourChanged)
118 EVT_ERASE_BACKGROUND (wxStyledTextCtrl::OnEraseBackground)
119 EVT_MENU_RANGE (-1, -1, wxStyledTextCtrl::OnMenu)
120 EVT_LISTBOX_DCLICK (-1, wxStyledTextCtrl::OnListBox)
121END_EVENT_TABLE()
122
123
124IMPLEMENT_CLASS(wxStyledTextCtrl, wxControl)
125IMPLEMENT_DYNAMIC_CLASS(wxStyledTextEvent, wxCommandEvent)
126
127//----------------------------------------------------------------------
128// Constructor and Destructor
129
130wxStyledTextCtrl::wxStyledTextCtrl(wxWindow *parent,
131 wxWindowID id,
132 const wxPoint& pos,
133 const wxSize& size,
134 long style,
135 const wxString& name) :
136 wxControl(parent, id, pos, size,
137 style | wxVSCROLL | wxHSCROLL | wxWANTS_CHARS | wxCLIP_CHILDREN,
138 wxDefaultValidator, name)
139{
140 m_swx = new ScintillaWX(this);
141 m_stopWatch.Start();
d6582821 142 m_lastKeyDownConsumed = FALSE;
f97d84a6
RD
143}
144
145
146wxStyledTextCtrl::~wxStyledTextCtrl() {
147 delete m_swx;
148}
149
150
151//----------------------------------------------------------------------
152
153long wxStyledTextCtrl::SendMsg(int msg, long wp, long lp) {
154
155 return m_swx->WndProc(msg, wp, lp);
156}
157
158
159#ifdef MAKELONG
160#undef MAKELONG
161#endif
162
163#define MAKELONG(a, b) ((a) | ((b) << 16))
164
165
166static long wxColourAsLong(const wxColour& co) {
167 return (((long)co.Blue() << 16) |
168 ((long)co.Green() << 8) |
169 ((long)co.Red()));
170}
171
172static wxColour wxColourFromLong(long c) {
173 wxColour clr;
174 clr.Set(c & 0xff, (c >> 8) & 0xff, (c >> 16) & 0xff);
175 return clr;
176}
177
178
179static wxColour wxColourFromSpec(const wxString& spec) {
180 // spec should be #RRGGBB
181 char* junk;
182 int red = strtol(spec.Mid(1,2), &junk, 16);
183 int green = strtol(spec.Mid(3,2), &junk, 16);
184 int blue = strtol(spec.Mid(5,2), &junk, 16);
185 return wxColour(red, green, blue);
186}
187
188
189//----------------------------------------------------------------------
190// BEGIN generated section. The following code is automatically generated
191// by gen_iface.py from the contents of Scintilla.iface. Do not edit
192// this file. Edit stc.cpp.in or gen_iface.py instead and regenerate.
193
194%(METHOD_IMPS)s
195
196// END of generated section
197//----------------------------------------------------------------------
198
199
200// Returns the line number of the line with the caret.
201int wxStyledTextCtrl::GetCurrentLine() {
202 int line = LineFromPosition(GetCurrentPos());
203 return line;
204}
205
206
207// Extract style settings from a spec-string which is composed of one or
208// more of the following comma separated elements:
209//
210// bold turns on bold
211// italic turns on italics
212// fore:#RRGGBB sets the foreground colour
213// back:#RRGGBB sets the background colour
214// face:[facename] sets the font face name to use
215// size:[num] sets the font size in points
216// eol turns on eol filling
217// underline turns on underlining
218//
219void wxStyledTextCtrl::StyleSetSpec(int styleNum, const wxString& spec) {
220
221 wxStringTokenizer tkz(spec, ",");
222 while (tkz.HasMoreTokens()) {
223 wxString token = tkz.GetNextToken();
224
225 wxString option = token.BeforeFirst(':');
226 wxString val = token.AfterFirst(':');
227
228 if (option == "bold")
229 StyleSetBold(styleNum, true);
230
231 else if (option == "italic")
232 StyleSetItalic(styleNum, true);
233
234 else if (option == "underline")
235 StyleSetUnderline(styleNum, true);
236
237 else if (option == "eol")
238 StyleSetEOLFilled(styleNum, true);
239
240 else if (option == "size") {
241 long points;
242 if (val.ToLong(&points))
243 StyleSetSize(styleNum, points);
244 }
245
246 else if (option == "face")
247 StyleSetFaceName(styleNum, val);
248
249 else if (option == "fore")
250 StyleSetForeground(styleNum, wxColourFromSpec(val));
251
252 else if (option == "back")
253 StyleSetBackground(styleNum, wxColourFromSpec(val));
254 }
255}
256
257
258// Set style size, face, bold, italic, and underline attributes from
259// a wxFont's attributes.
260void wxStyledTextCtrl::StyleSetFont(int styleNum, wxFont& font) {
261 int size = font.GetPointSize();
262 wxString faceName = font.GetFaceName();
263 bool bold = font.GetWeight() == wxBOLD;
264 bool italic = font.GetStyle() != wxNORMAL;
265 bool under = font.GetUnderlined();
266
267 // TODO: add encoding/charset mapping
268 StyleSetFontAttr(styleNum, size, faceName, bold, italic, under);
269}
270
271// Set all font style attributes at once.
272void wxStyledTextCtrl::StyleSetFontAttr(int styleNum, int size,
273 const wxString& faceName,
274 bool bold, bool italic,
275 bool underline) {
276 StyleSetSize(styleNum, size);
277 StyleSetFaceName(styleNum, faceName);
278 StyleSetBold(styleNum, bold);
279 StyleSetItalic(styleNum, italic);
280 StyleSetUnderline(styleNum, underline);
281
282 // TODO: add encoding/charset mapping
283}
284
285
286// Perform one of the operations defined by the wxSTC_CMD_* constants.
287void wxStyledTextCtrl::CmdKeyExecute(int cmd) {
288 SendMsg(cmd);
289}
290
291
292// Set the left and right margin in the edit area, measured in pixels.
293void wxStyledTextCtrl::SetMargins(int left, int right) {
294 SetMarginLeft(left);
295 SetMarginRight(right);
296}
297
298
299// Retrieve the start and end positions of the current selection.
300void wxStyledTextCtrl::GetSelection(int* startPos, int* endPos) {
301 if (startPos != NULL)
302 *startPos = SendMsg(SCI_GETSELECTIONSTART);
303 if (endPos != NULL)
304 *endPos = SendMsg(SCI_GETSELECTIONEND);
305}
306
307
308// Retrieve the point in the window where a position is displayed.
309wxPoint wxStyledTextCtrl::PointFromPosition(int pos) {
310 int x = SendMsg(SCI_POINTXFROMPOSITION, 0, pos);
311 int y = SendMsg(SCI_POINTYFROMPOSITION, 0, pos);
312 return wxPoint(x, y);
313}
314
315// Scroll enough to make the given line visible
316void wxStyledTextCtrl::ScrollToLine(int line) {
317 m_swx->DoScrollToLine(line);
318}
319
320
321// Scroll enough to make the given column visible
322void wxStyledTextCtrl::ScrollToColumn(int column) {
323 m_swx->DoScrollToColumn(column);
324}
325
326
327
328//----------------------------------------------------------------------
329// Event handlers
330
331void wxStyledTextCtrl::OnPaint(wxPaintEvent& evt) {
332 wxPaintDC dc(this);
333 wxRegion region = GetUpdateRegion();
334
335 m_swx->DoPaint(&dc, region.GetBox());
336}
337
338void wxStyledTextCtrl::OnScrollWin(wxScrollWinEvent& evt) {
339 if (evt.GetOrientation() == wxHORIZONTAL)
340 m_swx->DoHScroll(evt.GetEventType(), evt.GetPosition());
341 else
342 m_swx->DoVScroll(evt.GetEventType(), evt.GetPosition());
343}
344
345void wxStyledTextCtrl::OnSize(wxSizeEvent& evt) {
346 wxSize sz = GetClientSize();
347 m_swx->DoSize(sz.x, sz.y);
348}
349
350void wxStyledTextCtrl::OnMouseLeftDown(wxMouseEvent& evt) {
351 wxPoint pt = evt.GetPosition();
352 m_swx->DoButtonDown(Point(pt.x, pt.y), m_stopWatch.Time(),
353 evt.ShiftDown(), evt.ControlDown(), evt.AltDown());
354}
355
356void wxStyledTextCtrl::OnMouseMove(wxMouseEvent& evt) {
357 wxPoint pt = evt.GetPosition();
358 m_swx->DoButtonMove(Point(pt.x, pt.y));
359}
360
361void wxStyledTextCtrl::OnMouseLeftUp(wxMouseEvent& evt) {
362 wxPoint pt = evt.GetPosition();
363 m_swx->DoButtonUp(Point(pt.x, pt.y), m_stopWatch.Time(),
364 evt.ControlDown());
365}
366
367
65ec6247 368void wxStyledTextCtrl::OnContextMenu(wxContextMenuEvent& evt) {
f97d84a6 369 wxPoint pt = evt.GetPosition();
65ec6247 370 ScreenToClient(&pt.x, &pt.y);
f97d84a6
RD
371 m_swx->DoContextMenu(Point(pt.x, pt.y));
372}
373
37d62433
RD
374
375void wxStyledTextCtrl::OnMouseWheel(wxMouseEvent& evt) {
376 m_swx->DoMouseWheel(evt.GetWheelRotation(),
377 evt.GetWheelDelta(),
65ec6247
RD
378 evt.GetLinesPerAction(),
379 evt.ControlDown());
37d62433
RD
380}
381
382
f97d84a6
RD
383void wxStyledTextCtrl::OnChar(wxKeyEvent& evt) {
384 long key = evt.KeyCode();
f3c2c221
RD
385
386// printf("OnChar key:%%d consumed:%%d ctrl:%%d alt:%%d\n",
387// key, m_lastKeyDownConsumed, evt.ControlDown(), evt.AltDown());
388
389 // AltGr keys???
390