Skip to content

Commit

Permalink
Improve move menu and make it searchable (#916)
Browse files Browse the repository at this point in the history
Co-authored-by: Ryan Kornheisl <ryan@skarva.tech>
  • Loading branch information
leolost2605 and zeebok authored Jul 8, 2023
1 parent 5548587 commit a568a34
Show file tree
Hide file tree
Showing 4 changed files with 181 additions and 36 deletions.
102 changes: 102 additions & 0 deletions src/MessageList/FolderPopover/FolderPopover.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* SPDX-License-Identifier: GPL-3.0-or-later
* SPDX-FileCopyrightText: 2017-2023 elementary, Inc. (https://elementary.io)
*
* Authored by: Leonhard Kargl <leo.kargl@proton.me>
*/

public class Mail.FolderPopover : Gtk.Popover {
private Gtk.SearchEntry search_entry;
private Gtk.ListBox list_box;

construct {
search_entry = new Gtk.SearchEntry () {
margin_top = 3,
margin_bottom = 3,
margin_start = 3,
margin_end = 3
};

list_box = new Gtk.ListBox () {
activate_on_single_click = true
};
list_box.set_sort_func (sort_func);
list_box.set_filter_func (filter_func);

var scrolled_window = new Gtk.ScrolledWindow (null, null) {
child = list_box,
hexpand = true,
vexpand = true,
margin_bottom = 3,
hscrollbar_policy = NEVER
};

var box = new Gtk.Box (VERTICAL, 0);
box.add (search_entry);
box.add (new Gtk.Separator (HORIZONTAL));
box.add (scrolled_window);
box.show_all ();

width_request = 250;
height_request = 350;
child = box;

search_entry.search_changed.connect (() => list_box.invalidate_filter ());

list_box.row_activated.connect ((row) => {
if (row is FolderRow) {
var folder_row = (FolderRow)row;

popdown ();
((MainWindow)get_toplevel ()).activate_action (MainWindow.ACTION_MOVE, row.folder_info.full_name);
}
});
}

public void set_store (Camel.Store store) {
foreach (var child in list_box.get_children ()) {
child.destroy ();
}

store.get_folder_info.begin (null, Camel.StoreGetFolderInfoFlags.RECURSIVE, GLib.Priority.DEFAULT, null, (obj, res) => {
try {
var folder_info = store.get_folder_info.end (res);
update (folder_info, 0, store);
} catch (Error e) {
critical (e.message);
}
});
}

private void update (Camel.FolderInfo top, int depth, Camel.Store store) {
var folder_info = top;
while (folder_info != null) {
list_box.add (new FolderRow (depth, folder_info, store));

if (folder_info.child != null) {
update (folder_info.child, depth + 1, store);
}
folder_info = folder_info.next;
}
}

private int sort_func (Gtk.ListBoxRow row1, Gtk.ListBoxRow row2) {
if (row1 is FolderRow && row2 is FolderRow) {
var folder_row1 = (FolderRow) row1;
var folder_row2 = (FolderRow) row2;

return folder_row1.pos - folder_row2.pos;
}

return 0;
}

private bool filter_func (Gtk.ListBoxRow row) {
if (row is FolderRow) {
var folder_row = (FolderRow)row;
return search_entry.text.down ().strip () in folder_row.folder_info.display_name.down ();
}

return true;
}
}
72 changes: 72 additions & 0 deletions src/MessageList/FolderPopover/FolderRow.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* SPDX-License-Identifier: GPL-3.0-or-later
* SPDX-FileCopyrightText: 2017-2023 elementary, Inc. (https://elementary.io)
*
* Authored by: Leonhard Kargl <leo.kargl@proton.me>
*/

public class Mail.FolderRow : Gtk.ListBoxRow {
public int depth { get; construct; } //Currently not used
public Camel.FolderInfo folder_info { get; construct; }
public Camel.Store store { get; construct; }
public int pos { get; construct; }

public FolderRow (int depth, Camel.FolderInfo folder_info, Camel.Store store) {
Object (depth: depth, folder_info: folder_info, store: store);
}

construct {
var icon = new Gtk.Image.from_icon_name ("folder", MENU) {
margin_end = 3
};

var full_folder_info_flags = Utils.get_full_folder_info_flags (store, folder_info);
switch (full_folder_info_flags & Camel.FOLDER_TYPE_MASK) {
case Camel.FolderInfoFlags.TYPE_INBOX:
icon.set_from_icon_name ("mail-inbox", MENU);
pos = 1;
break;
case Camel.FolderInfoFlags.TYPE_DRAFTS:
icon.set_from_icon_name ("mail-drafts", MENU);
pos = 2;
break;
case Camel.FolderInfoFlags.TYPE_OUTBOX:
icon.set_from_icon_name ("mail-outbox", MENU);
pos = 3;
break;
case Camel.FolderInfoFlags.TYPE_SENT:
icon.set_from_icon_name ("mail-sent", MENU);
pos = 4;
break;
case Camel.FolderInfoFlags.TYPE_ARCHIVE:
icon.set_from_icon_name ("mail-archive", MENU);
pos = 5;
break;
case Camel.FolderInfoFlags.TYPE_TRASH:
icon.set_from_icon_name (folder_info.total == 0 ? "user-trash" : "user-trash-full", MENU);
pos = 6;
break;
case Camel.FolderInfoFlags.TYPE_JUNK:
icon.set_from_icon_name ("edit-flag", MENU);
pos = 7;
break;
default:
icon.set_from_icon_name ("folder", MENU);
pos = 8;
break;
}

var box = new Gtk.Box (HORIZONTAL, 0) {
margin_top = 3,
margin_bottom = 3,
margin_start = 12,
margin_end = 12
};

box.add (icon);
box.add (new Gtk.Label (folder_info.display_name));

child = box;
show_all ();
}
}
41 changes: 5 additions & 36 deletions src/MessageList/MessageList.vala
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ public class Mail.MessageList : Gtk.Box {
public signal void hovering_over_link (string? label, string? uri);
public Hdy.HeaderBar headerbar { get; private set; }

private Menu move_menu;
private Gtk.MenuButton move_button;
private FolderPopover folder_popover;
private Gtk.ListBox list_box;
private Gtk.ScrolledWindow scrolled_window;
private Gee.HashMap<string, MessageListItem> messages;
Expand Down Expand Up @@ -85,14 +84,13 @@ public class Mail.MessageList : Gtk.Box {
tooltip_text = _("Mark Conversation")
};

move_menu = new Menu ();
folder_popover = new FolderPopover ();

move_button = new Gtk.MenuButton () {
var move_button = new Gtk.MenuButton () {
action_name = MainWindow.ACTION_PREFIX + MainWindow.ACTION_MODIFY,
image = new Gtk.Image.from_icon_name ("folder", Gtk.IconSize.LARGE_TOOLBAR),
tooltip_text = _("Move Conversation to…"),
menu_model = move_menu,
use_popover = false
popover = folder_popover
};

var archive_button = new Gtk.Button.from_icon_name ("mail-archive", Gtk.IconSize.LARGE_TOOLBAR) {
Expand Down Expand Up @@ -157,27 +155,6 @@ public class Mail.MessageList : Gtk.Box {
add (scrolled_window);
}

public void update_move_menu (Camel.FolderInfo top, int depth) {
/* Hackish way of indenting subfolders */
var builder = new StringBuilder ();
for (int i = 0; i < depth; i++) {
builder.append (" ");
}

var folder_info = top;
while (folder_info != null) {
move_menu.append (
builder.str + folder_info.display_name,
Action.print_detailed_name (MainWindow.ACTION_PREFIX + MainWindow.ACTION_MOVE, folder_info.full_name)
);

if (folder_info.child != null) {
update_move_menu (folder_info.child, depth + 1);
}
folder_info = folder_info.next;
}
}

public void set_conversation (Camel.FolderThreadNode? node) {
/*
* Prevent the user from interacting with the message thread while it
Expand All @@ -203,15 +180,7 @@ public class Mail.MessageList : Gtk.Box {
can_move_thread (true);

var store = node.message.summary.folder.parent_store;
store.get_folder_info.begin (null, Camel.StoreGetFolderInfoFlags.RECURSIVE, GLib.Priority.DEFAULT, null, (obj, res) => {
try {
var folder_info = store.get_folder_info.end (res);
move_menu.remove_all ();
update_move_menu (folder_info, 0);
} catch (Error e) {
critical (e.message);
}
});
folder_popover.set_store (store);

var item = new MessageListItem (node.message);
list_box.add (item);
Expand Down
2 changes: 2 additions & 0 deletions src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ vala_files = files(
'FoldersView/GroupedFolderSourceItem.vala',
'FoldersView/SessionSourceItem.vala',
'MessageList/AttachmentButton.vala',
'MessageList/FolderPopover/FolderPopover.vala',
'MessageList/FolderPopover/FolderRow.vala',
'MessageList/MessageList.vala',
'MessageList/MessageListItem.vala',
'SourceList/CellRendererBadge.vala',
Expand Down

0 comments on commit a568a34

Please sign in to comment.