X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/5f6475c145b713efc0c3d8b482338438e927b763..c0badae10089ea785072d739df817b1f5f05c088:/src/msw/textctrl.cpp diff --git a/src/msw/textctrl.cpp b/src/msw/textctrl.cpp index 15311c9683..973f77d283 100644 --- a/src/msw/textctrl.cpp +++ b/src/msw/textctrl.cpp @@ -36,9 +36,9 @@ #include "wx/app.h" #include "wx/menu.h" #include "wx/math.h" + #include "wx/module.h" #endif -#include "wx/module.h" #include "wx/sysopt.h" #if wxUSE_CLIPBOARD @@ -50,7 +50,7 @@ #include #include "wx/msw/private.h" -#include "wx/msw/wrapshl.h" +#include "wx/msw/winundef.h" #include #include @@ -71,10 +71,10 @@ #include #endif -#include "wx/msw/missing.h" - #endif // wxUSE_RICHEDIT +#include "wx/msw/missing.h" + // ---------------------------------------------------------------------------- // private classes // ---------------------------------------------------------------------------- @@ -135,9 +135,13 @@ public: UpdatesCountFilter(int& count) : m_count(count) { - wxASSERT_MSG( m_count == -1, _T("wrong initial m_updatesCount value") ); + wxASSERT_MSG( m_count == -1 || m_count == -2, + _T("wrong initial m_updatesCount value") ); - m_count = 0; + if (m_count != -2) + m_count = 0; + //else: we don't want to count how many update events we get as we're going + // to ignore all of them } ~UpdatesCountFilter() @@ -287,16 +291,17 @@ LRESULT APIENTRY _EXPORT wxTextCtrlWndProc(HWND hWnd, WPARAM wParam, LPARAM lParam) { - wxWindow *win = wxFindWinFromHandle((WXHWND)hWnd); - switch ( message ) { case WM_CUT: case WM_COPY: case WM_PASTE: - if( win->HandleClipboardEvent( message ) ) - return 0; - break; + { + wxWindow *win = wxFindWinFromHandle((WXHWND)hWnd); + if( win->HandleClipboardEvent( message ) ) + return 0; + break; + } } return ::CallWindowProc(CASTWNDPROC gs_wndprocEdit, hWnd, message, wParam, lParam); } @@ -518,9 +523,6 @@ bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id, } #endif // wxUSE_RICHEDIT - if ( style & wxTE_FILENAME ) - wxEnableFileNameAutoComplete(GetHwnd()); - gs_wndprocEdit = wxSetWindowProc((HWND)GetHwnd(), wxTextCtrlWndProc); @@ -661,6 +663,15 @@ void wxTextCtrl::SetWindowStyleFlag(long style) // set/get the controls text // ---------------------------------------------------------------------------- +bool wxTextCtrl::IsEmpty() const +{ + // this is an optimization for multiline controls containing a lot of text + if ( IsMultiLine() && GetNumberOfLines() != 1 ) + return false; + + return wxTextCtrlBase::IsEmpty(); +} + wxString wxTextCtrl::GetValue() const { // range 0..-1 is special for GetRange() and means to retrieve all text @@ -784,7 +795,7 @@ wxString wxTextCtrl::GetRange(long from, long to) const return str; } -void wxTextCtrl::SetValue(const wxString& value) +void wxTextCtrl::DoSetValue(const wxString& value, int flags) { // if the text is long enough, it's faster to just set it instead of first // comparing it with the old one (chances are that it will be different @@ -792,7 +803,7 @@ void wxTextCtrl::SetValue(const wxString& value) // edit controls mostly) if ( (value.length() > 0x400) || (value != GetValue()) ) { - DoWriteText(value, false /* not selection only */); + DoWriteText(value, flags /* doesn't include SelectionOnly here */); // mark the control as being not dirty - we changed its text, not the // user @@ -810,7 +821,8 @@ void wxTextCtrl::SetValue(const wxString& value) DiscardEdits(); // still send an event for consistency - SendUpdateEvent(); + if (flags & SetValue_SendEvent) + SendUpdateEvent(); } } @@ -1008,8 +1020,9 @@ void wxTextCtrl::WriteText(const wxString& value) DoWriteText(value); } -void wxTextCtrl::DoWriteText(const wxString& value, bool selectionOnly) +void wxTextCtrl::DoWriteText(const wxString& value, int flags) { + bool selectionOnly = (flags & SetValue_SelectionOnly) != 0; wxString valueDos; if ( m_windowStyle & wxTE_MULTILINE ) valueDos = wxTextFile::Translate(value, wxTextFileType_Dos); @@ -1073,13 +1086,16 @@ void wxTextCtrl::DoWriteText(const wxString& value, bool selectionOnly) // we generate exactly one of them by ignoring all but the first one in // SendUpdateEvent() and generating one ourselves if we hadn't got any // notifications from Windows + if ( !(flags & SetValue_SendEvent) ) + m_updatesCount = -2; // suppress any update event + UpdatesCountFilter ucf(m_updatesCount); ::SendMessage(GetHwnd(), selectionOnly ? EM_REPLACESEL : WM_SETTEXT, // EM_REPLACESEL takes 1 to indicate the operation should be redoable selectionOnly ? 1 : 0, (LPARAM)valueDos.c_str()); - if ( !ucf.GotUpdate() ) + if ( !ucf.GotUpdate() && (flags & SetValue_SendEvent) ) { SendUpdateEvent(); } @@ -1233,7 +1249,8 @@ void wxTextCtrl::SetInsertionPointEnd() // if it doesn't actually move the caret anywhere and so the simple fact of // doing it results in horrible flicker when appending big amounts of text // to the control in a few chunks (see DoAddText() test in the text sample) - if ( GetInsertionPoint() == GetLastPosition() ) + const wxTextPos lastPosition = GetLastPosition(); + if ( GetInsertionPoint() == lastPosition ) { return; } @@ -1249,7 +1266,7 @@ void wxTextCtrl::SetInsertionPointEnd() else // !RichEdit 1.0 #endif // wxUSE_RICHEDIT { - pos = GetLastPosition(); + pos = lastPosition; } SetInsertionPoint(pos); @@ -1407,9 +1424,9 @@ void wxTextCtrl::DoSetSelection(long from, long to, bool scrollCaret) // Working with files // ---------------------------------------------------------------------------- -bool wxTextCtrl::LoadFile(const wxString& file) +bool wxTextCtrl::DoLoadFile(const wxString& file, int fileType) { - if ( wxTextCtrlBase::LoadFile(file) ) + if ( wxTextCtrlBase::DoLoadFile(file, fileType) ) { // update the size limit if needed AdjustSpaceLimit(); @@ -1429,7 +1446,7 @@ void wxTextCtrl::Replace(long from, long to, const wxString& value) // Set selection and remove it DoSetSelection(from, to, false /* don't scroll caret into view */); - DoWriteText(value, true /* selection only */); + DoWriteText(value); } void wxTextCtrl::Remove(long from, long to) @@ -1784,18 +1801,17 @@ void wxTextCtrl::OnDropFiles(wxDropFilesEvent& event) // kbd input processing // ---------------------------------------------------------------------------- -bool wxTextCtrl::MSWShouldPreProcessMessage(WXMSG* pMsg) +bool wxTextCtrl::MSWShouldPreProcessMessage(WXMSG* msg) { - MSG *msg = (MSG *)pMsg; - // check for our special keys here: if we don't do it and the parent frame // uses them as accelerators, they wouldn't work at all, so we disable // usual preprocessing for them if ( msg->message == WM_KEYDOWN ) { - WORD vkey = (WORD) msg->wParam; - if ( (HIWORD(msg->lParam) & KF_ALTDOWN) == KF_ALTDOWN ) + const WPARAM vkey = msg->wParam; + if ( HIWORD(msg->lParam) & KF_ALTDOWN ) { + // Alt-Backspace is accelerator for "Undo" if ( vkey == VK_BACK ) return false; } @@ -1813,6 +1829,9 @@ bool wxTextCtrl::MSWShouldPreProcessMessage(WXMSG* pMsg) // fall through case 0: + if ( IsMultiLine() && vkey == VK_RETURN ) + return false; + // fall through case 2: break; @@ -1841,7 +1860,7 @@ bool wxTextCtrl::MSWShouldPreProcessMessage(WXMSG* pMsg) } } - return wxControl::MSWShouldPreProcessMessage(pMsg); + return wxControl::MSWShouldPreProcessMessage(msg); } void wxTextCtrl::OnChar(wxKeyEvent& event) @@ -1971,6 +1990,11 @@ bool wxTextCtrl::SendUpdateEvent() // we hadn't updated the control ourselves, this event comes from // the user, don't need to ignore it nor update the count break; + + case -2: + // the control was updated programmatically and we do NOT want to + // send events + return false; } wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, GetId()); @@ -2564,11 +2588,23 @@ bool wxTextCtrl::SetStyle(long start, long end, const wxTextAttr& style) } } - if (pf.dwMask != 0) +#if wxUSE_RICHEDIT2 + if ( m_verRichEdit > 1 ) + { + if ( wxTheApp->GetLayoutDirection() == wxLayout_RightToLeft ) + { + // Use RTL paragraphs in RTL mode to get proper layout + pf.dwMask |= PFM_RTLPARA; + pf.wEffects |= PFE_RTLPARA; + } + } +#endif // wxUSE_RICHEDIT2 + + if ( pf.dwMask ) { // do format the selection bool ok = ::SendMessage(GetHwnd(), EM_SETPARAFORMAT, - 0, (LPARAM) &pf) != 0; + 0, (LPARAM) &pf) != 0; if ( !ok ) { wxLogDebug(_T("SendMessage(EM_SETPARAFORMAT, 0) failed"));