Plugins.FolderContext: Add support for showing folder info bars

Add Plugin.InfoBar to allow plugins to describe an info bar, add
methods to FolderContext to allow adding and removing them when
folders are displayed and implement them. Add a InfoBarStack to the
MainWindow for displaying folder info bars.
This commit is contained in:
Michael Gratton 2020-03-18 18:57:14 +11:00 committed by Michael James Gratton
parent c8dd0c94e7
commit 0e7d30f8cb
7 changed files with 126 additions and 0 deletions

View file

@ -96,6 +96,7 @@ src/client/plugin/plugin-error.vala
src/client/plugin/plugin-folder-extension.vala
src/client/plugin/plugin-folder-store.vala
src/client/plugin/plugin-folder.vala
src/client/plugin/plugin-info-bar.vala
src/client/plugin/plugin-notification-extension.vala
src/client/plugin/plugin-plugin-base.vala
src/client/plugin/plugin-trusted-extension.vala

View file

@ -12,6 +12,21 @@ internal class Application.FolderContext :
Geary.BaseObject, Plugin.FolderContext {
private class PluginInfoBar : Components.InfoBar {
private Plugin.InfoBar plugin;
public PluginInfoBar(Plugin.InfoBar plugin) {
base(plugin.status, plugin.description);
this.show_close_button = plugin.show_close_button;
this.plugin = plugin;
}
}
private unowned Client application;
private FolderStoreFactory folders_factory;
private Plugin.FolderStore folders;
@ -29,6 +44,35 @@ internal class Application.FolderContext :
return this.folders;
}
public void add_folder_info_bar(Plugin.Folder selected,
Plugin.InfoBar infobar,
uint priority) {
Geary.Folder? folder = this.folders_factory.get_engine_folder(selected);
if (folder != null) {
foreach (MainWindow main in this.application.get_main_windows()) {
if (main.selected_folder == folder) {
main.conversation_list_info_bars.add(
new PluginInfoBar(infobar)
);
}
}
}
}
public void remove_folder_info_bar(Plugin.Folder selected,
Plugin.InfoBar infobar) {
Geary.Folder? folder = this.folders_factory.get_engine_folder(selected);
if (folder != null) {
foreach (MainWindow main in this.application.get_main_windows()) {
if (main.selected_folder == folder) {
main.conversation_list_info_bars.remove(
new PluginInfoBar(infobar)
);
}
}
}
}
internal void destroy() {
this.folders_factory.destroy_folder_store(this.folders);
}

View file

@ -285,6 +285,11 @@ public class Application.MainWindow :
public SearchBar search_bar { get; private set; }
public ConversationListView conversation_list_view { get; private set; }
public ConversationViewer conversation_viewer { get; private set; }
public Components.InfoBarStack conversation_list_info_bars {
get; private set; default = new Components.InfoBarStack.exclusive();
}
public StatusBar status_bar { get; private set; default = new StatusBar(); }
private Controller controller;
@ -686,6 +691,8 @@ public class Application.MainWindow :
this.conversation_list_view.set_model(null);
}
this.conversation_list_info_bars.remove_all();
// With everything disposed of, update existing window
// state
@ -1214,6 +1221,9 @@ public class Application.MainWindow :
this.folder_list_scrolled.add(this.folder_list);
// Conversation list
this.conversation_box.pack_start(
this.conversation_list_info_bars, false, false, 0
);
this.conversation_list_view = new ConversationListView(
this.application.config
);

View file

@ -105,6 +105,7 @@ geary_client_vala_sources = files(
'plugin/plugin-folder-extension.vala',
'plugin/plugin-folder-store.vala',
'plugin/plugin-folder.vala',
'plugin/plugin-info-bar.vala',
'plugin/plugin-notification-extension.vala',
'plugin/plugin-plugin-base.vala',
'plugin/plugin-trusted-extension.vala',

View file

@ -50,4 +50,29 @@ public interface Plugin.FolderContext : Geary.BaseObject {
public abstract async FolderStore get_folders()
throws Error.PERMISSION_DENIED;
/**
* Adds an info bar to a folder, if selected.
*
* The info bar will be shown for the given folder if it is
* currently selected in any main window, which can be determined
* by connecting to the {@link folder_selected} signal. Further,
* if multiple info bars are added for the same folder, only the
* one with a higher priority will be shown. If that is closed or
* removed, the second highest will be shown, and so on. Once the
* selected folder changes, the info bars will be automatically
* removed.
*/
public abstract void add_folder_info_bar(Folder selected,
InfoBar infobar,
uint priority);
/**
* Removes an info bar from a folder, if selected.
*
* Removes the info bar from the given folder if it is currently
* selected in any main window.
*/
public abstract void remove_folder_info_bar(Folder selected,
InfoBar infobar);
}

View file

@ -0,0 +1,44 @@
/*
* Copyright © 2020 Michael Gratton <mike@vee.net>
*
* This software is licensed under the GNU Lesser General Public License
* (version 2.1 or later). See the COPYING file in this distribution.
*/
/**
* Enables plugins to report ongoing status messages.
*
* The info bar supports two text descriptions, a short (approximately
* 20 charters at most) status message, and a possibly longer
* explanation of what is happening.
*/
public class Plugin.InfoBar : Geary.BaseObject {
/**
* A short, human-readable status message.
*
* This should ideally be less than 20 characters long.
*/
public string status { get; private set; }
/**
* An optional, longer human-readable explanation of the status.
*
* This provides additional information and context for {@link
* status}.
*/
public string? description { get; private set; }
/** Determines if a close button is displayed by the info bar. */
public bool show_close_button { get; set; default = false; }
/** Constructs a new info bar with the given status. */
public InfoBar(string status,
string? description = null) {
this.status = status;
this.description = description;
}
}

View file

@ -96,6 +96,7 @@
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>