Separate and implement contact popover action from conversation message
This leads to a minor bit of UI string and code duplication, but substantially reduces the complexity of implementing the popover's actions. Hook up all remaining actions except open and save.
This commit is contained in:
parent
948ed5f95e
commit
68b2da17c5
4 changed files with 233 additions and 127 deletions
|
|
@ -12,15 +12,35 @@
|
|||
public class Conversation.ContactPopover : Gtk.Popover {
|
||||
|
||||
|
||||
private const string ACTION_COPY_EMAIL= "copy-email";
|
||||
private const string ACTION_LOAD_REMOTE = "load-remote";
|
||||
private const string ACTION_NEW_CONVERSATION = "new-conversation";
|
||||
private const string ACTION_OPEN = "open";
|
||||
private const string ACTION_SAVE = "save";
|
||||
private const string ACTION_SHOW_CONVERSATIONS = "show-conversations";
|
||||
private const string ACTION_STAR = "star";
|
||||
private const string ACTION_UNSTAR = "unstar";
|
||||
|
||||
private const string ACTION_GROUP = "con";
|
||||
|
||||
private const GLib.ActionEntry[] ACTION_ENTRIES = {
|
||||
{ACTION_COPY_EMAIL, on_copy_email, },
|
||||
{ACTION_LOAD_REMOTE, on_load_remote, null, "false" },
|
||||
{ACTION_NEW_CONVERSATION, on_new_conversation },
|
||||
{ACTION_OPEN, on_open },
|
||||
{ACTION_SAVE, on_save },
|
||||
{ACTION_SHOW_CONVERSATIONS, on_show_conversations },
|
||||
{ACTION_STAR, on_star, },
|
||||
{ACTION_UNSTAR, on_unstar, },
|
||||
};
|
||||
|
||||
|
||||
public Application.Contact contact { get; private set; }
|
||||
|
||||
public Geary.RFC822.MailboxAddress mailbox { get; private set; }
|
||||
|
||||
private GLib.Cancellable load_cancellable = new GLib.Cancellable();
|
||||
|
||||
[GtkChild]
|
||||
private Gtk.Grid container;
|
||||
|
||||
[GtkChild]
|
||||
private Gtk.Image avatar;
|
||||
|
||||
|
|
@ -36,45 +56,35 @@ public class Conversation.ContactPopover : Gtk.Popover {
|
|||
[GtkChild]
|
||||
private Gtk.Button unstarred_button;
|
||||
|
||||
[GtkChild]
|
||||
private Gtk.ModelButton open_button;
|
||||
|
||||
[GtkChild]
|
||||
private Gtk.ModelButton save_button;
|
||||
|
||||
[GtkChild]
|
||||
private Gtk.ModelButton load_remote_button;
|
||||
|
||||
private GLib.SimpleActionGroup actions = new GLib.SimpleActionGroup();
|
||||
|
||||
|
||||
public ContactPopover(Gtk.Widget relative_to,
|
||||
Application.Contact contact,
|
||||
Geary.RFC822.MailboxAddress mailbox) {
|
||||
|
||||
this.relative_to = relative_to;
|
||||
this.contact = contact;
|
||||
this.mailbox = mailbox;
|
||||
|
||||
this.load_remote_button.role = CHECK;
|
||||
|
||||
this.actions.add_action_entries(ACTION_ENTRIES, this);
|
||||
insert_action_group(ACTION_GROUP, this.actions);
|
||||
|
||||
contact.changed.connect(this.on_contact_changed);
|
||||
update();
|
||||
}
|
||||
|
||||
public void add_section(GLib.MenuModel section,
|
||||
Gee.Map<string,GLib.Variant> values) {
|
||||
Gtk.Separator separator = new Gtk.Separator(Gtk.Orientation.HORIZONTAL);
|
||||
separator.show();
|
||||
this.container.add(separator);
|
||||
for (int i = 0; i < section.get_n_items(); i++) {
|
||||
GLib.MenuItem item = new MenuItem.from_model(section, i);
|
||||
string action_fq = (string) item.get_attribute_value(
|
||||
Menu.ATTRIBUTE_ACTION, VariantType.STRING
|
||||
);
|
||||
|
||||
string action_name = action_fq.substring(action_fq.index_of(".") + 1);
|
||||
|
||||
Gtk.ModelButton button = new Gtk.ModelButton();
|
||||
button.text = (string) item.get_attribute_value(
|
||||
Menu.ATTRIBUTE_LABEL, VariantType.STRING
|
||||
);
|
||||
button.action_name = (string) item.get_attribute_value(
|
||||
Menu.ATTRIBUTE_ACTION, VariantType.STRING
|
||||
);
|
||||
button.action_target = values[action_name];
|
||||
button.show();
|
||||
|
||||
this.container.add(button);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts loading the avatar for the message's sender.
|
||||
*/
|
||||
|
|
@ -121,20 +131,94 @@ public class Conversation.ContactPopover : Gtk.Popover {
|
|||
this.contact_address.hide();
|
||||
}
|
||||
|
||||
bool is_desktop = this.contact.is_desktop_contact;
|
||||
|
||||
bool starred = false;
|
||||
bool unstarred = false;
|
||||
if (this.contact.is_desktop_contact) {
|
||||
if (is_desktop) {
|
||||
starred = this.contact.is_favourite;
|
||||
unstarred = !this.contact.is_favourite;
|
||||
}
|
||||
this.starred_button.set_visible(starred);
|
||||
this.unstarred_button.set_visible(unstarred);
|
||||
|
||||
|
||||
this.open_button.set_visible(is_desktop);
|
||||
this.save_button.set_visible(!is_desktop);
|
||||
this.load_remote_button.set_visible(!is_desktop);
|
||||
|
||||
GLib.SimpleAction load_remote = (GLib.SimpleAction)
|
||||
actions.lookup_action(ACTION_LOAD_REMOTE);
|
||||
load_remote.set_state(
|
||||
new GLib.Variant.boolean(
|
||||
is_desktop || this.contact.load_remote_resources
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private async void set_load_remote_resources(bool enabled) {
|
||||
try {
|
||||
yield this.contact.set_remote_resource_loading(enabled, null);
|
||||
} catch (GLib.Error err) {
|
||||
debug("Failed to set load remote resources for contact %s:, %s",
|
||||
this.contact.to_string(), err.message);
|
||||
}
|
||||
}
|
||||
|
||||
private async void set_favourite(bool enabled) {
|
||||
try {
|
||||
yield this.contact.set_favourite(enabled, null);
|
||||
} catch (GLib.Error err) {
|
||||
debug("Failed to set enabled state for contact %s:, %s",
|
||||
this.contact.to_string(), err.message);
|
||||
}
|
||||
}
|
||||
|
||||
private void on_contact_changed() {
|
||||
update();
|
||||
}
|
||||
|
||||
private void on_copy_email() {
|
||||
Gtk.Clipboard clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD);
|
||||
clipboard.set_text(this.mailbox.to_full_display(), -1);
|
||||
clipboard.store();
|
||||
}
|
||||
|
||||
private void on_load_remote(GLib.SimpleAction action) {
|
||||
bool state = !action.get_state().get_boolean();
|
||||
this.set_load_remote_resources.begin(state);
|
||||
}
|
||||
|
||||
private void on_new_conversation() {
|
||||
MainWindow? main = this.get_toplevel() as MainWindow;
|
||||
if (main != null) {
|
||||
main.open_composer_for_mailbox(this.mailbox);
|
||||
}
|
||||
}
|
||||
|
||||
private void on_open() {
|
||||
|
||||
}
|
||||
|
||||
private void on_save() {
|
||||
|
||||
}
|
||||
|
||||
private void on_show_conversations() {
|
||||
MainWindow? main = this.get_toplevel() as MainWindow;
|
||||
if (main != null) {
|
||||
main.show_search_bar("from:%s".printf(this.mailbox.address));
|
||||
}
|
||||
}
|
||||
|
||||
private void on_star() {
|
||||
this.set_favourite.begin(true);
|
||||
}
|
||||
|
||||
private void on_unstar() {
|
||||
this.set_favourite.begin(false);
|
||||
}
|
||||
|
||||
[GtkCallback]
|
||||
private void after_closed() {
|
||||
GLib.Idle.add(() => {
|
||||
|
|
|
|||
|
|
@ -32,11 +32,6 @@ public class ConversationMessage : Gtk.Grid, Geary.BaseInterface {
|
|||
|
||||
private const int MAX_INLINE_IMAGE_MAJOR_DIM = 1024;
|
||||
|
||||
private const string ACTION_CONTACT_LOAD_IMAGES = "contact-load-images";
|
||||
private const string ACTION_CONTACT_OPEN = "contact-open";
|
||||
private const string ACTION_CONTACT_SAVE = "contact-save";
|
||||
private const string ACTION_CONTACT_SHOW_CONVERSATIONS =
|
||||
"contact-show-conversations";
|
||||
private const string ACTION_CONVERSATION_NEW = "conversation-new";
|
||||
private const string ACTION_COPY_EMAIL = "copy-email";
|
||||
private const string ACTION_COPY_LINK = "copy-link";
|
||||
|
|
@ -203,9 +198,6 @@ public class ConversationMessage : Gtk.Grid, Geary.BaseInterface {
|
|||
}
|
||||
|
||||
|
||||
private static GLib.VariantType MAILBOX_TYPE = new GLib.VariantType("(ss)");
|
||||
|
||||
|
||||
/** Contact for the primary originator, if any. */
|
||||
internal Application.Contact? primary_contact {
|
||||
get; private set;
|
||||
|
|
@ -305,8 +297,6 @@ public class ConversationMessage : Gtk.Grid, Geary.BaseInterface {
|
|||
private MenuModel context_menu_email;
|
||||
private MenuModel context_menu_image;
|
||||
private MenuModel context_menu_main;
|
||||
private MenuModel context_menu_known_contact;
|
||||
private MenuModel context_menu_unknown_contact;
|
||||
private MenuModel? context_menu_inspector = null;
|
||||
|
||||
// Address fields that can be search through
|
||||
|
|
@ -406,18 +396,7 @@ public class ConversationMessage : Gtk.Grid, Geary.BaseInterface {
|
|||
|
||||
// Actions
|
||||
|
||||
add_action(ACTION_CONTACT_LOAD_IMAGES, true, VariantType.BOOLEAN)
|
||||
// XXX
|
||||
;
|
||||
add_action(ACTION_CONTACT_OPEN, true, VariantType.STRING)
|
||||
// XXX
|
||||
;
|
||||
add_action(ACTION_CONTACT_SAVE, true, ConversationMessage.MAILBOX_TYPE)
|
||||
// XXX
|
||||
;
|
||||
add_action(ACTION_CONTACT_SHOW_CONVERSATIONS, true, VariantType.STRING)
|
||||
.activate.connect(on_contact_show_conversations);
|
||||
add_action(ACTION_CONVERSATION_NEW, true, ConversationMessage.MAILBOX_TYPE)
|
||||
add_action(ACTION_CONVERSATION_NEW, true, VariantType.STRING)
|
||||
.activate.connect(on_new_conversation);
|
||||
add_action(ACTION_COPY_EMAIL, true, VariantType.STRING)
|
||||
.activate.connect(on_copy_email_address);
|
||||
|
|
@ -447,12 +426,6 @@ public class ConversationMessage : Gtk.Grid, Geary.BaseInterface {
|
|||
context_menu_email = (MenuModel) builder.get_object("context_menu_email");
|
||||
context_menu_image = (MenuModel) builder.get_object("context_menu_image");
|
||||
context_menu_main = (MenuModel) builder.get_object("context_menu_main");
|
||||
this.context_menu_known_contact = (MenuModel) builder.get_object(
|
||||
"context_menu_known_contact"
|
||||
);
|
||||
this.context_menu_unknown_contact = (MenuModel) builder.get_object(
|
||||
"context_menu_unknown_contact"
|
||||
);
|
||||
if (Args.inspector) {
|
||||
context_menu_inspector =
|
||||
(MenuModel) builder.get_object("context_menu_inspector");
|
||||
|
|
@ -1080,17 +1053,6 @@ public class ConversationMessage : Gtk.Grid, Geary.BaseInterface {
|
|||
|
||||
Gee.Map<string,GLib.Variant> values =
|
||||
new Gee.HashMap<string,GLib.Variant>();
|
||||
|
||||
GLib.Variant mailbox_var = new GLib.Variant.tuple(
|
||||
new GLib.Variant[] {
|
||||
address.name ?? "",
|
||||
address.address
|
||||
});
|
||||
values[ACTION_CONTACT_OPEN] = "not yet defined";
|
||||
values[ACTION_CONTACT_SAVE] = mailbox_var;
|
||||
values[ACTION_CONTACT_SHOW_CONVERSATIONS] = address.address;
|
||||
values[ACTION_CONTACT_LOAD_IMAGES] = false;
|
||||
values[ACTION_CONVERSATION_NEW] = mailbox_var;
|
||||
values[ACTION_COPY_EMAIL] = address.to_full_display();
|
||||
|
||||
Conversation.ContactPopover popover = new Conversation.ContactPopover(
|
||||
|
|
@ -1099,13 +1061,6 @@ public class ConversationMessage : Gtk.Grid, Geary.BaseInterface {
|
|||
address
|
||||
);
|
||||
popover.load_avatar.begin();
|
||||
popover.add_section(this.context_menu_email, values);
|
||||
popover.add_section(
|
||||
address_child.contact.is_desktop_contact
|
||||
? this.context_menu_known_contact
|
||||
: this.context_menu_unknown_contact,
|
||||
values
|
||||
);
|
||||
popover.set_position(Gtk.PositionType.BOTTOM);
|
||||
popover.closed.connect(() => {
|
||||
address_child.unset_state_flags(Gtk.StateFlags.ACTIVE);
|
||||
|
|
@ -1245,34 +1200,28 @@ public class ConversationMessage : Gtk.Grid, Geary.BaseInterface {
|
|||
remote_images_infobar.hide();
|
||||
}
|
||||
|
||||
private void on_contact_show_conversations(Variant? param) {
|
||||
string email = param as string;
|
||||
MainWindow? main = this.get_toplevel() as MainWindow;
|
||||
if (main != null && email != null) {
|
||||
main.show_search_bar("from:%s".printf(email));
|
||||
}
|
||||
}
|
||||
|
||||
private void on_new_conversation(Variant? param) {
|
||||
MainWindow? main = this.get_toplevel() as MainWindow;
|
||||
if (main != null &&
|
||||
param.get_type().equal(ConversationMessage.MAILBOX_TYPE)) {
|
||||
string? name = (string) param.get_child_value(0);
|
||||
Geary.RFC822.MailboxAddress mailbox = new Geary.RFC822.MailboxAddress(
|
||||
Geary.String.is_empty_or_whitespace(name) ? null : name,
|
||||
(string) param.get_child_value(1)
|
||||
);
|
||||
|
||||
main.open_composer_for_mailbox(mailbox);
|
||||
}
|
||||
}
|
||||
|
||||
private void on_copy_link(Variant? param) {
|
||||
Gtk.Clipboard clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD);
|
||||
clipboard.set_text(param.get_string(), -1);
|
||||
clipboard.store();
|
||||
}
|
||||
|
||||
private void on_new_conversation(Variant? param) {
|
||||
string value = param.get_string();
|
||||
if (value.has_prefix(Geary.ComposedEmail.MAILTO_SCHEME)) {
|
||||
value = value.substring(Geary.ComposedEmail.MAILTO_SCHEME.length, -1);
|
||||
}
|
||||
|
||||
MainWindow? main = this.get_toplevel() as MainWindow;
|
||||
if (main != null &&
|
||||
Geary.RFC822.MailboxAddress.is_valid_address(value)) {
|
||||
Geary.RFC822.MailboxAddress mailbox = new Geary.RFC822.MailboxAddress(
|
||||
null, value
|
||||
);
|
||||
main.open_composer_for_mailbox(mailbox);
|
||||
}
|
||||
}
|
||||
|
||||
private void on_copy_email_address(Variant? param) {
|
||||
string value = param.get_string();
|
||||
if (value.has_prefix(Geary.ComposedEmail.MAILTO_SCHEME)) {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
<property name="can_focus">False</property>
|
||||
<signal name="closed" handler="after_closed" after="yes" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkGrid" id="container">
|
||||
<object class="GtkGrid">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">10</property>
|
||||
|
|
@ -14,7 +14,6 @@
|
|||
<property name="margin_top">10</property>
|
||||
<property name="margin_bottom">10</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="row_spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkGrid">
|
||||
<property name="visible">True</property>
|
||||
|
|
@ -27,7 +26,7 @@
|
|||
<property name="receives_default">True</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="action_name">msg.contact-star</property>
|
||||
<property name="action_name">con.star</property>
|
||||
<property name="relief">none</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
|
|
@ -48,7 +47,7 @@
|
|||
<property name="receives_default">True</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="action_name">msg.contact-star</property>
|
||||
<property name="action_name">con.unstar</property>
|
||||
<property name="relief">none</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
|
|
@ -123,6 +122,104 @@
|
|||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="action_name">con.new-conversation</property>
|
||||
<property name="text" translatable="yes">_New Conversation…</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="action_name">con.copy-email</property>
|
||||
<property name="text" translatable="yes">Copy Email _Address</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton" id="save_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="action_name">con.save</property>
|
||||
<property name="text" translatable="yes">Save in Contacts…</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">7</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="action_name">con.show-conversations</property>
|
||||
<property name="text" translatable="yes">Show Conversations</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton" id="open_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="action_name">con.open</property>
|
||||
<property name="text" translatable="yes">Open in Contacts</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">6</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton" id="load_remote_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="action_name">con.load-remote</property>
|
||||
<property name="text" translatable="yes">Always Load Remote Images</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">8</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<style>
|
||||
|
|
|
|||
|
|
@ -38,30 +38,6 @@
|
|||
<attribute name="action">msg.copy-selection</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section id="context_menu_known_contact">
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">Sho_w Conversations</attribute>
|
||||
<attribute name="action">msg.contact-show-conversations</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Open in Contacts…</attribute>
|
||||
<attribute name="action">msg.contact-save</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section id="context_menu_unknown_contact">
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">Sho_w Conversations</attribute>
|
||||
<attribute name="action">msg.contact-show-conversations</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">Save in Con_tacts…</attribute>
|
||||
<attribute name="action">msg.contact-save</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">Always Load Remote Images</attribute>
|
||||
<attribute name="action">msg.contact-load-images</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section id="context_menu_inspector">
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Inspect…</attribute>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue