Revision: 7204
http://svn.sourceforge.net/mahogany/?rev=7204&view=rev
Author: vadz
Date: 2007-01-08 13:23:41 -0800 (Mon, 08 Jan 2007)
Log Message:
-----------
Refactoring, fixes and improvements to addresses expansion:
- extract the non-GUI login into functions in AdbManager.h/.cpp
- extract GUI logic for addresses in wxTextCtrl (and wxComboBox in the future)
in separate AddressExpander class
- better/more consistent handling of to:/cc:/... prefixes
- expand all addresses and not just the 1st one when Enter is pressed (bug 921)
Modified Paths:
--------------
trunk/M/M.vcproj
trunk/M/include/Composer.h
trunk/M/include/adb/AdbManager.h
trunk/M/include/gui/wxComposeView.h
trunk/M/src/adb/AdbManager.cpp
trunk/M/src/classes/MApplication.cpp
trunk/M/src/gui/wxComposeView.cpp
trunk/M/src/mail/MailFolder.cpp
Added Paths:
-----------
trunk/M/include/gui/AddressExpander.h
trunk/M/src/gui/AddressExpander.cpp
Modified: trunk/M/M.vcproj
===================================================================
--- trunk/M/M.vcproj 2007-01-08 00:09:32 UTC (rev 7203)
+++ trunk/M/M.vcproj 2007-01-08 21:23:41 UTC (rev 7204)
@@ -373,6 +373,9 @@
Name="gui"
Filter="">
<File
+
RelativePath=".\src\gui\AddressExpander.cpp">
+ </File>
+ <File
RelativePath=".\src\gui\ClickAtt.cpp">
</File>
<File
@@ -859,7 +862,8 @@
<Tool
Name="VCCustomBuildTool"
Description="Creating
MInterface.h and .cpp"
-
CommandLine="extra\scripts\m4.bat $(InputDir) $(InputDir)"
+
CommandLine="extra\scripts\m4.bat $(InputDir) $(InputDir)
+"
AdditionalDependencies="$(InputDir)/MInterface.mid;$(InputDir)/MInterface.cpp.m4;$(InputDir)/MInterface.h.m4;$(InputDir)/mid2cpp.m4;$(InputDir)/mid2h.m4"
Outputs="$(InputDir)/MInterface.cpp;$(InputDir)/MInterface.h"/>
</FileConfiguration>
@@ -868,7 +872,8 @@
<Tool
Name="VCCustomBuildTool"
Description="Creating
MInterface.h and .cpp"
-
CommandLine="extra\scripts\m4.bat $(InputDir) $(InputDir)"
+
CommandLine="extra\scripts\m4.bat $(InputDir) $(InputDir)
+"
AdditionalDependencies="$(InputDir)/MInterface.mid;$(InputDir)/MInterface.cpp.m4;$(InputDir)/MInterface.h.m4;$(InputDir)/mid2cpp.m4;$(InputDir)/mid2h.m4"
Outputs="$(InputDir)/MInterface.cpp;$(InputDir)/MInterface.h"/>
</FileConfiguration>
@@ -877,7 +882,8 @@
<Tool
Name="VCCustomBuildTool"
Description="Creating
MInterface.h and .cpp"
-
CommandLine="extra\scripts\m4.bat $(InputDir) $(InputDir)"
+
CommandLine="extra\scripts\m4.bat $(InputDir) $(InputDir)
+"
AdditionalDependencies="$(InputDir)/MInterface.mid;$(InputDir)/MInterface.cpp.m4;$(InputDir)/MInterface.h.m4;$(InputDir)/mid2cpp.m4;$(InputDir)/mid2h.m4"
Outputs="$(InputDir)/MInterface.cpp;$(InputDir)/MInterface.h"/>
</FileConfiguration>
@@ -886,7 +892,8 @@
<Tool
Name="VCCustomBuildTool"
Description="Creating
MInterface.h and .cpp"
-
CommandLine="extra\scripts\m4.bat $(InputDir) $(InputDir)"
+
CommandLine="extra\scripts\m4.bat $(InputDir) $(InputDir)
+"
AdditionalDependencies="$(InputDir)/MInterface.mid;$(InputDir)/MInterface.cpp.m4;$(InputDir)/MInterface.h.m4;$(InputDir)/mid2cpp.m4;$(InputDir)/mid2h.m4"
Outputs="$(InputDir)/MInterface.cpp;$(InputDir)/MInterface.h"/>
</FileConfiguration>
@@ -1880,6 +1887,9 @@
RelativePath=".\include\AddressCC.h">
</File>
<File
+ RelativePath=".\include\gui\AddressExpander.h">
+ </File>
+ <File
RelativePath=".\include\ASMailFolder.h">
</File>
<File
Modified: trunk/M/include/Composer.h
===================================================================
--- trunk/M/include/Composer.h 2007-01-08 00:09:32 UTC (rev 7203)
+++ trunk/M/include/Composer.h 2007-01-08 21:23:41 UTC (rev 7204)
@@ -56,6 +56,13 @@
class Composer
{
public:
+ /// Flags for AddRecipients()
+ enum
+ {
+ /// Expand the address before adding it
+ AddRcpt_Expand = 1
+ };
+
/**
@name Different ways to create a new composer window
@@ -186,7 +193,7 @@
/// adds recipients from addr (Recipient_Max means to reuse the last)
virtual void AddRecipients(const String& addr,
RecipientType rcptType = Recipient_Max,
- bool doLayout = true) = 0;
+ int flags = AddRcpt_Expand) = 0;
/// adds a "To" recipient
void AddTo(const String& addr) { AddRecipients(addr, Recipient_To); }
@@ -223,15 +230,6 @@
*/
virtual void AddHeaderEntry(const String& entry, const String& value) = 0;
- /**
- Expand the given string: this method handles address book completion and
- mailto: URLs parsing. It modifies the string passed to it in place.
-
- @param text the text to expand, modified by the method
- @return the inferred recipient type or Recipient_None if invalid address
- */
- virtual RecipientType ExpandRecipient(String *text) = 0;
-
//@}
/** @name Add/insert stuff into composer */
Modified: trunk/M/include/adb/AdbManager.h
===================================================================
--- trunk/M/include/adb/AdbManager.h 2007-01-08 00:09:32 UTC (rev 7203)
+++ trunk/M/include/adb/AdbManager.h 2007-01-08 21:23:41 UTC (rev 7204)
@@ -17,6 +17,8 @@
#include "adb/AdbEntry.h" // for AdbLookup_xxx constants
+#include "RecipientType.h"
+
#ifndef USE_PCH
# include <wx/dynarray.h>
#endif // USE_PCH
@@ -25,6 +27,8 @@
class AdbBook;
class AdbDataProvider;
+class WXDLLEXPORT wxFrame;
+
// arrays
WX_DEFINE_ARRAY(AdbBook *, ArrayAdbBooks);
WX_DEFINE_ARRAY(AdbEntryGroup *, ArrayAdbGroups);
@@ -186,10 +190,70 @@
@return FALSE if no matches, TRUE if at least one item matched
*/
-class wxFrame;
extern bool AdbExpand(wxArrayString& results,
const String& what,
int how,
wxFrame *frame);
+/**
+ Expand a single address coming from the user input.
+
+ The user input can be a full address, a mailto: URL or a string to be
+ expanded using AdbExpand().
+
+ This function doesn't support multiple comma-separated addresses, use
+ AdbExpandRecipients() for this. Nor does it support "cc:"-like
+ prefixes selecting the recipient type, as AdbExpandSingleRecipient() does.
+
+ @param address the address string, modified in place by this function
+ @param subject filled with the subject on output if it's specified as
+ part of the address (currently only happens with mailto)
+ and is left empty otherwise
+ @param profile to use for expansion options
+ @param parent window to use as parent for the dialogs
+ @return true if the address was expanded, false if the expansion was
+ cancelled (address is unchanged then)
+ */
+bool AdbExpandSingleAddress(String *address,
+ String *subject,
+ Profile *profile,
+ wxFrame *win);
+
+/**
+ Expand a single address coming from the user input, possibly with a
+ recipient type string.
+
+ This function does the same thing as AdbExpandSingleAddress() except that
+ accepts "to:", "cc:" &c prefixes.
+
+ Returns the recipient type (which can be Recipient_None if none was
+ explicitly specified) or Recipient_Max is expansion was cancelled and the
+ address is unchanged.
+ */
+RecipientType AdbExpandSingleRecipient(String *address,
+ String *subject,
+ Profile *profile,
+ wxFrame *win);
+
+/**
+ Expand all addresses in the specified string.
+
+ Returns the number of addresses which can be 0 if the control was empty
+ or -1 if the expansion was cancelled.
+
+ @param text contains the addresses to expand
+ @param addresses filled in with the addresses on return
+ @param rcptTypes filled in with RecipientType enum elements
+ @param subject filled with the subject on output
+ @param profile to use for expansion options
+ @param parent window to use as parent for the dialogs
+ @return number of addresses expanded or -1 if cancelled
+ */
+int AdbExpandAllRecipients(const String& text,
+ wxArrayString& addresses,
+ wxArrayInt& rcptTypes,
+ String *subject,
+ Profile *profile,
+ wxFrame *win);
+
#endif //_ADBMANAGER_H
Added: trunk/M/include/gui/AddressExpander.h
===================================================================
--- trunk/M/include/gui/AddressExpander.h (rev 0)
+++ trunk/M/include/gui/AddressExpander.h 2007-01-08 21:23:41 UTC (rev
7204)
@@ -0,0 +1,73 @@
+///////////////////////////////////////////////////////////////////////////////
+// Project: M - cross platform e-mail GUI client
+// File name: gui/AddressExpander.h
+// Purpose: declaration of AddressExpander class
+// Author: Vadim Zeitlin
+// Created: 2007-01-08
+// CVS-ID: $Id$
+// Copyright: (c) 1998-2007 Mahogany team
+// Licence: M license
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ @file gui/AddressExpander.h
+ @brief Declaration of AddressExpander helper.
+
+ AddressExpander can be used with any control which needs to expand email
+ addresses entered into it by user by looking them up in the address books.
+ */
+
+#ifndef _M_GUI_ADDRESSEXPANDER_H_
+#define _M_GUI_ADDRESSEXPANDER_H_
+
+#include "RecipientType.h"
+
+class WXDLLEXPORT wxFrame;
+class WXDLLEXPORT wxTextCtrl;
+
+/**
+ AddressExpander is not a control but can be associated with an existing
+ control to add support for expanding addresses in it.
+ */
+class AddressExpander
+{
+public:
+ /**
+ Create an AddressExpander associated with the given text entry zone.
+
+ @param text the associated text control
+ @param profile for expansion options
+ */
+ AddressExpander(wxTextCtrl *text, Profile *profile);
+
+ /**
+ Calls AdbExpandAllRecipients() for the control contents.
+
+ Doesn't modify the control contents.
+ */
+ int ExpandAll(wxArrayString& addresses,
+ wxArrayInt& rcptTypes,
+ String *subject) const;
+
+ /**
+ Replaces the last address entered into the control with its expansion.
+
+ @param subject filled in with the subject if the recipient contains it
+ @return type of the recipient if explicitly specified, Recipient_None if
+ none and Recipient_Max if nothing was expanded
+ */
+ RecipientType ExpandLast(String *subject);
+
+private:
+ // return the parent window for ADB functions
+ wxFrame *GetParentFrame() const;
+
+
+ wxTextCtrl *m_text;
+ Profile_obj m_profile;
+
+ DECLARE_NO_COPY_CLASS(AddressExpander)
+};
+
+#endif // _M_GUI_ADDRESSEXPANDER_H_
+
Modified: trunk/M/include/gui/wxComposeView.h
===================================================================
--- trunk/M/include/gui/wxComposeView.h 2007-01-08 00:09:32 UTC (rev 7203)
+++ trunk/M/include/gui/wxComposeView.h 2007-01-08 21:23:41 UTC (rev 7204)
@@ -169,14 +169,11 @@
/// sets Subject field
void SetSubject(const String &subj);
- /// adds recepients from addr (Recepient_Max means to reuse the last)
+ /// adds recipients from addr (Recipient_Max means to reuse the last)
virtual void AddRecipients(const String& addr,
RecipientType rcptType = Recipient_Max,
- bool doLayout = true);
+ int flags = AddRcpt_Expand);
- /// expands an address
- virtual RecipientType ExpandRecipient(String *text);
-
/// get from value (empty means default)
String GetFrom() const;
Modified: trunk/M/src/adb/AdbManager.cpp
===================================================================
--- trunk/M/src/adb/AdbManager.cpp 2007-01-08 00:09:32 UTC (rev 7203)
+++ trunk/M/src/adb/AdbManager.cpp 2007-01-08 21:23:41 UTC (rev 7204)
@@ -39,6 +39,12 @@
#include "adb/AdbDialogs.h"
// ----------------------------------------------------------------------------
+// options we use here
+// ----------------------------------------------------------------------------
+
+extern const MOption MP_ADB_SUBSTRINGEXPANSION;
+
+// ----------------------------------------------------------------------------
// types
// ----------------------------------------------------------------------------
@@ -339,6 +345,204 @@
return !results.IsEmpty();
}
+bool
+AdbExpandSingleAddress(String *address,
+ String *subject,
+ Profile *profile,
+ wxFrame *win)
+{
+ CHECK( address && subject, false, "NULL input address" );
+
+ subject->clear();
+
+ String textOrig = *address;
+
+ // remove "mailto:" prefix if it's there - this is convenient when you paste
+ // in an URL from the web browser
+ //
+ // TODO: add support for the mailto URL parameters, i.e. should support
+ // things like "mailto:[EMAIL PROTECTED]"
+ String newText;
+ if ( !textOrig.StartsWith(_T("mailto:"), &newText) )
+ {
+ // if the text already has a '@' inside it and looks like a full email
+ // address assume that it doesn't need to be expanded (this saves a lot
+ // of time as expanding a non existing address looks through all address
+ // books...)
+ size_t pos = textOrig.find('@');
+ if ( pos != String::npos && pos > 0 && pos < textOrig.length() )
+ {
+ // also check that the host part of the address is expanded - it
+ // should contain at least one dot normally
+ if ( wxStrchr(textOrig.c_str() + pos + 1, '.') )
+ {
+ // looks like a valid address - nothing to do
+ newText = textOrig;
+ }
+ }
+
+ if ( newText.empty() )
+ {
+ wxArrayString expansions;
+
+ if ( !AdbExpand(expansions,
+ textOrig,
+ READ_CONFIG(profile, MP_ADB_SUBSTRINGEXPANSION)
+ ? AdbLookup_Substring
+ : AdbLookup_StartsWith,
+ win) )
+ {
+ // cancelled, indicate it by returning invalid recipient type
+ return false;
+ }
+
+ // construct the replacement string(s)
+ size_t nExpCount = expansions.GetCount();
+ for ( size_t nExp = 0; nExp < nExpCount; nExp++ )
+ {
+ if ( nExp > 0 )
+ newText += ", ";
+
+ newText += expansions[nExp];
+ }
+ }
+ }
+ //else: address following mailto: doesn't need to be expanded
+
+ *address = newText;
+
+ return true;
+}
+
+RecipientType
+AdbExpandSingleRecipient(String *address,
+ String *subject,
+ Profile *profile,
+ wxFrame *win)
+{
+ CHECK( address, Recipient_Max, "NULL input address" );
+
+ String text = *address;
+ RecipientType rcptType = Recipient_None;
+ if ( text.length() > 3 )
+ {
+ // check for to:, cc: or bcc: prefix
+ if ( text[2u] == ':' )
+ {
+ if ( toupper(text[0u]) == 'T' && toupper(text[1u]) == 'O' )
+ rcptType = Recipient_To;
+ else if ( toupper(text[0u]) == 'C' && toupper(text[1u]) == 'C' )
+ rcptType = Recipient_Cc;
+ }
+ else if ( text[3u] == ':' && text(0, 3).Upper() == _T("BCC") )
+ {
+ rcptType = Recipient_Bcc;
+ }
+
+ if ( rcptType != Recipient_None )
+ {
+ // erase the prefix (length 2 or 3) with the colon
+ text.erase(0, rcptType == Recipient_Bcc ? 4 : 3);
+ }
+ }
+
+ if ( !AdbExpandSingleAddress(&text, subject, profile, win) )
+ return Recipient_Max;
+
+ *address = text;
+
+ return rcptType;
+}
+
+int
+AdbExpandAllRecipients(const String& text,
+ wxArrayString& addresses,
+ wxArrayInt& rcptTypes,
+ String *subject,
+ Profile *profile,
+ wxFrame *win)
+{
+ addresses.clear();
+ rcptTypes.clear();
+
+ int count = 0;
+ bool expandedSomething = false; // will be set to true if expand any address
+
+ // expand all addresses, one by one
+ const size_t len = text.length();
+ String address;
+ address.reserve(len);
+ bool quoted = false;
+ for ( size_t n = 0; n <= len; n++ )
+ {
+ switch ( const wxChar ch = n == len ? '\0' : text[n] )
+ {
+ case '"':
+ quoted = !quoted;
+ break;
+
+ case '\\':
+ // backslash escapes the next character (if there is one), so
+ // append it without special handling, even if it's a quote or
+ // address separator
+ if ( n < len - 1 )
+ address += text[++n];
+ else
+ wxLogWarning(_("Trailing backslash ignored."));
+ break;
+
+ case ' ':
+ // skip leading spaces unless they're quoted (note that we don't
+ // ignore trailing spaces because we want "Dan " to expand into
+ // "Dan Black" but not into "Danish guy")
+ if ( quoted || !address.empty() )
+ address += ch;
+ break;
+
+ case '\0':
+ if ( quoted )
+ {
+ wxLogWarning(_("Closing open quote implicitly."));
+ quoted = false;
+ }
+ // fall through
+
+ case ',':
+ case ';':
+ if ( !quoted )
+ {
+ // end of this address component, expand and remember it
+ RecipientType rcptType =
+ AdbExpandSingleRecipient(&address, subject, profile, win);
+ if ( rcptType != Recipient_Max )
+ {
+ expandedSomething = true;
+ }
+ else // expansion of this address failed
+ {
+ // still continue with the other ones but don't set
+ // expandedSomething so that our caller will know if we
+ // didn't do anything at all
+ rcptType = Recipient_None;
+ }
+
+ addresses.push_back(address);
+ rcptTypes.push_back(rcptType);
+ count++;
+ address.clear();
+ break;
+ }
+ //else: quoted address separators are not special, fall through
+
+ default:
+ // just accumulate in the current address
+ address += ch;
+ }
+ }
+
+ return expandedSomething ? count : -1;
+}
+
// ----------------------------------------------------------------------------
// AdbManager static functions and variables
// ----------------------------------------------------------------------------
Modified: trunk/M/src/classes/MApplication.cpp
===================================================================
--- trunk/M/src/classes/MApplication.cpp 2007-01-08 00:09:32 UTC (rev
7203)
+++ trunk/M/src/classes/MApplication.cpp 2007-01-08 21:23:41 UTC (rev
7204)
@@ -231,20 +231,17 @@
if ( composer )
{
+ composer->AddRecipients(cmdLineOpts.composer.to, Recipient_To);
composer->AddRecipients(cmdLineOpts.composer.bcc, Recipient_Bcc);
composer->AddRecipients(cmdLineOpts.composer.cc, Recipient_Cc);
composer->AddRecipients(cmdLineOpts.composer.newsgroups,
Recipient_Newsgroup);
- // the "to" parameter may be a mailto: URL, pass it through our expansion
- // function first
- String to = cmdLineOpts.composer.to;
- composer->ExpandRecipient(&to);
+ if ( !cmdLineOpts.composer.subject.empty() )
+ composer->SetSubject(cmdLineOpts.composer.subject);
+ //else: don't override the subject which could have been specified as
+ // part of "To:" recipient (common for mailto: URLs)
- composer->AddRecipients(to, Recipient_To);
-
- composer->SetSubject(cmdLineOpts.composer.subject);
-
composer->InsertText(cmdLineOpts.composer.body);
composer->ResetDirty();
Added: trunk/M/src/gui/AddressExpander.cpp
===================================================================
--- trunk/M/src/gui/AddressExpander.cpp (rev 0)
+++ trunk/M/src/gui/AddressExpander.cpp 2007-01-08 21:23:41 UTC (rev 7204)
@@ -0,0 +1,125 @@
+///////////////////////////////////////////////////////////////////////////////
+// Project: M - cross platform e-mail GUI client
+// File name: gui/AddressExpander.cpp
+// Purpose: AddressExpander implementation
+// Author: Vadim Zeitlin
+// Created: 2007-01-08
+// CVS-ID: $Id: wxComposeView.cpp 7203 2007-01-08 00:09:32Z vadz $
+// Copyright: (c) 1998-2007 Mahogany team
+// Licence: M license
+///////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+#include "Mpch.h"
+
+#ifndef USE_PCH
+# include "Mcommon.h"
+#endif
+
+#include "adb/AdbManager.h"
+
+#include "gui/AddressExpander.h"
+
+// ============================================================================
+// AddressExpander implementation
+// ============================================================================
+
+AddressExpander::AddressExpander(wxTextCtrl *text, Profile *profile)
+ : m_profile(profile)
+{
+ SafeIncRef(profile);
+
+ m_text = text;
+
+ // TODO: connect to TAB and Enter events to handle them automatically?
+}
+
+wxFrame *AddressExpander::GetParentFrame() const
+{
+ return (wxFrame *)wxGetTopLevelParent(m_text);
+}
+
+int
+AddressExpander::ExpandAll(wxArrayString& addresses,
+ wxArrayInt& rcptTypes,
+ String *subject) const
+{
+ return AdbExpandAllRecipients
+ (
+ m_text->GetValue(),
+ addresses,
+ rcptTypes,
+ subject,
+ m_profile,
+ GetParentFrame()
+ );
+}
+
+RecipientType AddressExpander::ExpandLast(String *subject)
+{
+ // find the last address
+ String text = m_text->GetValue();
+ const size_t len = text.length();
+ size_t start = 0;
+ bool quoted = false;
+ for ( size_t n = 0; n < len; n++ )
+ {
+ switch ( text[n] )
+ {
+ case '\\':
+ // skip the next character, even if it's a quote or separator
+ n++;
+ break;
+
+ case '"':
+ quoted = !quoted;
+ break;
+
+ case ',':
+ case ';':
+ if ( !quoted )
+ {
+ // keep the space if there is one following the separator
+ if ( n < len - 1 && text[n + 1] == ' ' )
+ n++;
+
+ start = n;
+ }
+ break;
+ }
+ }
+
+ // if we didn't find the final quote, skip over the initial one too
+ if ( quoted )
+ start++;
+
+ if ( start == len )
+ return Recipient_Max; // nothing to expand
+
+ // preserve the part before the address start
+ String textBefore;
+ start++;
+ textBefore.assign(text, 0, start);
+ text.erase(0, start);
+ text.Trim(false /* from left */);
+
+ // expand the address
+ RecipientType rcptType =
+ AdbExpandSingleRecipient(&text, subject, m_profile, GetParentFrame());
+
+ if ( rcptType != Recipient_Max )
+ {
+ m_text->SetValue(textBefore + text);
+ m_text->SetInsertionPointEnd();
+ }
+
+ return rcptType;
+}
+
Modified: trunk/M/src/gui/wxComposeView.cpp
===================================================================
--- trunk/M/src/gui/wxComposeView.cpp 2007-01-08 00:09:32 UTC (rev 7203)
+++ trunk/M/src/gui/wxComposeView.cpp 2007-01-08 21:23:41 UTC (rev 7204)
@@ -86,6 +86,7 @@
#include "HeadersDialogs.h"
+#include "gui/AddressExpander.h"
#include "gui/wxIdentityCombo.h"
#include "gui/wxOptionsDlg.h"
#include "gui/wxDialogLayout.h"
@@ -581,7 +582,8 @@
// different roles rather than because it is really needed.
// ----------------------------------------------------------------------------
-class wxAddressTextCtrl : public wxTextCtrlProcessingEnter
+class wxAddressTextCtrl : public wxTextCtrlProcessingEnter,
+ public AddressExpander
{
public:
// ctor
@@ -1217,16 +1219,34 @@
void wxRcptMainControl::OnAdd()
{
// expand before adding (make this optional?)
- RecipientType addrType = GetText()->DoExpand();
- if ( addrType == Recipient_None )
+ wxArrayString addresses;
+ wxArrayInt rcptTypes;
+ String subject;
+ const int count = GetText()->ExpandAll(addresses, rcptTypes, &subject);
+ if ( count == -1 )
{
- // cancelled or address is invalid
+ // cancelled by user
return;
}
- // add new recipient(s)
- m_composeView->AddRecipients(GetText()->GetValue(), addrType);
+ if ( !subject.empty() )
+ m_composeView->SetSubject(subject);
+ for ( unsigned n = 0; n < (unsigned)count; n++ )
+ {
+ // add new recipient(s)
+ RecipientType rcptType = (RecipientType)rcptTypes[n];
+ if ( rcptType == Recipient_None )
+ {
+ // use the default one
+ rcptType = GetType();
+ }
+
+ // don't [try to] expand the address again here
+ m_composeView->AddRecipients(addresses[n], rcptType,
+ !Composer::AddRcpt_Expand);
+ }
+
// clear the entry zone as recipient(s) were moved elsewhere
GetText()->SetValue(wxEmptyString);
}
@@ -1320,7 +1340,9 @@
wxAddressTextCtrl::wxAddressTextCtrl(wxWindow *parent,
wxRcptControl *rcptControl)
- : wxTextCtrlProcessingEnter(parent, wxTE_PROCESS_TAB)
+ : wxTextCtrlProcessingEnter(parent, wxTE_PROCESS_TAB),
+ AddressExpander(this,
+ rcptControl->GetComposer()->GetProfile())
{
m_rcptControl = rcptControl;
}
@@ -1377,15 +1399,11 @@
case Recipient_Cc:
case Recipient_Bcc:
{
- String text = GetValue();
+ String subject;
+ rcptType = ExpandLast(&subject);
- rcptType = GetComposer()->ExpandRecipient(&text);
-
- if ( rcptType != Recipient_None )
- {
- SetValue(text);
- SetInsertionPointEnd();
- }
+ if ( !subject.empty() )
+ m_rcptControl->GetComposer()->SetSubject(subject);
}
break;
@@ -2301,198 +2319,6 @@
// wxComposeView address headers stuff
// ----------------------------------------------------------------------------
-RecipientType
-wxComposeView::ExpandRecipient(String *textAddress)
-{
- // don't do anything for the newsgroups
- //
- // TODO-NEWS: expand using .newsrc?
- if ( m_mode == wxComposeView::Mode_News )
- {
- return Recipient_Newsgroup;
- }
-
- // try to expand the last component
- String& text = *textAddress;
-
- // trim spaces from left, but not (all) from right -- this allows "Dan " to
- // be expanded into "Dan Black" but not in "Danish Guy"
- text.Trim(FALSE);
- bool hasSpaceAtEnd = !text.empty() && text.Last() == ' ';
- text.Trim(TRUE);
- if ( !text.empty() && hasSpaceAtEnd )
- text += ' ';
-
- // check for the lone '"' simplifies the code for finding the starting
- // position below: it should be done here, otherwise the following loop
- // will crash!
- if ( text.empty() || text == '"' )
- {
- // don't do anything
- wxLogStatus(GetFrame(),
- _("Nothing to expand - please enter something."));
-
- return Recipient_None;
- }
-
- // find the starting position of the last address in the address list
- size_t nLastAddr;
- bool quoted = text.Last() == '"';
- if ( quoted )
- {
- // just find the matching quote (not escaped)
- const wxChar *pStart = text.c_str();
- const wxChar *p;
- for ( p = pStart + text.length() - 2; p >= pStart; p-- )
- {
- if ( *p == '"' )
- {
- // check that it's not escaped
- if ( (p == pStart) || (*(p - 1) != '\\') )
- {
- // ok, found it!
- break;
- }
- }
- }
-
- nLastAddr = p - pStart;
- }
- else // unquoted
- {
- // search back until the last address separator
- for ( nLastAddr = text.length() - 1; nLastAddr > 0; nLastAddr-- )
- {
- wxChar c = text[nLastAddr];
- if ( (c == ',') || (c == ';') )
- break;
- }
-
- if ( nLastAddr > 0 )
- {
- // move beyond the ',' or ';' which stopped the scan
- nLastAddr++;
- }
-
- // the address will probably never start with spaces but if it does, it
- // will be enough to just take it into quotes
- while ( wxIsspace(text[nLastAddr]) )
- {
- nLastAddr++;
- }
- }
-
- // so now we've got the text we'll be trying to expand
- String textOrig = text.c_str() + nLastAddr;
-
- // do we have an explicit address type specifier
- RecipientType addrType = Recipient_Max;
- if ( textOrig.length() > 3 )
- {
- // check for to:, cc: or bcc: prefix
- if ( textOrig[2u] == ':' )
- {
- if ( toupper(textOrig[0u]) == 'T' && toupper(textOrig[1u]) == 'O' )
- addrType = Recipient_To;
- else if ( toupper(textOrig[0u]) == 'C' && toupper(textOrig[1u]) ==
'C' )
- addrType = Recipient_Cc;
- }
- else if ( textOrig[3u] == ':' && textOrig(0, 3).Upper() == _T("BCC") )
- {
- addrType = Recipient_Bcc;
- }
-
- if ( addrType != Recipient_Max )
- {
- // erase the colon as well
- textOrig.erase(0, addrType == Recipient_Bcc ? 4 : 3);
- }
- }
-
- // remove "mailto:" prefix if it's there - this is convenient when you paste
- // in an URL from the web browser
- //
- // TODO: add support for the mailto URL parameters, i.e. should support
- // things like "mailto:[EMAIL PROTECTED]"
- String newText;
- if ( !textOrig.StartsWith(_T("mailto:"), &newText) )
- {
- // if the text already has a '@' inside it and looks like a full email
- // address assume that it doesn't need to be expanded (this saves a lot
- // of time as expanding a non existing address looks through all address
- // books...)
- size_t pos = textOrig.find('@');
- if ( pos != String::npos && pos > 0 && pos < textOrig.length() )
- {
- // also check that the host part of the address is expanded - it
- // should contain at least one dot normally
- if ( wxStrchr(textOrig.c_str() + pos + 1, '.') )
- {
- // looks like a valid address - nothing to do
- newText = textOrig;
- }
- }
-
- if ( newText.empty() )
- {
- wxArrayString expansions;
-
- if ( !AdbExpand(expansions,
- textOrig,
- READ_CONFIG(GetProfile(), MP_ADB_SUBSTRINGEXPANSION)
- ? AdbLookup_Substring
- : AdbLookup_StartsWith,
- this) )
- {
- // cancelled, don't do anything
- return Recipient_None;
- }
-
- // construct the replacement string(s)
- size_t nExpCount = expansions.GetCount();
- for ( size_t nExp = 0; nExp < nExpCount; nExp++ )
- {
- if ( nExp > 0 )
- newText += CANONIC_ADDRESS_SEPARATOR;
-
- newText += expansions[nExp];
- }
- }
- }
-
- // find the end of the previous address
- size_t nPrevAddrEnd;
- if ( nLastAddr > 0 )
- {
- // undo "++" above
- nLastAddr--;
- }
-
- for ( nPrevAddrEnd = nLastAddr; nPrevAddrEnd > 0; nPrevAddrEnd-- )
- {
- wxChar c = text[nPrevAddrEnd];
- if ( !wxIsspace(c) && (c != ',') && (c != ';') )
- {
- // this character is a part of previous string, leave it there
- nPrevAddrEnd++;
-
- break;
- }
- }
-
- // keep the text up to the address we expanded/processed
- wxString oldText(text, nPrevAddrEnd); // first nPrevAddrEnd chars
- if ( !oldText.empty() )
- {
- // there was something before, add separator
- oldText += CANONIC_ADDRESS_SEPARATOR;
- }
-
- text = oldText + newText;
-
- return addrType;
-}
-
void
wxComposeView::AddRecipientControls(const String& value, RecipientType rt)
{
@@ -2569,12 +2395,16 @@
}
void
-wxComposeView::AddRecipients(const String& address, RecipientType addrType,
bool doLayout)
+wxComposeView::AddRecipients(const String& addressOrig,
+ RecipientType addrType,
+ int flags)
{
// if there is no address, nothing to do
- if ( address.empty() )
+ if ( addressOrig.empty() )
return;
+ String address = addressOrig;
+
// invalid rcpt type means to reuse the last one
if ( addrType == Recipient_Max )
{
@@ -2605,6 +2435,15 @@
case Recipient_To:
case Recipient_Cc:
case Recipient_Bcc:
+ if ( flags & AddRcpt_Expand )
+ {
+ String subject;
+ AdbExpandSingleAddress(&address, &subject, GetProfile(), this);
+
+ if ( !subject.empty() )
+ SetSubject(subject);
+ }
+
// an email address
{
// split the string in addreses and add all of them
Modified: trunk/M/src/mail/MailFolder.cpp
===================================================================
--- trunk/M/src/mail/MailFolder.cpp 2007-01-08 00:09:32 UTC (rev 7203)
+++ trunk/M/src/mail/MailFolder.cpp 2007-01-08 21:23:41 UTC (rev 7204)
@@ -680,7 +680,7 @@
while ( n-- )
{
- cv->AddRecipients(rcptAddresses[n], (RecipientType)rcptTypes[n], (n >
0 ? false : true));
+ cv->AddRecipients(rcptAddresses[n], (RecipientType)rcptTypes[n]);
}
return;
@@ -869,7 +869,7 @@
while ( n-- )
{
- cv->AddRecipients(rcptAddresses[n], (RecipientType)rcptTypes[n], !n);
+ cv->AddRecipients(rcptAddresses[n], (RecipientType)rcptTypes[n]);
}
}
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Mahogany-cvsupdates mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mahogany-cvsupdates