]> git.saurik.com Git - wxWidgets.git/blob - src/common/textcmn.cpp
don't write the strings to the stream one char at a time, it's *horribly* slow
[wxWidgets.git] / src / common / textcmn.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: common/textcmn.cpp
3 // Purpose: implementation of platform-independent functions of wxTextCtrl
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 13.07.99
7 // RCS-ID: $Id$
8 // Copyright: (c) wxWindows team
9 // Licence: wxWindows license
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 #ifdef __GNUG__
17 #pragma implementation "textctrlbase.h"
18 #endif
19
20 // for compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 #if wxUSE_TEXTCTRL
28
29 #ifndef WX_PRECOMP
30 #include "wx/intl.h"
31 #include "wx/log.h"
32 #include "wx/textctrl.h"
33 #endif // WX_PRECOMP
34
35 #include "wx/ffile.h"
36
37 // ----------------------------------------------------------------------------
38 // macros
39 // ----------------------------------------------------------------------------
40
41 // we don't have any objects of type wxTextCtrlBase in the program, only
42 // wxTextCtrl, so this cast is safe
43 #define TEXTCTRL(ptr) ((wxTextCtrl *)(ptr))
44
45 // ============================================================================
46 // implementation
47 // ============================================================================
48
49 IMPLEMENT_DYNAMIC_CLASS(wxTextUrlEvent, wxCommandEvent)
50
51 DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_UPDATED)
52 DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_ENTER)
53 DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_URL)
54 DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_MAXLEN)
55
56 // ----------------------------------------------------------------------------
57 // ctor
58 // ----------------------------------------------------------------------------
59
60 wxTextCtrlBase::wxTextCtrlBase()
61 {
62 }
63
64 wxTextCtrlBase::~wxTextCtrlBase()
65 {
66 }
67
68 // ----------------------------------------------------------------------------
69 // style functions - not implemented here
70 // ----------------------------------------------------------------------------
71
72 /* static */
73 wxTextAttr wxTextAttr::Combine(const wxTextAttr& attr,
74 const wxTextAttr& attrDef,
75 const wxTextCtrlBase *text)
76 {
77 wxFont font = attr.GetFont();
78 if ( !font.Ok() )
79 {
80 font = attrDef.GetFont();
81
82 if ( text && !font.Ok() )
83 font = text->GetFont();
84 }
85
86 wxColour colFg = attr.GetTextColour();
87 if ( !colFg.Ok() )
88 {
89 colFg = attrDef.GetTextColour();
90
91 if ( text && !colFg.Ok() )
92 colFg = text->GetForegroundColour();
93 }
94
95 wxColour colBg = attr.GetBackgroundColour();
96 if ( !colBg.Ok() )
97 {
98 colBg = attrDef.GetBackgroundColour();
99
100 if ( text && !colBg.Ok() )
101 colBg = text->GetBackgroundColour();
102 }
103
104 return wxTextAttr(colFg, colBg, font);
105 }
106
107 // apply styling to text range
108 bool wxTextCtrlBase::SetStyle(long WXUNUSED(start), long WXUNUSED(end),
109 const wxTextAttr& WXUNUSED(style))
110 {
111 // to be implemented in derived TextCtrl classes
112 return FALSE;
113 }
114
115 // change default text attributes
116 bool wxTextCtrlBase::SetDefaultStyle(const wxTextAttr& style)
117 {
118 // keep the old attributes if the new style doesn't specify them unless the
119 // new style is empty - then reset m_defaultStyle (as there is no other way
120 // to do it)
121 if ( style.IsDefault() )
122 m_defaultStyle = style;
123 else
124 m_defaultStyle = wxTextAttr::Combine(style, m_defaultStyle, this);
125
126 return TRUE;
127 }
128
129 // get default text attributes
130 const wxTextAttr& wxTextCtrlBase::GetDefaultStyle() const
131 {
132 return m_defaultStyle;
133 }
134
135 // ----------------------------------------------------------------------------
136 // file IO functions
137 // ----------------------------------------------------------------------------
138
139 bool wxTextCtrlBase::LoadFile(const wxString& filename)
140 {
141 #if wxUSE_FFILE
142 wxFFile file(filename);
143 if ( file.IsOpened() )
144 {
145 wxString text;
146 if ( file.ReadAll(&text) )
147 {
148 SetValue(text);
149
150 DiscardEdits();
151
152 m_filename = filename;
153
154 return TRUE;
155 }
156 }
157
158 wxLogError(_("File couldn't be loaded."));
159 #endif // wxUSE_FFILE
160
161 return FALSE;
162 }
163
164 bool wxTextCtrlBase::SaveFile(const wxString& filename)
165 {
166 wxString filenameToUse = filename.IsEmpty() ? m_filename : filename;
167 if ( !filenameToUse )
168 {
169 // what kind of message to give? is it an error or a program bug?
170 wxLogDebug(wxT("Can't save textctrl to file without filename."));
171
172 return FALSE;
173 }
174
175 #if wxUSE_FFILE
176 wxFFile file(filename, "w");
177 if ( file.IsOpened() && file.Write(GetValue()) )
178 {
179 // it's not modified any longer
180 DiscardEdits();
181
182 m_filename = filename;
183
184 return TRUE;
185 }
186
187 wxLogError(_("The text couldn't be saved."));
188 #endif // wxUSE_FFILE
189
190 return FALSE;
191 }
192
193 // ----------------------------------------------------------------------------
194 // stream-like insertion operator
195 // ----------------------------------------------------------------------------
196
197 wxTextCtrl& wxTextCtrlBase::operator<<(const wxString& s)
198 {
199 AppendText(s);
200 return *TEXTCTRL(this);
201 }
202
203 wxTextCtrl& wxTextCtrlBase::operator<<(float f)
204 {
205 wxString str;
206 str.Printf(wxT("%.2f"), f);
207 AppendText(str);
208 return *TEXTCTRL(this);
209 }
210
211 wxTextCtrl& wxTextCtrlBase::operator<<(double d)
212 {
213 wxString str;
214 str.Printf(wxT("%.2f"), d);
215 AppendText(str);
216 return *TEXTCTRL(this);
217 }
218
219 wxTextCtrl& wxTextCtrlBase::operator<<(int i)
220 {
221 wxString str;
222 str.Printf(wxT("%d"), i);
223 AppendText(str);
224 return *TEXTCTRL(this);
225 }
226
227 wxTextCtrl& wxTextCtrlBase::operator<<(long i)
228 {
229 wxString str;
230 str.Printf(wxT("%ld"), i);
231 AppendText(str);
232 return *TEXTCTRL(this);
233 }
234
235 wxTextCtrl& wxTextCtrlBase::operator<<(const wxChar c)
236 {
237 return operator<<(wxString(c));
238 }
239
240 // ----------------------------------------------------------------------------
241 // streambuf methods implementation
242 // ----------------------------------------------------------------------------
243
244 #ifndef NO_TEXT_WINDOW_STREAM
245
246 int wxTextCtrlBase::overflow(int c)
247 {
248 AppendText((wxChar)c);
249
250 // return something different from EOF
251 return 0;
252 }
253
254 #endif // NO_TEXT_WINDOW_STREAM
255
256 // ----------------------------------------------------------------------------
257 // clipboard stuff
258 // ----------------------------------------------------------------------------
259
260 bool wxTextCtrlBase::CanCopy() const
261 {
262 // can copy if there's a selection
263 long from, to;
264 GetSelection(&from, &to);
265 return from != to;
266 }
267
268 bool wxTextCtrlBase::CanCut() const
269 {
270 // can cut if there's a selection and if we're not read only
271 return CanCopy() && IsEditable();
272 }
273
274 bool wxTextCtrlBase::CanPaste() const
275 {
276 // can paste if we are not read only
277 return IsEditable();
278 }
279
280 // ----------------------------------------------------------------------------
281 // emulating key presses
282 // ----------------------------------------------------------------------------
283
284 bool wxTextCtrlBase::EmulateKeyPress(const wxKeyEvent& event)
285 {
286 // the generic version is unused in wxMSW
287 #ifndef __WIN32__
288 wxChar ch;
289 int keycode = event.GetKeyCode();
290 switch ( keycode )
291 {
292 case WXK_NUMPAD0:
293 case WXK_NUMPAD1:
294 case WXK_NUMPAD2:
295 case WXK_NUMPAD3:
296 case WXK_NUMPAD4:
297 case WXK_NUMPAD5:
298 case WXK_NUMPAD6:
299 case WXK_NUMPAD7:
300 case WXK_NUMPAD8:
301 case WXK_NUMPAD9:
302 ch = _T('0') + keycode - WXK_NUMPAD0;
303 break;
304
305 case WXK_MULTIPLY:
306 case WXK_NUMPAD_MULTIPLY:
307 ch = _T('*');
308 break;
309
310 case WXK_ADD:
311 case WXK_NUMPAD_ADD:
312 ch = _T('+');
313 break;
314
315 case WXK_SUBTRACT:
316 case WXK_NUMPAD_SUBTRACT:
317 ch = _T('-');
318 break;
319
320 case WXK_DECIMAL:
321 case WXK_NUMPAD_DECIMAL:
322 ch = _T('.');
323 break;
324
325 case WXK_DIVIDE:
326 case WXK_NUMPAD_DIVIDE:
327 ch = _T('/');
328 break;
329
330 default:
331 if ( keycode < 256 && keycode >= 0 && isprint(keycode) )
332 {
333 // FIXME this is not going to work for non letters...
334 if ( !event.ShiftDown() )
335 {
336 keycode = tolower(keycode);
337 }
338
339 ch = (wxChar)keycode;
340 }
341 else
342 {
343 ch = _T('\0');
344 }
345 }
346
347 if ( ch )
348 {
349 WriteText(ch);
350
351 return TRUE;
352 }
353 #endif // !__WIN32__
354
355 return FALSE;
356 }
357
358 // ----------------------------------------------------------------------------
359 // selection and ranges
360 // ----------------------------------------------------------------------------
361
362 void wxTextCtrlBase::SelectAll()
363 {
364 SetSelection(0, GetLastPosition());
365 }
366
367 wxString wxTextCtrlBase::GetStringSelection() const
368 {
369 long from, to;
370 GetSelection(&from, &to);
371
372 return GetRange(from, to);
373 }
374
375 wxString wxTextCtrlBase::GetRange(long from, long to) const
376 {
377 wxString sel;
378 if ( from < to )
379 {
380 sel = GetValue().Mid(from, to - from);
381 }
382
383 return sel;
384 }
385
386 #else // !wxUSE_TEXTCTRL
387
388 // define this one even if !wxUSE_TEXTCTRL because it is also used by other
389 // controls (wxComboBox and wxSpinCtrl)
390 #include "wx/event.h"
391
392 DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_UPDATED)
393
394 #endif // wxUSE_TEXTCTRL/!wxUSE_TEXTCTRL
395