Revision: 7308
          http://mahogany.svn.sourceforge.net/mahogany/?rev=7308&view=rev
Author:   vadz
Date:     2007-07-29 18:31:52 -0700 (Sun, 29 Jul 2007)

Log Message:
-----------
many more Unicode fixes, things start working (and not only compiling now) but 
much more remains to be done; also extracted MIME header decoding function in 
its own file

Modified Paths:
--------------
    trunk/M/M.vcproj
    trunk/M/include/MailFolder.h
    trunk/M/include/Mcclient.h
    trunk/M/include/Message.h
    trunk/M/include/MessageCC.h
    trunk/M/include/MimePartCCBase.h
    trunk/M/include/XFace.h
    trunk/M/include/mail/VMessage.h
    trunk/M/src/adb/Collect.cpp
    trunk/M/src/classes/ComposeTemplate.cpp
    trunk/M/src/classes/MessageView.cpp
    trunk/M/src/classes/XFace.cpp
    trunk/M/src/gui/wxComposeView.cpp
    trunk/M/src/gui/wxIconManager.cpp
    trunk/M/src/gui/wxMessageView.cpp
    trunk/M/src/gui/wxllist.cpp
    trunk/M/src/mail/MailFolder.cpp
    trunk/M/src/mail/MailFolderCC.cpp
    trunk/M/src/mail/Message.cpp
    trunk/M/src/mail/MessageCC.cpp
    trunk/M/src/mail/MimePartCCBase.cpp
    trunk/M/src/mail/SendMessageCC.cpp
    trunk/M/src/mail/ThreadJWZ.cpp
    trunk/M/src/modules/Filters.cpp
    trunk/M/src/modules/spam/HeadersFilter.cpp

Added Paths:
-----------
    trunk/M/include/mail/MimeDecode.h
    trunk/M/src/mail/MimeDecode.cpp

Modified: trunk/M/M.vcproj
===================================================================
--- trunk/M/M.vcproj    2007-07-30 00:46:29 UTC (rev 7307)
+++ trunk/M/M.vcproj    2007-07-30 01:31:52 UTC (rev 7308)
@@ -588,6 +588,9 @@
                                        RelativePath=".\src\mail\MFui.cpp">
                                </File>
                                <File
+                                       
RelativePath=".\src\mail\MimeDecode.cpp">
+                               </File>
+                               <File
                                        
RelativePath=".\src\mail\MimePartCC.cpp">
                                </File>
                                <File

Modified: trunk/M/include/MailFolder.h
===================================================================
--- trunk/M/include/MailFolder.h        2007-07-30 00:46:29 UTC (rev 7307)
+++ trunk/M/include/MailFolder.h        2007-07-30 01:31:52 UTC (rev 7308)
@@ -913,17 +913,6 @@
    */
    static bool ImportFoldersMH(const String& root, bool allUnder = true);
 
-   /** RFC 2047 compliant message decoding: all encoded words from the header
-       are decoded, but only the encoding of the first of them is returned in
-       encoding output parameter (if non NULL).
-
-       @param in the RFC 2047 header string
-       @param encoding the pointer to the charset of the string (may be NULL)
-       @return the full 8bit decoded string
-   */
-   static String DecodeHeader(const String &in,
-                              wxFontEncoding *encoding = NULL);
-
    //@}
 
    /** @name mail subsystem initialization and shutdown */

Modified: trunk/M/include/Mcclient.h
===================================================================
--- trunk/M/include/Mcclient.h  2007-07-30 00:46:29 UTC (rev 7307)
+++ trunk/M/include/Mcclient.h  2007-07-30 01:31:52 UTC (rev 7308)
@@ -79,6 +79,33 @@
                     BODY **ppBody,
                     size_t *pHdrLen = NULL);
 
+
+/**
+   Cast a signed char string to unsigned char.
+
+   c-client wants unsigned char strings while we work with char pointers
+   everywhere, provide this macro-like helper function to cast the strings
+   to the correct type (this has the added benefit of forcing implicit
+   conversion of wxString::char_str() to "char *", i.e. we can write
+   UCHAR_CAST(s.char_str()) while (unsigned char *)s.char_str() wouldn't
+   compile)
+ */
+inline unsigned char *UCHAR_CAST(char *s)
+{
+   return reinterpret_cast<unsigned char *>(s);
+}
+
+/**
+   Cast an unsigned char string to a char one.
+
+   This is the reverse of UCHAR_CAST() and is useful for the strings returned
+   from c-client.
+ */
+inline char *CHAR_CAST(unsigned char *us)
+{
+   return reinterpret_cast<char *>(us);
+}
+
 //@}
 
 #endif  //MCCLIENT_H

Modified: trunk/M/include/Message.h
===================================================================
--- trunk/M/include/Message.h   2007-07-30 00:46:29 UTC (rev 7307)
+++ trunk/M/include/Message.h   2007-07-30 01:31:52 UTC (rev 7308)
@@ -162,7 +162,7 @@
        @param encodings if non NULL, filled with encodings of the headers
        @return the array containing the header values
    */
-   virtual wxArrayString GetHeaderLines(const wxChar **headers,
+   virtual wxArrayString GetHeaderLines(const char **headers,
                                         wxArrayInt *encodings = NULL) const = 
0;
 
    /**

Modified: trunk/M/include/MessageCC.h
===================================================================
--- trunk/M/include/MessageCC.h 2007-07-30 00:46:29 UTC (rev 7307)
+++ trunk/M/include/MessageCC.h 2007-07-30 01:31:52 UTC (rev 7308)
@@ -30,7 +30,7 @@
 {
 public:
    // get specfied header lines
-   virtual wxArrayString GetHeaderLines(const wxChar **headers,
+   virtual wxArrayString GetHeaderLines(const char **headers,
                                         wxArrayInt *encodings = NULL) const;
 
    virtual String GetHeader(void) const;

Modified: trunk/M/include/MimePartCCBase.h
===================================================================
--- trunk/M/include/MimePartCCBase.h    2007-07-30 00:46:29 UTC (rev 7307)
+++ trunk/M/include/MimePartCCBase.h    2007-07-30 01:31:52 UTC (rev 7308)
@@ -20,6 +20,8 @@
 
 #include "MimePart.h"
 
+#include <wx/fontenc.h>
+
 /**
    MimePartCCBase uses c-client structures for storing the message.
  */
@@ -134,6 +136,10 @@
 
    /// Flag telling whether we should free m_content or not
    bool m_ownsContent;
+
+
+   /// cached default encoding: only use GetTextEncoding() to access it
+   mutable wxFontEncoding m_encoding;
 };
 
 #endif // _M_MIMEPARTCCBASE_H_

Modified: trunk/M/include/XFace.h
===================================================================
--- trunk/M/include/XFace.h     2007-07-30 00:46:29 UTC (rev 7307)
+++ trunk/M/include/XFace.h     2007-07-30 01:31:52 UTC (rev 7308)
@@ -60,7 +60,7 @@
        @param filename obvious
        @return true on success
    */
-   bool CreateFromFile(const wxChar *filename);
+   bool CreateFromFile(const String& filename);
 
    static class wxImage GetXFaceImg(const String &filename,
                                     bool *hasimg = NULL,

Added: trunk/M/include/mail/MimeDecode.h
===================================================================
--- trunk/M/include/mail/MimeDecode.h                           (rev 0)
+++ trunk/M/include/mail/MimeDecode.h   2007-07-30 01:31:52 UTC (rev 7308)
@@ -0,0 +1,37 @@
+//////////////////////////////////////////////////////////////////////////////
+// Project:     M - cross platform e-mail GUI client
+// File name:   mail/MimeDecode.h: functions for MIME words decoding
+// Author:      Vadim Zeitlin
+// Created:     2007-07-29
+// CVS-ID:      $Id$
+// Copyright:   (C) 1997-2007 Mahogany Team
+// Licence:     M license
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef M_MAIL_MIMEDECODE_H
+#define M_MAIL_MIMEDECODE_H
+
+#include <wx/fontenc.h>
+
+/**
+   Various MIME helpers.
+ */
+namespace MIME
+{
+
+/**
+   RFC 2047 compliant message decoding.
+
+   All encoded words from the header are decoded, but only the encoding of the
+   first of them is returned in encoding output parameter (if non NULL).
+
+   @param in a message header
+   @param encoding the pointer to the charset of the string (may be NULL)
+   @return the fully decoded string
+*/
+String DecodeHeader(const String& in, wxFontEncoding *encoding = NULL);
+
+} // namespace MIME
+
+#endif // M_MAIL_MIMEDECODE_H
+


Property changes on: trunk/M/include/mail/MimeDecode.h
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Modified: trunk/M/include/mail/VMessage.h
===================================================================
--- trunk/M/include/mail/VMessage.h     2007-07-30 00:46:29 UTC (rev 7307)
+++ trunk/M/include/mail/VMessage.h     2007-07-30 01:31:52 UTC (rev 7308)
@@ -46,7 +46,7 @@
    /** @name Headers access */
    //@{
 
-   virtual wxArrayString GetHeaderLines(const wxChar **headers,
+   virtual wxArrayString GetHeaderLines(const char **headers,
                                         wxArrayInt *encodings = NULL) const
       { return m_message->GetHeaderLines(headers, encodings); }
 

Modified: trunk/M/src/adb/Collect.cpp
===================================================================
--- trunk/M/src/adb/Collect.cpp 2007-07-30 00:46:29 UTC (rev 7307)
+++ trunk/M/src/adb/Collect.cpp 2007-07-30 01:31:52 UTC (rev 7308)
@@ -33,9 +33,10 @@
 #include "Address.h"
 #include "Collect.h"
 #include "Message.h"
-#include "MailFolder.h"
 #include "pointers.h"
 
+#include "mail/MimeDecode.h"
+
 #include "adb/AdbManager.h"
 #include "adb/AdbBook.h"
 #include "adb/AdbDataProvider.h"
@@ -115,8 +116,7 @@
                         const String& groupName,
                         wxFrame *frame)
 {
-   String name = nameOrig;
-   name = MailFolder::DecodeHeader(name, 0);
+   String name = MIME::DecodeHeader(nameOrig);
 
    // we need an address and a name
    bool hasEmailAndName = true;
@@ -145,10 +145,10 @@
       CHECK_RET( manager, _T("can't get AdbManager") );
 
       String providerName;
-      
+
       AdbBook *autocollectbook = manager->CreateBook(
          bookName, NULL, &providerName );
-         
+
       RefCounter<AdbDataProvider> bookProvider(
          AdbDataProvider::GetProviderByName(providerName));
 

Modified: trunk/M/src/classes/ComposeTemplate.cpp
===================================================================
--- trunk/M/src/classes/ComposeTemplate.cpp     2007-07-30 00:46:29 UTC (rev 
7307)
+++ trunk/M/src/classes/ComposeTemplate.cpp     2007-07-30 01:31:52 UTC (rev 
7308)
@@ -32,6 +32,7 @@
 #  include <wx/frame.h>
 #endif // USE_PCH
 
+#include "mail/MimeDecode.h"
 #include "TemplateDialog.h"
 
 #include "Composer.h"
@@ -576,7 +577,7 @@
          name = GetNameForAddress(msg, MAT_REPLYTO);
       }
 
-      name = MailFolder::DecodeHeader(name);
+      name = MIME::DecodeHeader(name);
 
       // it's (quite) common to have quotes around the personal
       // part of the address, remove them if so
@@ -1408,7 +1409,7 @@
          //
          // FIXME: of course, this means that we lose the additional encoding
          //        info
-         *value = MailFolder::DecodeHeader(*value);
+         *value = MIME::DecodeHeader(*value);
       }
    }
 

Modified: trunk/M/src/classes/MessageView.cpp
===================================================================
--- trunk/M/src/classes/MessageView.cpp 2007-07-30 00:46:29 UTC (rev 7307)
+++ trunk/M/src/classes/MessageView.cpp 2007-07-30 01:31:52 UTC (rev 7308)
@@ -51,6 +51,7 @@
 #include "MessageViewer.h"
 #include "ViewFilter.h"
 
+#include "mail/MimeDecode.h"
 #include "MailFolderCC.h" // needed to properly include MessageCC.h
 #include "MessageCC.h"
 #include "MimePartCC.h"
@@ -1444,7 +1445,7 @@
       wxArrayString headerNonEnvValues;
       if ( countNonEnvHeaders )
       {
-         const wxChar **headerPtrs = new const wxChar *[countNonEnvHeaders + 
1];
+         const char **headerPtrs = new const char *[countNonEnvHeaders + 1];
 
          // have to copy the headers into a temp buffer unfortunately
          for ( nNonEnv = 0, n = 0; n < countHeaders; n++ )
@@ -1540,7 +1541,7 @@
 
             // extract encoding info from it
             wxFontEncoding enc;
-            headerValues.Add(MailFolder::DecodeHeader(value, &enc));
+            headerValues.Add(MIME::DecodeHeader(value, &enc));
             headerEncodings.Add(enc);
          }
          else // non env header
@@ -1559,24 +1560,30 @@
       // ... instead we show an icon for it
       if ( m_ProfileValues.showFaces )
       {
-         wxString xfaceString = headerValues[n++];
+         const wxString& xfaceString = headerValues[n++];
          if ( xfaceString.length() > 20 )
          // FIXME it was > 2, i.e. \r\n. Although if(uncompface(data) < 0) in
          // XFace.cpp should catch illegal data, it is not the case. For 
example,
          // for "X-Face: nope" some nonsense was displayed. So we use 20 for 
now.
          {
-            XFace *xface = new XFace;
-            xface->CreateFromXFace(wxConvertWX2MB(xfaceString));
-
-            char **xfaceXpm;
-            if ( xface->CreateXpm(&xfaceXpm) )
+            // valid X-Faces are always ASCII, so don't bother if conversion
+            // fails
+            const wxCharBuffer xfaceBuf(xfaceString.ToAscii());
+            if ( xfaceBuf )
             {
-               m_viewer->ShowXFace(wxBitmap(xfaceXpm));
+               XFace *xface = new XFace;
+               xface->CreateFromXFace(xfaceBuf);
 
-               wxIconManager::FreeImage(xfaceXpm);
+               char **xfaceXpm;
+               if ( xface->CreateXpm(&xfaceXpm) )
+               {
+                  m_viewer->ShowXFace(wxBitmap(xfaceXpm));
+
+                  wxIconManager::FreeImage(xfaceXpm);
+               }
+
+               delete xface;
             }
-
-            delete xface;
          }
       }
 

Modified: trunk/M/src/classes/XFace.cpp
===================================================================
--- trunk/M/src/classes/XFace.cpp       2007-07-30 00:46:29 UTC (rev 7307)
+++ trunk/M/src/classes/XFace.cpp       2007-07-30 01:31:52 UTC (rev 7308)
@@ -61,7 +61,7 @@
    if(xface) delete [] xface;
 
    xface = new char[2500];
-   strcpy(xface, data);
+   strncpy(xface, data, 2500);
    if(compface(xface) < 0)
    {
       delete [] xface;
@@ -70,9 +70,9 @@
       return false;
    }
    //convert it:
-   String out = strutil_enforceCRLF(wxConvertMB2WX(xface));
+   String out = strutil_enforceCRLF(wxString::FromAscii(xface));
    delete [] xface;
-   xface = strutil_strdup(wxConvertWX2MB(out));
+   xface = strutil_strdup(out.ToAscii());
    initialised = true;
    return true;
 #endif
@@ -157,7 +157,7 @@
       }
    }
    delete [] buf;
-   return CreateFromData(wxConvertWX2MB(dataString));
+   return CreateFromData(dataString.ToAscii());
 #endif
 }
 
@@ -250,11 +250,11 @@
 
 
 bool
-XFace::CreateFromFile(const wxChar *filename)
+XFace::CreateFromFile(const String& filename)
 {
-   wxImage img = GetXFaceImg(filename );
+   wxImage img = GetXFaceImg(filename);
    String datastring = ConvertImgToXFaceData(img);
-   return CreateFromData(wxConvertWX2MB(datastring));
+   return CreateFromData(datastring.ToAscii());
 }
 
 
@@ -331,9 +331,9 @@
       data = xface = NULL;
       return false;
    }
-   String out = strutil_enforceCRLF(wxConvertMB2WX(xface));
+   String out = strutil_enforceCRLF(wxString::FromAscii(xface));
    delete [] xface;
-   xface = strutil_strdup(wxConvertWX2MB(out));
+   xface = strutil_strdup(out.ToAscii());
    initialised = true;
    return true;
 #endif
@@ -503,7 +503,7 @@
 
          }
       }
-      (*xpm)[line++] = strutil_strdup(wxConvertWX2MB(tmp));
+      (*xpm)[line++] = strutil_strdup(tmp.ToAscii());
    }
    delete [] buf;
    (*xpm)[line++] = NULL;

Modified: trunk/M/src/gui/wxComposeView.cpp
===================================================================
--- trunk/M/src/gui/wxComposeView.cpp   2007-07-30 00:46:29 UTC (rev 7307)
+++ trunk/M/src/gui/wxComposeView.cpp   2007-07-30 01:31:52 UTC (rev 7308)
@@ -84,6 +84,8 @@
 
 #include "adb/AdbManager.h"
 
+#include "mail/MimeDecode.h"
+
 #include "TemplateDialog.h"
 #include "AttachDialog.h"
 #include "MFolder.h"
@@ -1619,7 +1621,7 @@
    while ( hdrIter.GetNext(&nameWithCase, &value) )
    {
       wxString name = nameWithCase.Upper();
-      value = MailFolder::DecodeHeader(value);
+      value = MIME::DecodeHeader(value);
 
       // test for some standard headers which need special treatment
       if ( name == _T("SUBJECT") )

Modified: trunk/M/src/gui/wxIconManager.cpp
===================================================================
--- trunk/M/src/gui/wxIconManager.cpp   2007-07-30 00:46:29 UTC (rev 7307)
+++ trunk/M/src/gui/wxIconManager.cpp   2007-07-30 01:31:52 UTC (rev 7308)
@@ -366,7 +366,7 @@
          {
             str = str.substr(1,str.length()-1);
             str = strutil_before(str,'"');
-            cpptr[line++] = strutil_strdup(wxConvertWX2MB(str));
+            cpptr[line++] = strutil_strdup(str.ToAscii());
          }
       }while(! in.fail());
       cpptr[line++] = NULL;

Modified: trunk/M/src/gui/wxMessageView.cpp
===================================================================
--- trunk/M/src/gui/wxMessageView.cpp   2007-07-30 00:46:29 UTC (rev 7307)
+++ trunk/M/src/gui/wxMessageView.cpp   2007-07-30 01:31:52 UTC (rev 7308)
@@ -41,6 +41,8 @@
 #include "MessageTemplate.h"
 #include "Message.h"
 
+#include "mail/MimeDecode.h"
+
 #include "gui/wxMessageView.h"
 
 // ----------------------------------------------------------------------------
@@ -85,7 +87,7 @@
       else
          return false;
 
-      *value = MailFolder::DecodeHeader(*value);
+      *value = MIME::DecodeHeader(*value);
 
       return true;
    }

Modified: trunk/M/src/gui/wxllist.cpp
===================================================================
--- trunk/M/src/gui/wxllist.cpp 2007-07-30 00:46:29 UTC (rev 7307)
+++ trunk/M/src/gui/wxllist.cpp 2007-07-30 01:31:52 UTC (rev 7308)
@@ -1908,9 +1908,7 @@
                     wxColour *fg,
                     wxColour *bg)
 {
-   wxCHECK_RET( font.Ok(), _T("invalid font in Clear()") );
-
-   DoClear(wxLayoutStyleInfo(font, fg, bg));
+   DoClear(wxLayoutStyleInfo(font.IsOk() ? font : *wxNORMAL_FONT, fg, bg));
 }
 
 void

Modified: trunk/M/src/mail/MailFolder.cpp
===================================================================
--- trunk/M/src/mail/MailFolder.cpp     2007-07-30 00:46:29 UTC (rev 7307)
+++ trunk/M/src/mail/MailFolder.cpp     2007-07-30 01:31:52 UTC (rev 7308)
@@ -41,6 +41,7 @@
 #include "MFPrivate.h"
 #include "mail/Driver.h"
 #include "mail/FolderPool.h"
+#include "mail/MimeDecode.h"
 #include "mail/ServerInfo.h"
 
 #include "Composer.h"
@@ -571,7 +572,7 @@
    // is this a follow-up to newsgroup?
    if ( replyKind == MailFolder::FOLLOWUP_TO_NEWSGROUP )
    {
-      cv->AddNewsgroup( MailFolder::DecodeHeader(msg->GetNewsgroups()) );
+      cv->AddNewsgroup(MIME::DecodeHeader(msg->GetNewsgroups()));
       return;
    }
 
@@ -616,11 +617,11 @@
          // try from address
          //
          // FIXME: original encoding is lost here
-         rcptMain = MailFolder::DecodeHeader(msg->From());
+         rcptMain = MIME::DecodeHeader(msg->From());
       }
       else // have Reply-To
       {
-         rcptMain = MailFolder::DecodeHeader(replyToAddresses[0]);
+         rcptMain = MIME::DecodeHeader(replyToAddresses[0]);
       }
 
       // an additional complication: when replying to a message written by
@@ -647,7 +648,7 @@
          for ( n = 1; n < countReplyTo; n++ )
          {
             // FIXME: same as above
-            rcptAddresses.Add(MailFolder::DecodeHeader(replyToAddresses[n]));
+            rcptAddresses.Add(MIME::DecodeHeader(replyToAddresses[n]));
             rcptTypes.Add(Recipient_To);
          }
       }
@@ -719,7 +720,7 @@
    for ( n = 0; n < count; n++ )
    {
       // FIXME: as above, we lose the original encoding here
-      otherAddresses[n] = MailFolder::DecodeHeader(otherAddresses[n]);
+      otherAddresses[n] = MIME::DecodeHeader(otherAddresses[n]);
    }
 
    // remove duplicates
@@ -912,8 +913,7 @@
    String newSubject;
    String replyPrefix = READ_CONFIG(profile, MP_REPLY_PREFIX);
 
-   // FIXME: original subject encoding is lost here
-   String subject = DecodeHeader(msg->Subject());
+   String subject = MIME::DecodeHeader(msg->Subject());
 
    // we may collapse "Re:"s in the subject if asked for it
    enum CRP // this is an abbreviation of "collapse reply prefix"
@@ -1038,10 +1038,10 @@
    cv->SetSubject(newSubject);
 
    // other headers
-   static const wxChar *headers[] =
+   static const char *headers[] =
    {
-      _T("Message-Id"),
-      _T("References"),
+      "Message-Id",
+      "References",
       NULL
    };
 
@@ -1119,11 +1119,8 @@
       CHECK( cv, NULL, _T("failed to create composer") );
    }
 
-   // FIXME: we shouldn't assume that all headers have the same encoding
-   //        so we should set the subject text and tell the composer its
-   //        encoding as well
    cv->SetSubject(READ_CONFIG(profile, MP_FORWARD_PREFIX) +
-                     DecodeHeader(msg->Subject()));
+                     MIME::DecodeHeader(msg->Subject()));
    cv->InitText(msg, params.msgview);
 
    return cv;

Modified: trunk/M/src/mail/MailFolderCC.cpp
===================================================================
--- trunk/M/src/mail/MailFolderCC.cpp   2007-07-30 00:46:29 UTC (rev 7307)
+++ trunk/M/src/mail/MailFolderCC.cpp   2007-07-30 01:31:52 UTC (rev 7308)
@@ -65,6 +65,7 @@
 #include "MFPrivate.h"
 #include "mail/Driver.h"
 #include "mail/FolderPool.h"
+#include "mail/MimeDecode.h"
 #include "mail/ServerInfo.h"
 
 // just to use wxFindFirstFile()/wxFindNextFile() for lockfile checking and
@@ -77,7 +78,6 @@
 #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__WINE__)
 #  undef   ERROR
 #endif
-#include <wx/fontmap.h>      // DecodeHeader() uses CharsetToEncoding()
 #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__WINE__)
 #  undef   ERROR
 #  define  ERROR (long) 2 // HACK - redefine again as in 
extra/src/c-client/mail.h
@@ -116,17 +116,6 @@
 // macros
 // ----------------------------------------------------------------------------
 
-// c-client wants unsigned char strings while we work with char pointers
-// everywhere, provide this macro-like helper function to cast the strings
-// to the correct type (this has the added benefit of forcing implicit
-// conversion of wxString::char_str() to "char *", i.e. we can write
-// UCHAR_CAST(s.char_str()) while (unsigned char *)s.char_str() wouldn't
-// compile)
-inline unsigned char *UCHAR_CAST(char *s)
-{
-   return reinterpret_cast<unsigned char *>(s);
-}
-
 /**
   @name checking folder macros
 
@@ -1542,261 +1531,6 @@
 }
 
 // ----------------------------------------------------------------------------
-// header decoding
-// ----------------------------------------------------------------------------
-
-/*
-   See RFC 2047 for the description of the encodings used in the mail headers.
-   Briefly, "encoded words" can be inserted which have the form of
-
-      encoded-word = "=?" charset "?" encoding "?" encoded-text "?="
-
-   where charset and encoding can't contain space, control chars or "specials"
-   and encoded-text can't contain spaces nor "?".
-
-   NB: don't be confused by 2 meanings of encoding here: it is both the
-       charset encoding for us and also QP/Base64 encoding for RFC 2047
- */
-static
-String DecodeHeaderOnce(const String& in, wxFontEncoding *pEncoding)
-{
-   // we don't enforce the sanity checks on charset and encoding - should we?
-   // const char *specials = "()<>@,;:\\\"[].?=";
-
-   wxFontEncoding encoding = wxFONTENCODING_SYSTEM;
-
-   // if the header starts with an encoded word, preceding whitespace must be
-   // ignored, so the flag must be set to true initially
-   bool maybeBetweenEncodedWords = true;
-
-   String out,
-          space;
-   out.reserve(in.length());
-   for ( const wxChar *p = in.c_str(); *p; p++ )
-   {
-      if ( *p == '=' && *(p + 1) == '?' )
-      {
-         // found encoded word
-
-         // save the start of it
-         const wxChar *pEncWordStart = p++;
-
-         // get the charset
-         String csName;
-         for ( p++; *p && *p != '?'; p++ ) // initial "++" to skip '?'
-         {
-            csName += *p;
-         }
-
-         if ( !*p )
-         {
-            wxLogDebug(_T("Invalid encoded word syntax in '%s': missing 
charset."),
-                       pEncWordStart);
-            out += pEncWordStart;
-
-            break;
-         }
-
-         wxFontEncoding encTmp = 
wxFontMapper::Get()->CharsetToEncoding(csName);
-
-#ifdef DEBUG
-         if ( encoding != wxFONTENCODING_SYSTEM && encoding != encTmp )
-         {
-            // this is a bug (well, missing feature) in Mahogany but so far
-            // I've never seen this happen -- in principle, it is, of course,
-            // possible
-            wxLogDebug(_T("This header contains encoded words with different ")
-                       _T("encodings and won't be rendered correctly."));
-         }
-#endif // DEBUG
-
-         encoding = encTmp;
-
-         // get the encoding in RFC 2047 sense
-         enum
-         {
-            Encoding_Unknown,
-            Encoding_Base64,
-            Encoding_QuotedPrintable
-         } enc2047 = Encoding_Unknown;
-
-         p++; // skip '?'
-         if ( *(p + 1) == '?' )
-         {
-            if ( *p == 'B' || *p == 'b' )
-               enc2047 = Encoding_Base64;
-            else if ( *p == 'Q' || *p == 'q' )
-               enc2047 = Encoding_QuotedPrintable;
-         }
-         //else: multi letter encoding unrecognized
-
-         if ( enc2047 == Encoding_Unknown )
-         {
-            wxLogDebug(_T("Unrecognized header encoding in '%s'."),
-                       pEncWordStart);
-
-            // scan until the end of the encoded word
-            const wxChar *pEncWordEnd = wxStrstr(p, _T("?="));
-            if ( !pEncWordEnd )
-            {
-               wxLogDebug(_T("Missing encoded word end marker in '%s'."),
-                          pEncWordStart);
-               out += pEncWordStart;
-
-               break;
-            }
-            else
-            {
-               out += String(pEncWordStart, pEncWordEnd);
-
-               p = pEncWordEnd;
-
-               continue;
-            }
-         }
-
-         p += 2; // skip "Q?" or "B?"
-
-         // get the encoded text
-         bool hasUnderscore = false;
-         const wxChar *pEncTextStart = p;
-         while ( *p && (p[0] != '?' || p[1] != '=') )
-         {
-            // this is needed for QP hack below
-            if ( *p == '_' )
-               hasUnderscore = true;
-
-            p++;
-         }
-
-         unsigned long lenEncWord = p - pEncTextStart;
-
-         if ( !*p )
-         {
-            wxLogDebug(_T("Missing encoded word end marker in '%s'."),
-                       pEncWordStart);
-            out += pEncWordStart;
-
-            break;
-         }
-
-         // skip '=' following '?'
-         p++;
-
-         // now decode the text using cclient functions
-         unsigned long len;
-         unsigned char *start = (unsigned char *)pEncTextStart;
-         void *text;
-         if ( enc2047 == Encoding_Base64 )
-         {
-            text = rfc822_base64(start, lenEncWord, &len);
-         }
-         else // QP
-         {
-            // cclient rfc822_qprint() behaves correctly and leaves '_' in the
-            // QP encoded text because this is what RFC says, however many
-            // broken clients replace spaces with underscores and so we undo it
-            // here -- in this case it's better to be user-friendly than
-            // standard-conforming
-            String strWithoutUnderscores;
-            if ( hasUnderscore )
-            {
-               strWithoutUnderscores = String(pEncTextStart, lenEncWord);
-               strWithoutUnderscores.Replace(_T("_"), _T(" "));
-               start = (unsigned char *)(const char *)strWithoutUnderscores;
-            }
-
-            text = rfc822_qprint(start, lenEncWord, &len);
-         }
-
-         String textDecoded;
-         if ( !text )
-         {
-            // if QP decoding failed it is probably better to show undecoded
-            // text than nothing at all
-            textDecoded = String(pEncTextStart, p + 1);
-         }
-         else // decoded ok
-         {
-            textDecoded.assign((const char *)text, len);
-            fs_give(&text);
-         }
-
-         // normally we leave the (8 bit) string as is and remember its
-         // encoding so that we may choose the font for displaying it
-         // correctly, but in case of UTF-7/8 we really need to transform it
-         // here as we don't have any UTF-7/8 fonts, so we should display a
-         // different string
-#if !wxUSE_UNICODE
-         if ( encoding == wxFONTENCODING_UTF7 ||
-                  encoding == wxFONTENCODING_UTF8 )
-         {
-            encoding = ConvertUTFToMB(&textDecoded, encoding);
-         }
-#endif // !wxUSE_UNICODE
-
-         out += textDecoded;
-
-         // forget the space before this encoded word, it must be ignored
-         space.clear();
-         maybeBetweenEncodedWords = true;
-      }
-      else if ( maybeBetweenEncodedWords &&
-                  (*p == _T(' ') || *p == _T('\r') || *p == _T('\n')) )
-      {
-         // spaces separating the encoded words must be ignored according
-         // to section 6.2 of the RFC 2047, so we don't output them immediately
-         // but delay until we know that what follows is not an encoded word
-         space += *p;
-      }
-      else // just another normal char
-      {
-         // if we got any delayed whitespace (see above), flush it now
-         if ( !space.empty() )
-         {
-            out += space;
-            space.clear();
-         }
-
-         out += *p;
-
-         maybeBetweenEncodedWords = false;
-      }
-   }
-
-   if ( pEncoding )
-      *pEncoding = encoding;
-
-   return out;
-}
-
-/* static */
-String MailFolder::DecodeHeader(const String& in, wxFontEncoding *pEncoding)
-{
-   if ( pEncoding )
-      *pEncoding = wxFONTENCODING_SYSTEM;
-
-   // some brain dead mailer encode the already encoded headers so to obtain
-   // the real header we keep decoding it until it stabilizes
-   String header,
-          headerOrig = in;
-   for ( ;; )
-   {
-      wxFontEncoding encoding;
-      header = DecodeHeaderOnce(headerOrig, &encoding);
-      if ( header == headerOrig )
-         break;
-
-      if ( pEncoding )
-         *pEncoding = encoding;
-
-      headerOrig = header;
-   }
-
-   return header;
-}
-
-// ----------------------------------------------------------------------------
 // MailFolderCC auth info
 // ----------------------------------------------------------------------------
 
@@ -4459,7 +4193,7 @@
    wxFontEncoding encoding;
    if ( !entry.m_To.empty() )
    {
-      entry.m_To = DecodeHeader(entry.m_To, &encoding);
+      entry.m_To = MIME::DecodeHeader(entry.m_To, &encoding);
    }
    else
    {
@@ -4468,37 +4202,22 @@
 
    wxFontEncoding encodingMsg = encoding;
 
-   entry.m_From = DecodeHeader(entry.m_From, &encoding);
+   entry.m_From = MIME::DecodeHeader(entry.m_From, &encoding);
    if ( (encoding != wxFONTENCODING_SYSTEM) &&
         (encoding != encodingMsg) )
    {
-      if ( encodingMsg != wxFONTENCODING_SYSTEM )
-      {
-         // VZ: I just want to know if this happens, we can't do anything
-         //     smart about this so far anyhow as we can't display the
-         //     different fields in different encodings
-         wxLogDebug(_T("Different encodings for From and To fields, From may 
be displayed incorrectly."));
-      }
-      else
-      {
+      if ( encodingMsg == wxFONTENCODING_SYSTEM )
          encodingMsg = encoding;
-      }
    }
 
    // subject
 
-   entry.m_Subject = DecodeHeader(wxConvertMB2WX(env->subject), &encoding);
+   entry.m_Subject = MIME::DecodeHeader(wxConvertMB2WX(env->subject), 
&encoding);
    if ( (encoding != wxFONTENCODING_SYSTEM) &&
         (encoding != encodingMsg) )
    {
-      if ( encodingMsg != wxFONTENCODING_SYSTEM )
-      {
-         wxLogDebug(_T("Different encodings for From and Subject fields, 
subject may be displayed incorrectly."));
-      }
-      else
-      {
+      if ( encodingMsg == wxFONTENCODING_SYSTEM )
          encodingMsg = encoding;
-      }
    }
 
    // all the other fields

Modified: trunk/M/src/mail/Message.cpp
===================================================================
--- trunk/M/src/mail/Message.cpp        2007-07-30 00:46:29 UTC (rev 7307)
+++ trunk/M/src/mail/Message.cpp        2007-07-30 01:31:52 UTC (rev 7308)
@@ -84,7 +84,7 @@
                             String& value,
                             wxFontEncoding *encoding) const
 {
-   const wxChar *headers[2];
+   const char *headers[2];
    headers[0] = line.c_str();
    headers[1] = NULL;
 

Modified: trunk/M/src/mail/MessageCC.cpp
===================================================================
--- trunk/M/src/mail/MessageCC.cpp      2007-07-30 00:46:29 UTC (rev 7307)
+++ trunk/M/src/mail/MessageCC.cpp      2007-07-30 01:31:52 UTC (rev 7308)
@@ -28,6 +28,7 @@
 #  include "MApplication.h"
 #endif // USE_PCH
 
+#include "mail/MimeDecode.h"
 #include "AddressCC.h"
 #include "MailFolderCC.h"
 #include "MessageCC.h"
@@ -135,8 +136,7 @@
 
    m_Profile->IncRef();
 
-   // move \n --> \r\n convention
-   m_msgText = 
strutil_strdup(wxConvertWX2MB(strutil_enforceCRLF(wxConvertMB2WX(text))));
+   m_msgText = strutil_strdup(text);
 
    if ( !CclientParseMessage(m_msgText, &m_Envelope, &m_Body) )
    {
@@ -164,20 +164,16 @@
 }
 
 // ----------------------------------------------------------------------------
-// MessageCC: envelop (i.e. fast) headers access
+// MessageCC: envelope (i.e. fast) headers access
 // ----------------------------------------------------------------------------
 
 String MessageCC::Subject(void) const
 {
    CheckEnvelope();
 
-   String subject;
-   if ( m_Envelope )
-      subject = wxConvertMB2WX(m_Envelope->subject);
-   else
-      FAIL_MSG( _T("should have envelop in Subject()") );
+   CHECK( m_Envelope, String(), _T("should have envelope in Subject()") );
 
-   return subject;
+   return MIME::DecodeHeader(wxString::From8BitData(m_Envelope->subject));
 }
 
 time_t
@@ -190,13 +186,9 @@
 {
    CheckEnvelope();
 
-   String date;
-   if ( m_Envelope )
-      date = m_Envelope->date;
-   else
-      FAIL_MSG( _T("should have envelop in Date()") );
+   CHECK( m_Envelope, String(), _T("should have envelope in Date()") );
 
-   return date;
+   return wxString::FromAscii((char *)m_Envelope->date);
 }
 
 String MessageCC::From(void) const
@@ -209,18 +201,9 @@
 {
    CheckEnvelope();
 
-   String id;
+   CHECK( m_Envelope, String(), _T("should have envelope in GetId()") );
 
-   if ( !m_Envelope )
-   {
-      FAIL_MSG( _T("no envelope in GetId") );
-   }
-   else
-   {
-      id = wxConvertMB2WX(m_Envelope->message_id);
-   }
-
-   return id;
+   return wxString::FromAscii(m_Envelope->message_id);
 }
 
 String
@@ -228,21 +211,9 @@
 {
    CheckEnvelope();
 
-   String newsgroups;
+   CHECK( m_Envelope, String(), _T("should have envelope in GetNewsgroups()") 
);
 
-   if ( !m_Envelope )
-   {
-      FAIL_MSG( _T("no envelope in GetNewsgroups") );
-   }
-   else
-   {
-      if ( !m_Envelope->newsgroups )
-      {
-         newsgroups = wxConvertMB2WX(m_Envelope->newsgroups);
-      }
-   }
-
-   return newsgroups;
+   return wxString::FromAscii(m_Envelope->newsgroups);
 }
 
 String
@@ -250,18 +221,9 @@
 {
    CheckEnvelope();
 
-   String ref;
+   CHECK( m_Envelope, String(), _T("should have envelope in GetReferences()") 
);
 
-   if ( !m_Envelope )
-   {
-      FAIL_MSG( _T("no envelope in GetReferences") );
-   }
-   else
-   {
-      ref = wxConvertMB2WX(m_Envelope->references);
-   }
-
-   return ref;
+   return wxString::FromAscii(m_Envelope->references);
 }
 
 String
@@ -269,18 +231,9 @@
 {
    CheckEnvelope();
 
-   String inreplyto;
+   CHECK( m_Envelope, String(), _T("should have envelope in GetInReplyTo()") );
 
-   if ( !m_Envelope )
-   {
-      FAIL_MSG( _T("no envelope in GetReferences") );
-   }
-   else
-   {
-      inreplyto = wxConvertMB2WX(m_Envelope->references);
-   }
-
-   return inreplyto;
+   return wxString::FromAscii(m_Envelope->in_reply_to);
 }
 
 // ----------------------------------------------------------------------------
@@ -317,11 +270,11 @@
 }
 
 wxArrayString
-MessageCC::GetHeaderLines(const wxChar **headersOrig,
+MessageCC::GetHeaderLines(const char **headersOrig,
                           wxArrayInt *encodings) const
 {
    // loop variable for iterating over headersOrig
-   const wxChar **headers;
+   const char **headers;
 
    // we should always return the arrays of correct size, this makes the
    // calling code simpler as it doesn't have to check for the number of
@@ -350,8 +303,8 @@
    STRINGLIST *scur = slist;
    for ( headers = headersOrig; ; )
    {
-      scur->text.size = strlen(wxConvertWX2MB(*headers));
-      scur->text.data = (unsigned char *)cpystr(wxConvertWX2MB(*headers));
+      scur->text.size = strlen(*headers);
+      scur->text.data = (unsigned char *)cpystr(*headers);
       if ( !*++headers )
       {
          // terminating NULL
@@ -380,7 +333,7 @@
                     valuesInDisorder;
 
       // extract the headers values
-      HeaderIterator hdrIter(wxConvertMB2WX(rc));
+      HeaderIterator hdrIter(wxString::From8BitData(rc));
       hdrIter.GetAll(&names, &valuesInDisorder);
 
       // and then copy the headers in order into the dst array
@@ -392,11 +345,7 @@
          int n = names.Index(*headers, FALSE /* not case sensitive */);
          if ( n != wxNOT_FOUND )
          {
-            value = MailFolderCC::DecodeHeader
-                    (
-                     valuesInDisorder[(size_t)n],
-                     &encoding
-                    );
+            value = MIME::DecodeHeader(valuesInDisorder[(size_t)n], &encoding);
          }
          else // no such header
          {
@@ -431,7 +380,7 @@
 MessageCC::GetAddressStruct(MessageAddressType type) const
 {
    CheckEnvelope();
-   CHECK( m_Envelope, NULL, _T("no envelop in GetAddressStruct()") );
+   CHECK( m_Envelope, NULL, _T("no envelope in GetAddressStruct()") );
 
    ADDRESS *addr;
 
@@ -493,6 +442,7 @@
 String
 MessageCC::FetchText(void) const
 {
+   char *text;
    if ( m_folder )
    {
       if ( !m_mailFullText )
@@ -538,12 +488,14 @@
       }
       //else: already have it, reuse as msg text doesn't change
 
-      return wxConvertMB2WX(m_mailFullText);
+      text = m_mailFullText;
    }
    else // from a text
    {
-      return wxConvertMB2WX(m_msgText);
+      text = m_msgText;
    }
+
+   return wxString::From8BitData(text);
 }
 
 // ----------------------------------------------------------------------------
@@ -896,7 +848,7 @@
             ASSERT_MSG(strlen(header) == len,
                        _T("DEBUG: Mailfolder corruption detected"));
 
-            str = wxConvertMB2WX(header);
+            str = wxString::From8BitData(header, len);
          }
       }
       else // folder-less message doesn't have headers (why?)!

Added: trunk/M/src/mail/MimeDecode.cpp
===================================================================
--- trunk/M/src/mail/MimeDecode.cpp                             (rev 0)
+++ trunk/M/src/mail/MimeDecode.cpp     2007-07-30 01:31:52 UTC (rev 7308)
@@ -0,0 +1,312 @@
+//////////////////////////////////////////////////////////////////////////////
+// Project:     M - cross platform e-mail GUI client
+// File name:   mail/MimeDecode.cpp: functions for MIME words decoding
+// Author:      Vadim Zeitlin
+// Created:     2007-07-29
+// CVS-ID:      $Id$
+// Copyright:   (C) 1997-2007 Mahogany Team
+// Licence:     M license
+///////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+#include "Mpch.h"
+
+#ifndef  USE_PCH
+   #include "Mcclient.h"
+#endif // !USE_PCH
+
+#include "mail/MimeDecode.h"
+
+#include <wx/fontmap.h>
+
+// ----------------------------------------------------------------------------
+// local helper functions
+// ----------------------------------------------------------------------------
+
+// this should only be used for const-incorrect c-client functions
+inline unsigned char *UCHAR_CCAST(const char *s)
+{
+   return reinterpret_cast<unsigned char *>(const_cast<char *>(s));
+}
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+/*
+   See RFC 2047 for the description of the encodings used in the mail headers.
+   Briefly, "encoded words" can be inserted which have the form of
+
+      encoded-word = "=?" charset "?" encoding "?" encoded-text "?="
+
+   where charset and encoding can't contain space, control chars or "specials"
+   and encoded-text can't contain spaces nor "?".
+
+   NB: don't be confused by 2 meanings of encoding here: it is both the
+       charset encoding for us and also QP/Base64 encoding for RFC 2047
+ */
+static
+String DecodeHeaderOnce(const String& in, wxFontEncoding *pEncoding)
+{
+   // we don't enforce the sanity checks on charset and encoding - should we?
+   // const char *specials = "()<>@,;:\\\"[].?=";
+
+   // there can be words in different encodings inside the same header so this
+   // variable doesn't really make sense but in practice only one encoding will
+   // be used in the entire header
+   wxFontEncoding encodingHeader = wxFONTENCODING_SYSTEM;
+
+   // if the header starts with an encoded word, preceding whitespace must be
+   // ignored, so the flag must be set to true initially
+   bool maybeBetweenEncodedWords = true;
+
+   String out,
+          space;
+   out.reserve(in.length());
+   for ( wxString::const_iterator p = in.begin(),
+                                end = in.end(),
+                               last = in.end() - 1; p != end; ++p )
+   {
+      if ( *p == '=' && p != last && *(p + 1) == '?' )
+      {
+         // found encoded word
+
+         // save the start of it
+         const wxString::const_iterator encWordStart = p++;
+
+         // get the charset
+         String csName;
+         for ( ++p; p != end && *p != '?'; ++p ) // initial "++" to skip '?'
+         {
+            csName += *p;
+         }
+
+         if ( p == end )
+         {
+            wxLogDebug(_T("Invalid encoded word syntax in '%s': missing 
charset."),
+                       in.c_str());
+            out += wxString(encWordStart, end);
+
+            break;
+         }
+
+         const wxFontEncoding
+            encodingWord = wxFontMapper::Get()->CharsetToEncoding(csName);
+
+         if ( encodingWord == wxFONTENCODING_SYSTEM )
+         {
+            wxLogDebug(_T("Unrecognized charset name \"%s\""), 
csName.mb_str());
+         }
+
+         // this is not a problem in Unicode build
+#if !wxUSE_UNICODE
+         if ( encodingHeader != wxFONTENCODING_SYSTEM &&
+               encodingHeader != encodingWord )
+         {
+            // this is a bug (well, missing feature) in ANSI build of Mahogany
+            wxLogDebug(_T("This header contains encoded words with different ")
+                       _T("encodings and won't be rendered correctly."));
+         }
+#endif // !wxUSE_UNICODE
+
+         encodingHeader = encodingWord;
+
+
+         // get the encoding in RFC 2047 sense
+         enum
+         {
+            Encoding_Unknown,
+            Encoding_Base64,
+            Encoding_QuotedPrintable
+         } enc2047 = Encoding_Unknown;
+
+         ++p; // skip '?'
+         if ( *(p + 1) == '?' )
+         {
+            if ( *p == 'B' || *p == 'b' )
+               enc2047 = Encoding_Base64;
+            else if ( *p == 'Q' || *p == 'q' )
+               enc2047 = Encoding_QuotedPrintable;
+         }
+         //else: multi letter encoding unrecognized
+
+         if ( enc2047 == Encoding_Unknown )
+         {
+            wxLogDebug(_T("Unrecognized header encoding in '%s'."), 
in.c_str());
+
+            // scan until the end of the encoded word
+            const size_t posEncWordStart = p - in.begin();
+            const size_t posEncWordEnd = in.find("?=", p - in.begin());
+            if ( posEncWordEnd == wxString::npos )
+            {
+               wxLogDebug(_T("Missing encoded word end marker in '%s'."),
+                          in.c_str());
+               out += wxString(encWordStart, end);
+
+               break;
+            }
+
+            // +2 to skip "?="
+            p += posEncWordEnd - posEncWordStart + 2;
+
+            // leave this word undecoded
+            out += wxString(encWordStart, p + 1);
+
+            continue;
+         }
+
+         p += 2; // skip "Q?" or "B?"
+
+         // get the encoded text
+         bool hasUnderscore = false;
+         const wxString::const_iterator encTextStart = p;
+         while ( p != last && (*p != '?' || *(p + 1) != '=') )
+         {
+            // this is needed for QP hack below
+            if ( *p == '_' )
+               hasUnderscore = true;
+
+            ++p;
+         }
+
+         if ( p == last )
+         {
+            wxLogDebug(_T("Missing encoded word end marker in '%s'."),
+                       in.c_str());
+            out += wxString(encWordStart, end);
+
+            break;
+         }
+
+         // convert the encoded word to char[] buffer for c-client
+         wxCharBuffer encWord(wxString(encTextStart, p).To8BitData());
+
+         // skip '=' following '?'
+         ++p;
+
+         String textDecoded;
+         if ( encWord )
+         {
+            const unsigned long lenEncWord = strlen(encWord);
+
+            // now decode the text using c-client functions
+            unsigned long len;
+            void *text;
+            if ( enc2047 == Encoding_Base64 )
+            {
+               text = rfc822_base64(UCHAR_CCAST(encWord), lenEncWord, &len);
+            }
+            else // QP
+            {
+               // cclient rfc822_qprint() behaves correctly and leaves '_' in 
the
+               // QP encoded text because this is what RFC says, however many
+               // broken clients replace spaces with underscores and so we 
undo it
+               // here -- in this case it's better to be user-friendly than
+               // standard-conforming
+               if ( hasUnderscore )
+               {
+                  for ( char *pc = encWord.data(); *pc; ++pc )
+                  {
+                     if ( *pc == '_' )
+                        *pc = ' ';
+                  }
+               }
+
+               text = rfc822_qprint(UCHAR_CCAST(encWord), lenEncWord, &len);
+            }
+
+            if ( text )
+            {
+               textDecoded = wxString((char *)text, wxCSConv(encodingWord), 
len);
+
+               fs_give(&text);
+            }
+         }
+
+         if ( textDecoded.empty() )
+         {
+            // if decoding failed it is probably better to show undecoded
+            // text than nothing at all
+            textDecoded = wxString(encWordStart, p + 1);
+         }
+
+         // normally we leave the (8 bit) string as is and remember its
+         // encoding so that we may choose the font for displaying it
+         // correctly, but in case of UTF-7/8 we really need to transform it
+         // here as we don't have any UTF-7/8 fonts, so we should display a
+         // different string
+#if !wxUSE_UNICODE
+         if ( encoding == wxFONTENCODING_UTF7 ||
+                  encoding == wxFONTENCODING_UTF8 )
+         {
+            encoding = ConvertUTFToMB(&textDecoded, encoding);
+         }
+#endif // !wxUSE_UNICODE
+
+         out += textDecoded;
+
+         // forget the space before this encoded word, it must be ignored
+         space.clear();
+         maybeBetweenEncodedWords = true;
+      }
+      else if ( maybeBetweenEncodedWords &&
+                  (*p == ' ' || *p == '\r' || *p == '\n') )
+      {
+         // spaces separating the encoded words must be ignored according
+         // to section 6.2 of the RFC 2047, so we don't output them immediately
+         // but delay until we know that what follows is not an encoded word
+         space += *p;
+      }
+      else // just another normal char
+      {
+         // if we got any delayed whitespace (see above), flush it now
+         if ( !space.empty() )
+         {
+            out += space;
+            space.clear();
+         }
+
+         out += *p;
+
+         maybeBetweenEncodedWords = false;
+      }
+   }
+
+   if ( pEncoding )
+      *pEncoding = encodingHeader;
+
+   return out;
+}
+
+String MIME::DecodeHeader(const String& in, wxFontEncoding *pEncoding)
+{
+   if ( pEncoding )
+      *pEncoding = wxFONTENCODING_SYSTEM;
+
+   // some brain dead mailer encode the already encoded headers so to obtain
+   // the real header we keep decoding it until it stabilizes
+   String header,
+          headerOrig = in;
+   for ( ;; )
+   {
+      wxFontEncoding encoding;
+      header = DecodeHeaderOnce(headerOrig, &encoding);
+      if ( header == headerOrig )
+         break;
+
+      if ( pEncoding )
+         *pEncoding = encoding;
+
+      headerOrig = header;
+   }
+
+   return header;
+}
+


Property changes on: trunk/M/src/mail/MimeDecode.cpp
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Modified: trunk/M/src/mail/MimePartCCBase.cpp
===================================================================
--- trunk/M/src/mail/MimePartCCBase.cpp 2007-07-30 00:46:29 UTC (rev 7307)
+++ trunk/M/src/mail/MimePartCCBase.cpp 2007-07-30 01:31:52 UTC (rev 7308)
@@ -28,6 +28,7 @@
 
 #include <wx/fontmap.h>
 
+#include "mail/MimeDecode.h"
 #include "MimePartCCBase.h"
 #include "MailFolder.h"         // for DecodeHeader()
 
@@ -54,6 +55,7 @@
    m_lenContent = 0;
    m_ownsContent = false;
 
+   m_encoding = wxFONTENCODING_SYSTEM;
 }
 
 void
@@ -146,7 +148,7 @@
 {
    // FIXME: we lose the encoding info here - but we don't have any way to
    //        return it from here currently
-   return 
MailFolder::DecodeHeader(wxString::From8BitData(m_body->description));
+   return MIME::DecodeHeader(wxString::From8BitData(m_body->description));
 }
 
 MimeXferEncoding MimePartCCBase::GetTransferEncoding() const
@@ -206,9 +208,7 @@
       }
    }
 
-   // FIXME: we lose the encoding info here - but we don't have any way to
-   //        return it from here currently
-   return MailFolder::DecodeHeader(value);
+   return MIME::DecodeHeader(value);
 }
 
 String MimePartCCBase::GetParam(const String& name) const
@@ -269,10 +269,22 @@
 
 wxFontEncoding MimePartCCBase::GetTextEncoding() const
 {
-   String charset = GetParam(_T("charset"));
+   if ( m_encoding == wxFONTENCODING_SYSTEM )
+   {
+      String charset = GetParam(_T("charset"));
 
-   return charset.empty() ? wxFONTENCODING_SYSTEM
-                          : wxFontMapper::Get()->CharsetToEncoding(charset);
+      if ( !charset.empty() )
+         m_encoding = wxFontMapper::Get()->CharsetToEncoding(charset);
+
+      // CharsetToEncoding() returns this for US-ASCII, treat it as Latin1 here
+      // as it's a strict subset; and if we don't have any charset information
+      // it's still the right choice
+      if ( m_encoding == wxFONTENCODING_SYSTEM ||
+            m_encoding == wxFONTENCODING_DEFAULT )
+         m_encoding = wxFONTENCODING_ISO8859_1;
+   }
+
+   return m_encoding;
 }
 
 // ----------------------------------------------------------------------------
@@ -451,7 +463,9 @@
    const char *p = reinterpret_cast<const char *>(GetContent(&len));
    wxString s;
    if ( p )
-      s = wxString::From8BitData(p, len);
+   {
+      s = wxString(p, wxCSConv(GetTextEncoding()), len);
+   }
 
    return s;
 }

Modified: trunk/M/src/mail/SendMessageCC.cpp
===================================================================
--- trunk/M/src/mail/SendMessageCC.cpp  2007-07-30 00:46:29 UTC (rev 7307)
+++ trunk/M/src/mail/SendMessageCC.cpp  2007-07-30 01:31:52 UTC (rev 7308)
@@ -522,11 +522,11 @@
    {
       case Prot_SMTP:
          {
-            static const wxChar *headers[] =
+            static const char *headers[] =
             {
-               _T("To"),
-               _T("Cc"),
-               _T("Bcc"),
+               "To",
+               "Cc",
+               "Bcc",
                NULL
             };
             wxArrayString recipients = message->GetHeaderLines(headers);
@@ -858,8 +858,7 @@
       }
 
       // put into string as we might want to do some more replacements...
-      String encword((wxChar*)textEnc, (size_t)lenEnc);
-      //String encword = strutil_strdup(wxConvertMB2WX(textEnc));
+      String encword(wxString::FromAscii(CHAR_CAST(textEnc), lenEnc));
 
       // hack: rfc822_8bit() doesn't encode spaces normally but we must
       // do it inside the headers

Modified: trunk/M/src/mail/ThreadJWZ.cpp
===================================================================
--- trunk/M/src/mail/ThreadJWZ.cpp      2007-07-30 00:46:29 UTC (rev 7307)
+++ trunk/M/src/mail/ThreadJWZ.cpp      2007-07-30 01:31:52 UTC (rev 7308)
@@ -124,7 +124,7 @@
       stateOld = state;
       state = normalText;
 
-      const char c = subject[i];
+      const wxChar c = subject[i];
       switch ( stateOld )
       {
          case notInPrefix:
@@ -1107,9 +1107,7 @@
    // value.
    // XNOFIXME: Is it possible to 'lock' the string until the hash-table
    // is destroyed ?
-   char *s = new char[str.Len()+1];
-   strcpy(s, wxConvertWX2MB(str.c_str()));
-   hash_add(hTable, s, container, 0);
+   hash_add(hTable, strdup(str.utf8_str()), container, 0);
 }
 
 
@@ -1130,7 +1128,7 @@
    size_t i;
    for (i = 0; i < (*hTable)->size; i++)
       for (ent = (*hTable)->table[i]; ent != 0; ent = ent->next)
-         delete [] ent->name;
+         free(ent->name);
    // and destroy the hash-table
    hash_destroy(hTable);
 }

Modified: trunk/M/src/modules/Filters.cpp
===================================================================
--- trunk/M/src/modules/Filters.cpp     2007-07-30 00:46:29 UTC (rev 7307)
+++ trunk/M/src/modules/Filters.cpp     2007-07-30 01:31:52 UTC (rev 7308)
@@ -38,6 +38,7 @@
 #include "MInterface.h"
 #include "SpamFilter.h"
 
+#include "mail/MimeDecode.h"
 #include "UIdArray.h"
 #include "Message.h"
 
@@ -75,14 +76,14 @@
 // ----------------------------------------------------------------------------
 
 // all recipient headers, more can be added (but always NULL terminate!)
-static const wxChar *headersRecipients[] =
+static const char *headersRecipients[] =
 {
-   _T("To"),
-   _T("CC"),
-   _T("Bcc"),
-   _T("Resent-To"),
-   _T("Resent-Cc"),
-   _T("Resent-Bcc"),
+   "To",
+   "CC",
+   "Bcc",
+   "Resent-To",
+   "Resent-Cc",
+   "Resent-Bcc",
    NULL
 };
 
@@ -2887,7 +2888,7 @@
 
 void FilterRuleApply::GetSenderSubject(String& from, String& subject, bool 
full)
 {
-   subject = MailFolder::DecodeHeader(m_parent->m_MailMessage->Subject());
+   subject = MIME::DecodeHeader(m_parent->m_MailMessage->Subject());
 
    AddressList_obj addrList(m_parent->m_MailMessage->GetAddressList(MAT_FROM));
    Address *addr = addrList ? addrList->GetFirst() : NULL;

Modified: trunk/M/src/modules/spam/HeadersFilter.cpp
===================================================================
--- trunk/M/src/modules/spam/HeadersFilter.cpp  2007-07-30 00:46:29 UTC (rev 
7307)
+++ trunk/M/src/modules/spam/HeadersFilter.cpp  2007-07-30 01:31:52 UTC (rev 
7308)
@@ -32,6 +32,7 @@
    #include <wx/filefn.h>     // for wxSplitPath
 #endif //USE_PCH
 
+#include "mail/MimeDecode.h"
 #include "MailFolder.h"
 #include "Message.h"
 
@@ -496,7 +497,7 @@
 {
    // consider that the message is a spam if its subject contains more
    // than half of non alpha numeric chars but isn't properly encoded
-   if ( subject != MailFolder::DecodeHeader(subject) )
+   if ( subject != MIME::DecodeHeader(subject) )
    {
       // an encoded subject can have 8 bit chars
       return false;


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
_______________________________________________
Mahogany-cvsupdates mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mahogany-cvsupdates

Reply via email to