[geary/wip/765516-gtk-widget-conversation-viewer: 93/107] Re-enable email menu actions and message star/unstar.
- From: Michael Gratton <mjog src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary/wip/765516-gtk-widget-conversation-viewer: 93/107] Re-enable email menu actions and message star/unstar.
- Date: Sun, 5 Jun 2016 12:35:18 +0000 (UTC)
commit 50caba0cfe1d05538bfd0912cd739b11d36e1f33
Author: Michael James Gratton <mike vee net>
Date: Sat Apr 23 14:17:41 2016 +1000
Re-enable email menu actions and message star/unstar.
* src/client/application/geary-controller.vala: Chase signal changes.
(GearyController::on_view_source): Moved view source code here from the
conversation viewer.
* src/client/conversation-viewer/conversation-email.vala: Add an action
group for the email for email-specific actions with the prefix
"msg". Add actions each of the items in the email menu. Move
email-specific signals here from ConversationViewer. Update actions
based on message state as needed.
* src/client/conversation-viewer/conversation-viewer.vala: Add signal
handlers for ConversationEmail's email flagging signals and forward
them on to the `mark_emails` signal, since we also want to batch up
email flag changes from here.
* ui/conversation-email.ui: Fix star/unstar action names.
* ui/conversation-message-menu.ui: Cromulify the email menu name.
src/client/application/geary-controller.vala | 41 +++-
.../conversation-viewer/conversation-email.vala | 260 ++++++++------------
.../conversation-viewer/conversation-viewer.vala | 47 +++-
ui/conversation-email.ui | 4 +-
ui/conversation-message-menu.ui | 2 +-
5 files changed, 172 insertions(+), 182 deletions(-)
---
diff --git a/src/client/application/geary-controller.vala b/src/client/application/geary-controller.vala
index bcbb1eb..982ca10 100644
--- a/src/client/application/geary-controller.vala
+++ b/src/client/application/geary-controller.vala
@@ -237,9 +237,6 @@ public class GearyController : Geary.BaseObject {
main_window.search_bar.search_text_changed.connect(on_search_text_changed);
main_window.conversation_viewer.email_row_added.connect(on_email_row_added);
main_window.conversation_viewer.email_row_removed.connect(on_email_row_removed);
- main_window.conversation_viewer.reply_to_message.connect(on_reply_to_message);
- main_window.conversation_viewer.reply_all_message.connect(on_reply_all_message);
- main_window.conversation_viewer.forward_message.connect(on_forward_message);
main_window.conversation_viewer.mark_emails.connect(on_conversation_viewer_mark_emails);
main_window.conversation_viewer.save_attachments.connect(on_save_attachments);
main_window.conversation_viewer.save_buffer_to_file.connect(on_save_buffer_to_file);
@@ -304,9 +301,6 @@ public class GearyController : Geary.BaseObject {
main_window.search_bar.search_text_changed.disconnect(on_search_text_changed);
main_window.conversation_viewer.email_row_added.disconnect(on_email_row_added);
main_window.conversation_viewer.email_row_removed.disconnect(on_email_row_removed);
- main_window.conversation_viewer.reply_to_message.disconnect(on_reply_to_message);
- main_window.conversation_viewer.reply_all_message.disconnect(on_reply_all_message);
- main_window.conversation_viewer.forward_message.disconnect(on_forward_message);
main_window.conversation_viewer.mark_emails.disconnect(on_conversation_viewer_mark_emails);
main_window.conversation_viewer.save_attachments.disconnect(on_save_attachments);
main_window.conversation_viewer.save_buffer_to_file.disconnect(on_save_buffer_to_file);
@@ -2660,15 +2654,23 @@ public class GearyController : Geary.BaseObject {
}
private void on_email_row_added(ConversationEmail message) {
+ message.reply_to_message.connect(on_reply_to_message);
+ message.reply_all_message.connect(on_reply_all_message);
+ message.forward_message.connect(on_forward_message);
message.link_activated.connect(on_link_activated);
message.attachment_activated.connect(on_attachment_activated);
message.edit_draft.connect(on_edit_draft);
+ message.view_source.connect(on_view_source);
}
private void on_email_row_removed(ConversationEmail message) {
+ message.reply_to_message.disconnect(on_reply_to_message);
+ message.reply_all_message.disconnect(on_reply_all_message);
+ message.forward_message.disconnect(on_forward_message);
message.link_activated.disconnect(on_link_activated);
message.attachment_activated.disconnect(on_attachment_activated);
message.edit_draft.disconnect(on_edit_draft);
+ message.view_source.disconnect(on_view_source);
}
private void on_link_activated(string link) {
@@ -2683,6 +2685,33 @@ public class GearyController : Geary.BaseObject {
create_compose_widget(ComposerWidget.ComposeType.NEW_MESSAGE, draft, null, null, true);
}
+
+ private void on_view_source(Geary.Email message) {
+ string source = (message.header.buffer.to_string() +
+ message.body.buffer.to_string());
+ string temporary_filename;
+ try {
+ int temporary_handle = FileUtils.open_tmp("geary-message-XXXXXX.txt",
+ out temporary_filename);
+ FileUtils.set_contents(temporary_filename, source);
+ FileUtils.close(temporary_handle);
+
+ // ensure this file is only readable by the user ... this
+ // needs to be done after the file is closed
+ FileUtils.chmod(temporary_filename, (int) (Posix.S_IRUSR | Posix.S_IWUSR));
+
+ string temporary_uri = Filename.to_uri(temporary_filename, null);
+ Gtk.show_uri(main_window.get_screen(), temporary_uri, Gdk.CURRENT_TIME);
+ } catch (Error error) {
+ ErrorDialog dialog = new ErrorDialog(
+ main_window,
+ _("Failed to open default text editor."),
+ error.message
+ );
+ dialog.run();
+ }
+ }
+
// Disables all single-message buttons and enables all multi-message buttons.
public void enable_multiple_message_buttons() {
update_tooltips();
diff --git a/src/client/conversation-viewer/conversation-email.vala
b/src/client/conversation-viewer/conversation-email.vala
index cc138ea..687dd83 100644
--- a/src/client/conversation-viewer/conversation-email.vala
+++ b/src/client/conversation-viewer/conversation-email.vala
@@ -21,6 +21,17 @@ public class ConversationEmail : Gtk.Box {
private const int ATTACHMENT_ICON_SIZE = 32;
private const int ATTACHMENT_PREVIEW_SIZE = 64;
+ private const string ACTION_FORWARD = "forward";
+ private const string ACTION_MARK_READ = "mark_read";
+ private const string ACTION_MARK_UNREAD = "mark_unread";
+ private const string ACTION_MARK_UNREAD_DOWN = "mark_unread_down";
+ private const string ACTION_PRINT = "print";
+ private const string ACTION_REPLY_SENDER = "reply_sender";
+ private const string ACTION_REPLY_ALL = "reply_all";
+ private const string ACTION_STAR = "star";
+ private const string ACTION_UNSTAR = "unstar";
+ private const string ACTION_VIEW_SOURCE = "view_source";
+
// The email message being displayed
public Geary.Email email { get; private set; }
@@ -41,6 +52,9 @@ public class ConversationEmail : Gtk.Box {
// Attachment ids that have been displayed inline
private Gee.HashSet<string> inlined_content_ids = new Gee.HashSet<string>();
+ // Message-specific actions
+ private SimpleActionGroup message_actions = new SimpleActionGroup();
+
[GtkChild]
private Gtk.Box action_box;
@@ -71,6 +85,25 @@ public class ConversationEmail : Gtk.Box {
[GtkChild]
private Gtk.ListStore attachments_model;
+ // Fired when the user clicks "reply" in the message menu.
+ public signal void reply_to_message(Geary.Email message);
+
+ // Fired when the user clicks "reply all" in the message menu.
+ public signal void reply_all_message(Geary.Email message);
+
+ // Fired when the user clicks "forward" in the message menu.
+ public signal void forward_message(Geary.Email message);
+
+ // Fired when the user updates the message's flags.
+ public signal void mark_email(
+ Geary.Email email, Geary.NamedFlag? to_add, Geary.NamedFlag? to_remove
+ );
+
+ // Fired when the user updates all message's flags from this down.
+ public signal void mark_email_from(
+ Geary.Email email, Geary.NamedFlag? to_add, Geary.NamedFlag? to_remove
+ );
+
// Fired on link activation in the web_view
public signal void link_activated(string link);
@@ -78,7 +111,10 @@ public class ConversationEmail : Gtk.Box {
public signal void attachment_activated(Geary.Attachment attachment);
// Fired the edit draft button is clicked.
- public signal void edit_draft(Geary.Email message);
+ public signal void edit_draft(Geary.Email email);
+
+ // Fired when the view source action is activated
+ public signal void view_source(Geary.Email email);
public ConversationEmail(Geary.Email email,
@@ -87,6 +123,38 @@ public class ConversationEmail : Gtk.Box {
this.email = email;
this.contact_store = contact_store;
+ add_action(ACTION_FORWARD).activate.connect(() => {
+ forward_message(this.email);
+ });
+ add_action(ACTION_PRINT).activate.connect(() => {
+ print();
+ });
+ add_action(ACTION_MARK_READ).activate.connect(() => {
+ mark_email(this.email, null, Geary.EmailFlags.UNREAD);
+ });
+ add_action(ACTION_MARK_UNREAD).activate.connect(() => {
+ mark_email(this.email, Geary.EmailFlags.UNREAD, null);
+ });
+ add_action(ACTION_MARK_UNREAD_DOWN).activate.connect(() => {
+ mark_email_from(this.email, Geary.EmailFlags.UNREAD, null);
+ });
+ add_action(ACTION_REPLY_ALL).activate.connect(() => {
+ reply_all_message(this.email);
+ });
+ add_action(ACTION_REPLY_SENDER).activate.connect(() => {
+ reply_to_message(this.email);
+ });
+ add_action(ACTION_STAR).activate.connect(() => {
+ mark_email(this.email, Geary.EmailFlags.FLAGGED, null);
+ });
+ add_action(ACTION_UNSTAR).activate.connect(() => {
+ mark_email(this.email, null, Geary.EmailFlags.FLAGGED);
+ });
+ add_action(ACTION_VIEW_SOURCE).activate.connect(() => {
+ view_source(this.email);
+ });
+ insert_action_group("msg", message_actions);
+
Geary.RFC822.Message message;
try {
message = email.get_message();
@@ -110,7 +178,10 @@ public class ConversationEmail : Gtk.Box {
});
primary_message.summary_box.pack_start(action_box, false, false, 0);
- email_menubutton.set_menu_model(build_message_menu(email));
+ Gtk.Builder builder = new Gtk.Builder.from_resource(
+ "/org/gnome/Geary/conversation-message-menu.ui"
+ );
+ email_menubutton.set_menu_model((MenuModel) builder.get_object("email_menu"));
email_menubutton.set_sensitive(false);
primary_message.infobar_box.pack_start(draft_infobar, false, false, 0);
@@ -178,81 +249,6 @@ public class ConversationEmail : Gtk.Box {
primary_message.hide_message_body();
}
- private MenuModel build_message_menu(Geary.Email email) {
- Gtk.Builder builder = new Gtk.Builder.from_resource(
- "/org/gnome/Geary/conversation-message-menu.ui"
- );
-
- MenuModel menu = (MenuModel) builder.get_object("conversation_message_menu");
-
- // menu.selection_done.connect(on_message_menu_selection_done);
-
- // int displayed = displayed_attachments(email);
- // if (displayed > 0) {
- // string mnemonic = ngettext("Save A_ttachment...", "Save All A_ttachments...",
- // displayed);
- // Gtk.MenuItem save_all_item = new Gtk.MenuItem.with_mnemonic(mnemonic);
- // save_all_item.activate.connect(() => save_attachments(email.attachments));
- // menu.append(save_all_item);
- // menu.append(new Gtk.SeparatorMenuItem());
- // }
-
- // if (!in_drafts_folder()) {
- // // Reply to a message.
- // Gtk.MenuItem reply_item = new Gtk.MenuItem.with_mnemonic(_("_Reply"));
- // reply_item.activate.connect(() => reply_to_message(email));
- // menu.append(reply_item);
-
- // // Reply to all on a message.
- // Gtk.MenuItem reply_all_item = new Gtk.MenuItem.with_mnemonic(_("Reply to _All"));
- // reply_all_item.activate.connect(() => reply_all_message(email));
- // menu.append(reply_all_item);
-
- // // Forward a message.
- // Gtk.MenuItem forward_item = new Gtk.MenuItem.with_mnemonic(_("_Forward"));
- // forward_item.activate.connect(() => forward_message(email));
- // menu.append(forward_item);
- // }
-
- // if (menu.get_children().length() > 0) {
- // // Separator.
- // menu.append(new Gtk.SeparatorMenuItem());
- // }
-
- // // Mark as read/unread.
- // if (email.is_unread().to_boolean(false)) {
- // Gtk.MenuItem mark_read_item = new Gtk.MenuItem.with_mnemonic(_("_Mark as Read"));
- // mark_read_item.activate.connect(() => on_mark_read_message(email));
- // menu.append(mark_read_item);
- // } else {
- // Gtk.MenuItem mark_unread_item = new Gtk.MenuItem.with_mnemonic(_("_Mark as Unread"));
- // mark_unread_item.activate.connect(() => on_mark_unread_message(email));
- // menu.append(mark_unread_item);
-
- // if (messages.size > 1 && messages.last() != email) {
- // Gtk.MenuItem mark_unread_from_here_item = new Gtk.MenuItem.with_mnemonic(
- // _("Mark Unread From _Here"));
- // mark_unread_from_here_item.activate.connect(() => on_mark_unread_from_here(email));
- // menu.append(mark_unread_from_here_item);
- // }
- // }
-
- // // Print a message.
- // Gtk.MenuItem print_item = new Gtk.MenuItem.with_mnemonic(Stock._PRINT_MENU);
- // print_item.activate.connect(() => on_print_message(email));
- // menu.append(print_item);
-
- // // Separator.
- // menu.append(new Gtk.SeparatorMenuItem());
-
- // // View original message source.
- // Gtk.MenuItem view_source_item = new Gtk.MenuItem.with_mnemonic(_("_View Source"));
- // view_source_item.activate.connect(() => on_view_source(email));
- // menu.append(view_source_item);
-
- return menu;
- }
-
public void update_flags(Geary.Email email) {
this.email.set_flags(email.email_flags);
update_email_state();
@@ -266,13 +262,32 @@ public class ConversationEmail : Gtk.Box {
get_style_context().add_class("geary_manual_read");
}
+ private SimpleAction add_action(string name) {
+ SimpleAction action = new SimpleAction(name, null);
+ message_actions.add_action(action);
+ return action;
+ }
+
+ private void set_action_enabled(string name, bool enabled) {
+ SimpleAction? action = this.message_actions.lookup(name) as SimpleAction;
+ if (action != null) {
+ action.set_enabled(enabled);
+ }
+ }
+
private void update_email_state(bool include_transitions=true) {
Geary.EmailFlags flags = email.email_flags;
Gtk.StyleContext style = get_style_context();
if (flags.is_unread()) {
+ set_action_enabled(ACTION_MARK_READ, true);
+ set_action_enabled(ACTION_MARK_UNREAD, false);
+ set_action_enabled(ACTION_MARK_UNREAD_DOWN, false);
style.add_class("geary_unread");
} else {
+ set_action_enabled(ACTION_MARK_READ, false);
+ set_action_enabled(ACTION_MARK_UNREAD, true);
+ set_action_enabled(ACTION_MARK_UNREAD_DOWN, true);
style.remove_class("geary_unread");
}
@@ -291,12 +306,14 @@ public class ConversationEmail : Gtk.Box {
}
}
+ private void print() {
+ // XXX this isn't anywhere near good enough
+ primary_message.web_view.get_main_frame().print();
+ }
+
private void on_flag_remote_images(ConversationMessage view) {
// XXX check we aren't already auto loading the image
- Geary.EmailFlags flags = new Geary.EmailFlags();
- flags.add(Geary.EmailFlags.LOAD_REMOTE_IMAGES);
- //get_viewer().mark_messages(Geary.iterate<Geary.EmailIdentifier>(email.id).to_array_list(),
- //flags, null);
+ mark_email(email, Geary.EmailFlags.LOAD_REMOTE_IMAGES, null);
}
@@ -348,64 +365,6 @@ public class ConversationEmail : Gtk.Box {
// get_viewer().save_attachments(attachments);
// }
- // private void on_mark_read_message(Geary.Email message) {
- // Geary.EmailFlags flags = new Geary.EmailFlags();
- // flags.add(Geary.EmailFlags.UNREAD);
- // get_viewer().mark_messages(Geary.iterate<Geary.EmailIdentifier>(message.id).to_array_list(),
null, flags);
- // mark_manual_read(message.id);
- // }
-
- // private void on_mark_unread_message(Geary.Email message) {
- // Geary.EmailFlags flags = new Geary.EmailFlags();
- // flags.add(Geary.EmailFlags.UNREAD);
- // get_viewer().mark_messages(Geary.iterate<Geary.EmailIdentifier>(message.id).to_array_list(),
flags, null);
- // mark_manual_read(message.id);
- // }
-
- // private void on_mark_unread_from_here(Geary.Email message) {
- // Geary.EmailFlags flags = new Geary.EmailFlags();
- // flags.add(Geary.EmailFlags.UNREAD);
-
- // Gee.Iterator<Geary.Email>? iter = messages.iterator_at(message);
- // if (iter == null) {
- // warning("Email not found in message list");
-
- // return;
- // }
-
- // // Build a list of IDs to mark.
- // Gee.ArrayList<Geary.EmailIdentifier> to_mark = new Gee.ArrayList<Geary.EmailIdentifier>();
- // to_mark.add(message.id);
- // while (iter.next())
- // to_mark.add(iter.get().id);
-
- // get_viewer().mark_messages(to_mark, flags, null);
- // foreach(Geary.EmailIdentifier id in to_mark)
- // mark_manual_read(id);
- // }
-
- // private void on_print_message(Geary.Email message) {
- // try {
- // email_to_element.get(message.id).get_class_list().add("print");
- // web_view.get_main_frame().print();
- // email_to_element.get(message.id).get_class_list().remove("print");
- // } catch (GLib.Error error) {
- // debug("Hiding elements for printing failed: %s", error.message);
- // }
- // }
-
- // private void flag_message() {
- // Geary.EmailFlags flags = new Geary.EmailFlags();
- // flags.add(Geary.EmailFlags.FLAGGED);
- // get_viewer().mark_messages(Geary.iterate<Geary.EmailIdentifier>(email.id).to_array_list(), flags,
null);
- // }
-
- // private void unflag_message() {
- // Geary.EmailFlags flags = new Geary.EmailFlags();
- // flags.add(Geary.EmailFlags.FLAGGED);
- // get_viewer().mark_messages(Geary.iterate<Geary.EmailIdentifier>(email.id).to_array_list(), null,
flags);
- // }
-
// private void show_attachment_menu(Geary.Email email, Geary.Attachment attachment) {
// attachment_menu = build_attachment_menu(email, attachment);
// attachment_menu.show_all();
@@ -570,27 +529,4 @@ public class ConversationEmail : Gtk.Box {
return pixbuf;
}
- // private void on_view_source(Geary.Email message) {
- // string source = message.header.buffer.to_string() + message.body.buffer.to_string();
-
- // try {
- // string temporary_filename;
- // int temporary_handle = FileUtils.open_tmp("geary-message-XXXXXX.txt",
- // out temporary_filename);
- // FileUtils.set_contents(temporary_filename, source);
- // FileUtils.close(temporary_handle);
-
- // // ensure this file is only readable by the user ... this needs to be done after the
- // // file is closed
- // FileUtils.chmod(temporary_filename, (int) (Posix.S_IRUSR | Posix.S_IWUSR));
-
- // string temporary_uri = Filename.to_uri(temporary_filename, null);
- // Gtk.show_uri(web_view.get_screen(), temporary_uri, Gdk.CURRENT_TIME);
- // } catch (Error error) {
- // ErrorDialog dialog = new ErrorDialog(GearyApplication.instance.controller.main_window,
- // _("Failed to open default text editor."), error.message);
- // dialog.run();
- // }
- // }
-
}
diff --git a/src/client/conversation-viewer/conversation-viewer.vala
b/src/client/conversation-viewer/conversation-viewer.vala
index bb433e3..701556f 100644
--- a/src/client/conversation-viewer/conversation-viewer.vala
+++ b/src/client/conversation-viewer/conversation-viewer.vala
@@ -58,16 +58,7 @@ public class ConversationViewer : Gtk.Stack {
// Fired when an email is removed from the view
public signal void email_row_removed(ConversationEmail email);
- // Fired when the user clicks "reply" in the message menu.
- public signal void reply_to_message(Geary.Email message);
-
- // Fired when the user clicks "reply all" in the message menu.
- public signal void reply_all_message(Geary.Email message);
-
- // Fired when the user clicks "forward" in the message menu.
- public signal void forward_message(Geary.Email message);
-
- // Fired when the user mark messages.
+ // Fired when the user marks messages.
public signal void mark_emails(Gee.Collection<Geary.EmailIdentifier> emails,
Geary.EmailFlags? flags_to_add, Geary.EmailFlags? flags_to_remove);
@@ -640,6 +631,8 @@ public class ConversationViewer : Gtk.Stack {
current_folder.account.get_contact_store(),
is_draft
);
+ conversation_email.mark_email.connect(on_mark_email);
+ conversation_email.mark_email_from.connect(on_mark_email_from);
ConversationMessage conversation_message = conversation_email.primary_message;
conversation_message.body_box.button_release_event.connect_after((event) => {
@@ -733,7 +726,39 @@ public class ConversationViewer : Gtk.Stack {
return SearchState.NONE;
}
-
+
+ private void on_mark_email(Geary.Email email,
+ Geary.NamedFlag? to_add,
+ Geary.NamedFlag? to_remove) {
+ Gee.Collection<Geary.EmailIdentifier> ids =
+ new Gee.LinkedList<Geary.EmailIdentifier>();
+ ids.add(email.id);
+ mark_emails(ids, flag_to_flags(to_add), flag_to_flags(to_remove));
+ }
+
+ private void on_mark_email_from(Geary.Email email,
+ Geary.NamedFlag? to_add,
+ Geary.NamedFlag? to_remove) {
+ Gee.Collection<Geary.EmailIdentifier> ids =
+ new Gee.LinkedList<Geary.EmailIdentifier>();
+ ids.add(email.id);
+ foreach (Geary.Email other in this.emails) {
+ if (Geary.Email.compare_sent_date_ascending(email, other) < 0) {
+ ids.add(other.id);
+ }
+ }
+ mark_emails(ids, flag_to_flags(to_add), flag_to_flags(to_remove));
+ }
+
+ private Geary.EmailFlags? flag_to_flags(Geary.NamedFlag? flag) {
+ Geary.EmailFlags flags = null;
+ if (flag != null) {
+ flags = new Geary.EmailFlags();
+ flags.add(flag);
+ }
+ return flags;
+ }
+
// Find bar opened.
private uint on_open_find_bar(uint state, uint event, void *user, Object? object) {
if (!conversation_find_bar.visible)
diff --git a/ui/conversation-email.ui b/ui/conversation-email.ui
index 8920951..5119148 100644
--- a/ui/conversation-email.ui
+++ b/ui/conversation-email.ui
@@ -42,7 +42,7 @@
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Mark this message as starred</property>
<property name="valign">start</property>
- <property name="action_name">win.message_star</property>
+ <property name="action_name">msg.star</property>
<property name="relief">none</property>
<child>
<object class="GtkImage">
@@ -66,7 +66,7 @@
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Mark this message as not starred</property>
<property name="valign">start</property>
- <property name="action_name">win.message_unstar</property>
+ <property name="action_name">msg.unstar</property>
<property name="relief">none</property>
<child>
<object class="GtkImage">
diff --git a/ui/conversation-message-menu.ui b/ui/conversation-message-menu.ui
index 022af36..f2ae478 100644
--- a/ui/conversation-message-menu.ui
+++ b/ui/conversation-message-menu.ui
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
- <menu id="conversation_message_menu">
+ <menu id="email_menu">
<section>
<item>
<attribute name="label" translatable="yes">_Save Attachments</attribute>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]