X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/442b35b53bf95f5c6c003ea9ddbefd17adbc2a00..f8b2997476e15b63f1699b9f7b6f1db2ae6b440c:/src/univ/textctrl.cpp diff --git a/src/univ/textctrl.cpp b/src/univ/textctrl.cpp index b6a4b8810d..3b15ef1070 100644 --- a/src/univ/textctrl.cpp +++ b/src/univ/textctrl.cpp @@ -6,7 +6,7 @@ // Created: 15.09.00 // RCS-ID: $Id$ // Copyright: (c) 2000 SciTech Software, Inc. (www.scitechsoft.com) -// Licence: wxWindows license +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// /* @@ -117,7 +117,7 @@ // headers // ---------------------------------------------------------------------------- -#ifdef __GNUG__ +#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) #pragma implementation "univtextctrl.h" #endif @@ -129,6 +129,8 @@ #if wxUSE_TEXTCTRL +#include + #ifndef WX_PRECOMP #include "wx/log.h" @@ -150,6 +152,10 @@ #include "wx/cmdproc.h" +#if wxUSE_CLIPBOARD +#include "wx/dataobj.h" +#endif + // turn extra wxTextCtrl-specific debugging on/off #define WXDEBUG_TEXT @@ -481,7 +487,7 @@ struct WXDLLEXPORT wxTextWrappedData : public wxTextMultiLineData // ---------------------------------------------------------------------------- /* - We use custom versions of wxWindows command processor to implement undo/redo + We use custom versions of wxWidgets command processor to implement undo/redo as we want to avoid storing the backpointer to wxTextCtrl in wxCommand itself: this is a waste of memory as all commands in the given command processor always have the same associated wxTextCtrl and so it makes sense @@ -522,6 +528,8 @@ public: virtual bool CanUndo() const; virtual bool Do(wxTextCtrl *text); + virtual bool Do() { return wxTextCtrlCommand::Do(); } + virtual bool Undo() { return wxTextCtrlCommand::Undo(); } virtual bool Undo(wxTextCtrl *text); private: @@ -545,6 +553,8 @@ public: virtual bool CanUndo() const; virtual bool Do(wxTextCtrl *text); + virtual bool Do() { return wxTextCtrlCommand::Do(); } + virtual bool Undo() { return wxTextCtrlCommand::Undo(); } virtual bool Undo(wxTextCtrl *text); private: @@ -604,8 +614,6 @@ BEGIN_EVENT_TABLE(wxTextCtrl, wxControl) EVT_CHAR(wxTextCtrl::OnChar) EVT_SIZE(wxTextCtrl::OnSize) - - EVT_IDLE(wxTextCtrl::OnIdle) END_EVENT_TABLE() IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl) @@ -661,11 +669,14 @@ 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 // TODO: support wxTE_NO_VSCROLL (?) @@ -684,6 +695,11 @@ 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; +#endif if ( !wxControl::Create(parent, id, pos, size, style, validator, name) ) @@ -725,6 +741,9 @@ bool wxTextCtrl::Create(wxWindow *parent, CreateInputHandler(wxINP_HANDLER_TEXTCTRL); + wxSizeEvent sizeEvent(GetSize(), GetId()); + GetEventHandler()->ProcessEvent(sizeEvent); + return TRUE; } @@ -1413,6 +1432,10 @@ void wxTextCtrl::SetSelection(wxTextPos from, wxTextPos to) } else // valid sel range { + // remember the 'to' position as the current position, used to move the + // caret there later + wxTextPos toOrig = to; + OrderPositions(from, to); wxCHECK_RET( to <= GetLastPosition(), @@ -1458,8 +1481,8 @@ void wxTextCtrl::SetSelection(wxTextPos from, wxTextPos to) } //else: nothing to do - // the insertion point is put at the end of selection - DoSetInsertionPoint(to); + // the insertion point is put at the location where the caret was moved + DoSetInsertionPoint(toOrig); } } @@ -1562,6 +1585,11 @@ bool wxTextCtrl::IsEditable() const return m_isEditable && IsEnabled(); } +void wxTextCtrl::MarkDirty() +{ + m_isModified = TRUE; +} + void wxTextCtrl::DiscardEdits() { m_isModified = FALSE; @@ -1620,6 +1648,9 @@ wxString wxTextCtrl::GetLineText(wxTextCoord line) const } else // multiline { + //this is called during DoGetBestSize + if (line == 0 && GetLineCount() == 0) return wxEmptyString ; + wxCHECK_MSG( (size_t)line < GetLineCount(), _T(""), _T("line index out of range") ); @@ -1850,7 +1881,9 @@ wxPoint wxTextCtrl::GetCaretPosition() const // pos may be -1 to show the current position void wxTextCtrl::ShowPosition(wxTextPos pos) { - HideCaret(); + bool showCaret = GetCaret() && GetCaret()->IsVisible(); + if (showCaret) + HideCaret(); if ( IsSingleLine() ) { @@ -1970,7 +2003,8 @@ void wxTextCtrl::ShowPosition(wxTextPos pos) } //else: multiline but no scrollbars, hence nothing to do - ShowCaret(); + if (showCaret) + ShowCaret(); } // ---------------------------------------------------------------------------- @@ -2314,7 +2348,7 @@ wxSize wxTextCtrl::DoGetBestClientSize() const lines = 5; else if ( lines > 10 ) lines = 10; - h *= 10; + h *= lines; } wxRect rectText; @@ -2429,7 +2463,7 @@ void wxTextCtrl::UpdateLastVisible() SData().m_colLastVisible += SData().m_colStart; wxLogTrace(_T("text"), _T("Last visible column/position is %d/%ld"), - SData().m_colLastVisible, SData().m_posLastVisible); + (int) SData().m_colLastVisible, (long) SData().m_posLastVisible); } void wxTextCtrl::OnSize(wxSizeEvent& event) @@ -3555,7 +3589,7 @@ void wxTextCtrl::UpdateScrollbars() MData().m_updateScrollbarY = FALSE; } -void wxTextCtrl::OnIdle(wxIdleEvent& event) +void wxTextCtrl::OnInternalIdle() { // notice that single line text control never has scrollbars if ( !IsSingleLine() && @@ -3563,8 +3597,7 @@ void wxTextCtrl::OnIdle(wxIdleEvent& event) { UpdateScrollbars(); } - - event.Skip(); + wxControl::OnInternalIdle(); } bool wxTextCtrl::SendAutoScrollEvents(wxScrollWinEvent& event) const @@ -4101,6 +4134,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; @@ -4165,7 +4199,7 @@ void wxTextCtrl::DoDraw(wxControlRenderer *renderer) // show caret first time only: we must show it after drawing the text or // the display can be corrupted when it's hidden - if ( !m_hasCaret && GetCaret() ) + if ( !m_hasCaret && GetCaret() && (FindFocus() == this) ) { ShowCaret(); @@ -4208,7 +4242,10 @@ bool wxTextCtrl::Enable(bool enable) if ( !wxTextCtrlBase::Enable(enable) ) return FALSE; - ShowCaret(enable); + if (FindFocus() == this && GetCaret() && + ((enable && !GetCaret()->IsVisible()) || + (!enable && GetCaret()->IsVisible()))) + ShowCaret(enable); return TRUE; } @@ -4244,7 +4281,9 @@ void wxTextCtrl::ShowCaret(bool show) caret->Move(GetCaretPosition()); // and show it there - caret->Show(show); + if ((show && !caret->IsVisible()) || + (!show && caret->IsVisible())) + caret->Show(show); } } @@ -4705,7 +4744,7 @@ wxTextPos wxStdTextCtrlInputHandler::HitTest(const wxTextCtrl *text, return pos; } -bool wxStdTextCtrlInputHandler::HandleKey(wxControl *control, +bool wxStdTextCtrlInputHandler::HandleKey(wxInputConsumer *consumer, const wxKeyEvent& event, bool pressed) { @@ -4822,22 +4861,22 @@ bool wxStdTextCtrlInputHandler::HandleKey(wxControl *control, if ( (action != wxACTION_NONE) && (action != wxACTION_TEXT_PREFIX_SEL) ) { - control->PerformAction(action, -1, str); + consumer->PerformAction(action, -1, str); return TRUE; } - return wxStdInputHandler::HandleKey(control, event, pressed); + return wxStdInputHandler::HandleKey(consumer, event, pressed); } -bool wxStdTextCtrlInputHandler::HandleMouse(wxControl *control, +bool wxStdTextCtrlInputHandler::HandleMouse(wxInputConsumer *consumer, const wxMouseEvent& event) { if ( event.LeftDown() ) { wxASSERT_MSG( !m_winCapture, _T("left button going down twice?") ); - wxTextCtrl *text = wxStaticCast(control, wxTextCtrl); + wxTextCtrl *text = wxStaticCast(consumer->GetInputWindow(), wxTextCtrl); m_winCapture = text; m_winCapture->CaptureMouse(); @@ -4853,7 +4892,7 @@ bool wxStdTextCtrlInputHandler::HandleMouse(wxControl *control, else if ( event.LeftDClick() ) { // select the word the cursor is on - control->PerformAction(wxACTION_TEXT_SEL_WORD); + consumer->PerformAction(wxACTION_TEXT_SEL_WORD); } else if ( event.LeftUp() ) { @@ -4866,10 +4905,10 @@ bool wxStdTextCtrlInputHandler::HandleMouse(wxControl *control, } } - return wxStdInputHandler::HandleMouse(control, event); + return wxStdInputHandler::HandleMouse(consumer, event); } -bool wxStdTextCtrlInputHandler::HandleMouseMove(wxControl *control, +bool wxStdTextCtrlInputHandler::HandleMouseMove(wxInputConsumer *consumer, const wxMouseEvent& event) { if ( m_winCapture ) @@ -4883,17 +4922,29 @@ bool wxStdTextCtrlInputHandler::HandleMouseMove(wxControl *control, } } - return wxStdInputHandler::HandleMouseMove(control, event); + return wxStdInputHandler::HandleMouseMove(consumer, event); } -bool wxStdTextCtrlInputHandler::HandleFocus(wxControl *control, - const wxFocusEvent& event) +bool +wxStdTextCtrlInputHandler::HandleFocus(wxInputConsumer *consumer, + const wxFocusEvent& event) { - wxTextCtrl *text = wxStaticCast(control, wxTextCtrl); + wxTextCtrl *text = wxStaticCast(consumer->GetInputWindow(), wxTextCtrl); // the selection appearance changes depending on whether we have the focus text->RefreshSelection(); + if (event.GetEventType() == wxEVT_SET_FOCUS) + { + if (text->GetCaret() && !text->GetCaret()->IsVisible()) + text->ShowCaret(); + } + else + { + if (text->GetCaret() && text->GetCaret()->IsVisible()) + text->HideCaret(); + } + // never refresh entirely return FALSE; }