+ // don't convert at all
+ return NULL;
+ }
+
+ // we trust OS to do conversion better than we can so try external
+ // conversion methods first
+ //
+ // the full order is:
+ // 1. OS conversion (iconv() under Unix or Win32 API)
+ // 2. hard coded conversions for UTF
+ // 3. wxEncodingConverter as fall back
+
+ // step (1)
+#ifdef HAVE_ICONV
+#if !wxUSE_FONTMAP
+ if ( m_name )
+#endif // !wxUSE_FONTMAP
+ {
+ wxString name(m_name);
+
+#if wxUSE_FONTMAP
+ if ( name.empty() )
+ name = wxFontMapper::Get()->GetEncodingName(m_encoding);
+#endif // wxUSE_FONTMAP
+
+ wxMBConv_iconv *conv = new wxMBConv_iconv(name);
+ if ( conv->IsOk() )
+ return conv;
+
+ delete conv;
+ }
+#endif // HAVE_ICONV
+
+#ifdef wxHAVE_WIN32_MB2WC
+ {
+ wxMBConv_win32 *conv = m_name ? new wxMBConv_win32(m_name)
+ : new wxMBConv_win32(m_encoding);
+ if ( conv->IsOk() )
+ return conv;
+
+ delete conv;
+ }
+#endif // wxHAVE_WIN32_MB2WC
+#if defined(__WXMAC__)
+ {
+ if ( m_name || ( m_encoding < wxFONTENCODING_UTF16BE ) )
+ {
+
+ wxMBConv_mac *conv = m_name ? new wxMBConv_mac(m_name)
+ : new wxMBConv_mac(m_encoding);
+ if ( conv->IsOk() )
+ return conv;
+
+ delete conv;
+ }
+ }
+#endif
+ // step (2)
+ wxFontEncoding enc = m_encoding;
+#if wxUSE_FONTMAP
+ if ( enc == wxFONTENCODING_SYSTEM && m_name )
+ {
+ // use "false" to suppress interactive dialogs -- we can be called from
+ // anywhere and popping up a dialog from here is the last thing we want to
+ // do
+ enc = wxFontMapper::Get()->CharsetToEncoding(m_name, false);
+ }
+#endif // wxUSE_FONTMAP
+
+ switch ( enc )
+ {
+ case wxFONTENCODING_UTF7:
+ return new wxMBConvUTF7;
+
+ case wxFONTENCODING_UTF8:
+ return new wxMBConvUTF8;
+
+ case wxFONTENCODING_UTF16BE:
+ return new wxMBConvUTF16BE;
+
+ case wxFONTENCODING_UTF16LE:
+ return new wxMBConvUTF16LE;
+
+ case wxFONTENCODING_UTF32BE:
+ return new wxMBConvUTF32BE;
+
+ case wxFONTENCODING_UTF32LE:
+ return new wxMBConvUTF32LE;
+
+ default:
+ // nothing to do but put here to suppress gcc warnings
+ ;
+ }
+
+ // step (3)
+#if wxUSE_FONTMAP
+ {
+ wxMBConv_wxwin *conv = m_name ? new wxMBConv_wxwin(m_name)
+ : new wxMBConv_wxwin(m_encoding);
+ if ( conv->IsOk() )
+ return conv;
+
+ delete conv;
+ }
+#endif // wxUSE_FONTMAP
+
+ // NB: This is a hack to prevent deadlock. What could otherwise happen
+ // in Unicode build: wxConvLocal creation ends up being here
+ // because of some failure and logs the error. But wxLog will try to
+ // attach timestamp, for which it will need wxConvLocal (to convert
+ // time to char* and then wchar_t*), but that fails, tries to log
+ // error, but wxLog has a (already locked) critical section that
+ // guards static buffer.
+ static bool alreadyLoggingError = false;
+ if (!alreadyLoggingError)
+ {
+ alreadyLoggingError = true;
+ wxLogError(_("Cannot convert from the charset '%s'!"),
+ m_name ? m_name
+ :
+#if wxUSE_FONTMAP
+ wxFontMapper::GetEncodingDescription(m_encoding).c_str()
+#else // !wxUSE_FONTMAP
+ wxString::Format(_("encoding %s"), m_encoding).c_str()
+#endif // wxUSE_FONTMAP/!wxUSE_FONTMAP
+ );
+ alreadyLoggingError = false;
+ }
+
+ return NULL;
+}
+
+void wxCSConv::CreateConvIfNeeded() const
+{
+ if ( m_deferred )
+ {
+ wxCSConv *self = (wxCSConv *)this; // const_cast
+
+#if wxUSE_INTL
+ // if we don't have neither the name nor the encoding, use the default
+ // encoding for this system
+ if ( !m_name && m_encoding == wxFONTENCODING_SYSTEM )