]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/textctrl.cpp
Copied gsockmsw.c revision 1.20
[wxWidgets.git] / src / msw / textctrl.cpp
index 76f8e162d81c3e2c8fb39f5e2c36499aa9db9421..7dd6a84fcfc42c2de707c7a87a0f025cf8046b56 100644 (file)
@@ -125,14 +125,14 @@ wxBEGIN_FLAGS( wxTextCtrlStyle )
     wxFLAGS_MEMBER(wxDOUBLE_BORDER)
     wxFLAGS_MEMBER(wxRAISED_BORDER)
     wxFLAGS_MEMBER(wxSTATIC_BORDER)
-    wxFLAGS_MEMBER(wxNO_BORDER)
+    wxFLAGS_MEMBER(wxBORDER)
 
     // standard window styles
     wxFLAGS_MEMBER(wxTAB_TRAVERSAL)
     wxFLAGS_MEMBER(wxCLIP_CHILDREN)
     wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW)
     wxFLAGS_MEMBER(wxWANTS_CHARS)
-    wxFLAGS_MEMBER(wxNO_FULL_REPAINT_ON_RESIZE)
+    wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE)
     wxFLAGS_MEMBER(wxALWAYS_SHOW_SB )
     wxFLAGS_MEMBER(wxVSCROLL)
     wxFLAGS_MEMBER(wxHSCROLL)
@@ -530,32 +530,49 @@ wxString wxTextCtrl::GetRange(long from, long to) const
             if ( to == -1 )
                 to = len;
 
+#if !wxUSE_UNICODE
             // 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) )
+            if ( GetRichVersion() > 1 )
             {
+                // we must have some encoding, otherwise any 8bit chars in the
+                // control are simply *lost* (replaced by '?')
+                wxFontEncoding encoding = wxFONTENCODING_SYSTEM;
+
                 wxFont font = m_defaultStyle.GetFont();
                 if ( !font.Ok() )
                     font = GetFont();
 
                 if ( font.Ok() )
                 {
-                   wxFontEncoding encoding = font.GetEncoding();
-                   if ( encoding != wxFONTENCODING_SYSTEM )
-                   {
-                       str = StreamOut(encoding);
-                   }
+                   encoding = font.GetEncoding();
+                }
+
+                if ( encoding == wxFONTENCODING_SYSTEM )
+                {
+                    encoding = wxLocale::GetSystemEncoding();
+                }
+
+                if ( encoding == wxFONTENCODING_SYSTEM )
+                {
+                    encoding = wxFONTENCODING_ISO8859_1;
+                }
+
+                str = StreamOut(encoding);
+
+                if ( !str.empty() )
+                {
+                    // we have to manually extract the required part, luckily
+                    // this is easy in this case as EOL characters in str are
+                    // just LFs because we remove CRs in wxRichEditStreamOut
+                    str = str.Mid(from, to - from);
                 }
             }
 
             // StreamOut() wasn't used or failed, try to do it in normal way
             if ( str.empty() )
+#endif // !wxUSE_UNICODE
             {
                 // alloc one extra WORD as needed by the control
                 wxStringBuffer tmp(str, ++len);
@@ -563,7 +580,7 @@ wxString wxTextCtrl::GetRange(long from, long to) const
 
                 TEXTRANGE textRange;
                 textRange.chrg.cpMin = from;
-                textRange.chrg.cpMax = to == -1 ? len : to;
+                textRange.chrg.cpMax = to;
                 textRange.lpstrText = p;
 
                 (void)SendMessage(GetHwnd(), EM_GETTEXTRANGE,
@@ -620,6 +637,9 @@ void wxTextCtrl::SetValue(const wxString& value)
     if ( (value.length() > 0x400) || (value != GetValue()) )
     {
         DoWriteText(value, FALSE /* not selection only */);
+        
+        // for compatibility, don't move the cursor when doing SetValue()
+        SetInsertionPoint(0);
     }
     else // same text
     {
@@ -632,9 +652,6 @@ void wxTextCtrl::SetValue(const wxString& value)
     // mark the control as being not dirty - we changed its text, not the
     // user
     DiscardEdits();
-
-    // for compatibility, don't move the cursor when doing SetValue()
-    SetInsertionPoint(0);
 }
 
 #if wxUSE_RICHEDIT && (!wxUSE_UNICODE || wxUSE_UNICODE_MSLU)
@@ -663,32 +680,42 @@ wxRichEditStreamIn(DWORD dwCookie, BYTE *buf, LONG cb, LONG *pcb)
     return 0;
 }
 
+// helper struct used to pass parameters from wxTextCtrl to wxRichEditStreamOut
+struct wxStreamOutData
+{
+    wchar_t *wpc;
+    size_t len;
+};
+
 DWORD CALLBACK
 wxRichEditStreamOut(DWORD dwCookie, BYTE *buf, LONG cb, LONG *pcb)
 {
     *pcb = 0;
 
-    wchar_t ** const ppws = (wchar_t **)dwCookie;
+    wxStreamOutData *data = (wxStreamOutData *)dwCookie;
 
     const wchar_t *wbuf = (const wchar_t *)buf;
-    wchar_t *wpc = *ppws;
-    while ( cb && *wpc )
+    wchar_t *wpc = data->wpc;
+    while ( cb )
     {
-         *wpc++ = *wbuf++;
+        wchar_t wch = *wbuf++;
+
+        // turn "\r\n" into "\n" on the fly
+        if ( wch != L'\r' )
+            *wpc++ = wch;
+        else
+            data->len--;
 
         cb -= sizeof(wchar_t);
         (*pcb) += sizeof(wchar_t);
     }
 
-    *ppws = wpc;
+    data->wpc = wpc;
 
     return 0;
 }
 
 
-// from utils.cpp
-extern WXDLLIMPEXP_BASE long wxEncodingToCodepage(wxFontEncoding encoding);
-
 #if wxUSE_UNICODE_MSLU
     #define UNUSED_IF_MSLU(param)
 #else
@@ -703,37 +730,22 @@ wxTextCtrl::StreamIn(const wxString& value,
 #if wxUSE_UNICODE_MSLU
     const wchar_t *wpc = value.c_str();
 #else // !wxUSE_UNICODE_MSLU
-    // 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
-    // than we do and always shows it in the default one
-
-    // first get the Windows code page for this encoding
-    long codepage = wxEncodingToCodepage(encoding);
-    if ( codepage == -1 )
-    {
-        // unknown encoding
-        return FALSE;
-    }
+    wxCSConv conv(encoding);
 
-    // next translate to Unicode using this code page
-    int len = ::MultiByteToWideChar(codepage, 0, value, -1, NULL, 0);
+    const size_t len = conv.MB2WC(NULL, value, value.length());
 
 #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
 
-    if ( !::MultiByteToWideChar(codepage, 0, value, -1,
-                                (wchar_t *)(const wchar_t *)wchBuf, len) )
-    {
-        wxLogLastError(_T("MultiByteToWideChar"));
-    }
-
-    // finally, stream it in the control
-    const wchar_t *wpc = wchBuf;
+    conv.MB2WC(wpc, value, value.length());
 #endif // wxUSE_UNICODE_MSLU
 
+    // finally, stream it in the control
     EDITSTREAM eds;
     wxZeroMemory(eds);
     eds.dwCookie = (DWORD)&wpc;
@@ -783,9 +795,13 @@ wxTextCtrl::StreamOut(wxFontEncoding encoding, bool selectionOnly) const
     wchar_t *wpc = wchBuf;
 #endif
 
+    wxStreamOutData data;
+    data.wpc = wpc;
+    data.len = len;
+
     EDITSTREAM eds;
     wxZeroMemory(eds);
-    eds.dwCookie = (DWORD)&wpc;
+    eds.dwCookie = (DWORD)&data;
     eds.pfnCallback = wxRichEditStreamOut;
 
     ::SendMessage
@@ -802,13 +818,17 @@ wxTextCtrl::StreamOut(wxFontEncoding encoding, bool selectionOnly) const
     }
     else // streamed out ok
     {
-        // now convert to the given encoding (this is a lossful conversion but
-        // what else can we do)
+        // NUL-terminate the string because its length could have been
+        // decreased by wxRichEditStreamOut
+        *(wchBuf.data() + data.len) = L'\0';
+
+        // now convert to the given encoding (this is a possibly lossful
+        // conversion but what else can we do)
         wxCSConv conv(encoding);
-        size_t lenNeeded = conv.WC2MB(NULL, wchBuf, len);
-        if ( lenNeeded )
+        size_t lenNeeded = conv.WC2MB(NULL, wchBuf, 0);
+        if ( lenNeeded++ )
         {
-            conv.WC2MB(wxStringBuffer(out, lenNeeded), wchBuf, len);
+            conv.WC2MB(wxStringBuffer(out, lenNeeded), wchBuf, lenNeeded);
         }
     }
 
@@ -872,6 +892,10 @@ void wxTextCtrl::DoWriteText(const wxString& value, bool selectionOnly)
                wxFontEncoding encoding = font.GetEncoding();
                if ( encoding != wxFONTENCODING_SYSTEM )
                {
+                   // 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 than we do and always shows it
+                   // in the default one
                    done = StreamIn(valueDos, encoding, selectionOnly);
                }
             }
@@ -1241,13 +1265,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 */);
 
-    SendMessage(GetHwnd(), EM_REPLACESEL,
-#ifdef __WIN32__
-                TRUE,
-#else
-                FALSE,
-#endif
-                (LPARAM)value.c_str());
+    DoWriteText(value, TRUE /* selection only */);
 }
 
 void wxTextCtrl::Remove(long from, long to)
@@ -1273,7 +1291,11 @@ bool wxTextCtrl::IsModified() const
     return SendMessage(GetHwnd(), EM_GETMODIFY, 0, 0) != 0;
 }
 
-// Makes 'unmodified'
+void wxTextCtrl::MarkDirty()
+{
+    SendMessage(GetHwnd(), EM_SETMODIFY, TRUE, 0L);
+}
+
 void wxTextCtrl::DiscardEdits()
 {
     SendMessage(GetHwnd(), EM_SETMODIFY, FALSE, 0L);