Update of /cvsroot/mahogany/M/src/gui
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29273/src/gui

Modified Files:
        wxMIMETreeDialog.cpp 
Log Message:
implemented saving of multiple attachments/messages at once

Index: wxMIMETreeDialog.cpp
===================================================================
RCS file: /cvsroot/mahogany/M/src/gui/wxMIMETreeDialog.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -b -u -2 -r1.1 -r1.2
--- wxMIMETreeDialog.cpp        13 Aug 2004 20:25:12 -0000      1.1
+++ wxMIMETreeDialog.cpp        13 Aug 2004 22:33:03 -0000      1.2
@@ -33,25 +33,27 @@
 #include "ClickAtt.h"
 
+#include "HeaderInfo.h"
+#include "MFolder.h"
+#include "MailFolder.h"
+#include "MessageView.h"
 #include "MimePart.h"
+#include "UIdArray.h"
+
 #include "MIMETreeDialog.h"
 
 // ----------------------------------------------------------------------------
-// MIME dialog classes
+// constants
 // ----------------------------------------------------------------------------
 
-class wxMIMETreeCtrl : public wxTreeCtrl
+// control ids
+enum
 {
-public:
-   wxMIMETreeCtrl(wxWindow *parent) : wxTreeCtrl(parent, -1)
-   {
-      InitImageLists();
-   }
-
-private:
-   void InitImageLists();
-
-   DECLARE_NO_COPY_CLASS(wxMIMETreeCtrl)
+   wxMIMETree_BtnSave = 100
 };
 
+// ----------------------------------------------------------------------------
+// tree client data containing the associated MIME part
+// ----------------------------------------------------------------------------
+
 class wxMIMETreeData : public wxTreeItemData
 {
@@ -65,5 +67,28 @@
 };
 
-class wxMIMETreeDialog : public wxManuallyLaidOutDialog
+// ----------------------------------------------------------------------------
+// tree containing MIME parts
+// ----------------------------------------------------------------------------
+
+class wxMIMETreeCtrl : public wxTreeCtrl
+{
+public:
+   wxMIMETreeCtrl(wxWindow *parent);
+
+   // return the MIME part associated with the given item
+   const MimePart *GetMIMEData(const wxTreeItemId& id) const
+   {
+      return (static_cast<wxMIMETreeData *>(GetItemData(id)))->GetMimePart();
+   }
+
+private:
+   DECLARE_NO_COPY_CLASS(wxMIMETreeCtrl)
+};
+
+// ----------------------------------------------------------------------------
+// MIME tree dialog itself
+// ----------------------------------------------------------------------------
+
+class wxMIMETreeDialog : public wxPDialog
 {
 public:
@@ -75,4 +100,9 @@
    // event handlers
    void OnTreeItemRightClick(wxTreeEvent& event);
+   void OnSave(wxCommandEvent& event);
+
+   // save selected attachments (to files) or messages (to folder)
+   void SaveAttachments(size_t count, const MimePart **parts);
+   void SaveMessages(size_t count, const MimePart **parts);
 
 private:
@@ -84,16 +114,18 @@
 
    // GUI controls
-   wxStaticBox *m_box;
-   wxTreeCtrl *m_treectrl;
+   wxMIMETreeCtrl *m_treectrl;
 
    // the parent message view
    MessageView *m_msgView;
 
+
    DECLARE_EVENT_TABLE()
    DECLARE_NO_COPY_CLASS(wxMIMETreeDialog)
 };
 
-BEGIN_EVENT_TABLE(wxMIMETreeDialog, wxManuallyLaidOutDialog)
+BEGIN_EVENT_TABLE(wxMIMETreeDialog, wxPDialog)
    EVT_TREE_ITEM_RIGHT_CLICK(-1, wxMIMETreeDialog::OnTreeItemRightClick)
+
+   EVT_BUTTON(wxMIMETree_BtnSave, wxMIMETreeDialog::OnSave)
 END_EVENT_TABLE()
 
@@ -107,5 +139,13 @@
 // ----------------------------------------------------------------------------
 
-void wxMIMETreeCtrl::InitImageLists()
+wxMIMETreeCtrl::wxMIMETreeCtrl(wxWindow *parent)
+              : wxTreeCtrl
+                (
+                  parent,
+                  -1,
+                  wxDefaultPosition,
+                  wxDefaultSize,
+                  wxTR_DEFAULT_STYLE | wxTR_MULTIPLE
+                )
 {
    wxIconManager *iconManager = mApplication->GetIconManager();
@@ -134,36 +174,55 @@
                                    wxWindow *parent,
                                    MessageView *msgView)
-                : wxManuallyLaidOutDialog(parent,
-                                          _("MIME structure of the message"),
-                                          _T("MimeTreeDialog"))
+                : wxPDialog
+                  (
+                     _T("MimeTreeDialog"),
+                     parent,
+                     String(M_TITLE_PREFIX) + _("MIME structure of the message"),
+                     wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER
+                  )
 {
    // init members
    m_msgView = msgView;
    m_countParts = 0;
-   m_box = NULL;
-   m_treectrl = NULL;
+   m_treectrl = new wxMIMETreeCtrl(this);
 
-   // create controls
-   wxLayoutConstraints *c;
 
-   // label will be set later below
-   m_box = CreateStdButtonsAndBox(_T(""), StdBtn_NoCancel);
+   // create and lay out the controls
+   // -------------------------------
 
-   m_treectrl = new wxMIMETreeCtrl(this);
-   c = new wxLayoutConstraints;
-   c->top.SameAs(m_box, wxTop, 4*LAYOUT_Y_MARGIN);
-   c->left.SameAs(m_box, wxLeft, 2*LAYOUT_X_MARGIN);
-   c->right.SameAs(m_box, wxRight, 2*LAYOUT_X_MARGIN);
-   c->bottom.SameAs(m_box, wxBottom, 2*LAYOUT_Y_MARGIN);
-   m_treectrl->SetConstraints(c);
+   // the box containing the tree control
+   wxStaticBox *box = new wxStaticBox(this, wxID_ANY, _T(""));
+   wxStaticBoxSizer *sizerBox = new wxStaticBoxSizer(box, wxHORIZONTAL);
+   sizerBox->Add(m_treectrl, 1, wxEXPAND | wxALL, LAYOUT_MARGIN);
+
+   // the buttons
+   wxSizer *sizerButtons = new wxBoxSizer(wxHORIZONTAL);
+   sizerButtons->AddStretchSpacer();
+   if ( m_msgView )
+   {
+      sizerButtons->Add(new wxButton(this, wxMIMETree_BtnSave, _("&Save...")),
+                           0, wxALL, LAYOUT_MARGIN);
+      sizerButtons->AddSpacer(2*LAYOUT_X_MARGIN);
+   }
+   sizerButtons->Add(new wxButton(this, wxID_CANCEL, _("&Close")),
+                        0, wxALL, LAYOUT_MARGIN);
 
-   // initialize them
+   // put everything together
+   wxSizer *sizerTop = new wxBoxSizer(wxVERTICAL);
+   sizerTop->Add(sizerBox, 1, wxEXPAND | wxALL, LAYOUT_MARGIN);
+   sizerTop->Add(sizerButtons, 0, wxEXPAND | (wxALL & ~wxTOP), LAYOUT_MARGIN);
+
+
+   // initialize the tree
    AddToTree(wxTreeItemId(), partRoot);
 
    m_treectrl->Expand(m_treectrl->GetRootItem());
+   m_treectrl->SetMinSize(wxSize(200, 200));
+
+   box->SetLabel(wxString::Format(_("%u MIME parts"), m_countParts));
 
-   m_box->SetLabel(wxString::Format(_("%u MIME parts"), m_countParts));
 
-   SetDefaultSize(4*wBtn, 10*hBtn);
+   SetSizer(sizerTop);
+   sizerTop->SetSizeHints(this);
 }
 
@@ -199,12 +258,182 @@
    if ( m_msgView )
    {
-      wxMIMETreeData *data =
-         (wxMIMETreeData *)m_treectrl->GetItemData(event.GetItem());
-
-      ClickableAttachment att(m_msgView, data->GetMimePart());
+      ClickableAttachment att(m_msgView,
+                              m_treectrl->GetMIMEData(event.GetItem()));
       att.ShowPopupMenu(m_treectrl, event.GetPoint());
    }
 }
 
+void wxMIMETreeDialog::OnSave(wxCommandEvent& WXUNUSED(event))
+{
+   CHECK_RET( m_msgView, _T("button shouldn't exist if no msg view") );
+
+   // get the selected items
+   wxArrayTreeItemIds selections;
+   const size_t count = m_treectrl->GetSelections(selections);
+   if ( !count )
+      return;
+
+   // get all MIME parts to save and also check if all of them are messages
+   bool allMsgs = true;
+   size_t nParts = 0;
+   scoped_array<const MimePart *> parts(new const MimePart *[count]);
+   for ( size_t n = 0; n < count; n++ )
+   {
+      const MimePart *mimepart = m_treectrl->GetMIMEData(selections[n]);
+      if ( !mimepart )
+      {
+         wxLogWarning(_("Failed to save MIME part \"%s\", skipping."),
+                      m_treectrl->GetItemText(selections[n]).c_str());
+         continue;
+      }
+
+      parts[nParts++] = mimepart;
+
+      allMsgs &= mimepart->GetType().GetPrimary() == MimeType::MESSAGE;
+   }
+
+   // if they're, then we're going to copy them to another folder instead of
+   // saving them to file(s)
+   if ( allMsgs )
+   {
+      SaveMessages(nParts, parts.get());
+   }
+   else // save attachments to file(s)
+   {
+      SaveAttachments(nParts, parts.get());
+   }
+}
+
+void wxMIMETreeDialog::SaveMessages(size_t count, const MimePart **parts)
+{
+   // get the folder to save messages to
+   MFolder_obj folderDst(MDialog_FolderChoose(this));
+   if ( !folderDst )
+   {
+      // cancelled by user
+      return;
+   }
+
+   // copy them to a temp file
+   wxString filename;
+   if ( !wxGetTempFileName(_T("Mtemp"), filename) )
+   {
+      wxLogError(_("Failed to save messages to temporary file."));
+
+      return;
+   }
+
+   for ( size_t n = 0; n < count; n++ )
+   {
+      const MimePart * const mimepart = parts[n];
+
+      unsigned long len;
+      const void *content = mimepart->GetContent(&len);
+      if ( !content || !MailFolder::SaveMessageAsMBOX(filename, content, len) )
+      {
+         wxLogWarning(_("Failed to save attachment %u"), (unsigned)n);
+      }
+   }
+
+   // now copy them from there to the folder
+   MFolder_obj folderSrc(MFolder::CreateTempFile(_T(""), filename));
+   if ( folderSrc )
+   {
+      MailFolder_obj mf(MailFolder::OpenFolder(folderSrc));
+      if ( mf )
+      {
+         // FIXME:horrible inefficient... we really should have some
+         //       MailFolder::SaveAllMessages() as we don't need UIDs here at
+         //       all, just msgnos
+         HeaderInfoList_obj hil(mf->GetHeaders());
+         if ( hil )
+         {
+            const size_t count = hil->Count();
+            UIdArray all;
+            all.Alloc(count);
+            for ( size_t n = 0; n < count; n++ )
+            {
+               HeaderInfo *hi = hil->GetItemByIndex(n);
+               if ( hi )
+                  all.Add(hi->GetUId());
+            }
+
+            if ( mf->SaveMessages(&all, folderDst) )
+            {
+               // everything is ok
+               return;
+            }
+         }
+      }
+   }
+
+   // if we got here, something failed above
+   wxLogError(_("Copying messages failed."));
+}
+
+void wxMIMETreeDialog::SaveAttachments(size_t count, const MimePart **parts)
+{
+   String dir = MDialog_DirRequester
+                (
+                  _("Choose directory to save attachments to:"),
+                  _T(""),
+                  this,
+                  _T("MimeSave")
+                );
+   if ( dir.empty() )
+   {
+      // cancelled by user
+      return;
+   }
+
+   for ( size_t n = 0; n < count; n++ )
+   {
+      const MimePart * const mimepart = parts[n];
+
+      String name = mimepart->GetFilename();
+      bool needToAsk = name.empty();
+
+      wxFileName fn(dir, name);
+      if ( !needToAsk )
+      {
+         // never ever overwrite files silently here, this is a security
+         // risk
+         needToAsk = fn.FileExists();
+      }
+
+      String filename;
+      if ( needToAsk )
+      {
+         filename = wxPFileSelector
+                    (
+                        _T("MimeSave"),
+                        _("Attachment has a name of existinf file,\n"
+                          "please choose another one:"),
+                        dir,  // default path
+                        NULL, // default name
+                        NULL, // default ext
+                        NULL, // default filter
+                        wxSAVE |
+                        wxOVERWRITE_PROMPT,
+                        this
+                    );
+
+         if ( filename.empty() )
+         {
+            // cancelled
+            continue;
+         }
+      }
+      else
+      {
+         filename = fn.GetFullPath();
+      }
+
+      if ( !m_msgView->MimeSave(mimepart, filename) )
+      {
+         wxLogWarning(_("Failed to save attachment %u"), (unsigned)n);
+      }
+   }
+}
 
 // ----------------------------------------------------------------------------



-------------------------------------------------------
SF.Net email is sponsored by Shop4tech.com-Lowest price on Blank Media
100pk Sonic DVD-R 4x for only $29 -100pk Sonic DVD+R for only $33
Save 50% off Retail on Ink & Toner - Free Shipping and Free Gift.
http://www.shop4tech.com/z/Inkjet_Cartridges/9_108_r285
_______________________________________________
Mahogany-cvsupdates mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/mahogany-cvsupdates

Reply via email to