X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/0ec1179b86dac6c87ad9f2cd126f87e92642c62c..8a3f03ffce938a24ecc154b614072457b3900ed0:/src/common/textentrycmn.cpp diff --git a/src/common/textentrycmn.cpp b/src/common/textentrycmn.cpp index 67443dcdad..cb81ea0779 100644 --- a/src/common/textentrycmn.cpp +++ b/src/common/textentrycmn.cpp @@ -26,25 +26,137 @@ #if wxUSE_TEXTCTRL || wxUSE_COMBOBOX #ifndef WX_PRECOMP + #include "wx/window.h" + #include "wx/dataobj.h" #endif //WX_PRECOMP #include "wx/textentry.h" +#include "wx/clipbrd.h" + +// ---------------------------------------------------------------------------- +// wxTextEntryHintData +// ---------------------------------------------------------------------------- + +class WXDLLIMPEXP_CORE wxTextEntryHintData wxBIND_OR_CONNECT_HACK_ONLY_BASE_CLASS +{ +public: + wxTextEntryHintData(wxTextEntryBase *entry, wxWindow *win) + : m_entry(entry), + m_win(win) + { + wxBIND_OR_CONNECT_HACK(win, wxEVT_SET_FOCUS, wxFocusEventHandler, + wxTextEntryHintData::OnSetFocus, this); + wxBIND_OR_CONNECT_HACK(win, wxEVT_KILL_FOCUS, wxFocusEventHandler, + wxTextEntryHintData::OnKillFocus, this); + + // we don't have any hint yet + m_showsHint = false; + } + + // default dtor is ok + + // are we showing the hint right now? + bool ShowsHint() const { return m_showsHint; } + + void SetHintString(const wxString& hint) + { + m_hint = hint; + + if ( m_showsHint ) + { + // update it immediately + m_entry->ChangeValue(hint); + } + //else: the new hint will be shown later + } + + const wxString& GetHintString() const { return m_hint; } + +private: + void OnSetFocus(wxFocusEvent& event) + { + // hide the hint if we were showing it + if ( m_showsHint ) + { + // Clear() would send an event which we don't want, so do it like + // this + m_entry->ChangeValue(wxString()); + m_win->SetForegroundColour(m_colFg); + + m_showsHint = false; + } + + event.Skip(); + } + + void OnKillFocus(wxFocusEvent& event) + { + // restore the hint if the user didn't do anything in the control + if ( m_entry->IsEmpty() ) + { + m_entry->ChangeValue(m_hint); + + m_colFg = m_win->GetForegroundColour(); + m_win->SetForegroundColour(*wxLIGHT_GREY); + + m_showsHint = true; + } + + event.Skip(); + } + + // the text control we're associated with (as its interface and its window) + wxTextEntryBase * const m_entry; + wxWindow * const m_win; + + // the original foreground colour of m_win before we changed it + wxColour m_colFg; + + // the hint passed to wxTextEntry::SetHint() + wxString m_hint; + + // true if we're currently showing it, for this we must be empty and not + // have focus + bool m_showsHint; + + wxDECLARE_NO_COPY_CLASS(wxTextEntryHintData); +}; // ============================================================================ // wxTextEntryBase implementation // ============================================================================ +wxTextEntryBase::~wxTextEntryBase() +{ + delete m_hintData; +} + +// ---------------------------------------------------------------------------- +// text accessors +// ---------------------------------------------------------------------------- + +wxString wxTextEntryBase::GetValue() const +{ + return m_hintData && m_hintData->ShowsHint() ? wxString() : DoGetValue(); +} + wxString wxTextEntryBase::GetRange(long from, long to) const { wxString sel; - if ( from < to ) + wxString value = GetValue(); + + if ( from < to && (long)value.length() >= to ) { - sel = GetValue().substr(from, to - from); + sel = value.substr(from, to - from); } return sel; } +// ---------------------------------------------------------------------------- +// text operations +// ---------------------------------------------------------------------------- + void wxTextEntryBase::AppendText(const wxString& text) { SetInsertionPointEnd(); @@ -57,6 +169,8 @@ void wxTextEntryBase::DoSetValue(const wxString& value, int flags) SelectAll(); WriteText(value); + + SetInsertionPoint(0); } void wxTextEntryBase::Replace(long from, long to, const wxString& value) @@ -66,9 +180,14 @@ void wxTextEntryBase::Replace(long from, long to, const wxString& value) Remove(from, to); } + SetInsertionPoint(from); WriteText(value); } +// ---------------------------------------------------------------------------- +// selection +// ---------------------------------------------------------------------------- + bool wxTextEntryBase::HasSelection() const { long from, to; @@ -77,6 +196,14 @@ bool wxTextEntryBase::HasSelection() const return from < to; } +void wxTextEntryBase::RemoveSelection() +{ + long from, to; + GetSelection(& from, & to); + if (from != -1 && to != -1) + Remove(from, to); +} + wxString wxTextEntryBase::GetStringSelection() const { long from, to; @@ -85,6 +212,10 @@ wxString wxTextEntryBase::GetStringSelection() const return GetRange(from, to); } +// ---------------------------------------------------------------------------- +// clipboard +// ---------------------------------------------------------------------------- + bool wxTextEntryBase::CanCopy() const { return HasSelection(); @@ -97,7 +228,41 @@ bool wxTextEntryBase::CanCut() const bool wxTextEntryBase::CanPaste() const { - return IsEditable(); + if ( IsEditable() ) + { +#if wxUSE_CLIPBOARD + // check if there is any text on the clipboard + if ( wxTheClipboard->IsSupported(wxDF_TEXT) +#if wxUSE_UNICODE + || wxTheClipboard->IsSupported(wxDF_UNICODETEXT) +#endif // wxUSE_UNICODE + ) + { + return true; + } +#endif // wxUSE_CLIPBOARD + } + + return false; +} + +// ---------------------------------------------------------------------------- +// hints support +// ---------------------------------------------------------------------------- + +bool wxTextEntryBase::SetHint(const wxString& hint) +{ + if ( !m_hintData ) + m_hintData = new wxTextEntryHintData(this, GetEditableWindow()); + + m_hintData->SetHintString(hint); + + return true; +} + +wxString wxTextEntryBase::GetHint() const +{ + return m_hintData ? m_hintData->GetHintString() : wxString(); } #endif // wxUSE_TEXTCTRL || wxUSE_COMBOBOX