diff --git a/src/client/composer/composer-window.vala b/src/client/composer/composer-window.vala
index 32b8a678..36a8d47d 100644
--- a/src/client/composer/composer-window.vala
+++ b/src/client/composer/composer-window.vala
@@ -9,6 +9,7 @@ public class ComposerWindow : Gtk.Window {
public enum ComposeType {
NEW_MESSAGE,
REPLY,
+ REPLY_ALL,
FORWARD
}
@@ -171,10 +172,11 @@ public class ComposerWindow : Gtk.Window {
private ContactEntryCompletion[] contact_entry_completions;
public ComposerWindow(Geary.Account account, ComposeType compose_type,
- Geary.ContactStore? contact_store, Geary.ComposedEmail? prefill = null) {
+ Geary.Email? referred = null) {
this.account = account;
this.compose_type = compose_type;
+ Geary.ContactStore? contact_store = account.get_contact_store();
contact_entry_completions = {
new ContactEntryCompletion(contact_store),
new ContactEntryCompletion(contact_store),
@@ -283,30 +285,57 @@ public class ComposerWindow : Gtk.Window {
add_accel_group(ui.get_accel_group());
GearyApplication.instance.load_ui_file_for_manager(ui, "composer_accelerators.ui");
- if (prefill != null) {
- if (prefill.from != null)
- from = prefill.from.to_rfc822_string();
- if (prefill.to != null)
- to = prefill.to.to_rfc822_string();
- if (prefill.cc != null)
- cc = prefill.cc.to_rfc822_string();
- if (prefill.bcc != null)
- bcc = prefill.bcc.to_rfc822_string();
- if (prefill.in_reply_to != null)
- in_reply_to = prefill.in_reply_to.value;
- if (prefill.references != null)
- references = prefill.references.to_rfc822_string();
- if (prefill.subject != null)
- subject = prefill.subject.value;
- if (prefill.body_html != null)
- body_html = prefill.body_html.buffer.to_string();
- if (body_html == null && prefill.body_text != null)
- body_html = "
" + prefill.body_text.buffer.to_string() + "
";
- }
-
+ from = account.information.get_from().to_rfc822_string();
update_from_field();
from_multiple.changed.connect(on_from_changed);
+ if (referred != null) {
+ switch (compose_type) {
+ case ComposeType.NEW_MESSAGE:
+ if (referred.to != null)
+ to = referred.to.to_rfc822_string();
+ if (referred.cc != null)
+ cc = referred.cc.to_rfc822_string();
+ if (referred.bcc != null)
+ bcc = referred.bcc.to_rfc822_string();
+ if (referred.in_reply_to != null)
+ in_reply_to = referred.in_reply_to.value;
+ if (referred.references != null)
+ references = referred.references.to_rfc822_string();
+ if (referred.subject != null)
+ subject = referred.subject.value;
+ try {
+ body_html = referred.get_message().get_body(true);
+ } catch (Error error) {
+ debug("Error getting messae body: %s", error.message);
+ }
+ break;
+
+ case ComposeType.REPLY:
+ case ComposeType.REPLY_ALL:
+ string? sender_address = account.information.get_mailbox_address().address;
+ to = Geary.RFC822.Utils.create_to_addresses_for_reply(referred, sender_address);
+ if (compose_type == ComposeType.REPLY_ALL)
+ cc = Geary.RFC822.Utils.create_cc_addresses_for_reply_all(referred, sender_address);
+ subject = Geary.RFC822.Utils.create_subject_for_reply(referred);
+ in_reply_to = referred.message_id.value;
+ references = Geary.RFC822.Utils.reply_references(referred);
+ body_html = "\n\n" + Geary.RFC822.Utils.quote_email_for_reply(referred, true);
+ break;
+
+ case ComposeType.FORWARD:
+ subject = Geary.RFC822.Utils.create_subject_for_forward(referred);
+ body_html = "\n\n" + Geary.RFC822.Utils.quote_email_for_forward(referred, true);
+ break;
+ }
+
+ foreach(Geary.Attachment attachment in referred.attachments) {
+ File? attachment_file = File.new_for_path(attachment.filepath);
+ if (attachment_file != null)
+ add_attachment(attachment_file);
+ }
+ }
+
editor = new WebKit.WebView();
edit_fixer = new WebViewEditFixer(editor);
@@ -387,11 +416,54 @@ public class ComposerWindow : Gtk.Window {
chain.append(attachments_box);
chain.append(button_area);
box.set_focus_chain(chain);
-
- if(prefill != null) {
- foreach(File attachment_file in prefill.attachment_files) {
- add_attachment(attachment_file);
+ }
+
+ public ComposerWindow.from_mailto(Geary.Account account, string mailto) {
+ this(account, ComposeType.NEW_MESSAGE);
+
+ Gee.HashMultiMap headers = new Gee.HashMultiMap();
+ if (mailto.length > Geary.ComposedEmail.MAILTO_SCHEME.length) {
+ // Parse the mailto link.
+ string[] parts = mailto.substring(Geary.ComposedEmail.MAILTO_SCHEME.length).split("?", 2);
+ string email = Uri.unescape_string(parts[0]);
+ string[] params = parts.length == 2 ? parts[1].split("&") : new string[0];
+ foreach (string param in params) {
+ string[] param_parts = param.split("=", 2);
+ if (param_parts.length == 2) {
+ headers.set(Uri.unescape_string(param_parts[0]).down(),
+ Uri.unescape_string(param_parts[1]));
+ }
}
+
+ // Assemble the headers.
+ if (headers.contains("from"))
+ // Should this really be allowed?
+ from = Geary.Collection.get_first(headers.get("from"));
+
+ if (email.length > 0 && headers.contains("to"))
+ to = "%s,%s".printf(email, Geary.Collection.get_first(headers.get("to")));
+ else if (email.length > 0)
+ to = email;
+ else if (headers.contains("to"))
+ to = Geary.Collection.get_first(headers.get("to"));
+
+ if (headers.contains("cc"))
+ cc = Geary.Collection.get_first(headers.get("cc"));
+
+ if (headers.contains("bcc"))
+ bcc = Geary.Collection.get_first(headers.get("bcc"));
+
+ if (headers.contains("subject"))
+ subject = Geary.Collection.get_first(headers.get("subject"));
+
+ if (headers.contains("body"))
+ body_html = Geary.HTML.preserve_whitespace(Geary.HTML.escape_markup(
+ Geary.Collection.get_first(headers.get("body"))));
+
+ foreach (string attachment in headers.get("attach"))
+ add_attachment(File.new_for_uri(attachment));
+ foreach (string attachment in headers.get("attachment"))
+ add_attachment(File.new_for_uri(attachment));
}
}
@@ -522,19 +594,19 @@ public class ComposerWindow : Gtk.Window {
email.bcc = bcc_entry.addresses;
if (!Geary.String.is_empty(in_reply_to))
- email.in_reply_to = new Geary.RFC822.MessageID(in_reply_to);
+ email.in_reply_to = in_reply_to;
if (!Geary.String.is_empty(references))
- email.references = new Geary.RFC822.MessageIDList.from_rfc822_string(references);
+ email.references = references;
if (!Geary.String.is_empty(subject))
- email.subject = new Geary.RFC822.Subject(subject);
+ email.subject = subject;
email.attachment_files.add_all(attachment_files);
if (compose_as_html)
- email.body_html = new Geary.RFC822.Text(new Geary.Memory.StringBuffer(get_html()));
- email.body_text = new Geary.RFC822.Text(new Geary.Memory.StringBuffer(get_text()));
+ email.body_html = get_html();
+ email.body_text = get_text();
// User-Agent
email.mailer = GearyApplication.PRGNAME + "/" + GearyApplication.VERSION;
diff --git a/src/client/geary-controller.vala b/src/client/geary-controller.vala
index cbc6aa47..6be4ec05 100644
--- a/src/client/geary-controller.vala
+++ b/src/client/geary-controller.vala
@@ -1173,13 +1173,15 @@ public class GearyController {
}
private void create_compose_window(ComposerWindow.ComposeType compose_type,
- Geary.ComposedEmail? prefill = null) {
+ Geary.Email? referred = null, string? mailto = null) {
if (current_account == null)
return;
- Geary.ContactStore? contact_store = current_account.get_contact_store();
- ComposerWindow window = new ComposerWindow(current_account, compose_type, contact_store,
- prefill);
+ ComposerWindow window;
+ if (mailto != null)
+ window = new ComposerWindow.from_mailto(current_account, mailto);
+ else
+ window = new ComposerWindow(current_account, compose_type, referred);
window.set_position(Gtk.WindowPosition.CENTER);
window.send.connect(on_send);
@@ -1200,8 +1202,7 @@ public class GearyController {
}
private void on_reply_to_message(Geary.Email message) {
- create_compose_window(ComposerWindow.ComposeType.REPLY, new Geary.ComposedEmail.as_reply(
- new DateTime.now_local(), get_from(), message));
+ create_compose_window(ComposerWindow.ComposeType.REPLY, message);
}
private void on_reply_to_message_action() {
@@ -1211,8 +1212,7 @@ public class GearyController {
}
private void on_reply_all_message(Geary.Email message) {
- create_compose_window(ComposerWindow.ComposeType.REPLY, new Geary.ComposedEmail.as_reply_all(
- new DateTime.now_local(), get_from(), message));
+ create_compose_window(ComposerWindow.ComposeType.REPLY_ALL, message);
}
private void on_reply_all_message_action() {
@@ -1222,8 +1222,7 @@ public class GearyController {
}
private void on_forward_message(Geary.Email message) {
- create_compose_window(ComposerWindow.ComposeType.FORWARD, new Geary.ComposedEmail.as_forward(
- new DateTime.now_local(), get_from(), message));
+ create_compose_window(ComposerWindow.ComposeType.FORWARD, message);
}
private void on_forward_message_action() {
@@ -1303,13 +1302,8 @@ public class GearyController {
main_window.conversation_viewer.web_view.zoom_level = 1.0f;
}
- private Geary.RFC822.MailboxAddress get_sender() {
- return new Geary.RFC822.MailboxAddress(current_account.information.real_name,
- current_account.information.email);
- }
-
private Geary.RFC822.MailboxAddresses get_from() {
- return new Geary.RFC822.MailboxAddresses.single(get_sender());
+ return current_account.information.get_from();
}
private void on_send(ComposerWindow composer_window) {
@@ -1395,7 +1389,7 @@ public class GearyController {
}
public void compose_mailto(string mailto) {
- create_compose_window(ComposerWindow.ComposeType.NEW_MESSAGE, new Geary.ComposedEmail.from_mailto(mailto, get_from()));
+ create_compose_window(ComposerWindow.ComposeType.NEW_MESSAGE, null, mailto);
}
// Returns a list of composer windows for an account, or null if none.
diff --git a/src/engine/api/geary-account-information.vala b/src/engine/api/geary-account-information.vala
index 5538ba83..6cf19ef1 100644
--- a/src/engine/api/geary-account-information.vala
+++ b/src/engine/api/geary-account-information.vala
@@ -457,6 +457,13 @@ public class Geary.AccountInformation : BaseObject {
return new RFC822.MailboxAddress(real_name, email);
}
+ /**
+ * Returns a MailboxAddresses object with this mailbox address.
+ */
+ public RFC822.MailboxAddresses get_from() {
+ return new RFC822.MailboxAddresses.single(get_mailbox_address());
+ }
+
public static int compare_ascending(AccountInformation a, AccountInformation b) {
int diff = a.ordinal - b.ordinal;
if (diff != 0)
diff --git a/src/engine/api/geary-composed-email.vala b/src/engine/api/geary-composed-email.vala
index 8fdf8fd9..e61eb7cf 100644
--- a/src/engine/api/geary-composed-email.vala
+++ b/src/engine/api/geary-composed-email.vala
@@ -21,20 +21,20 @@ 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.MessageID? in_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 RFC822.MessageIDList? references { get; set; default = null; }
- public RFC822.Subject? subject { get; set; default = null; }
- public RFC822.Text? body_text { get; set; default = null; }
- public RFC822.Text? body_html { get; set; default = null; }
+ public string? references { get; set; default = null; }
+ public string? subject { get; set; default = null; }
+ public string? body_text { get; set; default = null; }
+ public string? body_html { get; set; default = null; }
public string? mailer { get; set; default = null; }
public Gee.Set attachment_files { get; private set;
default = new Gee.HashSet(File.hash, (EqualFunc) File.equal); }
public ComposedEmail(DateTime date, RFC822.MailboxAddresses from,
RFC822.MailboxAddresses? to = null, RFC822.MailboxAddresses? cc = null,
- RFC822.MailboxAddresses? bcc = null, RFC822.Subject? subject = null,
- RFC822.Text? body_text = null, RFC822.Text? body_html = null) {
+ RFC822.MailboxAddresses? bcc = null, string? subject = null,
+ string? body_text = null, string? body_html = null) {
this.date = date;
this.from = from;
this.to = to;
@@ -44,223 +44,5 @@ public class Geary.ComposedEmail : BaseObject {
this.body_text = body_text;
this.body_html = body_html;
}
-
- public ComposedEmail.as_reply(DateTime date, RFC822.MailboxAddresses from, Geary.Email source) {
- this (date, from);
- assert(source.fields.fulfills(REQUIRED_REPLY_FIELDS));
-
- string? sender_address = (from.size > 0 ? from.get_all().first().address : null);
- to = create_to_addresses_for_reply(source, sender_address);
- subject = create_subject_for_reply(source);
- set_reply_references(source);
-
- body_text = new RFC822.Text(new Geary.Memory.StringBuffer("\n\n" +
- Geary.RFC822.Utils.quote_email_for_reply(source, false)));
- body_html = new RFC822.Text(new Geary.Memory.StringBuffer("\n\n" +
- Geary.RFC822.Utils.quote_email_for_reply(source, true)));
-
- add_attachments_from_source(source);
- }
-
- public ComposedEmail.as_reply_all(DateTime date, RFC822.MailboxAddresses from, Geary.Email source) {
- this (date, from);
- assert(source.fields.fulfills(REQUIRED_REPLY_FIELDS));
-
- string? sender_address = (from.size > 0 ? from.get_all().first().address : null);
- to = create_to_addresses_for_reply(source, sender_address);
- cc = create_cc_addresses_for_reply_all(source, sender_address);
- subject = create_subject_for_reply(source);
- set_reply_references(source);
-
- body_text = new RFC822.Text(new Geary.Memory.StringBuffer("\n\n" +
- Geary.RFC822.Utils.quote_email_for_reply(source, false)));
- body_html = new RFC822.Text(new Geary.Memory.StringBuffer("\n\n" +
- Geary.RFC822.Utils.quote_email_for_reply(source, true)));
-
- add_attachments_from_source(source);
- }
-
- public ComposedEmail.as_forward(DateTime date, RFC822.MailboxAddresses from, Geary.Email source) {
- this (date, from);
-
- subject = create_subject_for_forward(source);
-
- body_text = new RFC822.Text(new Geary.Memory.StringBuffer("\n\n" +
- Geary.RFC822.Utils.quote_email_for_forward(source, false)));
- body_html = new RFC822.Text(new Geary.Memory.StringBuffer("\n\n" +
- Geary.RFC822.Utils.quote_email_for_forward(source, true)));
-
- add_attachments_from_source(source);
- }
-
- private void add_attachments_from_source(Geary.Email source) {
- foreach (Geary.Attachment attachment in source.attachments) {
- File? attachment_file = File.new_for_path(attachment.filepath);
- if (attachment_file != null)
- attachment_files.add(attachment_file);
- }
- }
-
- public ComposedEmail.from_mailto(string mailto, RFC822.MailboxAddresses default_from) {
- DateTime date = new DateTime.now_local();
- RFC822.MailboxAddresses from = default_from;
- RFC822.MailboxAddresses? to = null;
- RFC822.MailboxAddresses? cc = null;
- RFC822.MailboxAddresses? bcc = null;
- RFC822.Subject? subject = null;
- RFC822.Text? body_text = null;
- RFC822.Text? body_html = null;
-
- Gee.HashMultiMap headers = new Gee.HashMultiMap();
- if (mailto.length > MAILTO_SCHEME.length) {
- // Parse the mailto link.
- string[] parts = mailto.substring(MAILTO_SCHEME.length).split("?", 2);
- string email = Uri.unescape_string(parts[0]);
- string[] params = parts.length == 2 ? parts[1].split("&") : new string[0];
- foreach (string param in params) {
- string[] param_parts = param.split("=", 2);
- if (param_parts.length == 2) {
- headers.set(Uri.unescape_string(param_parts[0]).down(),
- Uri.unescape_string(param_parts[1]));
- }
- }
-
- // Assemble the headers.
- if (headers.contains("from")) {
- from = new RFC822.MailboxAddresses.from_rfc822_string(
- Geary.Collection.get_first(headers.get("from")));
- }
-
- if (email.length > 0 && headers.contains("to")) {
- to = new RFC822.MailboxAddresses.from_rfc822_string("%s,%s".printf(email,
- Geary.Collection.get_first(headers.get("to"))));
- } else if (email.length > 0) {
- to = new RFC822.MailboxAddresses.from_rfc822_string(email);
- } else if (headers.contains("to")) {
- to = new RFC822.MailboxAddresses.from_rfc822_string(
- Geary.Collection.get_first(headers.get("to")));
- }
-
- if (headers.contains("cc")) {
- cc = new RFC822.MailboxAddresses.from_rfc822_string(
- Geary.Collection.get_first(headers.get("cc")));
- }
-
- if (headers.contains("bcc")) {
- bcc = new RFC822.MailboxAddresses.from_rfc822_string(
- Geary.Collection.get_first(headers.get("bcc")));
- }
-
- if (headers.contains("subject")) {
- subject = new RFC822.Subject(Geary.Collection.get_first(headers.get("subject")));
- }
-
- if (headers.contains("body")) {
- string body = Geary.Collection.get_first(headers.get("body"));
-
- body_text = new RFC822.Text(new Geary.Memory.StringBuffer(body));
- body_html = new RFC822.Text(new Geary.Memory.StringBuffer(
- Geary.HTML.preserve_whitespace(Geary.HTML.escape_markup(body))));
- }
- }
-
- // And construct!
- this(date, from, to, cc, bcc, subject, body_text, body_html);
-
- // Add attachments directly to public member ... need to call base constructor before doing
- // so
- foreach (string attachment in headers.get("attach")) {
- attachment_files.add(File.new_for_uri(attachment));
- }
-
- foreach (string attachment in headers.get("attachment")) {
- attachment_files.add(File.new_for_uri(attachment));
- }
- }
-
- private void set_reply_references(Geary.Email source) {
- in_reply_to = source.message_id;
- reply_to_email = source;
-
- // generate list for References
- Gee.ArrayList list = new Gee.ArrayList();
-
- // 1. Start with the source's References list
- if (source.references != null && source.references.list.size > 0)
- list.add_all(source.references.list);
-
- // 2. If there's an In-Reply-To Message-ID and it's not the last Message-ID on the
- // References list, append it
- if (source.in_reply_to != null && list.size > 0 && !list.last().equals(source.in_reply_to))
- list.add(source.in_reply_to);
-
- // 3. Append the source's Message-ID, if available.
- if (source.message_id != null)
- list.add(source.message_id);
-
- references = (list.size > 0) ? new RFC822.MessageIDList.from_list(list) : null;
- }
-
- private Geary.RFC822.Subject create_subject_for_reply(Geary.Email email) {
- return (email.subject ?? new Geary.RFC822.Subject("")).create_reply();
- }
-
- private Geary.RFC822.Subject create_subject_for_forward(Geary.Email email) {
- return (email.subject ?? new Geary.RFC822.Subject("")).create_forward();
- }
-
- // Removes address from the list of addresses. If the list contains only the given address, the
- // behavior depends on empty_ok: if true the list will be emptied, otherwise it will leave the
- // address in the list once. Used to remove the sender's address from a list of addresses being
- // created for the "reply to" recipients.
- private static void remove_address(Gee.List addresses,
- string address, bool empty_ok = false) {
- for (int i = 0; i < addresses.size; ++i) {
- if (addresses[i].address == address && (empty_ok || addresses.size > 1))
- addresses.remove_at(i--);
- }
- }
-
- private Geary.RFC822.MailboxAddresses? create_to_addresses_for_reply(Geary.Email email,
- string? sender_address = null) {
- Gee.List new_to =
- new Gee.ArrayList();
-
- // If we're replying to something we sent, send it to the same people we originally did.
- // Otherwise, we'll send to the reply-to address or the from address.
- if (email.to != null && !String.is_empty(sender_address) && email.from.contains(sender_address))
- new_to.add_all(email.to.get_all());
- else if (email.reply_to != null)
- new_to.add_all(email.reply_to.get_all());
- else if (email.from != null)
- new_to.add_all(email.from.get_all());
-
- // Exclude the current sender. No need to receive the mail they're sending.
- if (!String.is_empty(sender_address))
- remove_address(new_to, sender_address);
-
- return new_to.size > 0 ? new Geary.RFC822.MailboxAddresses(new_to) : null;
- }
-
- private Geary.RFC822.MailboxAddresses? create_cc_addresses_for_reply_all(Geary.Email email,
- string? sender_address = null) {
- Gee.List new_cc = new Gee.ArrayList();
-
- // If we're replying to something we received, also add other recipients. Don't do this for
- // emails we sent, since everyone we sent it to is already covered in
- // create_to_addresses_for_reply().
- if (email.to != null && (String.is_empty(sender_address) ||
- !email.from.contains(sender_address)))
- new_cc.add_all(email.to.get_all());
-
- if (email.cc != null)
- new_cc.add_all(email.cc.get_all());
-
- // Again, exclude the current sender.
- if (!String.is_empty(sender_address))
- remove_address(new_cc, sender_address, true);
-
- return new_cc.size > 0 ? new Geary.RFC822.MailboxAddresses(new_cc) : null;
- }
}
diff --git a/src/engine/rfc822/rfc822-message.vala b/src/engine/rfc822/rfc822-message.vala
index f5c85d52..c5eaaa04 100644
--- a/src/engine/rfc822/rfc822-message.vala
+++ b/src/engine/rfc822/rfc822-message.vala
@@ -83,18 +83,18 @@ public class Geary.RFC822.Message : BaseObject {
}
if (email.in_reply_to != null) {
- in_reply_to = email.in_reply_to;
- message.set_header(HEADER_IN_REPLY_TO, email.in_reply_to.value);
+ in_reply_to = new Geary.RFC822.MessageID(email.in_reply_to);
+ message.set_header(HEADER_IN_REPLY_TO, email.in_reply_to);
}
if (email.references != null) {
- references = email.references;
- message.set_header(HEADER_REFERENCES, email.references.to_rfc822_string());
+ references = new Geary.RFC822.MessageIDList.from_rfc822_string(email.references);
+ message.set_header(HEADER_REFERENCES, email.references);
}
if (email.subject != null) {
- subject = email.subject;
- message.set_subject(email.subject.value);
+ subject = new Geary.RFC822.Subject(email.subject);
+ message.set_subject(email.subject);
}
// User-Agent
@@ -107,7 +107,7 @@ public class Geary.RFC822.Message : BaseObject {
GMime.Part? body_text = null;
if (email.body_text != null) {
GMime.DataWrapper content = new GMime.DataWrapper.with_stream(
- new GMime.StreamMem.with_buffer(email.body_text.buffer.get_array()),
+ new GMime.StreamMem.with_buffer(email.body_text.data),
GMime.ContentEncoding.DEFAULT);
body_text = new GMime.Part();
@@ -119,7 +119,7 @@ public class Geary.RFC822.Message : BaseObject {
GMime.Part? body_html = null;
if (email.body_html != null) {
GMime.DataWrapper content = new GMime.DataWrapper.with_stream(
- new GMime.StreamMem.with_buffer(email.body_html.buffer.get_array()),
+ new GMime.StreamMem.with_buffer(email.body_html.data),
GMime.ContentEncoding.DEFAULT);
body_html = new GMime.Part();
diff --git a/src/engine/rfc822/rfc822-utils.vala b/src/engine/rfc822/rfc822-utils.vala
index 5bf158bb..bbbedde9 100644
--- a/src/engine/rfc822/rfc822-utils.vala
+++ b/src/engine/rfc822/rfc822-utils.vala
@@ -10,6 +10,92 @@ namespace Geary.RFC822.Utils {
// in UTF-8, and is unmolested by GMime.FilterHTML.
public const char QUOTE_MARKER = '\x7f';
+public string create_subject_for_reply(Geary.Email email) {
+ return (email.subject ?? new Geary.RFC822.Subject("")).create_reply().value;
+}
+
+public string create_subject_for_forward(Geary.Email email) {
+ return (email.subject ?? new Geary.RFC822.Subject("")).create_forward().value;
+}
+
+// Removes address from the list of addresses. If the list contains only the given address, the
+// behavior depends on empty_ok: if true the list will be emptied, otherwise it will leave the
+// address in the list once. Used to remove the sender's address from a list of addresses being
+// created for the "reply to" recipients.
+private void remove_address(Gee.List addresses,
+ string address, bool empty_ok = false) {
+ for (int i = 0; i < addresses.size; ++i) {
+ if (addresses[i].address == address && (empty_ok || addresses.size > 1))
+ addresses.remove_at(i--);
+ }
+}
+
+public string create_to_addresses_for_reply(Geary.Email email,
+ string? sender_address = null) {
+ Gee.List new_to =
+ new Gee.ArrayList();
+
+ // If we're replying to something we sent, send it to the same people we originally did.
+ // Otherwise, we'll send to the reply-to address or the from address.
+ if (email.to != null && !String.is_empty(sender_address) && email.from.contains(sender_address))
+ new_to.add_all(email.to.get_all());
+ else if (email.reply_to != null)
+ new_to.add_all(email.reply_to.get_all());
+ else if (email.from != null)
+ new_to.add_all(email.from.get_all());
+
+ // Exclude the current sender. No need to receive the mail they're sending.
+ if (!String.is_empty(sender_address))
+ remove_address(new_to, sender_address);
+
+ return new_to.size > 0 ? new Geary.RFC822.MailboxAddresses(new_to).to_rfc822_string() : "";
+}
+
+public string create_cc_addresses_for_reply_all(Geary.Email email,
+ string? sender_address = null) {
+ Gee.List new_cc = new Gee.ArrayList();
+
+ // If we're replying to something we received, also add other recipients. Don't do this for
+ // emails we sent, since everyone we sent it to is already covered in
+ // create_to_addresses_for_reply().
+ if (email.to != null && (String.is_empty(sender_address) ||
+ !email.from.contains(sender_address)))
+ new_cc.add_all(email.to.get_all());
+
+ if (email.cc != null)
+ new_cc.add_all(email.cc.get_all());
+
+ // Again, exclude the current sender.
+ if (!String.is_empty(sender_address))
+ remove_address(new_cc, sender_address, true);
+
+ return new_cc.size > 0 ? new Geary.RFC822.MailboxAddresses(new_cc).to_rfc822_string() : "";
+}
+
+public string reply_references(Geary.Email source) {
+ // generate list for References
+ Gee.ArrayList list = new Gee.ArrayList();
+
+ // 1. Start with the source's References list
+ if (source.references != null && source.references.list.size > 0)
+ list.add_all(source.references.list);
+
+ // 2. If there's an In-Reply-To Message-ID and it's not the last Message-ID on the
+ // References list, append it
+ if (source.in_reply_to != null && list.size > 0 && !list.last().equals(source.in_reply_to))
+ list.add(source.in_reply_to);
+
+ // 3. Append the source's Message-ID, if available.
+ if (source.message_id != null)
+ list.add(source.message_id);
+
+ string[] strings = new string[list.size];
+ for(int i = 0; i < list.size; ++i)
+ strings[i] = list[i].value;
+
+ return (list.size > 0) ? string.joinv(" ", strings) : "";
+}
+
public string email_addresses_for_reply(Geary.RFC822.MailboxAddresses? addresses,
bool html_format) {
diff --git a/src/mailer/main.vala b/src/mailer/main.vala
index 15ed0982..ec79b1e6 100644
--- a/src/mailer/main.vala
+++ b/src/mailer/main.vala
@@ -18,8 +18,8 @@ async void main_async() throws Error {
for (int ctr = 0; ctr < arg_count; ctr++) {
string subj_msg = "#%d".printf(ctr + 1);
- composed_email.subject = new Geary.RFC822.Subject(subj_msg);
- composed_email.body_text = new Geary.RFC822.Text(new Geary.Memory.StringBuffer(subj_msg));
+ composed_email.subject = subj_msg;
+ composed_email.body_text = subj_msg;
Geary.RFC822.Message msg = new Geary.RFC822.Message.from_composed_email(composed_email);
stdout.printf("\n\n%s\n\n", msg.to_string());