implemented, tested and documented wxTextCtrl::SetMaxLength()
[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 #ifndef NO_TEXT_WINDOW_STREAM
63 #if wxUSE_IOSTREAMH
64 if (allocate())
65 setp(base(),ebuf());
66 #else
67 m_streambuf = new char[64];
68 setp(m_streambuf, m_streambuf + 64);
69 #endif //wxUSE_IOSTREAMH
70 #endif // NO_TEXT_WINDOW_STREAM
71 }
72
73 wxTextCtrlBase::~wxTextCtrlBase()
74 {
75 #ifndef NO_TEXT_WINDOW_STREAM
76 #if !wxUSE_IOSTREAMH
77 delete[] m_streambuf;
78 #endif
79 #endif
80 }
81
82 // ----------------------------------------------------------------------------
83 // style functions - not implemented here
84 // ----------------------------------------------------------------------------
85
86 // apply styling to text range
87 bool wxTextCtrlBase::SetStyle(long WXUNUSED(start), long WXUNUSED(end),
88 const wxTextAttr& WXUNUSED(style))
89 {
90 // to be implemented in derived TextCtrl classes
91 return FALSE;
92 }
93
94 // change default text attributes
95 bool wxTextCtrlBase::SetDefaultStyle(const wxTextAttr &style)
96 {
97 m_defaultStyle = style;
98 return TRUE;
99 }
100
101 // get default text attributes
102 const wxTextAttr& wxTextCtrlBase::GetDefaultStyle() const
103 {
104 return m_defaultStyle;
105 }
106
107 // ----------------------------------------------------------------------------
108 // file IO functions
109 // ----------------------------------------------------------------------------
110
111 bool wxTextCtrlBase::LoadFile(const wxString& filename)
112 {
113 #if wxUSE_FFILE
114 wxFFile file(filename);
115 if ( file.IsOpened() )
116 {
117 wxString text;
118 if ( file.ReadAll(&text) )
119 {
120 SetValue(text);
121
122 DiscardEdits();
123
124 m_filename = filename;
125
126 return TRUE;
127 }
128 }
129
130 wxLogError(_("File couldn't be loaded."));
131 #endif // wxUSE_FFILE
132
133 return FALSE;
134 }
135
136 bool wxTextCtrlBase::SaveFile(const wxString& filename)
137 {
138 wxString filenameToUse = filename.IsEmpty() ? m_filename : filename;
139 if ( !filenameToUse )
140 {
141 // what kind of message to give? is it an error or a program bug?
142 wxLogDebug(wxT("Can't save textctrl to file without filename."));
143
144 return FALSE;
145 }
146
147 #if wxUSE_FFILE
148 wxFFile file(filename, "w");
149 if ( file.IsOpened() && file.Write(GetValue()) )
150 {
151 // it's not modified any longer
152 DiscardEdits();
153
154 m_filename = filename;
155
156 return TRUE;
157 }
158
159 wxLogError(_("The text couldn't be saved."));
160 #endif // wxUSE_FFILE
161
162 return FALSE;
163 }
164
165 // ----------------------------------------------------------------------------
166 // stream-like insertion operator
167 // ----------------------------------------------------------------------------
168
169 wxTextCtrl& wxTextCtrlBase::operator<<(const wxString& s)
170 {
171 AppendText(s);
172 return *TEXTCTRL(this);
173 }
174
175 wxTextCtrl& wxTextCtrlBase::operator<<(float f)
176 {
177 wxString str;
178 str.Printf(wxT("%.2f"), f);
179 AppendText(str);
180 return *TEXTCTRL(this);
181 }
182
183 wxTextCtrl& wxTextCtrlBase::operator<<(double d)
184 {
185 wxString str;
186 str.Printf(wxT("%.2f"), d);
187 AppendText(str);
188 return *TEXTCTRL(this);
189 }
190
191 wxTextCtrl& wxTextCtrlBase::operator<<(int i)
192 {
193 wxString str;
194 str.Printf(wxT("%d"), i);
195 AppendText(str);
196 return *TEXTCTRL(this);
197 }
198
199 wxTextCtrl& wxTextCtrlBase::operator<<(long i)
200 {
201 wxString str;
202 str.Printf(wxT("%ld"), i);
203 AppendText(str);
204 return *TEXTCTRL(this);
205 }
206
207 wxTextCtrl& wxTextCtrlBase::operator<<(const wxChar c)
208 {
209 return operator<<(wxString(c));
210 }
211
212 // ----------------------------------------------------------------------------
213 // streambuf methods implementation
214 // ----------------------------------------------------------------------------
215
216 #ifndef NO_TEXT_WINDOW_STREAM
217
218 int wxTextCtrlBase::overflow( int WXUNUSED(c) )
219 {
220 int len = pptr() - pbase();
221 char *txt = new char[len+1];
222 strncpy(txt, pbase(), len);
223 txt[len] = '\0';
224 (*this) << txt;
225 setp(pbase(), epptr());
226 delete[] txt;
227 return EOF;
228 }
229
230 int wxTextCtrlBase::sync()
231 {
232 int len = pptr() - pbase();
233 char *txt = new char[len+1];
234 strncpy(txt, pbase(), len);
235 txt[len] = '\0';
236 (*this) << txt;
237 setp(pbase(), epptr());
238 delete[] txt;
239 return 0;
240 }
241
242 int wxTextCtrlBase::underflow()
243 {
244 return EOF;
245 }
246
247 #endif // NO_TEXT_WINDOW_STREAM
248
249 // ----------------------------------------------------------------------------
250 // clipboard stuff
251 // ----------------------------------------------------------------------------
252
253 bool wxTextCtrlBase::CanCopy() const
254 {
255 // can copy if there's a selection
256 long from, to;
257 GetSelection(&from, &to);
258 return from != to;
259 }
260
261 bool wxTextCtrlBase::CanCut() const
262 {
263 // can cut if there's a selection and if we're not read only
264 return CanCopy() && IsEditable();
265 }
266
267 bool wxTextCtrlBase::CanPaste() const
268 {
269 // can paste if we are not read only
270 return IsEditable();
271 }
272
273 // ----------------------------------------------------------------------------
274 // misc
275 // ----------------------------------------------------------------------------
276
277 void wxTextCtrlBase::SelectAll()
278 {
279 SetSelection(0, GetLastPosition());
280 }
281
282 #else // !wxUSE_TEXTCTRL
283
284 // define this one even if !wxUSE_TEXTCTRL because it is also used by other
285 // controls (wxComboBox and wxSpinCtrl)
286 #include "wx/event.h"
287
288 DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_UPDATED)
289
290 #endif // wxUSE_TEXTCTRL/!wxUSE_TEXTCTRL
291