Revision: 7425
          http://mahogany.svn.sourceforge.net/mahogany/?rev=7425&view=rev
Author:   vadz
Date:     2008-04-22 18:14:45 -0700 (Tue, 22 Apr 2008)

Log Message:
-----------
allow using wildcards in the headers selected to be shown in the message view

Modified Paths:
--------------
    trunk/M/CHANGES
    trunk/M/include/Message.h
    trunk/M/include/MessageView.h
    trunk/M/src/classes/MessageView.cpp
    trunk/M/src/gui/wxHeadersDialogs.cpp
    trunk/M/src/mail/HeaderIterator.cpp

Modified: trunk/M/CHANGES
===================================================================
--- trunk/M/CHANGES     2008-04-22 22:34:54 UTC (rev 7424)
+++ trunk/M/CHANGES     2008-04-23 01:14:45 UTC (rev 7425)
@@ -9,7 +9,8 @@
 Release 0.68 '' September xx, 2007
 ---------------------------------------
 
-2008-04-23 VZ: Added support for "Face:" header, similar to "X-Face:"
+2008-04-23 VZ: Allow using wildcards in the headers selected to be seen.
+2008-04-22 VZ: Added support for "Face:" header, similar to "X-Face:"
 2008-04-21 VZ: Allow adding custom headers to show in the message view
 2007-08-04 VZ: Allow autocollecting addresses in outgoing messages only
 2007-04-26 VZ: Add the possibility to treat different addresses as equivalent

Modified: trunk/M/include/Message.h
===================================================================
--- trunk/M/include/Message.h   2008-04-22 22:34:54 UTC (rev 7424)
+++ trunk/M/include/Message.h   2008-04-23 01:14:45 UTC (rev 7425)
@@ -65,7 +65,11 @@
       Collapse = 0,
 
       /// return the headers spanning multiple lines in their original form
-      MultiLineOk = 1
+      MultiLineOk = 1,
+
+      /// don't merge together the values of all occurrences of a header,
+      /// instead return multiple entries for it (only valid for GetAll())
+      DuplicatesOk = 2
    };
 
 
@@ -87,6 +91,16 @@
    bool GetNext(String *name, String *value, int flags = Collapse);
 
    /**
+      This is the same as GetNext() above except that the header is also
+      MIME-decoded.
+
+      @a enc may be NULL, in this case the encoding is not returned but the
+      header is still decoded.
+    */
+   bool GetNextDecoded(String *name, String *value, wxFontEncoding *enc,
+                       int flags = Collapse);
+
+   /**
      Get all headers at once. If a header occurs more than once, its values are
      concatenated together with "\r\n" separating them.
 
@@ -100,6 +114,17 @@
                  int flags = Collapse);
 
    /**
+      This is the same as GetAll() above except that the returned headers are
+      MIME-decoded and their encodings are returned.
+
+      @a encodings may be NULL if the caller doesn't care about the encodings.
+    */
+   size_t GetAllDecoded(wxArrayString *names,
+                        wxArrayString *values,
+                        wxArrayInt *encodings,
+                        int flags = Collapse);
+
+   /**
      Resets the iterator so that the next call to GetNext() will return the
      first header of the message (again).
     */

Modified: trunk/M/include/MessageView.h
===================================================================
--- trunk/M/include/MessageView.h       2008-04-22 22:34:54 UTC (rev 7424)
+++ trunk/M/include/MessageView.h       2008-04-23 01:14:45 UTC (rev 7425)
@@ -527,10 +527,15 @@
    /// extracted from them (called by ShowHeaders() only)
    void ShowAllHeaders(ViewableInfoFromHeaders *vi);
 
-   /// show just the selected headers
+   /// show just the selected headers (array elements are literal header names)
    void
    ShowSelectedHeaders(const wxArrayString& headers, ViewableInfoFromHeaders 
*vi);
 
+   /// show all headers matching the array elements (which can contain 
wildcards)
+   void
+   ShowMatchingHeaders(const wxArrayString& headers, ViewableInfoFromHeaders 
*vi);
+
+   /// show information collected in vi while examining the headers
    void ShowInfoFromHeaders(const ViewableInfoFromHeaders& vi);
 
    /**

Modified: trunk/M/src/classes/MessageView.cpp
===================================================================
--- trunk/M/src/classes/MessageView.cpp 2008-04-22 22:34:54 UTC (rev 7424)
+++ trunk/M/src/classes/MessageView.cpp 2008-04-23 01:14:45 UTC (rev 7425)
@@ -1250,10 +1250,37 @@
                         const String& valueOrig,
                         wxFontEncoding encHeader)
 {
+   // show the header name -- this is simple as it's always ASCII
    m_viewer->ShowHeaderName(name);
 
+
+   // next deal with the encoding to use for the header value (and as using
+   // correct encoding can involve re-encoding the text, make a copy of it)
    String value(valueOrig);
+   if ( encHeader == wxFONTENCODING_SYSTEM )
+   {
+      if ( m_encodingUser != wxFONTENCODING_DEFAULT )
+      {
+         // use the user specified encoding if none specified in the header
+         // itself
+         encHeader = m_encodingUser;
+
+         RecodeText(&value, wxFONTENCODING_ISO8859_1, m_encodingUser);
+      }
+      else if ( m_encodingAuto != wxFONTENCODING_SYSTEM )
+      {
+         encHeader = m_encodingAuto;
+      }
+   }
+
 #if !wxUSE_UNICODE
+   // special handling for the UTF-7|8 if it's not supported natively
+   if ( encHeader == wxFONTENCODING_UTF8 ||
+         encHeader == wxFONTENCODING_UTF7 )
+   {
+      encHeader = ConvertUTFToMB(&value, encHeader);
+   }
+
    if ( encHeader != wxFONTENCODING_SYSTEM )
    {
       // convert the string to an encoding we can show, if needed
@@ -1261,6 +1288,7 @@
    }
 #endif // !wxUSE_UNICODE
 
+
    // don't highlight URLs in headers which contain message IDs or other things
    // which look just like the URLs but, in fact, are not ones
    bool highlightURLs = m_ProfileValues.highlightURLs;
@@ -1362,7 +1390,9 @@
 
    String name,
           value;
-   while ( headers.GetNext(&name, &value, HeaderIterator::MultiLineOk) )
+   wxFontEncoding enc;
+   while ( headers.GetNextDecoded(&name, &value, &enc,
+                                  HeaderIterator::MultiLineOk) )
    {
       if ( m_ProfileValues.showFaces )
       {
@@ -1374,15 +1404,68 @@
 #endif // HAVE_XFACES
       }
 
-      wxFontEncoding encHeader = wxFONTENCODING_SYSTEM;
-      if ( m_encodingUser != wxFONTENCODING_DEFAULT )
+      ShowHeader(name, value, enc);
+   }
+}
+
+void
+MessageView::ShowMatchingHeaders(const wxArrayString& headersToShow,
+                                 ViewableInfoFromHeaders *vi)
+{
+   wxArrayString headerNames,
+                 headerValues;
+   wxArrayInt headerEncodings;
+   size_t countHeaders = m_mailMessage->GetHeaderIterator().GetAllDecoded
+                         (
+                           &headerNames,
+                           &headerValues,
+                           &headerEncodings,
+                           HeaderIterator::DuplicatesOk |
+                           HeaderIterator::MultiLineOk
+                         );
+
+   const size_t countToShow = headersToShow.size();
+   for ( size_t n = 0; n < countToShow; n++ )
+   {
+      const String& hdr = headersToShow[n];
+
+      // as we use HeaderIterator::DuplicatesOk above we can have multiple
+      // occurrences of this header so loop until we find all of them
+      for ( ;; )
       {
-         RecodeText(&value, wxFONTENCODING_ISO8859_1, m_encodingUser);
+         int pos = wxNOT_FOUND;
+         if ( hdr.find_first_of("*?") == String::npos )
+         {
+            pos = headerNames.Index(hdr, false /* case-insensitive */);
+         }
+         else // this header is a wildcard
+         {
+            for ( size_t m = 0; m < countHeaders; m++ )
+            {
+               if ( headerNames[m].Matches(hdr) )
+               {
+                  pos = m;
+                  break;
+               }
+            }
+         }
 
-         encHeader = m_encodingUser;
+         if ( pos == wxNOT_FOUND )
+            break;
+
+         ShowHeader(headerNames[pos],
+                    headerValues[pos],
+                    static_cast<wxFontEncoding>(headerEncodings[pos]));
+
+         // we shouldn't show the same header more than once and this could
+         // happen when using the wildcards (e.g. if we show "X-Foo" and "X-*"
+         // headers and didn't remove "X-Foo" after showing it, it would be
+         // also found during the second pass)
+         headerNames.RemoveAt(pos);
+         headerValues.RemoveAt(pos);
+         headerEncodings.RemoveAt(pos);
+         countHeaders--;
       }
-
-      ShowHeader(name, value, encHeader);
    }
 }
 
@@ -1641,31 +1724,7 @@
          // use it later when showing the body
          encInHeaders = encHeader;
       }
-      else // no encoding in the header
-      {
-         if ( m_encodingUser != wxFONTENCODING_DEFAULT )
-         {
-            // use the user specified encoding if none specified in the header
-            // itself
-            encHeader = m_encodingUser;
 
-            RecodeText(&value, wxFONTENCODING_ISO8859_1, m_encodingUser);
-         }
-         else if ( m_encodingAuto != wxFONTENCODING_SYSTEM )
-         {
-            encHeader = m_encodingAuto;
-         }
-      }
-
-#if !wxUSE_UNICODE
-      // special handling for the UTF-7|8 if it's not supported natively
-      if ( encHeader == wxFONTENCODING_UTF8 ||
-            encHeader == wxFONTENCODING_UTF7 )
-      {
-         encHeader = ConvertUTFToMB(&value, encHeader);
-      }
-#endif // !wxUSE_UNICODE
-
       // show the header and mark the URLs in it
       const String& name = headerNames[n];
 
@@ -1806,18 +1865,28 @@
    else // show just the selected headers
    {
       // get all the headers we need to display
-      wxString allHeaders = READ_CONFIG(GetProfile(), MP_MSGVIEW_HEADERS);
+      wxString headers = READ_CONFIG(GetProfile(), MP_MSGVIEW_HEADERS);
 
       // ignore trailing colon as it would result in a dummy empty name after
       // splitting (and unfortunately this extra colon can occur as some old M
       // versions had it in the default value of MP_MSGVIEW_HEADERS by mistake)
-      if ( !allHeaders.empty() && *allHeaders.rbegin() == ':' )
-         allHeaders.erase(allHeaders.length() - 1);
+      if ( !headers.empty() && *headers.rbegin() == ':' )
+         headers.erase(headers.length() - 1);
 
-      if ( allHeaders.empty() )
+      if ( headers.empty() )
          return;
 
-      ShowSelectedHeaders(strutil_restore_array(allHeaders), &vi);
+      const wxArrayString headersArray = strutil_restore_array(headers);
+
+      // if we are using wildcards we need to examine all the headers anyhow so
+      // just do it, otherwise we can retrieve just the headers we need (this
+      // can make a huge difference, the default headers typically are ~100
+      // bytes while the entire message header is commonly 2-3KB and sometimes
+      // more)
+      if ( headers.find_first_of("*?") != String::npos )
+         ShowMatchingHeaders(headersArray, &vi);
+      else
+         ShowSelectedHeaders(headersArray, &vi);
    }
 
    // display anything requiring special treatment that we found in the headers

Modified: trunk/M/src/gui/wxHeadersDialogs.cpp
===================================================================
--- trunk/M/src/gui/wxHeadersDialogs.cpp        2008-04-22 22:34:54 UTC (rev 
7424)
+++ trunk/M/src/gui/wxHeadersDialogs.cpp        2008-04-23 01:14:45 UTC (rev 
7425)
@@ -546,6 +546,9 @@
    m_profile = profile;
    SafeIncRef(profile);
 
+   m_textAdd->SetToolTip(_("Type the name of the header here.\n"
+                           "You may use wildcard characters '*' and '?'."));
+
    SetDefaultSize(6*wBtn, 10*hBtn);
 }
 

Modified: trunk/M/src/mail/HeaderIterator.cpp
===================================================================
--- trunk/M/src/mail/HeaderIterator.cpp 2008-04-22 22:34:54 UTC (rev 7424)
+++ trunk/M/src/mail/HeaderIterator.cpp 2008-04-23 01:14:45 UTC (rev 7425)
@@ -25,6 +25,7 @@
    #include "Mcommon.h"
 #endif // USE_PCH
 
+#include "mail/MimeDecode.h"
 #include "Message.h"
 
 // ============================================================================
@@ -206,22 +207,44 @@
    return !name->empty();
 }
 
+bool
+HeaderIterator::GetNextDecoded(String *name,
+                               String *value,
+                               wxFontEncoding *enc,
+                               int flags)
+{
+   if ( !GetNext(name, value, flags) )
+      return false;
+
+   // RFC 2047 has detailed rules about where exactly are encoded words allowed
+   // but currently we just decode everything except for some fields which are
+   // certain not to contain them
+   if ( wxStricmp(*name, "Received") != 0 )
+   {
+      *value = MIME::DecodeHeader(*value, enc);
+   }
+
+   return true;
+}
+
 size_t
-HeaderIterator::GetAll(wxArrayString *names, wxArrayString *values, int flags)
+HeaderIterator::GetAll(wxArrayString *names,
+                       wxArrayString *values,
+                       int flags)
 {
    CHECK( names && values, 0, _T("NULL pointer in HeaderIterator::GetAll()") );
 
    String name, value;
    while ( GetNext(&name, &value, flags) )
    {
-      int idxName = names->Index(name);
+      int idxName = flags & DuplicatesOk ? wxNOT_FOUND : names->Index(name);
       if ( idxName == wxNOT_FOUND )
       {
          // a header we haven't seen yet
          names->Add(name);
          values->Add(value);
       }
-      else // another occurence of a previously seen header
+      else // another occurrence of a previously seen header
       {
          // append to the existing value
          (*values)[(size_t)idxName] << _T("\n") << value;
@@ -231,3 +254,33 @@
    return names->GetCount();
 }
 
+size_t
+HeaderIterator::GetAllDecoded(wxArrayString *names,
+                              wxArrayString *values,
+                              wxArrayInt *encodings,
+                              int flags)
+{
+   CHECK( names && values, 0, "NULL pointer in 
HeaderIterator::GetAllDecoded()" );
+
+   String name, value;
+   wxFontEncoding enc;
+   while ( GetNextDecoded(&name, &value, &enc, flags) )
+   {
+      int idxName = flags & DuplicatesOk ? wxNOT_FOUND : names->Index(name);
+      if ( idxName == wxNOT_FOUND )
+      {
+         // a header we haven't seen yet
+         names->Add(name);
+         values->Add(value);
+         if ( encodings )
+            encodings->Add(enc);
+      }
+      else // another occurrence of a previously seen header
+      {
+         // append to the existing value
+         (*values)[(size_t)idxName] << _T("\n") << value;
+      }
+   }
+
+   return names->GetCount();
+}


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 the 2008 JavaOne(SM) Conference 
Don't miss this year's exciting event. There's still time to save $100. 
Use priority code J8TL2D2. 
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
Mahogany-cvsupdates mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mahogany-cvsupdates

Reply via email to