Update of /cvsroot/mahogany/M/src/gui
In directory usw-pr-cvs1:/tmp/cvs-serv11528/src/gui

Modified Files:
        wxComposeView.cpp wxMDialogs.cpp wxMenuDefs.cpp 
        wxMsgCmdProc.cpp wxOptionsDlg.cpp 
Log Message:
implemented message editing/postponing and the drafts folder - all very rough
but seems to sort of work


Index: wxComposeView.cpp
===================================================================
RCS file: /cvsroot/mahogany/M/src/gui/wxComposeView.cpp,v
retrieving revision 1.255
retrieving revision 1.256
diff -b -u -2 -r1.255 -r1.256
--- wxComposeView.cpp   13 Mar 2002 22:30:03 -0000      1.255
+++ wxComposeView.cpp   16 Mar 2002 23:38:48 -0000      1.256
@@ -108,4 +108,5 @@
 extern const MOption MP_CVIEW_FONT_DESC;
 extern const MOption MP_CVIEW_FONT_SIZE;
+extern const MOption MP_DRAFTS_FOLDER;
 extern const MOption MP_EXTERNALEDITOR;
 extern const MOption MP_HOSTNAME;
@@ -127,4 +128,5 @@
 extern const MPersMsgBox *M_MSGBOX_ASK_VCARD;
 extern const MPersMsgBox *M_MSGBOX_CONFIG_NET_FROM_COMPOSE;
+extern const MPersMsgBox *M_MSGBOX_DRAFT_SAVED;
 extern const MPersMsgBox *M_MSGBOX_FIX_TEMPLATE;
 extern const MPersMsgBox *M_MSGBOX_MIME_TYPE_CORRECT;
@@ -143,6 +145,6 @@
 };
 
-// the default message title
-#define COMPOSER_TITLE (_("Message Composition"))
+// the composer frame title
+#define COMPOSER_TITLE _("Message Composition")
 
 // separate multiple addresses with commas
@@ -544,5 +546,5 @@
    if ( m_Type == Type_Data )
    {
-      delete [] (char *)m_Data;
+      free(m_Data);
    }
 }
@@ -926,65 +928,63 @@
 
 // ----------------------------------------------------------------------------
-// wxComposeView creation: static functions
+// wxComposeView creation: static creator functions
 // ----------------------------------------------------------------------------
 
-/** Constructor for posting news.
-    @param parentProfile parent profile
-    @param hide if true, do not show frame
-    @return pointer to the new compose view
-*/
-Composer *
-Composer::CreateNewArticle(const MailFolder::Params& params,
-                           Profile *parentProfile,
+static wxComposeView *CreateComposeView(Profile *profile,
+                                        const MailFolder::Params& params,
+                                        wxComposeView::Mode mode,
+                                        wxComposeView::MessageKind kind,
                            bool hide)
 {
    wxWindow *parent = mApplication->TopLevelFrame();
-   wxComposeView *cv = new wxComposeView("ComposeViewNews", parent);
-   cv->m_mode = wxComposeView::Mode_News;
-   cv->m_kind = wxComposeView::Message_New;
-   cv->m_template = params.templ;
+   wxComposeView *cv = new wxComposeView
+                           (
+                              "ComposeViewNews",
+                              mode,
+                              kind,
+                              parent
+                           );
+
+   cv->SetTemplate(params.templ);
    cv->SetTitle(COMPOSER_TITLE);
-   cv->Create(parent, parentProfile);
+   cv->Create(parent, profile, hide);
 
    return cv;
 }
 
-/** Constructor for sending mail.
-    @param parentProfile parent profile
-    @param hide if true, do not show frame
-    @return pointer to the new compose view
-*/
 Composer *
-Composer::CreateNewMessage(const MailFolder::Params& params,
-                           Profile *parentProfile,
+Composer::CreateNewArticle(const MailFolder::Params& params,
+                           Profile *profile,
                            bool hide)
 {
-   wxWindow *parent = mApplication->TopLevelFrame();
-   wxComposeView *cv = new wxComposeView("ComposeViewMail", parent);
-   cv->m_mode = wxComposeView::Mode_Mail;
-   cv->m_kind = wxComposeView::Message_New;
-   cv->m_template = params.templ;
-   cv->SetTitle(COMPOSER_TITLE);
-   cv->Create(parent,parentProfile);
+   return CreateComposeView(profile, params,
+                            wxComposeView::Mode_News,
+                            wxComposeView::Message_New,
+                            hide);
+}
 
-   return cv;
+Composer *
+Composer::CreateNewMessage(const MailFolder::Params& params,
+                           Profile *profile,
+                           bool hide)
+{
+   return CreateComposeView(profile, params,
+                            wxComposeView::Mode_Mail,
+                            wxComposeView::Message_New,
+                            hide);
 }
 
 Composer *
 Composer::CreateReplyMessage(const MailFolder::Params& params,
-                             Profile *parentProfile,
+                             Profile *profile,
                              Message *original,
                              bool hide)
 {
-   wxComposeView *cv = CreateNewMessage(parentProfile, hide)->GetComposeView();
+   wxComposeView *cv = CreateComposeView(profile, params,
+                                         wxComposeView::Mode_Mail,
+                                         wxComposeView::Message_Reply,
+                                         hide);
 
-   cv->m_kind = wxComposeView::Message_Reply;
-   cv->m_template = params.templ;
-
-   cv->m_OriginalMessage = original;
-   SafeIncRef(cv->m_OriginalMessage);
-
-   // write reply by default in the same encoding as the original message
-   cv->SetEncodingToSameAs(original);
+   cv->SetOriginal(original);
 
    return cv;
@@ -993,15 +993,79 @@
 Composer *
 Composer::CreateFwdMessage(const MailFolder::Params& params,
-                           Profile *parentProfile,
+                           Profile *profile,
                            Message *original,
                            bool hide)
 {
-   wxComposeView *cv = CreateNewMessage(parentProfile, hide)->GetComposeView();
+   wxComposeView *cv = CreateComposeView(profile, params,
+                                         wxComposeView::Mode_Mail,
+                                         wxComposeView::Message_Forward,
+                                         hide);
+
+   cv->SetOriginal(original);
+
+   return cv;
+}
+
+Composer *
+Composer::EditMessage(Profile *profile, Message *msg)
+{
+   CHECK( msg, NULL, "no message to edit?" );
+
+   // first, create the composer
+
+   // create dummy params object as we need one for CreateNewMessage()
+   MailFolder::Params params("");
+
+   Composer *cv = CreateNewMessage(params, profile);
+
+   // next, import the message body in it
+   cv->InsertMimePart(msg->GetTopMimePart());
+
+   cv->ResetDirty();
+
+   // finally, also import all headers
 
-   cv->m_kind = wxComposeView::Message_Forward;
-   cv->m_template = params.templ;
+   // except the ones in ignoredHeaders:
 
-   // preserve message encoding when forwarding it
-   cv->SetEncodingToSameAs(original);
+   // first ignore those which are generated by the transport layer as it
+   // doesn't make sense to generate them at all a MUA
+   wxSortedArrayString ignoredHeaders;
+   ignoredHeaders.Add("RECEIVED");
+   ignoredHeaders.Add("RETURN-PATH");
+   ignoredHeaders.Add("DELIVERED-TO");
+
+   // second, ignore some headers which we always generate ourselves and don't
+   // allow the user to override anyhow
+   ignoredHeaders.Add("MIME-VERSION");
+   ignoredHeaders.Add("CONTENT-TYPE");
+   ignoredHeaders.Add("CONTENT-DISPOSITION");
+   ignoredHeaders.Add("CONTENT-TRANSFER-ENCODING");
+
+   wxArrayString names, values;
+   size_t count = msg->GetAllHeaders(&names, &values);
+   for ( size_t n = 0; n < count; n++ )
+   {
+      wxString name = names[n].Upper();
+
+      // test for some standard headers which need special treatment
+      if ( name == "SUBJECT" )
+         cv->SetSubject(values[n]);
+      else if ( name == "FROM" )
+         cv->SetFrom(values[n]);
+      else if ( name == "TO" )
+         cv->AddTo(values[n]);
+      else if ( name == "CC" )
+         cv->AddCc(values[n]);
+      else if ( name == "BCC" )
+         cv->AddBcc(values[n]);
+      else if ( ignoredHeaders.Index(name) == wxNOT_FOUND )
+         cv->AddHeaderEntry(names[n], values[n]);
+      //else: we ignore this one
+   }
+
+   // use the same language as we had used before
+   ((wxComposeView *)cv)->SetEncodingToSameAs(msg);
+
+   msg->DecRef();
 
    return cv;
@@ -1013,7 +1077,11 @@
 
 wxComposeView::wxComposeView(const String &name,
+                             Mode mode,
+                             MessageKind kind,
                              wxWindow *parent)
              : wxMFrame(name,parent)
 {
+   m_mode = mode;
+   m_kind = kind;
    m_name = name;
    m_pidEditor = 0;
@@ -1031,4 +1099,15 @@
 }
 
+void wxComposeView::SetOriginal(Message *original)
+{
+   CHECK_RET( original, "no original message in composer" );
+
+   m_OriginalMessage = original;
+   m_OriginalMessage->IncRef();
+
+   // write reply by default in the same encoding as the original message
+   SetEncodingToSameAs(original);
+}
+
 wxComposeView::~wxComposeView()
 {
@@ -1814,6 +1893,5 @@
       if ( hasCard )
       {
-         InsertData(strutil_strdup(vcard), vcard.length(),
-                    "text/x-vcard", filename);
+         InsertData(strdup(vcard), vcard.length(), "text/x-vcard", filename);
       }
    }
@@ -1864,6 +1942,5 @@
 void wxComposeView::SetEncodingToSameAs(Message *msg)
 {
-   if ( !msg )
-      return;
+   CHECK_RET( msg, "no message in SetEncodingToSameAs" );
 
    // find the first text part with non default encoding
@@ -1961,12 +2038,30 @@
    {
       // ask the user if he wants to save the changes
-      canClose = MDialog_YesNoDialog
+      MDlgResult rc = MDialog_YesNoCancel
                  (
-                  _("There are unsaved changes, close anyway?"),
+                        _("There are unsaved changes, would you like to save the "
+                          "as a draft?\n"
+                          "\n"
+                          "You may also choose \"Cancel\" to not close this "
+                          "window at all."),
                   this, // parent
                   MDIALOG_YESNOTITLE,
-                  M_DLG_NO_DEFAULT,
-                  M_MSGBOX_UNSAVED_PROMPT
+                        M_DLG_NO_DEFAULT
                  );
+
+      switch ( rc )
+      {
+         case MDlg_No:
+            canClose = true;
+            break;
+
+         case MDlg_Yes:
+            if ( SaveAsDraft() )
+               break;
+            //else: fall through and don't close the window
+
+         case MDlg_Cancel:
+            canClose = false;
+      }
    }
    else
@@ -2018,4 +2113,11 @@
          break;
 
+      case WXMENU_COMPOSE_SAVE_AS_DRAFT:
+         if ( SaveAsDraft() )
+         {
+            Close();
+         }
+         break;
+
       case WXMENU_COMPOSE_PREVIEW:
          {
@@ -2560,4 +2662,75 @@
 }
 
+void
+wxComposeView::InsertMimePart(const MimePart *mimePart)
+{
+   CHECK_RET( mimePart, "no top MIME part in the message to edit?" );
+
+   MimeType type = mimePart->GetType();
+   switch ( type.GetPrimary() )
+   {
+      case MimeType::MULTIPART:
+         {
+            const MimePart *partChild = mimePart->GetNested();
+
+            String subtype = type.GetSubType();
+            if ( subtype == "ALTERNATIVE" )
+            {
+               // assume that we can edit the first subpart, this must be the
+               // most "rough" one and as we only support editing text, if we
+               // can edit anything at all it's going to be this one
+               InsertMimePart(partChild);
+            }
+            else // assume MIXED for all others
+            {
+               // and so simply insert all parts in turn
+               while ( partChild )
+               {
+                  InsertMimePart(partChild);
+
+                  partChild = partChild->GetNext();
+               }
+            }
+         }
+         break;
+
+      case MimeType::TEXT:
+         // cast is ok - it's a text part
+         InsertText((const char *)mimePart->GetContent());
+         break;
+
+      case MimeType::MESSAGE:
+      case MimeType::APPLICATION:
+      case MimeType::AUDIO:
+      case MimeType::IMAGE:
+      case MimeType::VIDEO:
+      case MimeType::MODEL:
+      case MimeType::OTHER:
+         // anything else gets inserted as an attachment
+         {
+            // we need to make a copy of the data as we're going to free() it
+            unsigned long len;
+            const void *data = mimePart->GetContent(&len);
+            CHECK_RET( data, "failed to retrieve the message data" );
+
+            void *data2 = malloc(len);
+            memcpy(data2, data, len);
+
+            InsertData(data2, len,
+                       mimePart->GetType().GetFull(), mimePart->GetFilename());
+         }
+         break;
+
+      case MimeType::CUSTOM1:
+      case MimeType::CUSTOM2:
+      case MimeType::CUSTOM3:
+      case MimeType::CUSTOM4:
+      case MimeType::CUSTOM5:
+      case MimeType::CUSTOM6:
+      default:
+         FAIL_MSG( "unknown MIME type" );
+   }
+}
+
 // ----------------------------------------------------------------------------
 // wxComposeView sending the message
@@ -2970,4 +3143,11 @@
 // -----------------------------------------------------------------------------
 
+void
+wxComposeView::SetFrom(const String& from)
+{
+   m_from = from;
+   m_txtFrom->SetValue(from);
+}
+
 /// sets From field using the current profile
 void
@@ -2981,6 +3161,5 @@
       if ( addr )
       {
-         m_from = addr->GetAddress();
-         m_txtFrom->SetValue(m_from);
+         SetFrom(addr->GetAddress());
       }
    }
@@ -3024,11 +3203,15 @@
 }
 
-/// save the first text part of the message to the given file
+// ----------------------------------------------------------------------------
+// wxComposeView saving
+// ----------------------------------------------------------------------------
+
+// save the first text part of the message to the given file
 bool
 wxComposeView::SaveMsgTextToFile(const String& filename) const
 {
-   // TODO write (and read later...) headers too!
+   // TODO write (and read later...) headers too?
 
-   // write the text part of the message into a file
+   // write all text parts of the message into a file
    wxFile file(filename, wxFile::write_append);
    if ( !file.IsOpened() )
@@ -3039,5 +3222,5 @@
    }
 
-   // export all text parts of the message
+   // iterate over all message parts
    for ( EditorContentPart *part = m_editor->GetFirstPart();
          part;
@@ -3057,4 +3240,91 @@
 
    ((wxComposeView *)this)->ResetDirty(); // const_cast
+
+   return true;
+}
+
+// from upgrade.cpp, this forward decl will disappear once we move it somewhere
+// else (most likely MFolder?)
+extern int
+VerifyStdFolder(const MOption& optName,
+                const String& nameDefault,
+                int flags,
+                const String& comment,
+                MFolderIndex idxInTree = MFolderIndex_Max,
+                int icon = -1);
+
+bool wxComposeView::SaveAsDraft() const
+{
+   SendMessage_obj msg = BuildMessage();
+   if ( !msg )
+   {
+      wxLogError(_("Failed to create the message to save."));
+
+      return false;
+   }
+
+   // ensure that the "Drafts" folder we're going to save the message to exists
+   String nameDrafts = READ_CONFIG(m_Profile, MP_DRAFTS_FOLDER);
+   if ( !nameDrafts.empty() )
+   {
+      if ( !MFolder_obj(nameDrafts) )
+         nameDrafts.clear();
+   }
+
+   if ( nameDrafts.empty() )
+   {
+      // try the standard folder
+      int rc = VerifyStdFolder
+               (
+                  MP_DRAFTS_FOLDER,
+                  _("Drafts"),
+                  0,
+                  _("Folder where the postponed messages are stored,"),
+                  MFolderIndex_Draft
+               );
+
+      if ( !rc )
+      {
+         wxLogError(_("Please try specifying another \"Drafts\" folder in "
+                      "the preferences dialog."));
+         return false;
+      }
+
+      // VerifyStdFolder() writes the name to profile
+      nameDrafts = READ_APPCONFIG(MP_DRAFTS_FOLDER);
+
+      if ( rc == -1 )
+      {
+         // refresh the tree to show the newly created folder
+         MEventManager::Send(
+            new MEventFolderTreeChangeData(nameDrafts,
+                                           MEventFolderTreeChangeData::Create)
+         );
+      }
+   }
+
+   if ( !msg->WriteToFolder(nameDrafts) )
+   {
+      wxLogError(_("Failed to save the message as a draft."));
+
+      return false;
+   }
+
+   // do this so that we can close unconditionally now
+   wxComposeView *self = (wxComposeView *)this;
+   self->ResetDirty(); // const_cast
+
+   MDialog_Message
+   (
+      String::Format
+      (
+         _("Your message has been saved in the folder '%s',\n"
+           "simply open it and choose \"Message|Edit in composer\" to\n"
+           "continue writing it."),
+         nameDrafts.c_str()
+      ),
+      self->GetFrame(),
+      M_MSGBOX_DRAFT_SAVED
+   );
 
    return true;

Index: wxMDialogs.cpp
===================================================================
RCS file: /cvsroot/mahogany/M/src/gui/wxMDialogs.cpp,v
retrieving revision 1.359
retrieving revision 1.360
diff -b -u -2 -r1.359 -r1.360
--- wxMDialogs.cpp      13 Mar 2002 15:50:32 -0000      1.359
+++ wxMDialogs.cpp      16 Mar 2002 23:38:48 -0000      1.360
@@ -121,4 +121,10 @@
 
 // ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
+
+#define M_TITLE_PREFIX _("Mahogany: ")
+
+// ----------------------------------------------------------------------------
 // the images names
 // ----------------------------------------------------------------------------
@@ -450,4 +456,14 @@
 }
 
+// get the msg box style for a question dialog box
+static inline long GetYesNoMsgBoxStyle(int flags)
+{
+   int style = GetMsgBoxStyle(wxYES_NO | wxICON_QUESTION);
+   if ( flags & M_DLG_NO_DEFAULT )
+      style |= wxNO_DEFAULT;
+
+   return GetMsgBoxStyle(style);
+}
+
 // needed to fix a bug/misfeature of wxWin 2.2.x: an already deleted window may
 // be used as parent for the newly created dialogs, don't let this happen
@@ -515,5 +531,5 @@
                                    const wxString& strDefault,
                                    bool passwordflag)
-   : wxDialog(parent, -1, wxString("Mahogany : ") + strCaption,
+   : wxDialog(parent, -1, wxString(M_TITLE_PREFIX) + strCaption,
               wxDefaultPosition,
               wxDefaultSize,
@@ -658,5 +674,5 @@
    CloseSplash();
    NoBusyCursor no;
-   wxMessageBox(msg, wxString("Mahogany : ") + title,
+   wxMessageBox(msg, wxString(M_TITLE_PREFIX) + title,
                 GetMsgBoxStyle(wxOK|wxICON_EXCLAMATION),
                 GetDialogParent(parent));
@@ -682,5 +698,5 @@
       + String(strerror(errno));
 
-   MDialog_ErrorMessage(msg.c_str(), parent, wxString("Mahogany : ")+title, modal);
+   MDialog_ErrorMessage(msg.c_str(), parent, wxString(M_TITLE_PREFIX)+title, modal);
 }
 
@@ -698,5 +714,5 @@
    String msg = String(message) + _("\nExiting application...");
 
-   MDialog_ErrorMessage(message,parent, wxString("Mahogany : ")+title,true);
+   MDialog_ErrorMessage(message,parent, wxString(M_TITLE_PREFIX)+title,true);
    mApplication->Exit();
 }
@@ -721,7 +737,4 @@
       return;
 
-   wxString caption = "Mahogany : ";
-   caption += title;
-
    CloseSplash();
    NoBusyCursor noBC;
@@ -731,5 +744,5 @@
       configPath,
       message,
-      caption,
+      String(M_TITLE_PREFIX) + title,
       GetMsgBoxStyle(wxOK | wxICON_INFORMATION) | (flags & M_DLG_DISABLE),
       GetDialogParent(parent)
@@ -737,4 +750,47 @@
 }
 
+void MDialog_Message(char const *message,
+                     const wxWindow *parent,
+                     const MPersMsgBox *persMsg,
+                     char const *title)
+{
+   String configPath;
+   if ( persMsg )
+      configPath = GetPersMsgBoxName(persMsg);
+
+   MDialog_Message(message, parent, title,
+                   persMsg ? configPath.c_str() : NULL);
+}
+
+MDlgResult MDialog_YesNoCancel(char const *message,
+                               const wxWindow *parent,
+                               char const *title,
+                               int flags)
+{
+   CloseSplash();
+   NoBusyCursor noBC;
+
+   switch ( wxMessageBox
+            (
+               message,
+               String("Mahogany: ") + title,
+               GetYesNoMsgBoxStyle(flags) | wxCANCEL,
+               GetDialogParent(parent)
+            ) )
+   {
+      case wxNO:
+         return MDlg_No;
+
+      case wxYES:
+         return MDlg_Yes;
+
+      default:
+         FAIL_MSG( "unexpected wxMessageBox return value" );
+         // fall through
+
+      case wxCANCEL:
+         return MDlg_Cancel;
+   }
+}
 
 /** simple Yes/No dialog
@@ -810,11 +866,4 @@
    CloseSplash();
 
-   wxString caption = "Mahogany : ";
-   caption += title;
-
-   int style = GetMsgBoxStyle(wxYES_NO | wxICON_QUESTION);
-   if ( flags & M_DLG_NO_DEFAULT )
-      style |= wxNO_DEFAULT;
-
    bool wasDisabled;
    int rc = wxPMessageBox
@@ -822,7 +871,8 @@
                path,
                message,
-               caption,
+               String(M_TITLE_PREFIX) + title,
+               GetYesNoMsgBoxStyle(flags) |
                // these bits are equal to the corresponding wx constants
-               style | (flags & (M_DLG_NOT_ON_NO | M_DLG_DISABLE)),
+                  (flags & (M_DLG_NOT_ON_NO | M_DLG_DISABLE)),
                GetDialogParent(parent),
                NULL,
@@ -959,5 +1009,5 @@
                                     GetDialogParent(parent),
                                     _("Please choose an entry:"),
-                                    wxString("Mahogany : ") +
+                                    wxString(M_TITLE_PREFIX) +
                                        _("Expansion options"),
                                     nEntryCount,

Index: wxMenuDefs.cpp
===================================================================
RCS file: /cvsroot/mahogany/M/src/gui/wxMenuDefs.cpp,v
retrieving revision 1.181
retrieving revision 1.182
diff -b -u -2 -r1.181 -r1.182
--- wxMenuDefs.cpp      13 Mar 2002 16:38:28 -0000      1.181
+++ wxMenuDefs.cpp      16 Mar 2002 23:38:48 -0000      1.182
@@ -306,7 +306,8 @@
 
    // the available accelerators for this menu:
-   // bijqwz
+   // bjqwz
 
-   { WXMENU_MSG_OPEN,      gettext_noop("&Open"),             gettext_noop("View 
selected message")    , FALSE },
+   { WXMENU_MSG_OPEN,      gettext_noop("&Open"),             gettext_noop("View 
+selected message in a separate window")    , FALSE },
+   { WXMENU_MSG_EDIT,      gettext_noop("Ed&it in composer"), gettext_noop("Edit 
+selected message in composer")    , FALSE },
    { WXMENU_MSG_PRINT,     gettext_noop("&Print\tCtrl-P"),            
gettext_noop("Print this message")       , FALSE },
    { WXMENU_MSG_PRINT_PREVIEW, gettext_noop("Print Pre&view"),gettext_noop("Preview a 
printout of this message")       , FALSE },
@@ -418,9 +419,13 @@
 
    // the available accelerators for this menu:
-   // ABDFGJMOQRUXYZ
+   // ABFGJMOQRUXYZ
    { WXMENU_COMPOSE_INSERTFILE, gettext_noop("&Insert file...\tCtrl-I"),
                                 gettext_noop("Attach a file to the message")          
  , FALSE },
-   { WXMENU_COMPOSE_LOADTEXT,gettext_noop("I&nsert text...\tCtrl-T"), 
gettext_noop("Insert text file")         , FALSE },
-   { WXMENU_COMPOSE_SEND,  gettext_noop("&Send\tShift-Ctrl-X"),             
gettext_noop("Send the message now")     , FALSE },
+   { WXMENU_COMPOSE_LOADTEXT,       gettext_noop("I&nsert text...\tCtrl-T"),
+                                    gettext_noop("Insert text file")         , FALSE 
+},
+   { WXMENU_COMPOSE_SEND,           gettext_noop("&Send\tShift-Ctrl-X"),
+                                    gettext_noop("Send the message now")     , FALSE 
+},
+   { WXMENU_COMPOSE_SAVE_AS_DRAFT,  gettext_noop("Close and save as &draft"),
+                                    gettext_noop("Close the window and save the 
+message in the drafts folder")     , FALSE },
    { WXMENU_COMPOSE_SEND_LATER, gettext_noop("Send &Later\tShift-Ctrl-L"),
                                 gettext_noop("Schedule the message to be send at a 
later time.")     , FALSE },

Index: wxMsgCmdProc.cpp
===================================================================
RCS file: /cvsroot/mahogany/M/src/gui/wxMsgCmdProc.cpp,v
retrieving revision 1.17
retrieving revision 1.18
diff -b -u -2 -r1.17 -r1.18
--- wxMsgCmdProc.cpp    15 Feb 2002 19:42:14 -0000      1.17
+++ wxMsgCmdProc.cpp    16 Mar 2002 23:38:48 -0000      1.18
@@ -42,4 +42,5 @@
 #include "TemplateDialog.h"
 #include "MessageView.h"
+#include "Composer.h"
 
 #include "MsgCmdProc.h"
@@ -149,4 +150,5 @@
 
    void OpenMessages(const UIdArray& selections);
+   void EditMessages(const UIdArray& selections);
 
    void PrintOrPreviewMessages(const UIdArray& selections, bool preview);
@@ -220,4 +222,7 @@
    UIdArray m_UIdsCopiedOk;
 
+   /// the list of tickets we want to open the compose windows for
+   ASTicketList *m_TicketsToEditList;
+
    /// MEventManager reg info
    void *m_regASyncResult;
@@ -548,5 +553,8 @@
    m_TicketList = ASTicketList::Create();
    m_TicketsToDeleteList = ASTicketList::Create();
+
+   // these are created on demand
    m_TicketsDroppedList = NULL;
+   m_TicketsToEditList = NULL;
 }
 
@@ -564,4 +572,7 @@
       m_TicketsDroppedList->DecRef();
 
+   if ( m_TicketsToEditList )
+      m_TicketsToEditList->DecRef();
+
    if ( m_asmf )
       m_asmf->DecRef();
@@ -640,4 +651,8 @@
          break;
 
+      case WXMENU_MSG_EDIT:
+         EditMessages(messages);
+         break;
+
 
       case WXMENU_MSG_SAVE_TO_FOLDER:
@@ -901,4 +916,24 @@
 
 void
+MsgCmdProcImpl::EditMessages(const UIdArray& selections)
+{
+   if ( !m_TicketsToEditList )
+      m_TicketsToEditList = ASTicketList::Create();
+
+   size_t n = selections.Count();
+   for ( size_t i = 0; i < n; i++ )
+   {
+      Ticket t = m_asmf->GetMessage(selections[i], this);
+
+      m_TicketsToEditList->Add(t);
+
+      AsyncStatusHandler *status =
+         new AsyncStatusHandler(this, _("Retrieving messages..."));
+
+      status->Monitor(t, _("Failed to retrieve messages to edit them."));
+   }
+}
+
+void
 MsgCmdProcImpl::PrintOrPreviewMessages(const UIdArray& selections, bool view)
 {
@@ -1484,4 +1519,21 @@
             }
             break;
+
+         case ASMailFolder::Op_GetMessage:
+            if ( m_TicketsToEditList->Contains(t) )
+            {
+               m_TicketsToEditList->Remove(t);
+
+               // edit the message in composer
+               Message *msg =
+                  ((ASMailFolder::ResultMessage *)result)->GetMessage();
+
+               Composer::EditMessage(m_asmf->GetProfile(), msg);
+            }
+            else
+            {
+               // we don't use them for anything else yet
+               FAIL_MSG( "unexpected GetMessage() ticket" );
+            }
 
          // nothing special to do for these cases

Index: wxOptionsDlg.cpp
===================================================================
RCS file: /cvsroot/mahogany/M/src/gui/wxOptionsDlg.cpp,v
retrieving revision 1.320
retrieving revision 1.321
diff -b -u -2 -r1.320 -r1.321
--- wxOptionsDlg.cpp    13 Mar 2002 17:29:56 -0000      1.320
+++ wxOptionsDlg.cpp    16 Mar 2002 23:38:48 -0000      1.321
@@ -305,4 +305,5 @@
    ConfigField_UseTrash,
    ConfigField_TrashName,
+   ConfigField_DraftsName,
    ConfigField_FoldersFileFormat,
    ConfigField_StatusFormatHelp,
@@ -1185,4 +1186,5 @@
    { gettext_noop("Use &Trash folder"), Field_Bool, -1},
    { gettext_noop("&Trash folder name"), Field_Folder, ConfigField_UseTrash},
+   { gettext_noop("&Drafts folder name"), Field_Folder, -1 },
    { gettext_noop("Default format for mailbox files"
                   ":Unix mbx mailbox:Unix mailbox:MMDF (SCO Unix):Tenex (Unix MM 
format)"),
@@ -1702,4 +1704,5 @@
    CONFIG_ENTRY(MP_USE_TRASH_FOLDER),
    CONFIG_ENTRY(MP_TRASH_FOLDER),
+   CONFIG_ENTRY(MP_DRAFTS_FOLDER),
    CONFIG_ENTRY(MP_FOLDER_FILE_DRIVER),
    CONFIG_NONE(),


_______________________________________________
Mahogany-cvsupdates mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/mahogany-cvsupdates

Reply via email to