#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
#include "wx/msw/private.h"
#include "wx/msw/winundef.h"
+#include "wx/msw/mslu.h"
#include <string.h>
#include <stdlib.h>
#include <richedit.h>
#endif
-#include "wx/msw/missing.h"
-
#endif // wxUSE_RICHEDIT
+#include "wx/msw/missing.h"
+
// ----------------------------------------------------------------------------
// private classes
// ----------------------------------------------------------------------------
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()
wxCONSTRUCTOR_6( wxTextCtrl , wxWindow* , Parent , wxWindowID , Id , wxString , Value , wxPoint , Position , wxSize , Size , long , WindowStyle)
#else
-IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl)
+IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxTextCtrlBase)
#endif
-BEGIN_EVENT_TABLE(wxTextCtrl, wxControl)
+BEGIN_EVENT_TABLE(wxTextCtrl, wxTextCtrlBase)
EVT_CHAR(wxTextCtrl::OnChar)
EVT_DROP_FILES(wxTextCtrl::OnDropFiles)
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);
}
// 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
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
// 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
DiscardEdits();
// still send an event for consistency
- SendUpdateEvent();
+ if (flags & SetValue_SendEvent)
+ SendUpdateEvent();
}
}
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);
// 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();
}
// 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;
}
else // !RichEdit 1.0
#endif // wxUSE_RICHEDIT
{
- pos = GetLastPosition();
+ pos = lastPosition;
}
SetInsertionPoint(pos);
// 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();
// 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)
// 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;
}
// fall through
case 0:
+ if ( IsMultiLine() && vkey == VK_RETURN )
+ return false;
+ // fall through
case 2:
break;
}
}
- return wxControl::MSWShouldPreProcessMessage(pMsg);
+ return wxControl::MSWShouldPreProcessMessage(msg);
}
void wxTextCtrl::OnChar(wxKeyEvent& event)
// 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());
}
}
- 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"));