adapt to wx conventions for scroll wheel differences between horizontal and vertical...
[wxWidgets.git] / src / osx / textentry_osx.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/textentry_osx.cpp
3 // Purpose: wxTextEntry
4 // Author: Stefan Csomor
5 // Modified by: Kevin Ollivier
6 // Created: 1998-01-01
7 // RCS-ID: $Id$
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #include "wx/wxprec.h"
13
14 #if wxUSE_TEXTCTRL
15
16 #include "wx/textctrl.h"
17
18 #ifndef WX_PRECOMP
19 #include "wx/intl.h"
20 #include "wx/app.h"
21 #include "wx/utils.h"
22 #include "wx/dc.h"
23 #include "wx/button.h"
24 #include "wx/menu.h"
25 #include "wx/settings.h"
26 #include "wx/msgdlg.h"
27 #include "wx/toplevel.h"
28 #endif
29
30 #ifdef __DARWIN__
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #else
34 #include <stat.h>
35 #endif
36
37 #if wxUSE_STD_IOSTREAM
38 #if wxUSE_IOSTREAMH
39 #include <fstream.h>
40 #else
41 #include <fstream>
42 #endif
43 #endif
44
45 #include "wx/filefn.h"
46 #include "wx/sysopt.h"
47 #include "wx/thread.h"
48 #include "wx/textcompleter.h"
49
50 #include "wx/osx/private.h"
51
52 wxTextEntry::wxTextEntry()
53 {
54 m_completer = NULL;
55 m_editable = true;
56 m_maxLength = 0;
57 }
58
59 wxTextEntry::~wxTextEntry()
60 {
61 delete m_completer;
62 }
63
64 wxString wxTextEntry::DoGetValue() const
65 {
66 wxCHECK_MSG( GetTextPeer(), wxString(), "Must create the control first" );
67
68 return GetTextPeer()->GetStringValue() ;
69 }
70
71 void wxTextEntry::GetSelection(long* from, long* to) const
72 {
73 wxCHECK_RET( GetTextPeer(), "Must create the control first" );
74
75 GetTextPeer()->GetSelection( from , to ) ;
76 }
77
78 void wxTextEntry::SetMaxLength(unsigned long len)
79 {
80 if ( GetTextPeer()->CanClipMaxLength() )
81 GetTextPeer()->SetMaxLength(len);
82 m_maxLength = len ;
83 }
84
85 // Clipboard operations
86
87 void wxTextEntry::Copy()
88 {
89 wxCHECK_RET( GetTextPeer(), "Must create the control first" );
90
91 if (CanCopy())
92 GetTextPeer()->Copy() ;
93 }
94
95 void wxTextEntry::Cut()
96 {
97 wxCHECK_RET( GetTextPeer(), "Must create the control first" );
98
99 if (CanCut())
100 GetTextPeer()->Cut() ;
101 }
102
103 void wxTextEntry::Paste()
104 {
105 wxCHECK_RET( GetTextPeer(), "Must create the control first" );
106
107 if (CanPaste())
108 GetTextPeer()->Paste() ;
109 }
110
111 bool wxTextEntry::CanCopy() const
112 {
113 // Can copy if there's a selection
114 long from, to;
115 GetSelection( &from, &to );
116
117 return (from != to);
118 }
119
120 bool wxTextEntry::CanCut() const
121 {
122 if ( !IsEditable() )
123 return false;
124
125 // Can cut if there's a selection
126 long from, to;
127 GetSelection( &from, &to );
128
129 return (from != to);
130 }
131
132 bool wxTextEntry::CanPaste() const
133 {
134 if (!IsEditable())
135 return false;
136
137 wxCHECK_MSG( GetTextPeer(), false, "Must create the control first" );
138
139 return GetTextPeer()->CanPaste() ;
140 }
141
142 void wxTextEntry::SetEditable(bool editable)
143 {
144 if ( editable == m_editable )
145 return;
146
147 m_editable = editable ;
148
149 wxCHECK_RET( GetTextPeer(), "Must create the control first" );
150 GetTextPeer()->SetEditable( editable ) ;
151 }
152
153 void wxTextEntry::SetInsertionPoint(long pos)
154 {
155 SetSelection( pos , pos ) ;
156 }
157
158 void wxTextEntry::SetInsertionPointEnd()
159 {
160 long pos = GetLastPosition();
161 SetInsertionPoint( pos );
162 }
163
164 long wxTextEntry::GetInsertionPoint() const
165 {
166 long begin, end ;
167 GetSelection( &begin , &end ) ;
168
169 return begin ;
170 }
171
172 wxTextPos wxTextEntry::GetLastPosition() const
173 {
174 wxCHECK_MSG( GetTextPeer(), -1, "Must create the control first" );
175
176 return GetTextPeer()->GetLastPosition() ;
177 }
178
179 void wxTextEntry::Remove(long from, long to)
180 {
181 wxCHECK_RET( GetTextPeer(), "Must create the control first" );
182
183 {
184 EventsSuppressor noevents(this);
185 GetTextPeer()->Remove( from , to );
186 }
187
188 SendTextUpdatedEventIfAllowed();
189 }
190
191 void wxTextEntry::SetSelection(long from, long to)
192 {
193 wxCHECK_RET( GetTextPeer(), "Must create the control first" );
194
195 GetTextPeer()->SetSelection( from , to ) ;
196 }
197
198 void wxTextEntry::WriteText(const wxString& str)
199 {
200 wxCHECK_RET( GetTextPeer(), "Must create the control first" );
201
202 {
203 EventsSuppressor noevents(this);
204 GetTextPeer()->WriteText( str );
205 }
206
207 SendTextUpdatedEventIfAllowed();
208 }
209
210 void wxTextEntry::Clear()
211 {
212 wxCHECK_RET( GetTextPeer(), "Must create the control first" );
213
214 {
215 EventsSuppressor noevents(this);
216 GetTextPeer()->Clear();
217 }
218
219 SendTextUpdatedEventIfAllowed();
220 }
221
222 bool wxTextEntry::IsEditable() const
223 {
224 return m_editable ;
225 }
226
227 bool wxTextEntry::SendMaxLenEvent()
228 {
229 wxWindow *win = GetEditableWindow();
230 wxCHECK_MSG( win, false, "can't send an event without a window" );
231
232 wxCommandEvent event(wxEVT_TEXT_MAXLEN, win->GetId());
233
234 // do not do this as it could be very inefficient if the text control
235 // contains a lot of text and we're not using ref-counted wxString
236 // implementation -- instead, event.GetString() will query the control for
237 // its current text if needed
238 //event.SetString(win->GetValue());
239
240 event.SetEventObject(win);
241 return win->HandleWindowEvent(event);
242 }
243
244 // ----------------------------------------------------------------------------
245 // Undo/redo
246 // ----------------------------------------------------------------------------
247
248 void wxTextEntry::Undo()
249 {
250 wxCHECK_RET( GetTextPeer(), "Must create the control first" );
251
252 if (CanUndo())
253 GetTextPeer()->Undo() ;
254 }
255
256 void wxTextEntry::Redo()
257 {
258 wxCHECK_RET( GetTextPeer(), "Must create the control first" );
259
260 if (CanRedo())
261 GetTextPeer()->Redo() ;
262 }
263
264 bool wxTextEntry::CanUndo() const
265 {
266 if ( !IsEditable() )
267 return false ;
268
269 wxCHECK_MSG( GetTextPeer(), false, "Must create the control first" );
270
271 return GetTextPeer()->CanUndo() ;
272 }
273
274 bool wxTextEntry::CanRedo() const
275 {
276 if ( !IsEditable() )
277 return false ;
278
279 wxCHECK_MSG( GetTextPeer(), false, "Must create the control first" );
280
281 return GetTextPeer()->CanRedo() ;
282 }
283
284 wxTextWidgetImpl * wxTextEntry::GetTextPeer() const
285 {
286 wxWindow * const win = const_cast<wxTextEntry *>(this)->GetEditableWindow();
287
288 return win ? dynamic_cast<wxTextWidgetImpl *>(win->GetPeer()) : NULL;
289 }
290
291 // ----------------------------------------------------------------------------
292 // Auto-completion
293 // ----------------------------------------------------------------------------
294
295 bool wxTextEntry::DoAutoCompleteStrings(const wxArrayString& choices)
296 {
297 wxTextCompleterFixed * const completer = new wxTextCompleterFixed;
298 completer->SetCompletions(choices);
299
300 return DoAutoCompleteCustom(completer);
301 }
302
303 bool wxTextEntry::DoAutoCompleteCustom(wxTextCompleter *completer)
304 {
305 m_completer = completer;
306
307 return true;
308 }
309
310 #endif // wxUSE_TEXTCTRL