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