wxTextCtrl::GetValue() lost (replaced with question marks) all characters not in the current encoding -- but now it shouldn't
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@23729 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -54,6 +54,7 @@ All (GUI):
|
|||||||
wxMSW:
|
wxMSW:
|
||||||
|
|
||||||
- fixed wxTE_*WRAP styles handling
|
- fixed wxTE_*WRAP styles handling
|
||||||
|
- wxTextCtrl::GetValue() works with text in non default encoding
|
||||||
|
|
||||||
wxGTK:
|
wxGTK:
|
||||||
|
|
||||||
|
@@ -207,12 +207,13 @@ protected:
|
|||||||
// false if we hit the limit set by SetMaxLength() and so didn't change it
|
// false if we hit the limit set by SetMaxLength() and so didn't change it
|
||||||
bool AdjustSpaceLimit();
|
bool AdjustSpaceLimit();
|
||||||
|
|
||||||
#if wxUSE_RICHEDIT
|
#if wxUSE_RICHEDIT && (!wxUSE_UNICODE || wxUSE_UNICODE_MSLU)
|
||||||
// replace the selection or the entire control contents with the given text
|
// replace the selection or the entire control contents with the given text
|
||||||
// in the specified encoding
|
// in the specified encoding
|
||||||
bool StreamIn(const wxString& value,
|
bool StreamIn(const wxString& value, wxFontEncoding encoding, bool selOnly);
|
||||||
wxFontEncoding encoding,
|
|
||||||
bool selOnly);
|
// get the contents of the control out as text in the given encoding
|
||||||
|
wxString StreamOut(wxFontEncoding encoding, bool selOnly = false) const;
|
||||||
#endif // wxUSE_RICHEDIT
|
#endif // wxUSE_RICHEDIT
|
||||||
|
|
||||||
// replace the contents of the selection or of the entire control with the
|
// replace the contents of the selection or of the entire control with the
|
||||||
|
@@ -73,16 +73,6 @@
|
|||||||
|
|
||||||
#endif // wxUSE_RICHEDIT
|
#endif // wxUSE_RICHEDIT
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// private functions
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#if wxUSE_RICHEDIT
|
|
||||||
|
|
||||||
DWORD CALLBACK wxRichEditStreamIn(DWORD dwCookie, BYTE *buf, LONG cb, LONG *pcb);
|
|
||||||
|
|
||||||
#endif // wxUSE_RICHEDIT
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// private classes
|
// private classes
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -537,6 +527,35 @@ wxString wxTextCtrl::GetRange(long from, long to) const
|
|||||||
int len = GetWindowTextLength(GetHwnd());
|
int len = GetWindowTextLength(GetHwnd());
|
||||||
if ( len > from )
|
if ( len > from )
|
||||||
{
|
{
|
||||||
|
if ( to == -1 )
|
||||||
|
to = len;
|
||||||
|
|
||||||
|
// we must use EM_STREAMOUT if we don't want to lose all characters
|
||||||
|
// not representable in the current character set (EM_GETTEXTRANGE
|
||||||
|
// simply replaces them with question marks...)
|
||||||
|
//
|
||||||
|
// as EM_STREAMOUT only works for the entire controls contents (or
|
||||||
|
// just the selection but it's probably a bad idea to play games
|
||||||
|
// with selection here...), we can't use it unless we're called
|
||||||
|
// from GetValue(), i.e. we want to retrieve all text
|
||||||
|
if ( GetRichVersion() > 1 && (from == 0 && to >= len) )
|
||||||
|
{
|
||||||
|
wxFont font = m_defaultStyle.GetFont();
|
||||||
|
if ( !font.Ok() )
|
||||||
|
font = GetFont();
|
||||||
|
|
||||||
|
if ( font.Ok() )
|
||||||
|
{
|
||||||
|
wxFontEncoding encoding = font.GetEncoding();
|
||||||
|
if ( encoding != wxFONTENCODING_SYSTEM )
|
||||||
|
{
|
||||||
|
str = StreamOut(encoding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// StreamOut() wasn't used or failed, try to do it in normal way
|
||||||
|
if ( str.empty() )
|
||||||
{
|
{
|
||||||
// alloc one extra WORD as needed by the control
|
// alloc one extra WORD as needed by the control
|
||||||
wxStringBuffer tmp(str, ++len);
|
wxStringBuffer tmp(str, ++len);
|
||||||
@@ -620,12 +639,17 @@ void wxTextCtrl::SetValue(const wxString& value)
|
|||||||
|
|
||||||
#if wxUSE_RICHEDIT && (!wxUSE_UNICODE || wxUSE_UNICODE_MSLU)
|
#if wxUSE_RICHEDIT && (!wxUSE_UNICODE || wxUSE_UNICODE_MSLU)
|
||||||
|
|
||||||
DWORD CALLBACK wxRichEditStreamIn(DWORD dwCookie, BYTE *buf, LONG cb, LONG *pcb)
|
// TODO: using memcpy() would improve performance a lot for big amounts of text
|
||||||
|
|
||||||
|
DWORD CALLBACK
|
||||||
|
wxRichEditStreamIn(DWORD dwCookie, BYTE *buf, LONG cb, LONG *pcb)
|
||||||
{
|
{
|
||||||
*pcb = 0;
|
*pcb = 0;
|
||||||
|
|
||||||
|
const wchar_t ** const ppws = (const wchar_t **)dwCookie;
|
||||||
|
|
||||||
wchar_t *wbuf = (wchar_t *)buf;
|
wchar_t *wbuf = (wchar_t *)buf;
|
||||||
const wchar_t *wpc = *(const wchar_t **)dwCookie;
|
const wchar_t *wpc = *ppws;
|
||||||
while ( cb && *wpc )
|
while ( cb && *wpc )
|
||||||
{
|
{
|
||||||
*wbuf++ = *wpc++;
|
*wbuf++ = *wpc++;
|
||||||
@@ -634,25 +658,51 @@ DWORD CALLBACK wxRichEditStreamIn(DWORD dwCookie, BYTE *buf, LONG cb, LONG *pcb)
|
|||||||
(*pcb) += sizeof(wchar_t);
|
(*pcb) += sizeof(wchar_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
*(const wchar_t **)dwCookie = wpc;
|
*ppws = wpc;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DWORD CALLBACK
|
||||||
|
wxRichEditStreamOut(DWORD dwCookie, BYTE *buf, LONG cb, LONG *pcb)
|
||||||
|
{
|
||||||
|
*pcb = 0;
|
||||||
|
|
||||||
|
wchar_t ** const ppws = (wchar_t **)dwCookie;
|
||||||
|
|
||||||
|
const wchar_t *wbuf = (const wchar_t *)buf;
|
||||||
|
wchar_t *wpc = *ppws;
|
||||||
|
while ( cb && *wpc )
|
||||||
|
{
|
||||||
|
*wpc++ = *wbuf++;
|
||||||
|
|
||||||
|
cb -= sizeof(wchar_t);
|
||||||
|
(*pcb) += sizeof(wchar_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
*ppws = wpc;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// from utils.cpp
|
// from utils.cpp
|
||||||
extern WXDLLIMPEXP_BASE long wxEncodingToCodepage(wxFontEncoding encoding);
|
extern WXDLLIMPEXP_BASE long wxEncodingToCodepage(wxFontEncoding encoding);
|
||||||
|
|
||||||
#if wxUSE_UNICODE_MSLU
|
#if wxUSE_UNICODE_MSLU
|
||||||
bool wxTextCtrl::StreamIn(const wxString& value,
|
#define UNUSED_IF_MSLU(param)
|
||||||
wxFontEncoding WXUNUSED(encoding),
|
#else
|
||||||
|
#define UNUSED_IF_MSLU(param) param
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool
|
||||||
|
wxTextCtrl::StreamIn(const wxString& value,
|
||||||
|
wxFontEncoding UNUSED_IF_MSLU(encoding),
|
||||||
bool selectionOnly)
|
bool selectionOnly)
|
||||||
{
|
{
|
||||||
|
#if wxUSE_UNICODE_MSLU
|
||||||
const wchar_t *wpc = value.c_str();
|
const wchar_t *wpc = value.c_str();
|
||||||
#else // !wxUSE_UNICODE_MSLU
|
#else // !wxUSE_UNICODE_MSLU
|
||||||
bool wxTextCtrl::StreamIn(const wxString& value,
|
|
||||||
wxFontEncoding encoding,
|
|
||||||
bool selectionOnly)
|
|
||||||
{
|
|
||||||
// we have to use EM_STREAMIN to force richedit control 2.0+ to show any
|
// we have to use EM_STREAMIN to force richedit control 2.0+ to show any
|
||||||
// text in the non default charset -- otherwise it thinks it knows better
|
// text in the non default charset -- otherwise it thinks it knows better
|
||||||
// than we do and always shows it in the default one
|
// than we do and always shows it in the default one
|
||||||
@@ -716,6 +766,61 @@ bool wxTextCtrl::StreamIn(const wxString& value,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !wxUSE_UNICODE_MSLU
|
||||||
|
|
||||||
|
wxString
|
||||||
|
wxTextCtrl::StreamOut(wxFontEncoding encoding, bool selectionOnly) const
|
||||||
|
{
|
||||||
|
wxString out;
|
||||||
|
|
||||||
|
const int len = GetWindowTextLength(GetHwnd());
|
||||||
|
|
||||||
|
#if wxUSE_WCHAR_T
|
||||||
|
wxWCharBuffer wchBuf(len);
|
||||||
|
wchar_t *wpc = wchBuf.data();
|
||||||
|
#else
|
||||||
|
wchar_t *wchBuf = (wchar_t *)malloc((len + 1)*sizeof(wchar_t));
|
||||||
|
wchar_t *wpc = wchBuf;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
EDITSTREAM eds;
|
||||||
|
wxZeroMemory(eds);
|
||||||
|
eds.dwCookie = (DWORD)&wpc;
|
||||||
|
eds.pfnCallback = wxRichEditStreamOut;
|
||||||
|
|
||||||
|
::SendMessage
|
||||||
|
(
|
||||||
|
GetHwnd(),
|
||||||
|
EM_STREAMOUT,
|
||||||
|
SF_TEXT | SF_UNICODE | (selectionOnly ? SFF_SELECTION : 0),
|
||||||
|
(LPARAM)&eds
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( eds.dwError )
|
||||||
|
{
|
||||||
|
wxLogLastError(_T("EM_STREAMOUT"));
|
||||||
|
}
|
||||||
|
else // streamed out ok
|
||||||
|
{
|
||||||
|
// now convert to the given encoding (this is a lossful conversion but
|
||||||
|
// what else can we do)
|
||||||
|
wxCSConv conv(encoding);
|
||||||
|
size_t lenNeeded = conv.WC2MB(NULL, wchBuf, len);
|
||||||
|
if ( lenNeeded )
|
||||||
|
{
|
||||||
|
conv.WC2MB(wxStringBuffer(out, lenNeeded), wchBuf, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !wxUSE_WCHAR_T
|
||||||
|
free(wchBuf);
|
||||||
|
#endif // !wxUSE_WCHAR_T
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // !wxUSE_UNICODE_MSLU
|
||||||
|
|
||||||
#endif // wxUSE_RICHEDIT
|
#endif // wxUSE_RICHEDIT
|
||||||
|
|
||||||
void wxTextCtrl::WriteText(const wxString& value)
|
void wxTextCtrl::WriteText(const wxString& value)
|
||||||
|
Reference in New Issue
Block a user