]> git.saurik.com Git - wxWidgets.git/blame - src/common/textentrycmn.cpp
fixing focus, fixes #11911
[wxWidgets.git] / src / common / textentrycmn.cpp
CommitLineData
0ec1179b
VZ
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
86116620
RR
29 #include "wx/window.h"
30 #include "wx/dataobj.h"
0ec1179b
VZ
31#endif //WX_PRECOMP
32
33#include "wx/textentry.h"
fa2f57be 34#include "wx/clipbrd.h"
0ec1179b 35
63f7d502
VZ
36// ----------------------------------------------------------------------------
37// wxTextEntryHintData
38// ----------------------------------------------------------------------------
39
40class WXDLLIMPEXP_CORE wxTextEntryHintData wxBIND_OR_CONNECT_HACK_ONLY_BASE_CLASS
41{
42public:
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);
135b23b2
VZ
51
52 // we don't have any hint yet
53 m_showsHint = false;
63f7d502
VZ
54 }
55
56 // default dtor is ok
57
135b23b2
VZ
58 // are we showing the hint right now?
59 bool ShowsHint() const { return m_showsHint; }
60
63f7d502
VZ
61 void SetHintString(const wxString& hint)
62 {
63 m_hint = hint;
64
135b23b2 65 if ( m_showsHint )
63f7d502
VZ
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
75private:
63f7d502
VZ
76 void OnSetFocus(wxFocusEvent& event)
77 {
78 // hide the hint if we were showing it
135b23b2 79 if ( m_showsHint )
63f7d502
VZ
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);
135b23b2
VZ
85
86 m_showsHint = false;
63f7d502
VZ
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);
135b23b2
VZ
101
102 m_showsHint = true;
63f7d502
VZ
103 }
104
105 event.Skip();
106 }
107
135b23b2 108 // the text control we're associated with (as its interface and its window)
63f7d502
VZ
109 wxTextEntryBase * const m_entry;
110 wxWindow * const m_win;
111
135b23b2 112 // the original foreground colour of m_win before we changed it
63f7d502
VZ
113 wxColour m_colFg;
114
135b23b2 115 // the hint passed to wxTextEntry::SetHint()
63f7d502
VZ
116 wxString m_hint;
117
135b23b2
VZ
118 // true if we're currently showing it, for this we must be empty and not
119 // have focus
120 bool m_showsHint;
121
63f7d502
VZ
122 wxDECLARE_NO_COPY_CLASS(wxTextEntryHintData);
123};
124
0ec1179b
VZ
125// ============================================================================
126// wxTextEntryBase implementation
127// ============================================================================
128
63f7d502
VZ
129wxTextEntryBase::~wxTextEntryBase()
130{
131 delete m_hintData;
132}
133
134// ----------------------------------------------------------------------------
135b23b2 135// text accessors
63f7d502
VZ
136// ----------------------------------------------------------------------------
137
135b23b2
VZ
138wxString wxTextEntryBase::GetValue() const
139{
140 return m_hintData && m_hintData->ShowsHint() ? wxString() : DoGetValue();
141}
142
0ec1179b
VZ
143wxString wxTextEntryBase::GetRange(long from, long to) const
144{
145 wxString sel;
e9863f4e 146 wxString value = GetValue();
2b42a870
VZ
147
148 if ( from < to && (long)value.length() >= to )
0ec1179b 149 {
2b42a870 150 sel = value.substr(from, to - from);
0ec1179b
VZ
151 }
152
153 return sel;
154}
155
135b23b2
VZ
156// ----------------------------------------------------------------------------
157// text operations
158// ----------------------------------------------------------------------------
159
0ec1179b
VZ
160void wxTextEntryBase::AppendText(const wxString& text)
161{
162 SetInsertionPointEnd();
163 WriteText(text);
164}
165
166void wxTextEntryBase::DoSetValue(const wxString& value, int flags)
167{
168 EventsSuppressor noeventsIf(this, !(flags & SetValue_SendEvent));
169
170 SelectAll();
171 WriteText(value);
a5125dc6
VZ
172
173 SetInsertionPoint(0);
0ec1179b
VZ
174}
175
176void wxTextEntryBase::Replace(long from, long to, const wxString& value)
177{
178 {
179 EventsSuppressor noevents(this);
180 Remove(from, to);
181 }
182
059979d8 183 SetInsertionPoint(from);
0ec1179b
VZ
184 WriteText(value);
185}
186
63f7d502
VZ
187// ----------------------------------------------------------------------------
188// selection
189// ----------------------------------------------------------------------------
190
0ec1179b
VZ
191bool wxTextEntryBase::HasSelection() const
192{
193 long from, to;
194 GetSelection(&from, &to);
195
196 return from < to;
197}
198
5a25f858
VZ
199void wxTextEntryBase::RemoveSelection()
200{
201 long from, to;
202 GetSelection(& from, & to);
203 if (from != -1 && to != -1)
204 Remove(from, to);
205}
206
0ec1179b
VZ
207wxString wxTextEntryBase::GetStringSelection() const
208{
209 long from, to;
210 GetSelection(&from, &to);
211
212 return GetRange(from, to);
213}
214
63f7d502
VZ
215// ----------------------------------------------------------------------------
216// clipboard
217// ----------------------------------------------------------------------------
218
0ec1179b
VZ
219bool wxTextEntryBase::CanCopy() const
220{
221 return HasSelection();
222}
223
224bool wxTextEntryBase::CanCut() const
225{
226 return CanCopy() && IsEditable();
227}
228
229bool wxTextEntryBase::CanPaste() const
230{
fa2f57be
VZ
231 if ( IsEditable() )
232 {
233#if wxUSE_CLIPBOARD
234 // check if there is any text on the clipboard
fa9cd5d3
VZ
235 if ( wxTheClipboard->IsSupported(wxDF_TEXT)
236#if wxUSE_UNICODE
237 || wxTheClipboard->IsSupported(wxDF_UNICODETEXT)
238#endif // wxUSE_UNICODE
239 )
240 {
fa2f57be 241 return true;
fa9cd5d3 242 }
fa2f57be
VZ
243#endif // wxUSE_CLIPBOARD
244 }
245
246 return false;
0ec1179b
VZ
247}
248
63f7d502
VZ
249// ----------------------------------------------------------------------------
250// hints support
251// ----------------------------------------------------------------------------
252
253bool 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
263wxString wxTextEntryBase::GetHint() const
264{
265 return m_hintData ? m_hintData->GetHintString() : wxString();
266}
267
0847e36e
JS
268// ----------------------------------------------------------------------------
269// margins support
270// ----------------------------------------------------------------------------
271
272bool wxTextEntryBase::DoSetMargins(const wxPoint& WXUNUSED(pt))
273{
274 return false;
275}
276
277wxPoint wxTextEntryBase::DoGetMargins() const
278{
279 return wxPoint(-1, -1);
280}
281
50135807
VZ
282// ----------------------------------------------------------------------------
283// events
284// ----------------------------------------------------------------------------
285
286/* static */
287bool 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
0ec1179b 303#endif // wxUSE_TEXTCTRL || wxUSE_COMBOBOX