[geary] Specify "Reply-To:" in composer fields: Bug #714588



commit 108d0abe4cd3cdb04377baa3603a60b2be7d2f5c
Author: mar-v-in <github rvin mooo com>
Date:   Tue Nov 4 14:44:05 2014 -0800

    Specify "Reply-To:" in composer fields: Bug #714588
    
    This also closes bug #713808, as lesser-used fields (Reply-To, Bcc)
    are hidden unless the user expands the composer to show them.  Right
    now that is an option in the composer's toolbar menu; that may change
    in the future if we can find the right place to put the widgetry.

 THANKS                                   |    1 +
 src/client/composer/composer-widget.vala |   53 ++++++++++++++++++++++++++++-
 src/engine/api/geary-composed-email.vala |    1 +
 src/engine/rfc822/rfc822-message.vala    |    6 +++
 ui/composer.glade                        |   51 +++++++++++++++++++++++++++--
 ui/composer_accelerators.ui              |    1 +
 6 files changed, 108 insertions(+), 5 deletions(-)
---
diff --git a/THANKS b/THANKS
index 4f5279a..9b974e9 100644
--- a/THANKS
+++ b/THANKS
@@ -25,6 +25,7 @@ Avi Levy <avi w levy gmail com>
 Simon Lipp <bugs-gnome simon lipp name>
 Brendan Long <self brendanlong com>
 Angelo Marchesin <marchesin angelo gmail com>
+mar-v-in <github rvin mooo com>
 Kai Mast <mail kai-mast de>
 William Jon McCann <william jon mccann gmail com>
 Thomas Moschny <thomas moschny gmx de>
diff --git a/src/client/composer/composer-widget.vala b/src/client/composer/composer-widget.vala
index e0b966f..de0e5fe 100644
--- a/src/client/composer/composer-widget.vala
+++ b/src/client/composer/composer-widget.vala
@@ -48,6 +48,7 @@ public class ComposerWidget : Gtk.EventBox {
     public const string ACTION_COLOR = "color";
     public const string ACTION_INSERT_LINK = "insertlink";
     public const string ACTION_COMPOSE_AS_HTML = "compose as html";
+    public const string ACTION_SHOW_EXTENDED = "show extended";
     public const string ACTION_CLOSE = "close";
     public const string ACTION_DETACH = "detach";
     public const string ACTION_SEND = "send";
@@ -139,6 +140,11 @@ public class ComposerWidget : Gtk.EventBox {
         get { return bcc_entry.get_text(); }
         set { bcc_entry.set_text(value); }
     }
+
+    public string reply_to {
+        get { return reply_to_entry.get_text(); }
+        set { reply_to_entry.set_text(value); }
+    }
     
     public string in_reply_to { get; set; }
     public string references { get; set; }
@@ -160,6 +166,11 @@ public class ComposerWidget : Gtk.EventBox {
         get { return ((Gtk.ToggleAction) actions.get_action(ACTION_COMPOSE_AS_HTML)).active; }
         set { ((Gtk.ToggleAction) actions.get_action(ACTION_COMPOSE_AS_HTML)).active = value; }
     }
+
+    public bool show_extended {
+        get { return ((Gtk.ToggleAction) actions.get_action(ACTION_SHOW_EXTENDED)).active; }
+        set { ((Gtk.ToggleAction) actions.get_action(ACTION_SHOW_EXTENDED)).active = value; }
+    }
     
     public ComposerState state { get; set; }
     
@@ -169,7 +180,7 @@ public class ComposerWidget : Gtk.EventBox {
     
     public bool blank {
         get {
-            return to_entry.empty && cc_entry.empty && bcc_entry.empty &&
+            return to_entry.empty && cc_entry.empty && bcc_entry.empty && reply_to_entry.empty &&
                 subject_entry.buffer.length == 0 && !editor.can_undo() && attachment_files.size == 0;
         }
     }
@@ -190,7 +201,10 @@ public class ComposerWidget : Gtk.EventBox {
     private Gtk.ComboBoxText from_multiple = new Gtk.ComboBoxText();
     private EmailEntry to_entry;
     private EmailEntry cc_entry;
+    private Gtk.Label bcc_label;
     private EmailEntry bcc_entry;
+    private Gtk.Label reply_to_label;
+    private EmailEntry reply_to_entry;
     public Gtk.Entry subject_entry;
     private Gtk.Label message_overlay_label;
     private Gtk.Box attachments_box;
@@ -209,6 +223,7 @@ public class ComposerWidget : Gtk.EventBox {
     private Gtk.MenuItem color_item;
     private Gtk.MenuItem html_item;
     private Gtk.MenuItem html_item2;
+    private Gtk.MenuItem extended_item;
     
     private Gtk.ActionGroup actions;
     private string? hover_url = null;
@@ -288,13 +303,19 @@ public class ComposerWidget : Gtk.EventBox {
         (builder.get_object("cc") as Gtk.EventBox).add(cc_entry);
         bcc_entry = new EmailEntry(this);
         (builder.get_object("bcc") as Gtk.EventBox).add(bcc_entry);
+        reply_to_entry = new EmailEntry(this);
+        (builder.get_object("reply to") as Gtk.EventBox).add(reply_to_entry);
         
         Gtk.Label to_label = (Gtk.Label) builder.get_object("to label");
         Gtk.Label cc_label = (Gtk.Label) builder.get_object("cc label");
-        Gtk.Label bcc_label = (Gtk.Label) builder.get_object("bcc label");
+        bcc_label = (Gtk.Label) builder.get_object("bcc label");
+        reply_to_label = (Gtk.Label) builder.get_object("reply to label");
         to_label.set_mnemonic_widget(to_entry);
         cc_label.set_mnemonic_widget(cc_entry);
         bcc_label.set_mnemonic_widget(bcc_entry);
+        reply_to_label.set_mnemonic_widget(reply_to_entry);
+
+        to_entry.margin_top = cc_entry.margin_top = bcc_entry.margin_top = reply_to_entry.margin_top = 6;
         
         // TODO: It would be nicer to set the completions inside the EmailEntry constructor. But in
         // testing, this can cause non-deterministic segfaults. Investigate why, and fix if possible.
@@ -332,6 +353,7 @@ public class ComposerWidget : Gtk.EventBox {
         to_entry.changed.connect(validate_send_button);
         cc_entry.changed.connect(validate_send_button);
         bcc_entry.changed.connect(validate_send_button);
+        reply_to_entry.changed.connect(validate_send_button);
         
         if (get_direction () == Gtk.TextDirection.RTL) {
             actions.get_action(ACTION_INDENT).icon_name = "format-indent-more-rtl-symbolic";
@@ -362,6 +384,7 @@ public class ComposerWidget : Gtk.EventBox {
         
         actions.get_action(ACTION_REMOVE_FORMAT).activate.connect(on_remove_format);
         actions.get_action(ACTION_COMPOSE_AS_HTML).activate.connect(on_compose_as_html);
+        actions.get_action(ACTION_SHOW_EXTENDED).activate.connect(on_show_extended);
         
         actions.get_action(ACTION_INDENT).activate.connect(on_indent);
         actions.get_action(ACTION_OUTDENT).activate.connect(on_action);
@@ -506,6 +529,8 @@ public class ComposerWidget : Gtk.EventBox {
         color_item.related_action = ui.get_action("ui/color");
         html_item = new Gtk.CheckMenuItem();
         html_item.related_action = ui.get_action("ui/htmlcompose");
+        extended_item = new Gtk.CheckMenuItem();
+        extended_item.related_action = ui.get_action("ui/extended");
         
         html_item2 = new Gtk.CheckMenuItem();
         html_item2.related_action = ui.get_action("ui/htmlcompose");
@@ -635,6 +660,7 @@ public class ComposerWidget : Gtk.EventBox {
 
         bind_event(editor,"a", "click", (Callback) on_link_clicked, this);
         update_actions();
+        on_show_extended();
     }
     
     // Glade only allows one accelerator per-action. This method adds extra accelerators not defined
@@ -736,6 +762,9 @@ public class ComposerWidget : Gtk.EventBox {
         
         if (bcc_entry.addresses != null)
             email.bcc = bcc_entry.addresses;
+
+        if (reply_to_entry.addresses != null)
+            email.reply_to = reply_to_entry.addresses;
         
         if (!Geary.String.is_empty(in_reply_to))
             email.in_reply_to = in_reply_to;
@@ -1306,6 +1335,9 @@ public class ComposerWidget : Gtk.EventBox {
             if (bcc_entry.addresses != null)
                 foreach(Geary.RFC822.MailboxAddress addr in bcc_entry.addresses)
                     tooltip.append(_("Bcc: ") + addr.get_full_address() + "\n");
+            if (reply_to_entry.addresses != null)
+                foreach(Geary.RFC822.MailboxAddress addr in reply_to_entry.addresses)
+                    tooltip.append(_("Reply-To: ") + addr.get_full_address() + "\n");
             header.set_recipients(label, tooltip.str.slice(0, -1));  // Remove trailing \n
         }
         
@@ -1453,6 +1485,16 @@ public class ComposerWidget : Gtk.EventBox {
         }
         GearyApplication.instance.config.compose_as_html = compose_as_html;
     }
+
+    private void on_show_extended() {
+        if (!show_extended) {
+            bcc_label.visible = bcc_entry.visible = reply_to_label.visible = reply_to_entry.visible = false;
+        } else {
+            if (state == ComposerState.INLINE_COMPACT)
+                state = ComposerState.INLINE;
+            bcc_label.visible = bcc_entry.visible = reply_to_label.visible = reply_to_entry.visible = true;
+        }
+    }
     
     private void toggle_toolbar_buttons(bool show) {
         actions.get_action(ACTION_BOLD).visible =
@@ -1467,6 +1509,9 @@ public class ComposerWidget : Gtk.EventBox {
         GtkUtil.clear_menu(menu);
         
         menu.append(html_item2);
+
+        menu.append(new Gtk.SeparatorMenuItem());
+        menu.append(extended_item);
         menu.show_all();
     }
     
@@ -1487,6 +1532,9 @@ public class ComposerWidget : Gtk.EventBox {
         menu.append(new Gtk.SeparatorMenuItem());
         
         menu.append(html_item);
+
+        menu.append(new Gtk.SeparatorMenuItem());
+        menu.append(extended_item);
         menu.show_all(); // Call this or only menu items associated with actions will be displayed.
     }
     
@@ -2048,6 +2096,7 @@ public class ComposerWidget : Gtk.EventBox {
         to_entry.completion = new ContactEntryCompletion(contact_list_store);
         cc_entry.completion = new ContactEntryCompletion(contact_list_store);
         bcc_entry.completion = new ContactEntryCompletion(contact_list_store);
+        reply_to_entry.completion = new ContactEntryCompletion(contact_list_store);
     }
     
 }
diff --git a/src/engine/api/geary-composed-email.vala b/src/engine/api/geary-composed-email.vala
index 35c1e82..a9f9403 100644
--- a/src/engine/api/geary-composed-email.vala
+++ b/src/engine/api/geary-composed-email.vala
@@ -21,6 +21,7 @@ public class Geary.ComposedEmail : BaseObject {
     public RFC822.MailboxAddresses? to { get; set; default = null; }
     public RFC822.MailboxAddresses? cc { get; set; default = null; }
     public RFC822.MailboxAddresses? bcc { get; set; default = null; }
+    public RFC822.MailboxAddresses? reply_to { get; set; default = null; }
     public string? in_reply_to { get; set; default = null; }
     public Geary.Email? reply_to_email { get; set; default = null; }
     public string? references { get; set; default = null; }
diff --git a/src/engine/rfc822/rfc822-message.vala b/src/engine/rfc822/rfc822-message.vala
index 1d5daec..4402ffd 100644
--- a/src/engine/rfc822/rfc822-message.vala
+++ b/src/engine/rfc822/rfc822-message.vala
@@ -25,6 +25,7 @@ public class Geary.RFC822.Message : BaseObject {
     public RFC822.MailboxAddresses? to { get; private set; default = null; }
     public RFC822.MailboxAddresses? cc { get; private set; default = null; }
     public RFC822.MailboxAddresses? bcc { get; private set; default = null; }
+    public RFC822.MailboxAddresses? reply_to { get; private set; default = null; }
     public RFC822.MessageIDList? in_reply_to { get; private set; default = null; }
     public RFC822.MessageIDList? references { get; private set; default = null; }
     public RFC822.Subject? subject { get; private set; default = null; }
@@ -119,6 +120,11 @@ public class Geary.RFC822.Message : BaseObject {
                 message.add_recipient(GMime.RecipientType.BCC, mailbox.name, mailbox.address);
         }
 
+        if (email.reply_to != null) {
+            reply_to = email.reply_to;
+            message.set_reply_to(email.reply_to.to_rfc822_string());
+        }
+
         if (email.in_reply_to != null) {
             in_reply_to = new Geary.RFC822.MessageIDList.from_rfc822_string(email.in_reply_to);
             message.set_header(HEADER_IN_REPLY_TO, email.in_reply_to);
diff --git a/ui/composer.glade b/ui/composer.glade
index 3874eda..2119fca 100644
--- a/ui/composer.glade
+++ b/ui/composer.glade
@@ -141,6 +141,12 @@
       </object>
     </child>
     <child>
+      <object class="GtkToggleAction" id="show extended">
+        <property name="label" translatable="yes">Show Extended Fields</property>
+        <property name="icon_name">show-more</property>
+      </object>
+    </child>
+    <child>
       <object class="GtkAction" id="close">
         <property name="icon_name">window-close-symbolic</property>
       </object>
@@ -251,7 +257,7 @@
                 <property name="margin_left">6</property>
                 <property name="margin_right">6</property>
                 <property name="margin_top">6</property>
-                <property name="row_spacing">6</property>
+                <property name="row_spacing">0</property>
                 <property name="column_spacing">6</property>
                 <child>
                   <object class="GtkLabel" id="to label">
@@ -262,6 +268,7 @@
                     <property name="use_underline">True</property>
                     <property name="justify">right</property>
                     <property name="mnemonic_widget">to</property>
+                    <property name="margin_top">6</property>
                     <style>
                       <class name="dim-label"/>
                     </style>
@@ -282,6 +289,7 @@
                     <property name="use_underline">True</property>
                     <property name="justify">right</property>
                     <property name="mnemonic_widget">to</property>
+                    <property name="margin_top">6</property>
                     <style>
                       <class name="dim-label"/>
                     </style>
@@ -326,10 +334,11 @@
                     <property name="hexpand">True</property>
                     <property name="invisible_char">•</property>
                     <property name="invisible_char_set">True</property>
+                    <property name="margin_top">6</property>
                   </object>
                   <packing>
                     <property name="left_attach">1</property>
-                    <property name="top_attach">4</property>
+                    <property name="top_attach">5</property>
                     <property name="width">1</property>
                     <property name="height">1</property>
                   </packing>
@@ -343,13 +352,14 @@
                     <property name="use_underline">True</property>
                     <property name="justify">right</property>
                     <property name="mnemonic_widget">subject</property>
+                    <property name="margin_top">6</property>
                     <style>
                       <class name="dim-label"/>
                     </style>
                   </object>
                   <packing>
                     <property name="left_attach">0</property>
-                    <property name="top_attach">4</property>
+                    <property name="top_attach">5</property>
                     <property name="width">1</property>
                     <property name="height">1</property>
                   </packing>
@@ -363,6 +373,7 @@
                     <property name="use_underline">True</property>
                     <property name="justify">right</property>
                     <property name="mnemonic_widget">to</property>
+                    <property name="margin_top">6</property>
                     <style>
                       <class name="dim-label"/>
                     </style>
@@ -388,6 +399,40 @@
                   </packing>
                 </child>
                 <child>
+                  <object class="GtkLabel" id="reply to label">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="xalign">1</property>
+                    <property name="label" translatable="yes">_Reply-To</property>
+                    <property name="use_underline">True</property>
+                    <property name="justify">right</property>
+                    <property name="mnemonic_widget">to</property>
+                    <property name="margin_top">6</property>
+                    <style>
+                      <class name="dim-label"/>
+                    </style>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">4</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkEventBox" id="reply to">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="hexpand">True</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">4</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
                   <object class="GtkLabel" id="from label">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
diff --git a/ui/composer_accelerators.ui b/ui/composer_accelerators.ui
index 8620587..fa2acfe 100644
--- a/ui/composer_accelerators.ui
+++ b/ui/composer_accelerators.ui
@@ -15,6 +15,7 @@
     
     <accelerator action="removeformat" />
     <accelerator action="compose as html" name="htmlcompose" />
+    <accelerator action="show extended" name="extended" />
     
     <accelerator action="indent" />
     <accelerator action="outdent" />


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]