Return after activating already opened document in wxDocManager.
[wxWidgets.git] / src / common / textentrycmn.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/textentrycmn.cpp
3 // Purpose: wxTextEntryBase implementation
4 // Author: Vadim Zeitlin
5 // Created: 2007-09-26
6 // RCS-ID: $Id$
7 // Copyright: (c) 2007 Vadim Zeitlin <vadim@wxwindows.org>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
10
11 // ============================================================================
12 // declarations
13 // ============================================================================
14
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18
19 // for compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 #if wxUSE_TEXTCTRL || wxUSE_COMBOBOX
27
28 #ifndef WX_PRECOMP
29 #include "wx/window.h"
30 #include "wx/dataobj.h"
31 #endif //WX_PRECOMP
32
33 #include "wx/textentry.h"
34 #include "wx/clipbrd.h"
35
36 // ----------------------------------------------------------------------------
37 // wxTextEntryHintData
38 // ----------------------------------------------------------------------------
39
40 class WXDLLIMPEXP_CORE wxTextEntryHintData wxBIND_OR_CONNECT_HACK_ONLY_BASE_CLASS
41 {
42 public:
43 wxTextEntryHintData(wxTextEntryBase *entry, wxWindow *win)
44 : m_entry(entry),
45 m_win(win)
46 {
47 wxBIND_OR_CONNECT_HACK(win, wxEVT_SET_FOCUS, wxFocusEventHandler,
48 wxTextEntryHintData::OnSetFocus, this);
49 wxBIND_OR_CONNECT_HACK(win, wxEVT_KILL_FOCUS, wxFocusEventHandler,
50 wxTextEntryHintData::OnKillFocus, this);
51
52 // we don't have any hint yet
53 m_showsHint = false;
54 }
55
56 // default dtor is ok
57
58 // are we showing the hint right now?
59 bool ShowsHint() const { return m_showsHint; }
60
61 void SetHintString(const wxString& hint)
62 {
63 m_hint = hint;
64
65 if ( m_showsHint )
66 {
67 // update it immediately
68 m_entry->ChangeValue(hint);
69 }
70 //else: the new hint will be shown later
71 }
72
73 const wxString& GetHintString() const { return m_hint; }
74
75 private:
76 void OnSetFocus(wxFocusEvent& event)
77 {
78 // hide the hint if we were showing it
79 if ( m_showsHint )
80 {
81 // Clear() would send an event which we don't want, so do it like
82 // this
83 m_entry->ChangeValue(wxString());
84 m_win->SetForegroundColour(m_colFg);
85
86 m_showsHint = false;
87 }
88
89 event.Skip();
90 }
91
92 void OnKillFocus(wxFocusEvent& event)
93 {
94 // restore the hint if the user didn't do anything in the control
95 if ( m_entry->IsEmpty() )
96 {
97 m_entry->ChangeValue(m_hint);
98
99 m_colFg = m_win->GetForegroundColour();
100 m_win->SetForegroundColour(*wxLIGHT_GREY);
101
102 m_showsHint = true;
103 }
104
105 event.Skip();
106 }
107
108 // the text control we're associated with (as its interface and its window)
109 wxTextEntryBase * const m_entry;
110 wxWindow * const m_win;
111
112 // the original foreground colour of m_win before we changed it
113 wxColour m_colFg;
114
115 // the hint passed to wxTextEntry::SetHint()
116 wxString m_hint;
117
118 // true if we're currently showing it, for this we must be empty and not
119 // have focus
120 bool m_showsHint;
121
122 wxDECLARE_NO_COPY_CLASS(wxTextEntryHintData);
123 };
124
125 // ============================================================================
126 // wxTextEntryBase implementation
127 // ============================================================================
128
129 wxTextEntryBase::~wxTextEntryBase()
130 {
131 delete m_hintData;
132 }
133
134 // ----------------------------------------------------------------------------
135 // text accessors
136 // ----------------------------------------------------------------------------
137
138 wxString wxTextEntryBase::GetValue() const
139 {
140 return m_hintData && m_hintData->ShowsHint() ? wxString() : DoGetValue();
141 }
142
143 wxString wxTextEntryBase::GetRange(long from, long to) const
144 {
145 wxString sel;
146 wxString value = GetValue();
147
148 if ( from < to && (long)value.length() >= to )
149 {
150 sel = value.substr(from, to - from);
151 }
152
153 return sel;
154 }
155
156 // ----------------------------------------------------------------------------
157 // text operations
158 // ----------------------------------------------------------------------------
159
160 void wxTextEntryBase::AppendText(const wxString& text)
161 {
162 SetInsertionPointEnd();
163 WriteText(text);
164 }
165
166 void wxTextEntryBase::DoSetValue(const wxString& value, int flags)
167 {
168 EventsSuppressor noeventsIf(this, !(flags & SetValue_SendEvent));
169
170 SelectAll();
171 WriteText(value);
172
173 SetInsertionPoint(0);
174 }
175
176 void wxTextEntryBase::Replace(long from, long to, const wxString& value)
177 {
178 {
179 EventsSuppressor noevents(this);
180 Remove(from, to);
181 }
182
183 SetInsertionPoint(from);
184 WriteText(value);
185 }
186
187 // ----------------------------------------------------------------------------
188 // selection
189 // ----------------------------------------------------------------------------
190
191 bool wxTextEntryBase::HasSelection() const
192 {
193 long from, to;
194 GetSelection(&from, &to);
195
196 return from < to;
197 }
198
199 void wxTextEntryBase::RemoveSelection()
200 {
201 long from, to;
202 GetSelection(& from, & to);
203 if (from != -1 && to != -1)
204 Remove(from, to);
205 }
206
207 wxString wxTextEntryBase::GetStringSelection() const
208 {
209 long from, to;
210 GetSelection(&from, &to);
211
212 return GetRange(from, to);
213 }
214
215 // ----------------------------------------------------------------------------
216 // clipboard
217 // ----------------------------------------------------------------------------
218
219 bool wxTextEntryBase::CanCopy() const
220 {
221 return HasSelection();
222 }
223
224 bool wxTextEntryBase::CanCut() const
225 {
226 return CanCopy() && IsEditable();
227 }
228
229 bool wxTextEntryBase::CanPaste() const
230 {
231 if ( IsEditable() )
232 {
233 #if wxUSE_CLIPBOARD
234 // check if there is any text on the clipboard
235 if ( wxTheClipboard->IsSupported(wxDF_TEXT)
236 #if wxUSE_UNICODE
237 || wxTheClipboard->IsSupported(wxDF_UNICODETEXT)
238 #endif // wxUSE_UNICODE
239 )
240 {
241 return true;
242 }
243 #endif // wxUSE_CLIPBOARD
244 }
245
246 return false;
247 }
248
249 // ----------------------------------------------------------------------------
250 // hints support
251 // ----------------------------------------------------------------------------
252
253 bool wxTextEntryBase::SetHint(const wxString& hint)
254 {
255 if ( !m_hintData )
256 m_hintData = new wxTextEntryHintData(this, GetEditableWindow());
257
258 m_hintData->SetHintString(hint);
259
260 return true;
261 }
262
263 wxString wxTextEntryBase::GetHint() const
264 {
265 return m_hintData ? m_hintData->GetHintString() : wxString();
266 }
267
268 // ----------------------------------------------------------------------------
269 // margins support
270 // ----------------------------------------------------------------------------
271
272 bool wxTextEntryBase::DoSetMargins(const wxPoint& WXUNUSED(pt))
273 {
274 return false;
275 }
276
277 wxPoint wxTextEntryBase::DoGetMargins() const
278 {
279 return wxPoint(-1, -1);
280 }
281
282 // ----------------------------------------------------------------------------
283 // events
284 // ----------------------------------------------------------------------------
285
286 /* static */
287 bool wxTextEntryBase::SendTextUpdatedEvent(wxWindow *win)
288 {
289 wxCHECK_MSG( win, false, "can't send an event without a window" );
290
291 wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, win->GetId());
292
293 // do not do this as it could be very inefficient if the text control
294 // contains a lot of text and we're not using ref-counted wxString
295 // implementation -- instead, event.GetString() will query the control for
296 // its current text if needed
297 //event.SetString(win->GetValue());
298
299 event.SetEventObject(win);
300 return win->HandleWindowEvent(event);
301 }
302
303 #endif // wxUSE_TEXTCTRL || wxUSE_COMBOBOX