Merge branch 'wip/279-convo-list-context-labels' into 'mainline'
Conversation list context menu fixes Closes #279 See merge request GNOME/geary!272
This commit is contained in:
commit
dd1b816958
5 changed files with 76 additions and 31 deletions
|
|
@ -279,7 +279,6 @@ public class Application.Controller : Geary.BaseObject {
|
|||
// Create the main window (must be done after creating actions.)
|
||||
main_window = new MainWindow(this.application);
|
||||
main_window.retry_service_problem.connect(on_retry_service_problem);
|
||||
main_window.on_shift_key.connect(on_shift_key);
|
||||
main_window.notify["has-toplevel-focus"].connect(on_has_toplevel_focus);
|
||||
|
||||
setup_actions();
|
||||
|
|
@ -1049,9 +1048,12 @@ public class Application.Controller : Geary.BaseObject {
|
|||
// Update widgets and such to match capabilities of the current folder ... sensitivity is handled
|
||||
// by other utility methods
|
||||
private void update_ui() {
|
||||
main_window.main_toolbar.selected_conversations = this.selected_conversations.size;
|
||||
main_window.main_toolbar.show_trash_button = current_folder_supports_trash() ||
|
||||
!(current_folder is Geary.FolderSupport.Remove);
|
||||
this.main_window.main_toolbar.selected_conversations =
|
||||
this.selected_conversations.size;
|
||||
this.main_window.main_toolbar.update_trash_button(
|
||||
!this.main_window.is_shift_down &&
|
||||
current_folder_supports_trash()
|
||||
);
|
||||
}
|
||||
|
||||
private void on_folder_selected(Geary.Folder? folder) {
|
||||
|
|
@ -1424,15 +1426,6 @@ public class Application.Controller : Geary.BaseObject {
|
|||
return sender.cancel_exit();
|
||||
}
|
||||
|
||||
private void on_shift_key(bool pressed) {
|
||||
if (main_window != null && main_window.main_toolbar != null
|
||||
&& current_account != null && current_folder != null) {
|
||||
main_window.main_toolbar.show_trash_button =
|
||||
(!pressed && current_folder_supports_trash()) ||
|
||||
!(current_folder is Geary.FolderSupport.Remove);
|
||||
}
|
||||
}
|
||||
|
||||
// this signal does not necessarily indicate that the application previously didn't have
|
||||
// focus and now it does
|
||||
private void on_has_toplevel_focus() {
|
||||
|
|
|
|||
|
|
@ -24,8 +24,7 @@ public class MainToolbar : Gtk.Box {
|
|||
public FolderPopover move_folder_menu { get; private set; default = new FolderPopover(); }
|
||||
// How many conversations are selected right now. Should automatically be updated.
|
||||
public int selected_conversations { get; set; }
|
||||
// Whether to show the trash or the delete button
|
||||
public bool show_trash_button { get; set; default = true; }
|
||||
|
||||
|
||||
// Folder header elements
|
||||
[GtkChild]
|
||||
|
|
@ -52,6 +51,8 @@ public class MainToolbar : Gtk.Box {
|
|||
[GtkChild]
|
||||
private Gtk.ToggleButton find_button;
|
||||
|
||||
private bool show_trash_button = true;
|
||||
|
||||
// Load these at construction time
|
||||
private Gtk.Image trash_image = new Gtk.Image.from_icon_name("user-trash-symbolic", Gtk.IconSize.MENU);
|
||||
private Gtk.Image delete_image = new Gtk.Image.from_icon_name("edit-delete-symbolic", Gtk.IconSize.MENU);
|
||||
|
|
@ -84,7 +85,6 @@ public class MainToolbar : Gtk.Box {
|
|||
|
||||
// Setup conversation header elements
|
||||
this.notify["selected-conversations"].connect(() => update_conversation_buttons());
|
||||
this.notify["show-trash-button"].connect(() => update_conversation_buttons());
|
||||
this.mark_message_button.popover = new Gtk.Popover.from_model(null, mark_menu);
|
||||
this.copy_message_button.popover = copy_folder_menu;
|
||||
this.move_message_button.popover = move_folder_menu;
|
||||
|
|
@ -116,6 +116,11 @@ public class MainToolbar : Gtk.Box {
|
|||
conversation_header.show();
|
||||
}
|
||||
|
||||
public void update_trash_button(bool show_trash) {
|
||||
this.show_trash_button = show_trash;
|
||||
update_conversation_buttons();
|
||||
}
|
||||
|
||||
private void set_window_buttons() {
|
||||
string[] buttons = Gtk.Settings.get_default().gtk_decoration_layout.split(":");
|
||||
this.show_close_button_left = this.show_close_button;
|
||||
|
|
@ -146,8 +151,8 @@ public class MainToolbar : Gtk.Box {
|
|||
this.selected_conversations
|
||||
);
|
||||
this.archive_button.tooltip_text = ngettext(
|
||||
"Archive conversation (A)",
|
||||
"Archive conversations (A)",
|
||||
"Archive conversation",
|
||||
"Archive conversations",
|
||||
this.selected_conversations
|
||||
);
|
||||
|
||||
|
|
@ -155,16 +160,16 @@ public class MainToolbar : Gtk.Box {
|
|||
this.trash_delete_button.action_name = "win."+Application.Controller.ACTION_TRASH_CONVERSATION;
|
||||
this.trash_delete_button.image = trash_image;
|
||||
this.trash_delete_button.tooltip_text = ngettext(
|
||||
"Move conversation to Trash (Delete, Backspace)",
|
||||
"Move conversations to Trash (Delete, Backspace)",
|
||||
"Move conversation to Trash",
|
||||
"Move conversations to Trash",
|
||||
this.selected_conversations
|
||||
);
|
||||
} else {
|
||||
this.trash_delete_button.action_name = "win."+Application.Controller.ACTION_DELETE_CONVERSATION;
|
||||
this.trash_delete_button.image = delete_image;
|
||||
this.trash_delete_button.tooltip_text = ngettext(
|
||||
"Delete conversation (Shift+Delete)",
|
||||
"Delete conversations (Shift+Delete)",
|
||||
"Delete conversation",
|
||||
"Delete conversations",
|
||||
this.selected_conversations
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,9 @@ public class MainWindow : Gtk.ApplicationWindow, Geary.BaseInterface {
|
|||
get; private set; default = null;
|
||||
}
|
||||
|
||||
/** Specifies if the Shift key is currently being held. */
|
||||
public bool is_shift_down { get; private set; default = false; }
|
||||
|
||||
private Geary.AggregateProgressMonitor progress_monitor = new Geary.AggregateProgressMonitor();
|
||||
|
||||
// Used to save/load the window state between sessions.
|
||||
|
|
@ -727,7 +730,12 @@ public class MainWindow : Gtk.ApplicationWindow, Geary.BaseInterface {
|
|||
Gtk.Widget? focus = get_focus();
|
||||
if (focus == null ||
|
||||
(!(focus is Gtk.Entry) && !(focus is ComposerWebView))) {
|
||||
on_shift_key(event.type == Gdk.EventType.KEY_PRESS);
|
||||
this.is_shift_down = (event.type == Gdk.EventType.KEY_PRESS);
|
||||
this.main_toolbar.update_trash_button(
|
||||
!this.is_shift_down &&
|
||||
current_folder_supports_trash()
|
||||
);
|
||||
on_shift_key(this.is_shift_down);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -736,6 +744,16 @@ public class MainWindow : Gtk.ApplicationWindow, Geary.BaseInterface {
|
|||
return (SimpleAction) lookup_action(name);
|
||||
}
|
||||
|
||||
private bool current_folder_supports_trash() {
|
||||
Geary.Folder? current = this.current_folder;
|
||||
return (
|
||||
current != null &&
|
||||
current.special_folder_type != TRASH &&
|
||||
!current_folder.properties.is_local_only &&
|
||||
(current_folder as Geary.FolderSupport.Move) != null
|
||||
);
|
||||
}
|
||||
|
||||
private void on_scan_completed(Geary.App.ConversationMonitor monitor) {
|
||||
// Done scanning. Check if we have enough messages to fill
|
||||
// the conversation list; if not, trigger a load_more();
|
||||
|
|
|
|||
|
|
@ -318,8 +318,28 @@ public class ConversationListView : Gtk.TreeView, Geary.BaseInterface {
|
|||
if (event.button == 3 && event.type == Gdk.EventType.BUTTON_PRESS) {
|
||||
Geary.App.Conversation conversation = get_model().get_conversation_at_path(path);
|
||||
|
||||
Menu context_menu_model = new Menu();
|
||||
context_menu_model.append(_("Delete conversation"), "win."+Application.Controller.ACTION_DELETE_CONVERSATION);
|
||||
GLib.Menu context_menu_model = new GLib.Menu();
|
||||
if (!this.main_window.is_shift_down) {
|
||||
context_menu_model.append(
|
||||
/// Translators: Context menu item
|
||||
ngettext(
|
||||
"Move conversation to _Trash",
|
||||
"Move conversations to _Trash",
|
||||
this.selected.size
|
||||
),
|
||||
"win." + Application.Controller.ACTION_ARCHIVE_CONVERSATION
|
||||
);
|
||||
} else {
|
||||
context_menu_model.append(
|
||||
/// Translators: Context menu item
|
||||
ngettext(
|
||||
"_Delete conversation",
|
||||
"_Delete conversations",
|
||||
this.selected.size
|
||||
),
|
||||
"win." + Application.Controller.ACTION_DELETE_CONVERSATION
|
||||
);
|
||||
}
|
||||
|
||||
if (conversation.is_unread())
|
||||
context_menu_model.append(_("Mark as _Read"), "win."+Application.Controller.ACTION_MARK_AS_READ);
|
||||
|
|
@ -338,9 +358,18 @@ public class ConversationListView : Gtk.TreeView, Geary.BaseInterface {
|
|||
actions_section.append(_("_Forward"), "win."+Application.Controller.ACTION_FORWARD_MESSAGE);
|
||||
context_menu_model.append_section(null, actions_section);
|
||||
|
||||
Gtk.Menu context_menu = new Gtk.Menu.from_model(context_menu_model);
|
||||
context_menu.insert_action_group("win", this.main_window);
|
||||
context_menu.popup_at_pointer(event);
|
||||
// Use a popover rather than a regular context menu since
|
||||
// the latter grabs the event queue, so the MainWindow
|
||||
// will not receive events if the user releases Shift,
|
||||
// making the trash/delete header bar state wrong.
|
||||
Gtk.Popover context_menu = new Gtk.Popover.from_model(
|
||||
this, context_menu_model
|
||||
);
|
||||
Gdk.Rectangle dest = Gdk.Rectangle();
|
||||
dest.x = (int) event.x;
|
||||
dest.y = (int) event.y;
|
||||
context_menu.set_pointing_to(dest);
|
||||
context_menu.popup();
|
||||
|
||||
// When the conversation under the mouse is selected, stop event propagation
|
||||
return get_selection().path_is_selected(path);
|
||||
|
|
|
|||
|
|
@ -46,15 +46,15 @@
|
|||
<section id="email_menu_trash">
|
||||
<item>
|
||||
<!-- Translators: Menu item to move a single, specific message
|
||||
to the trash -->
|
||||
<attribute name="label" translatable="yes">_Trash</attribute>
|
||||
to the trash folder -->
|
||||
<attribute name="label" translatable="yes">Move message to _Trash</attribute>
|
||||
<attribute name="action">eml.trash_msg</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section id="email_menu_delete">
|
||||
<item>
|
||||
<!-- Translators: Menu item to delete a single, specific message -->
|
||||
<attribute name="label" translatable="yes">_Delete…</attribute>
|
||||
<attribute name="label" translatable="yes">_Delete message…</attribute>
|
||||
<attribute name="action">eml.delete_msg</attribute>
|
||||
</item>
|
||||
</section>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue