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.
This commit is contained in:
parent
2c0e29552a
commit
108d0abe4c
6 changed files with 108 additions and 5 deletions
1
THANKS
1
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>
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
@ -140,6 +141,11 @@ public class ComposerWidget : Gtk.EventBox {
|
|||
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; }
|
||||
|
||||
|
|
@ -161,6 +167,11 @@ public class ComposerWidget : Gtk.EventBox {
|
|||
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; }
|
||||
|
||||
public ComposeType compose_type { get; private set; default = ComposeType.NEW_MESSAGE; }
|
||||
|
|
@ -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
|
||||
|
|
@ -737,6 +763,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
|
||||
}
|
||||
|
||||
|
|
@ -1454,6 +1486,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 =
|
||||
actions.get_action(ACTION_ITALIC).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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -140,6 +140,12 @@
|
|||
<property name="icon_name">text-html</property>
|
||||
</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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -387,6 +398,40 @@
|
|||
<property name="height">1</property>
|
||||
</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>
|
||||
|
|
|
|||
|
|
@ -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" />
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue