[Xfce4-commits] <postler:master> Implement attaching, display in a treeview and sending

Christian Dywan noreply at xfce.org
Tue Nov 30 20:24:01 CET 2010


Updating branch refs/heads/master
         to a68b101b098258ab5beea8011a95c493779fdaad (commit)
       from dc8bafee16bf4beac84a009df9dee9b6f622fd70 (commit)

commit a68b101b098258ab5beea8011a95c493779fdaad
Author: Bernd Prünster <bernd.pruenster at gmail.com>
Date:   Tue Nov 30 20:23:34 2010 +0100

    Implement attaching, display in a treeview and sending

 postler/postler-composer.vala |  131 +++++++++++++++++++++++++++++++++++-----
 1 files changed, 114 insertions(+), 17 deletions(-)

diff --git a/postler/postler-composer.vala b/postler/postler-composer.vala
index d5c26c6..54f6698 100644
--- a/postler/postler-composer.vala
+++ b/postler/postler-composer.vala
@@ -18,7 +18,8 @@ public class Postler.Composer : Gtk.Window {
     Gtk.VBox shelf;
     Gtk.Toolbar toolbar;
     Postler.Content content;
-
+    Gtk.TreeView att_view;
+    Gtk.ListStore attachments;
     Gtk.ComboBox combo_from;
     Gtk.Entry entry_to;
     Gtk.Entry entry_copy;
@@ -105,25 +106,89 @@ public class Postler.Composer : Gtk.Window {
                 }
                 var now = new Soup.Date.from_now (0);
                 string copy = entry_copy.text;
-                string header = ("From: %s\nTo: %s\n%s%s"
-                    + "MIME-Version: 1.0\nContent-Transfer-Encoding: 8bit\n"
-                    + "Content-Type: text/plain; charset=UTF-8\n"
-                    + "Subject: %s\nDate: %s\nX-Mailer: %s\n"
-                    + (info.reply != null ? "Reply-To: " + info.reply + "\n" : "")
-                    + (info.organization != null ?
-                        "Organization: " + info.organization + "\n" : "")
-                    + "\n").printf (
-                        sender,
-                        entry_to.text,
-                        copy != "" ? "CC: " : "", copy != "" ? copy + "\n" : "",
-                        entry_subject.text,
-                        now.to_string (Soup.DateFormat.RFC2822),
-                        Postler.App.get_user_agent ()
-                    );
+                string header = "";
+                Gtk.TreeIter att_iter;
+                if (!(attachments.get_iter_first (out att_iter))) {
+                    header = ("From: %s\nTo: %s\n%s%s"
+                        + "MIME-Version: 1.0\nContent-Transfer-Encoding: 8bit\n"
+                        + "Content-Type: text/plain; charset=UTF-8\n"
+                        + "Subject: %s\nDate: %s\nX-Mailer: %s\n"
+                        + (info.reply != null ? "Reply-To: " + info.reply + "\n" : "")
+                        + (info.organization != null ?
+                            "Organization: " + info.organization + "\n" : "")
+                        + "\n").printf (
+                            sender,
+                            entry_to.text,
+                            copy != "" ? "CC: " : "", copy != "" ? copy + "\n" : "",
+                            entry_subject.text,
+                            now.to_string (Soup.DateFormat.RFC2822),
+                            Postler.App.get_user_agent ()
+                        );
+                }
                 content.select_all ();
                 content.copy_clipboard ();
                 var clipboard = content.get_clipboard (Gdk.SELECTION_CLIPBOARD);
                 string body = clipboard.wait_for_text ();
+                if (attachments.get_iter_first (out att_iter)) {
+                    string boundary = GLib.Checksum.compute_for_string (
+                        GLib.ChecksumType.MD5,
+                        body + now.to_string (Soup.DateFormat.RFC2822));
+                    header = ("From: %s\nTo: %s\n%s%s"
+                        + "MIME-Version: 1.0\n"
+                        + "Content-Type: multipart/mixed; boundary=" + boundary + "\n"
+                        + "Subject: %s\nDate: %s\nX-Mailer: %s\n"
+                        + (info.reply != null ? "Reply-To: " + info.reply + "\n" : "")
+                        + (info.organization != null ?
+                            "Organization: " + info.organization + "\n" : "")
+                        + "\n").printf (
+                            sender,
+                            entry_to.text,
+                            copy != "" ? "CC: " : "", copy != "" ? copy + "\n" : "",
+                            entry_subject.text,
+                            now.to_string (Soup.DateFormat.RFC2822),
+                            Postler.App.get_user_agent ()
+                      );
+                    StringBuilder body_builder = new StringBuilder (body);
+                    body_builder.prepend ("Content-Type: text/plain; charset=UTF-8\n\n");
+                    body_builder.prepend ("--" + boundary + "\n");
+                    body_builder.append_c ('\n');
+                    string fname;
+                    attachments.get (att_iter, 0, out fname);
+                    try {
+                        body_builder.append ("--" + boundary + "\n");
+                        uchar[] data = {};
+                        FileUtils.get_data (fname, out data);
+                        bool uncertain;
+                        string mime_type = g_content_type_guess (fname, data,
+                                                                 out uncertain);
+                        var fname_parts = fname.split ("/");
+                        var filename = fname_parts[fname_parts.length-1];
+                        body_builder.append ("Content-Type: " + mime_type + "\n"
+                            + "Content-Disposition: attachment; "
+                            + "filename=\"" + filename + "\"\n"
+                            + "Content-Transfer-Encoding: base64\n\n"
+                            + GLib.Base64.encode (data));
+                        while (attachments.iter_next (ref att_iter)) {
+                            attachments.get (att_iter, 0, out fname);
+                            body_builder.append ("\n--" + boundary + "\n");
+                            FileUtils.get_data (fname, out data);
+                            mime_type = g_content_type_guess (fname, data,
+                                                              out uncertain);
+                            fname_parts = fname.split ("/");
+                            filename = fname_parts[fname_parts.length - 1];
+                            body_builder.append ("Content-Type: " + mime_type + "\n"
+                                + "Content-Disposition: attachment; "
+                                + "filename=\"" + filename + "\"\n"
+                                + "Content-Transfer-Encoding: base64\n\n"
+                                + GLib.Base64.encode (data));
+                        }
+                        body_builder.append ("\n--" + boundary + "--");
+                        body = body_builder.str;
+                    } catch (Error e) {
+                        GLib.message (_("Failed to add attachment: %s"), fname);
+                    }
+                }
+
                 try {
                     /* TODO: Put in /Queue/new/ first and move on success */
                     string filename = sent + "/cur/"
@@ -183,6 +248,31 @@ public class Postler.Composer : Gtk.Window {
         insert_text ("> " + selected.replace ("\n", "\\n> "));
     }
 
+    void action_insert_attachment (Gtk.Action action) {
+        string filename = null;
+        var filechooser = new Gtk.FileChooserDialog (_("Attach File..."),
+            null, Gtk.FileChooserAction.OPEN,
+            Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
+            Gtk.STOCK_OPEN, Gtk.ResponseType.ACCEPT);
+        filechooser.set_current_folder (Environment.get_home_dir ());
+        if (filechooser.run () == Gtk.ResponseType.ACCEPT)
+            filename = filechooser.get_filename ();
+        else
+            filename = null;
+        filechooser.destroy ();
+        if (filename == null)
+            return;
+        insert_attachment (filename);
+    }
+
+    void insert_attachment (string path_to_file) {
+        Gtk.TreeIter att_iter;
+        attachments.append (out att_iter);
+        attachments.set (att_iter,0,path_to_file);
+        att_view.show ();
+        attachments.get_iter_first (out att_iter);
+    }
+
     void action_insert_emoticon (Gtk.Action action) {
         unowned string name = action.name;
         string emoticon;
@@ -204,7 +294,7 @@ public class Postler.Composer : Gtk.Window {
         { "MessageSave", Gtk.STOCK_SAVE, N_("Save as _Draft"), "<Ctrl>s",
           N_("Save message as draft"), null },
         { "FileAttach", STOCK_MAIL_ATTACHMENT, N_("_Attach File"), "",
-          N_("Attach a file to the message"), null },
+          N_("Attach a file to the message"), action_insert_attachment },
         { "Close", Gtk.STOCK_CLOSE, null, "Escape",
           N_("Close the window"), action_close },
         { "Edit", null, N_("_Edit") },
@@ -286,6 +376,13 @@ public class Postler.Composer : Gtk.Window {
         content = new Postler.Content ();
         var scrolled = new Postler.ScrolledWindow (content);
         shelf.pack_start (scrolled, true, true, 0);
+        att_view = new Gtk.TreeView ();
+        attachments = new Gtk.ListStore (2, typeof (string), typeof (long));
+        att_view.insert_column_with_attributes (-1, "Attachments",
+            new Gtk.CellRendererText (), "text", 0);
+        att_view.set_model (attachments);
+        att_view.set_no_show_all (true);
+        shelf.pack_start (att_view, true, true, 0);
         shelf.show_all ();
 
         actions.get_action ("MessageSend").sensitive = false;



More information about the Xfce4-commits mailing list