]> git.saurik.com Git - wxWidgets.git/blame - src/common/textcmn.cpp
always NUL-terminate log messages, even if they're longer than buffer size
[wxWidgets.git] / src / common / textcmn.cpp
CommitLineData
a1b82138
VZ
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
55d99c7a 9// Licence: wxWindows licence
a1b82138
VZ
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
1e6feb95 15
bf3e0fbd
KB
16#ifdef __GNUG__
17 #pragma implementation "textctrlbase.h"
18#endif
1e6feb95 19
a1b82138
VZ
20// for compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
1e6feb95
VZ
27#if wxUSE_TEXTCTRL
28
a1b82138 29#ifndef WX_PRECOMP
0efe5ba7
VZ
30 #include "wx/intl.h"
31 #include "wx/log.h"
a1b82138
VZ
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
c57e3339
VZ
49IMPLEMENT_DYNAMIC_CLASS(wxTextUrlEvent, wxCommandEvent)
50
51DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_UPDATED)
52DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_ENTER)
53DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_URL)
d7eee191 54DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_MAXLEN)
c57e3339 55
a1b82138
VZ
56// ----------------------------------------------------------------------------
57// ctor
58// ----------------------------------------------------------------------------
59
60wxTextCtrlBase::wxTextCtrlBase()
61{
fa40e7a1
SB
62}
63
64wxTextCtrlBase::~wxTextCtrlBase()
65{
a1b82138
VZ
66}
67
4bc1afd5
VZ
68// ----------------------------------------------------------------------------
69// style functions - not implemented here
70// ----------------------------------------------------------------------------
71
eda40bfc
VZ
72/* static */
73wxTextAttr 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
4bc1afd5
VZ
107// apply styling to text range
108bool 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
eda40bfc 116bool wxTextCtrlBase::SetDefaultStyle(const wxTextAttr& style)
4bc1afd5 117{
c598f225
VZ
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);
eda40bfc 125
4bc1afd5
VZ
126 return TRUE;
127}
128
129// get default text attributes
130const wxTextAttr& wxTextCtrlBase::GetDefaultStyle() const
131{
132 return m_defaultStyle;
133}
134
a1b82138
VZ
135// ----------------------------------------------------------------------------
136// file IO functions
137// ----------------------------------------------------------------------------
138
139bool wxTextCtrlBase::LoadFile(const wxString& filename)
140{
1e6feb95 141#if wxUSE_FFILE
a1b82138
VZ
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."));
1e6feb95 159#endif // wxUSE_FFILE
a1b82138
VZ
160
161 return FALSE;
162}
163
164bool 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?
223d09f6 170 wxLogDebug(wxT("Can't save textctrl to file without filename."));
a1b82138
VZ
171
172 return FALSE;
173 }
174
1e6feb95 175#if wxUSE_FFILE
f68c6b52 176 wxFFile file(filename, _T("w"));
a1b82138
VZ
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."));
1e6feb95 188#endif // wxUSE_FFILE
a1b82138
VZ
189
190 return FALSE;
191}
192
193// ----------------------------------------------------------------------------
194// stream-like insertion operator
195// ----------------------------------------------------------------------------
196
197wxTextCtrl& wxTextCtrlBase::operator<<(const wxString& s)
198{
199 AppendText(s);
200 return *TEXTCTRL(this);
201}
202
203wxTextCtrl& wxTextCtrlBase::operator<<(float f)
204{
205 wxString str;
223d09f6 206 str.Printf(wxT("%.2f"), f);
a1b82138
VZ
207 AppendText(str);
208 return *TEXTCTRL(this);
209}
210
211wxTextCtrl& wxTextCtrlBase::operator<<(double d)
212{
213 wxString str;
223d09f6 214 str.Printf(wxT("%.2f"), d);
a1b82138
VZ
215 AppendText(str);
216 return *TEXTCTRL(this);
217}
218
219wxTextCtrl& wxTextCtrlBase::operator<<(int i)
220{
221 wxString str;
223d09f6 222 str.Printf(wxT("%d"), i);
a1b82138
VZ
223 AppendText(str);
224 return *TEXTCTRL(this);
225}
226
227wxTextCtrl& wxTextCtrlBase::operator<<(long i)
228{
229 wxString str;
223d09f6 230 str.Printf(wxT("%ld"), i);
a1b82138
VZ
231 AppendText(str);
232 return *TEXTCTRL(this);
233}
234
a324a7bc 235wxTextCtrl& wxTextCtrlBase::operator<<(const wxChar c)
a1b82138
VZ
236{
237 return operator<<(wxString(c));
238}
239
240// ----------------------------------------------------------------------------
241// streambuf methods implementation
242// ----------------------------------------------------------------------------
243
244#ifndef NO_TEXT_WINDOW_STREAM
245
d73e6791 246int wxTextCtrlBase::overflow(int c)
a1b82138 247{
d73e6791 248 AppendText((wxChar)c);
a1b82138 249
d73e6791 250 // return something different from EOF
a1b82138
VZ
251 return 0;
252}
253
a1b82138
VZ
254#endif // NO_TEXT_WINDOW_STREAM
255
1e6feb95
VZ
256// ----------------------------------------------------------------------------
257// clipboard stuff
258// ----------------------------------------------------------------------------
259
260bool 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
268bool 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
274bool wxTextCtrlBase::CanPaste() const
275{
276 // can paste if we are not read only
277 return IsEditable();
278}
279
94af7d45
VZ
280// ----------------------------------------------------------------------------
281// emulating key presses
282// ----------------------------------------------------------------------------
283
284bool wxTextCtrlBase::EmulateKeyPress(const wxKeyEvent& event)
285{
286 // the generic version is unused in wxMSW
287#ifndef __WIN32__
02a48e3b 288 wxChar ch = 0;
94af7d45
VZ
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
cd916794
VZ
330 case WXK_DELETE:
331 case WXK_NUMPAD_DELETE:
332 // delete the character at cursor
333 {
334 const long pos = GetInsertionPoint(),
335 last = GetLastPosition();
336 if ( pos < last )
337 Remove(pos, pos + 1);
338 }
339 break;
340
341 case WXK_BACK:
342 // delete the character before the cursor
343 {
344 const long pos = GetInsertionPoint();
345 if ( pos > 0 )
346 Remove(pos - 1, pos);
347 }
348 break;
349
94af7d45 350 default:
401eb3de 351 if ( keycode < 256 && keycode >= 0 && wxIsprint(keycode) )
94af7d45
VZ
352 {
353 // FIXME this is not going to work for non letters...
354 if ( !event.ShiftDown() )
355 {
401eb3de 356 keycode = wxTolower(keycode);
94af7d45
VZ
357 }
358
359 ch = (wxChar)keycode;
360 }
361 else
362 {
363 ch = _T('\0');
364 }
365 }
366
367 if ( ch )
368 {
369 WriteText(ch);
370
371 return TRUE;
372 }
373#endif // !__WIN32__
374
375 return FALSE;
376}
377
1e6feb95 378// ----------------------------------------------------------------------------
a5aa8086 379// selection and ranges
1e6feb95
VZ
380// ----------------------------------------------------------------------------
381
382void wxTextCtrlBase::SelectAll()
383{
384 SetSelection(0, GetLastPosition());
385}
386
eef97940 387wxString wxTextCtrlBase::GetStringSelection() const
18414479
VZ
388{
389 long from, to;
390 GetSelection(&from, &to);
391
a5aa8086
VZ
392 return GetRange(from, to);
393}
394
395wxString wxTextCtrlBase::GetRange(long from, long to) const
396{
18414479
VZ
397 wxString sel;
398 if ( from < to )
399 {
400 sel = GetValue().Mid(from, to - from);
401 }
402
403 return sel;
404}
405
ad0bae85
VZ
406#else // !wxUSE_TEXTCTRL
407
408// define this one even if !wxUSE_TEXTCTRL because it is also used by other
409// controls (wxComboBox and wxSpinCtrl)
410#include "wx/event.h"
411
412DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_UPDATED)
413
414#endif // wxUSE_TEXTCTRL/!wxUSE_TEXTCTRL
1e6feb95 415