1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/textentrycmn.cpp
3 // Purpose: wxTextEntryBase implementation
4 // Author: Vadim Zeitlin
7 // Copyright: (c) 2007 Vadim Zeitlin <vadim@wxwindows.org>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
19 // for compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
26 #if wxUSE_TEXTCTRL || wxUSE_COMBOBOX
29 #include "wx/window.h"
30 #include "wx/dataobj.h"
33 #include "wx/textentry.h"
34 #include "wx/clipbrd.h"
36 // ----------------------------------------------------------------------------
37 // wxTextEntryHintData
38 // ----------------------------------------------------------------------------
40 class WXDLLIMPEXP_CORE wxTextEntryHintData wxBIND_OR_CONNECT_HACK_ONLY_BASE_CLASS
43 wxTextEntryHintData(wxTextEntryBase
*entry
, wxWindow
*win
)
46 m_text(m_entry
->GetValue())
48 wxBIND_OR_CONNECT_HACK(win
, wxEVT_SET_FOCUS
, wxFocusEventHandler
,
49 wxTextEntryHintData::OnSetFocus
, this);
50 wxBIND_OR_CONNECT_HACK(win
, wxEVT_KILL_FOCUS
, wxFocusEventHandler
,
51 wxTextEntryHintData::OnKillFocus
, this);
52 wxBIND_OR_CONNECT_HACK(win
, wxEVT_COMMAND_TEXT_UPDATED
,
53 wxCommandEventHandler
,
54 wxTextEntryHintData::OnTextChanged
, this);
59 // Get the real text of the control such as it was before we replaced it
61 const wxString
& GetText() const { return m_text
; }
63 // Set the hint to show, shouldn't be empty normally.
65 // This should be called after creating a new wxTextEntryHintData object
66 // and may be called more times in the future.
67 void SetHintString(const wxString
& hint
)
71 if ( !m_win
->HasFocus() )
72 ShowHintIfAppropriate();
73 //else: The new hint will be shown later when we lose focus.
76 const wxString
& GetHintString() const { return m_hint
; }
79 // Show the hint in the window if we should do it, i.e. if the window
80 // doesn't have any text of its own.
81 void ShowHintIfAppropriate()
83 // Never overwrite existing window text.
84 if ( !m_text
.empty() )
87 // Save the old text colour and set a more inconspicuous one for the
89 m_colFg
= m_win
->GetForegroundColour();
90 m_win
->SetForegroundColour(*wxLIGHT_GREY
);
92 m_entry
->DoSetValue(m_hint
, wxTextEntryBase::SetValue_NoEvent
);
95 // Restore the original text colour if we had changed it to show the hint
96 // and not restored it yet.
97 void RestoreTextColourIfNecessary()
101 m_win
->SetForegroundColour(m_colFg
);
102 m_colFg
= wxColour();
106 void OnSetFocus(wxFocusEvent
& event
)
108 // If we had been showing the hint before, remove it now and restore
109 // the normal colour.
110 if ( m_text
.empty() )
112 RestoreTextColourIfNecessary();
114 m_entry
->DoSetValue(wxString(), wxTextEntryBase::SetValue_NoEvent
);
120 void OnKillFocus(wxFocusEvent
& event
)
122 // Restore the hint if the user didn't enter anything.
123 ShowHintIfAppropriate();
128 void OnTextChanged(wxCommandEvent
& event
)
130 // Update the stored window text.
132 // Notice that we can't use GetValue() nor wxCommandEvent::GetString()
133 // which uses it internally because this would just forward back to us
134 // so go directly to the private method which returns the real control
136 m_text
= m_entry
->DoGetValue();
138 // If this event is generated because of calling SetValue(), the
139 // control may still have the hint text colour, reset it in this case.
140 RestoreTextColourIfNecessary();
146 // the text control we're associated with (as its interface and its window)
147 wxTextEntryBase
* const m_entry
;
148 wxWindow
* const m_win
;
150 // the original foreground colour of m_win before we changed it
153 // The hint passed to wxTextEntry::SetHint(), never empty.
156 // The real text of the window.
160 wxDECLARE_NO_COPY_CLASS(wxTextEntryHintData
);
163 // ============================================================================
164 // wxTextEntryBase implementation
165 // ============================================================================
167 wxTextEntryBase::~wxTextEntryBase()
172 // ----------------------------------------------------------------------------
174 // ----------------------------------------------------------------------------
176 wxString
wxTextEntryBase::GetValue() const
178 return m_hintData
? m_hintData
->GetText() : DoGetValue();
181 wxString
wxTextEntryBase::GetRange(long from
, long to
) const
184 wxString value
= GetValue();
186 if ( from
< to
&& (long)value
.length() >= to
)
188 sel
= value
.substr(from
, to
- from
);
194 // ----------------------------------------------------------------------------
196 // ----------------------------------------------------------------------------
198 void wxTextEntryBase::AppendText(const wxString
& text
)
200 SetInsertionPointEnd();
204 void wxTextEntryBase::DoSetValue(const wxString
& value
, int flags
)
206 EventsSuppressor
noeventsIf(this, !(flags
& SetValue_SendEvent
));
211 SetInsertionPoint(0);
214 void wxTextEntryBase::Replace(long from
, long to
, const wxString
& value
)
217 EventsSuppressor
noevents(this);
221 SetInsertionPoint(from
);
225 // ----------------------------------------------------------------------------
227 // ----------------------------------------------------------------------------
229 bool wxTextEntryBase::HasSelection() const
232 GetSelection(&from
, &to
);
237 void wxTextEntryBase::RemoveSelection()
240 GetSelection(& from
, & to
);
241 if (from
!= -1 && to
!= -1)
245 wxString
wxTextEntryBase::GetStringSelection() const
248 GetSelection(&from
, &to
);
250 return GetRange(from
, to
);
253 // ----------------------------------------------------------------------------
255 // ----------------------------------------------------------------------------
257 bool wxTextEntryBase::CanCopy() const
259 return HasSelection();
262 bool wxTextEntryBase::CanCut() const
264 return CanCopy() && IsEditable();
267 bool wxTextEntryBase::CanPaste() const
272 // check if there is any text on the clipboard
273 if ( wxTheClipboard
->IsSupported(wxDF_TEXT
)
275 || wxTheClipboard
->IsSupported(wxDF_UNICODETEXT
)
276 #endif // wxUSE_UNICODE
281 #endif // wxUSE_CLIPBOARD
287 // ----------------------------------------------------------------------------
289 // ----------------------------------------------------------------------------
291 bool wxTextEntryBase::SetHint(const wxString
& hint
)
296 m_hintData
= new wxTextEntryHintData(this, GetEditableWindow());
298 m_hintData
->SetHintString(hint
);
300 else if ( m_hintData
)
302 // Setting empty hint removes any currently set one.
306 //else: Setting empty hint when we don't have any doesn't do anything.
311 wxString
wxTextEntryBase::GetHint() const
313 return m_hintData
? m_hintData
->GetHintString() : wxString();
316 // ----------------------------------------------------------------------------
318 // ----------------------------------------------------------------------------
320 bool wxTextEntryBase::DoSetMargins(const wxPoint
& WXUNUSED(pt
))
325 wxPoint
wxTextEntryBase::DoGetMargins() const
327 return wxPoint(-1, -1);
330 // ----------------------------------------------------------------------------
332 // ----------------------------------------------------------------------------
335 bool wxTextEntryBase::SendTextUpdatedEvent(wxWindow
*win
)
337 wxCHECK_MSG( win
, false, "can't send an event without a window" );
339 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, win
->GetId());
341 // do not do this as it could be very inefficient if the text control
342 // contains a lot of text and we're not using ref-counted wxString
343 // implementation -- instead, event.GetString() will query the control for
344 // its current text if needed
345 //event.SetString(win->GetValue());
347 event
.SetEventObject(win
);
348 return win
->HandleWindowEvent(event
);
351 #endif // wxUSE_TEXTCTRL || wxUSE_COMBOBOX