Revision: 7420
http://mahogany.svn.sourceforge.net/mahogany/?rev=7420&view=rev
Author: vadz
Date: 2008-04-20 18:59:12 -0700 (Sun, 20 Apr 2008)
Log Message:
-----------
allow adding custom headers to be shown in the message view
Modified Paths:
--------------
trunk/M/CHANGES
trunk/M/include/gui/wxSelectionDlg.h
trunk/M/src/gui/wxHeadersDialogs.cpp
trunk/M/src/gui/wxMDialogs.cpp
Modified: trunk/M/CHANGES
===================================================================
--- trunk/M/CHANGES 2008-04-19 23:59:00 UTC (rev 7419)
+++ trunk/M/CHANGES 2008-04-21 01:59:12 UTC (rev 7420)
@@ -9,6 +9,7 @@
Release 0.68 '' September xx, 2007
---------------------------------------
+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
2007-01-10 VZ: Show the message subject in the composer window title bar
Modified: trunk/M/include/gui/wxSelectionDlg.h
===================================================================
--- trunk/M/include/gui/wxSelectionDlg.h 2008-04-19 23:59:00 UTC (rev
7419)
+++ trunk/M/include/gui/wxSelectionDlg.h 2008-04-21 01:59:12 UTC (rev
7420)
@@ -19,15 +19,31 @@
// wxSelectionsOrderDialog
// ----------------------------------------------------------------------------
-// helper class used by MDialog_GetSelectionsInOrder and
-// wxMsgViewHeadersDialog elsewhere
+// helper class used by MDialog_GetSelectionsInOrder and wxMsgViewHeadersDialog
+// elsewhere: it allows to show to the user the list of strings which can be
+// individually checked/unchecked and reordered and, possibly, edited (added,
+// changed or removed) by user
class wxSelectionsOrderDialog : public wxManuallyLaidOutDialog
{
public:
+ // flags for optional features
+ enum
+ {
+ // default: the list of strings can't be modified at all
+ Allow_Nothing = 0,
+
+ // allow adding user-defined strings to the list (virtual OnItemAdd() is
+ // called to validate them)
+ Allow_Add = 1
+
+ // add Allow_Edit/Delete later if needed
+ };
+
wxSelectionsOrderDialog(wxWindow *parent,
const wxString& message,
const wxString& caption,
- const wxString& profileKey);
+ const wxString& profileKey,
+ int extraFeatures = Allow_Nothing);
// did anything really changed?
bool HasChanges() const { return m_hasChanges; }
@@ -37,8 +53,24 @@
virtual bool TransferDataToWindow() = 0;
virtual bool TransferDataFromWindow() = 0;
- // implementation only from now on
+protected:
+ // can be overridden if the derived class wants to know when the 2 items in
+ // the check list box are exchanged (after this has happened)
+ virtual void OnItemSwap(size_t /* item1 */, size_t /* item2 */) { }
+ // can be overridden to validate the string before adding it to the
+ // checklistbox; the string is not added if this method returns false
+ //
+ // the base class version checks if the string is already present in the
+ // list and returns false if it is, so make sure to call it from the derived
+ // class unless this check is undesirable
+ //
+ // notice that it is only called if Allow_Add was used
+ virtual bool OnItemAdd(const wxString& item);
+
+
+ // event handlers
+
// check list box event handler
void OnCheckLstBoxToggle(wxCommandEvent&) { m_hasChanges = TRUE; }
@@ -48,18 +80,24 @@
// up/down buttons notifications
void OnButtonUp(wxCommandEvent&) { OnButtonMove(TRUE); }
void OnButtonDown(wxCommandEvent&) { OnButtonMove(FALSE); }
+ void OnButtonMove(bool up);
-protected:
- // can be overridden if the derived class wants to know when the 2 items in
- // the check list box are exchanged (after this has happened)
- virtual void OnItemSwap(size_t /* item1 */, size_t /* item2 */) { }
+ // handlers for the controls used for adding items: notice that it's ok to
+ // dereference m_textAdd here without checking that it's non-NULL as these
+ // handlers are only connected if it is being used
+ void OnAdd(wxCommandEvent&) { DoAddItem(m_textAdd->GetValue()); }
+ void OnUpdateAddButton(wxUpdateUIEvent& event)
+ {
+ event.Enable( !m_textAdd->IsEmpty() );
+ }
- // real button events handler
- void OnButtonMove(bool up);
-
// update the buttons state to reflect the selection in the checklistbox
void UpdateButtons(int sel);
+ // add a new item to the list box
+ void DoAddItem(const wxString& item);
+
+
// the box around all our controls (here for wxFolderViewColumnsDialog only)
wxStaticBox *m_box;
@@ -67,6 +105,9 @@
wxButton *m_btnUp,
*m_btnDown;
+ // the text containing the new item to add (only !NULL if Allow_Add used)
+ wxTextCtrl *m_textAdd;
+
// the check list box containing the items we reorder
wxCheckListBox *m_checklstBox;
Modified: trunk/M/src/gui/wxHeadersDialogs.cpp
===================================================================
--- trunk/M/src/gui/wxHeadersDialogs.cpp 2008-04-19 23:59:00 UTC (rev
7419)
+++ trunk/M/src/gui/wxHeadersDialogs.cpp 2008-04-21 01:59:12 UTC (rev
7420)
@@ -110,6 +110,51 @@
};
// ----------------------------------------------------------------------------
+// private functions
+// ----------------------------------------------------------------------------
+
+namespace
+{
+
+/**
+ Checks if the given string is a valid header name conforming to RFC 2822.
+
+ @param header The string to check.
+ @param reason If non-NULL, filled with the explanation of why the header
+ name is invalid if the function returns false.
+ @return true if the header name is valid, false otherwise
+ */
+bool IsValidHeaderName(const wxString& header, wxString *reason)
+{
+ for ( wxString::const_iterator p = header.begin(); p != header.end(); ++p )
+ {
+ // RFC 822 allows '/' but we don't because it has a special meaning for
+ // the profiles/wxConfig; other characters are excluded in accordance
+ // with the definition of the header name in the section 2.2 of RFC 2822
+ wxChar c = *p;
+ if ( c < 32 || c > 126 )
+ {
+ if ( reason )
+ *reason = "only ASCII characters are allowed";
+
+ return false;
+ }
+
+ if ( c == ':' )
+ {
+ if ( reason )
+ *reason = "colons are not allowed";
+
+ return false;
+ }
+ }
+
+ return true;
+}
+
+} // anonymous namespace
+
+// ----------------------------------------------------------------------------
// private classes
// ----------------------------------------------------------------------------
@@ -166,6 +211,10 @@
virtual bool TransferDataToWindow();
virtual bool TransferDataFromWindow();
+protected:
+ // validate the header names
+ virtual bool OnItemAdd(const wxString& item);
+
private:
Profile *m_profile;
@@ -485,16 +534,19 @@
wxMsgViewHeadersDialog::wxMsgViewHeadersDialog(Profile *profile,
wxWindow *parent)
- : wxSelectionsOrderDialog(parent,
- _("&Headers"),
- _("Configure headers to show "
- "in message view"),
- _T("MsgViewHeaders"))
+ : wxSelectionsOrderDialog
+ (
+ parent,
+ _("&Headers to show in message view"),
+ _("Configure message view headers"),
+ _T("MsgViewHeaders"),
+ Allow_Add
+ )
{
m_profile = profile;
SafeIncRef(profile);
- SetDefaultSize(3*wBtn, 10*hBtn);
+ SetDefaultSize(6*wBtn, 10*hBtn);
}
wxMsgViewHeadersDialog::~wxMsgViewHeadersDialog()
@@ -502,6 +554,23 @@
SafeDecRef(m_profile);
}
+bool wxMsgViewHeadersDialog::OnItemAdd(const wxString& item)
+{
+ if ( !wxSelectionsOrderDialog::OnItemAdd(item) )
+ return false;
+
+ wxString reason;
+ if ( !IsValidHeaderName(item, &reason) )
+ {
+ wxLogWarning(_("\"%s\" is not a valid header name: %s."),
+ item.c_str(), reason.c_str());
+
+ return false;
+ }
+
+ return true;
+}
+
bool wxMsgViewHeadersDialog::TransferDataToWindow()
{
// colon separated list of all the headers (even if they're not all shown)
@@ -749,20 +818,23 @@
m_headerName = m_textctrlName->GetValue();
// check that this is a valid header name
- for ( const wxChar *pc = m_headerName.c_str(); *pc; pc++ )
+ wxString reason;
+ if ( IsValidHeaderName(m_headerName, &reason) )
{
- // RFC 822 allows '/' but we don't because it has a special meaning for
- // the profiles/wxConfig; other characters are excluded in accordance
- // with the definition of the header name in the RFC
- wxChar c = *pc;
- if ( c < 32 || c > 126 || c == ':' || c == '/' )
+ // in addition to the standard RFC checks we also forbid slashes as this
+ // string is used as profile key
+ if ( m_headerName.find('/') != wxString::npos )
{
- wxLogError(_("The character '%c' is invalid in the header name, "
- "please replace or remove it."), c);
- return false;
+ reason = "slashes are not allowed in this context";
}
}
+ if ( !reason.empty() )
+ {
+ wxLogError(_("Specified header name is invalid: %s."), reason.c_str());
+ return false;
+ }
+
m_headerValue = m_textctrlValue->GetValue();
if ( m_checkboxRemember )
@@ -1119,7 +1191,7 @@
void wxCustomHeadersDialog::OnDelete(wxCommandEvent& WXUNUSED(event))
{
- size_t sel = 0; // inititialize it to fix compiler warnings
+ size_t sel = 0; // initialize it to fix compiler warnings
CHECK_RET( GetSelection(&sel), _T("button should be disabled") );
m_listctrl->DeleteItem(sel);
Modified: trunk/M/src/gui/wxMDialogs.cpp
===================================================================
--- trunk/M/src/gui/wxMDialogs.cpp 2008-04-19 23:59:00 UTC (rev 7419)
+++ trunk/M/src/gui/wxMDialogs.cpp 2008-04-21 01:59:12 UTC (rev 7420)
@@ -2399,15 +2399,21 @@
return selections->GetCount();
}
-// ----------------------------------------------------------------------------
+// ============================================================================
// wxSelectionsOrderDialog
+// ============================================================================
+
// ----------------------------------------------------------------------------
+// event table
+// ----------------------------------------------------------------------------
// control ids for wxSelectionsOrderDialog
enum
{
Button_Up = 1000,
- Button_Down
+ Button_Down,
+ Button_Add,
+ Text_Add
};
BEGIN_EVENT_TABLE(wxSelectionsOrderDialog, wxManuallyLaidOutDialog)
@@ -2419,13 +2425,19 @@
EVT_LISTBOX(-1, wxSelectionsOrderDialog::OnCheckLstBoxSelChanged)
END_EVENT_TABLE()
+// ----------------------------------------------------------------------------
+// wxSelectionsOrderDialog ctor
+// ----------------------------------------------------------------------------
+
wxSelectionsOrderDialog::wxSelectionsOrderDialog(wxWindow *parent,
const wxString& message,
const wxString& caption,
- const wxString& profileKey)
+ const wxString& profileKey,
+ int extraFeatures)
: wxManuallyLaidOutDialog(parent, caption, profileKey)
{
m_hasChanges = false;
+ m_textAdd = NULL;
// layout the controls
// -------------------
@@ -2454,13 +2466,56 @@
c->height.AsIs();
m_btnUp->SetConstraints(c);
+ // optional controls for string editing below the list box
+ wxControl *ctrlBelow = NULL;
+ if ( extraFeatures & Allow_Add )
+ {
+ wxStaticText *labelAdd = new wxStaticText(this, -1, _("&Add another:"));
+ c = new wxLayoutConstraints();
+ c->left.SameAs(m_box, wxLeft, 2*LAYOUT_X_MARGIN);
+ c->bottom.SameAs(m_box, wxBottom, 2*LAYOUT_Y_MARGIN);
+ c->width.AsIs();
+ c->height.AsIs();
+ labelAdd->SetConstraints(c);
+
+ m_textAdd = new wxTextCtrl(this, Text_Add, "",
+ wxDefaultSize, wxDefaultPosition,
+ wxTE_PROCESS_ENTER);
+ c = new wxLayoutConstraints();
+ c->left.RightOf(labelAdd, LAYOUT_X_MARGIN);
+ c->centreY.SameAs(labelAdd, wxCentreY);
+ c->right.LeftOf(m_btnDown, 2*LAYOUT_X_MARGIN);
+ c->height.AsIs();
+ m_textAdd->SetConstraints(c);
+
+ wxButton *btnAdd = new wxButton(this, Button_Add, _("A&dd"));
+ c = new wxLayoutConstraints();
+ c->left.RightOf(m_textAdd, LAYOUT_Y_MARGIN);
+ c->centreY.SameAs(m_textAdd, wxCentreY);
+ c->width.SameAs(m_btnDown, wxWidth);
+ c->height.AsIs();
+ btnAdd->SetConstraints(c);
+
+ ctrlBelow = btnAdd;
+
+ Connect(Button_Add, wxEVT_COMMAND_BUTTON_CLICKED,
+ wxCommandEventHandler(wxSelectionsOrderDialog::OnAdd));
+ Connect(Text_Add, wxEVT_COMMAND_TEXT_ENTER,
+ wxCommandEventHandler(wxSelectionsOrderDialog::OnAdd));
+ Connect(Button_Add, wxEVT_UPDATE_UI,
+
wxUpdateUIEventHandler(wxSelectionsOrderDialog::OnUpdateAddButton));
+ }
+
// a checklistbox with headers on the space which is left
m_checklstBox = new wxCheckListBox(this, -1);
c = new wxLayoutConstraints();
c->left.SameAs(m_box, wxLeft, 2*LAYOUT_X_MARGIN);
c->right.LeftOf(m_btnDown, 2*LAYOUT_X_MARGIN);
c->top.SameAs(m_box, wxTop, 4*LAYOUT_Y_MARGIN);
- c->bottom.SameAs(m_box, wxBottom, 2*LAYOUT_Y_MARGIN);
+ if ( ctrlBelow )
+ c->bottom.SameAs(ctrlBelow, wxTop, 2*LAYOUT_Y_MARGIN);
+ else
+ c->bottom.SameAs(m_box, wxBottom, 2*LAYOUT_Y_MARGIN);
m_checklstBox->SetConstraints(c);
UpdateButtons(m_checklstBox->GetSelection());
@@ -2469,6 +2524,43 @@
SetDefaultSize(3*wBtn, 7*hBtn);
}
+// ----------------------------------------------------------------------------
+// wxSelectionsOrderDialog handling adding items
+// ----------------------------------------------------------------------------
+
+bool wxSelectionsOrderDialog::OnItemAdd(const wxString& item)
+{
+ int count = m_checklstBox->GetCount();
+ for ( int n = 0; n < count; n++ )
+ {
+ if ( m_checklstBox->GetString(n) == item )
+ {
+ wxLogWarning(_("The string \"%s\" is already present in the list."),
+ item.c_str());
+
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void wxSelectionsOrderDialog::DoAddItem(const wxString& item)
+{
+ if ( OnItemAdd(item) )
+ {
+ const int pos = m_checklstBox->Append(item);
+
+ // we consider that the new item was added in order to be used, so be
+ // smart and do it by default
+ m_checklstBox->Check(pos);
+ }
+}
+
+// ----------------------------------------------------------------------------
+// wxSelectionsOrderDialog event handlers
+// ----------------------------------------------------------------------------
+
void wxSelectionsOrderDialog::UpdateButtons(int sel)
{
// only enable buttons if there is something selected and also if pressing
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