X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/a290fa5a7deebe9d96c0c0089d18e27d4bd9b624..69659fd770f615210efac4b4fa741b3ad6223616:/src/univ/textctrl.cpp diff --git a/src/univ/textctrl.cpp b/src/univ/textctrl.cpp index 84f5c7d78b..487fb2fca0 100644 --- a/src/univ/textctrl.cpp +++ b/src/univ/textctrl.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: univ/textctrl.cpp +// Name: src/univ/textctrl.cpp // Purpose: wxTextCtrl // Author: Vadim Zeitlin // Modified by: @@ -47,7 +47,7 @@ is true in which case a single LINE may correspond to multiple ROWs. A text position is an unsigned int (which for reasons of compatibility is - still a long) from 0 to GetLastPosition() inclusive. The positions + still a long as wxTextPos) from 0 to GetLastPosition() inclusive. The positions correspond to the gaps between the letters so the position 0 is just before the first character and the last position is the one beyond the last character. For an empty text control GetLastPosition() returns 0. @@ -117,10 +117,6 @@ // headers // ---------------------------------------------------------------------------- -#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) - #pragma implementation "univtextctrl.h" -#endif - #include "wx/wxprec.h" #ifdef __BORLANDC__ @@ -129,16 +125,17 @@ #if wxUSE_TEXTCTRL -#include +#include "wx/textctrl.h" #ifndef WX_PRECOMP #include "wx/log.h" - #include "wx/dcclient.h" #include "wx/validate.h" - #include "wx/textctrl.h" + #include "wx/dataobj.h" #endif +#include + #include "wx/clipbrd.h" #include "wx/textfile.h" @@ -152,10 +149,6 @@ #include "wx/cmdproc.h" -#if wxUSE_CLIPBOARD -#include "wx/dataobj.h" -#endif - // turn extra wxTextCtrl-specific debugging on/off #define WXDEBUG_TEXT @@ -172,6 +165,33 @@ #include "wx/tokenzr.h" #endif // WXDEBUG_TEXT_REPLACE +// ---------------------------------------------------------------------------- +// wxStdTextCtrlInputHandler: this control handles only the mouse/kbd actions +// common to Win32 and GTK, platform-specific things are implemented elsewhere +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxStdTextCtrlInputHandler : public wxStdInputHandler +{ +public: + wxStdTextCtrlInputHandler(wxInputHandler *inphand); + + virtual bool HandleKey(wxInputConsumer *consumer, + const wxKeyEvent& event, + bool pressed); + virtual bool HandleMouse(wxInputConsumer *consumer, + const wxMouseEvent& event); + virtual bool HandleMouseMove(wxInputConsumer *consumer, + const wxMouseEvent& event); + virtual bool HandleFocus(wxInputConsumer *consumer, const wxFocusEvent& event); + +protected: + // get the position of the mouse click + static wxTextPos HitTest(const wxTextCtrl *text, const wxPoint& pos); + + // capture data + wxTextCtrl *m_winCapture; +}; + // ---------------------------------------------------------------------------- // private functions // ---------------------------------------------------------------------------- @@ -197,7 +217,7 @@ static inline void OrderPositions(wxTextPos& from, wxTextPos& to) // the value which is never used for text position, even not -1 which is // sometimes used for some special meaning -static const wxTextPos INVALID_POS_VALUE = -2; +static const wxTextPos INVALID_POS_VALUE = wxInvalidTextCoord; // overlap between pages (when using PageUp/Dn) in lines static const size_t PAGE_OVERLAP_IN_LINES = 1; @@ -207,7 +227,7 @@ static const size_t PAGE_OVERLAP_IN_LINES = 1; // ---------------------------------------------------------------------------- // the data only used by single line text controls -struct WXDLLEXPORT wxTextSingleLineData +struct wxTextSingleLineData { // the position of the first visible pixel and the first visible column wxCoord m_ofsHorz; @@ -231,7 +251,7 @@ struct WXDLLEXPORT wxTextSingleLineData }; // the data only used by multi line text controls -struct WXDLLEXPORT wxTextMultiLineData +struct wxTextMultiLineData { // the lines of text wxArrayString m_lines; @@ -280,7 +300,7 @@ struct WXDLLEXPORT wxTextMultiLineData }; // the data only used by multi line text controls in line wrap mode -class WXDLLEXPORT wxWrappedLineData +class wxWrappedLineData { // these functions set all our values, so give them access to them friend void wxTextCtrl::LayoutLine(wxTextCoord line, @@ -440,7 +460,7 @@ WX_DECLARE_OBJARRAY(wxWrappedLineData, wxArrayWrappedLinesData); #include "wx/arrimpl.cpp" WX_DEFINE_OBJARRAY(wxArrayWrappedLinesData); -struct WXDLLEXPORT wxTextWrappedData : public wxTextMultiLineData +struct wxTextWrappedData : public wxTextMultiLineData { // the width of the column to the right of the text rect used for the // indicator mark display for the wrapped lines @@ -610,13 +630,13 @@ private: // implementation // ============================================================================ -BEGIN_EVENT_TABLE(wxTextCtrl, wxControl) +BEGIN_EVENT_TABLE(wxTextCtrl, wxTextCtrlBase) EVT_CHAR(wxTextCtrl::OnChar) EVT_SIZE(wxTextCtrl::OnSize) END_EVENT_TABLE() -IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl) +IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxTextCtrlBase) // ---------------------------------------------------------------------------- // creation @@ -630,6 +650,7 @@ void wxTextCtrl::Init() m_isModified = false; m_isEditable = true; + m_wrapLines = false; m_posLast = m_curPos = @@ -639,9 +660,6 @@ void wxTextCtrl::Init() m_heightLine = m_widthAvg = -1; - // init wxScrollHelper - SetWindow(this); - // init the undo manager m_cmdProcessor = new wxTextCtrlCommandProcessor(this); @@ -669,23 +687,27 @@ bool wxTextCtrl::Create(wxWindow *parent, style |= wxALWAYS_SHOW_SB; } - // wxTE_WORDWRAP is 0 for now so we don't need the code below -#if 0 - if ( style & wxTE_WORDWRAP ) - { - // wrapping words means wrapping, hence no horz scrollbar - style &= ~wxHSCROLL; - } -#endif // 0 + // wrapping style: wxTE_DONTWRAP == wxHSCROLL so if it's _not_ given, + // we won't have horizontal scrollbar automatically, no need to do + // anything // TODO: support wxTE_NO_VSCROLL (?) // create data object for normal multiline or for controls with line // wrap as needed if ( style & wxHSCROLL ) + { m_data.mdata = new wxTextMultiLineData; - else + } + else // we must wrap lines if we don't have horizontal scrollbar + { + // NB: we can't rely on HasFlag(wxHSCROLL) as the flags can change + // later and even wxWindow::Create() itself temporarily resets + // wxHSCROLL in wxUniv, so remember that we have a wrapped data + // and not just a multi line data in a separate variable + m_wrapLines = true; m_data.wdata = new wxTextWrappedData; + } } else { @@ -695,7 +717,7 @@ bool wxTextCtrl::Create(wxWindow *parent, // create data object for single line controls m_data.sdata = new wxTextSingleLineData; } - + #if wxUSE_TWO_WINDOWS if ((style & wxBORDER_MASK) == 0) style |= wxBORDER_SUNKEN; @@ -728,7 +750,7 @@ bool wxTextCtrl::Create(wxWindow *parent, RecalcFontMetrics(); SetValue(value); - SetBestSize(size); + SetInitialSize(size); m_isEditable = !(style & wxTE_READONLY); @@ -766,7 +788,7 @@ wxTextCtrl::~wxTextCtrl() // set/get the value // ---------------------------------------------------------------------------- -void wxTextCtrl::SetValue(const wxString& value) +void wxTextCtrl::DoSetValue(const wxString& value, int flags) { if ( IsSingleLine() && (value == GetValue()) ) { @@ -781,7 +803,8 @@ void wxTextCtrl::SetValue(const wxString& value) SetInsertionPoint(0); } - // TODO: should we generate the event or not, finally? + if ( flags & SetValue_SendEvent ) + SendTextUpdatedEvent(); } const wxArrayString& wxTextCtrl::GetLines() const @@ -821,7 +844,7 @@ wxString wxTextCtrl::GetValue() const void wxTextCtrl::Clear() { - SetValue(_T("")); + SetValue(wxEmptyString); } bool wxTextCtrl::ReplaceLine(wxTextCoord line, @@ -1249,7 +1272,7 @@ void wxTextCtrl::Remove(wxTextPos from, wxTextPos to) // if necessary OrderPositions(from, to); - Replace(from, to, _T("")); + Replace(from, to, wxEmptyString); } void wxTextCtrl::WriteText(const wxString& text) @@ -1421,8 +1444,12 @@ wxString wxTextCtrl::GetSelectionText() const void wxTextCtrl::SetSelection(wxTextPos from, wxTextPos to) { // selecting till -1 is the same as selecting to the end - if ( to == -1 && from != -1 ) + if ( to == -1 ) { + // and selecting (-1, -1) range is the same as selecting everything, by + // convention + if ( from == -1 ) + from = 0; to = GetLastPosition(); } @@ -1650,8 +1677,8 @@ wxString wxTextCtrl::GetLineText(wxTextCoord line) const { //this is called during DoGetBestSize if (line == 0 && GetLineCount() == 0) return wxEmptyString ; - - wxCHECK_MSG( (size_t)line < GetLineCount(), _T(""), + + wxCHECK_MSG( (size_t)line < GetLineCount(), wxEmptyString, _T("line index out of range") ); return GetLines()[line]; @@ -1670,7 +1697,7 @@ wxTextPos wxTextCtrl::XYToPosition(wxTextCoord x, wxTextCoord y) const // if they are out of range if ( IsSingleLine() ) { - return x > GetLastPosition() || y > 0 ? wxDefaultCoord : x; + return ( x > GetLastPosition() || y > 0 ) ? wxOutOfRangeTextCoord : x; } else // multiline { @@ -2360,7 +2387,7 @@ wxSize wxTextCtrl::DoGetBestClientSize() const void wxTextCtrl::UpdateTextRect() { - wxRect rectTotal(wxPoint(0, 0), GetClientSize()); + wxRect rectTotal(GetClientSize()); wxCoord *extraSpace = WrapLines() ? &WData().m_widthMark : NULL; m_rectText = GetRenderer()->GetTextClientArea(this, rectTotal, extraSpace); @@ -2695,7 +2722,7 @@ size_t wxTextCtrl::GetPartOfWrappedLine(const wxChar* text, //else: we can just see it // wrap at any character or only at words boundaries? - if ( !(GetWindowStyle() & wxTE_LINEWRAP) ) + if ( !(GetWindowStyle() & wxTE_CHARWRAP) ) { // find the (last) not word char before this word wxTextCoord colWordStart; @@ -3719,7 +3746,7 @@ void wxTextCtrl::RefreshTextRange(wxTextPos start, wxTextPos end) { // intermediate line or the last one but we need to refresh it // until the end anyhow - do it - posCount = wxSTRING_MAXLEN; + posCount = wxString::npos; } else // last line { @@ -4146,7 +4173,7 @@ void wxTextCtrl::DoDraw(wxControlRenderer *renderer) // the update region is in window coords and text area is in the client // ones, so it must be shifted before computing intersection wxRegion rgnUpdate = GetUpdateRegion(); - + wxRect rectTextArea = GetRealTextArea(); wxPoint pt = GetClientAreaOrigin(); wxRect rectTextAreaAdjusted = rectTextArea; @@ -4270,9 +4297,6 @@ void wxTextCtrl::CreateCaret() { // FIXME use renderer caret = new wxCaret(this, 1, GetLineHeight()); -#ifndef __WXMSW__ - caret->SetBlinkTime(0); -#endif // __WXMSW__ } else { @@ -4680,7 +4704,6 @@ bool wxTextCtrl::PerformAction(const wxControlAction& actionOrig, wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, GetId()); InitCommandEvent(event); - event.SetString(GetValue()); GetEventHandler()->ProcessEvent(event); // as the text changed... @@ -4696,6 +4719,9 @@ void wxTextCtrl::OnChar(wxKeyEvent& event) if ( !event.HasModifiers() ) { int keycode = event.GetKeyCode(); +#if wxUSE_UNICODE + wxChar unicode = event.GetUnicodeKey(); +#endif if ( keycode == WXK_RETURN ) { if ( IsSingleLine() || (GetWindowStyle() & wxTE_PROCESS_ENTER) ) @@ -4717,6 +4743,14 @@ void wxTextCtrl::OnChar(wxKeyEvent& event) // skip event.Skip() below return; } +#if wxUSE_UNICODE + else if (unicode > 0) + { + PerformAction(wxACTION_TEXT_INSERT, -1, unicode); + + return; + } +#endif } #ifdef __WXDEBUG__ // Ctrl-R refreshes the control in debug mode @@ -4727,6 +4761,14 @@ void wxTextCtrl::OnChar(wxKeyEvent& event) event.Skip(); } +/* static */ +wxInputHandler *wxTextCtrl::GetStdInputHandler(wxInputHandler *handlerDef) +{ + static wxStdTextCtrlInputHandler s_handler(handlerDef); + + return &s_handler; +} + // ---------------------------------------------------------------------------- // wxStdTextCtrlInputHandler // ---------------------------------------------------------------------------- @@ -4816,14 +4858,12 @@ bool wxStdTextCtrlInputHandler::HandleKey(wxInputConsumer *consumer, break; case WXK_PAGEDOWN: - case WXK_NEXT: // we don't map Ctrl-PgUp/Dn to anything special - what should it // to? for now, it's the same as without control action << wxACTION_TEXT_PAGE_DOWN; break; case WXK_PAGEUP: - case WXK_PRIOR: action << wxACTION_TEXT_PAGE_UP; break;