Closes #6963 Search upgrade progress bar
This commit is contained in:
parent
463199a14e
commit
2e9403162e
11 changed files with 357 additions and 49 deletions
|
|
@ -45,6 +45,7 @@ engine/api/geary-folder-supports-remove.vala
|
|||
engine/api/geary-logging.vala
|
||||
engine/api/geary-named-flag.vala
|
||||
engine/api/geary-named-flags.vala
|
||||
engine/api/geary-progress-monitor.vala
|
||||
engine/api/geary-search-folder.vala
|
||||
engine/api/geary-service-provider.vala
|
||||
engine/api/geary-special-folder-type.vala
|
||||
|
|
@ -267,6 +268,7 @@ client/ui/folder-menu.vala
|
|||
client/ui/icon-factory.vala
|
||||
client/ui/main-toolbar.vala
|
||||
client/ui/main-window.vala
|
||||
client/ui/monitored-progress-bar.vala
|
||||
|
||||
client/util/util-date.vala
|
||||
client/util/util-email.vala
|
||||
|
|
|
|||
|
|
@ -77,6 +77,12 @@ along with Geary; if not, write to the Free Software Foundation, Inc.,
|
|||
|
||||
public Configuration config { get; private set; }
|
||||
|
||||
/**
|
||||
* Fired when the current account in the UI has changed.
|
||||
* TODO: This signal really belongs in the controller. See #7032 for the refactoring ticket.
|
||||
*/
|
||||
public signal void current_account_changed(Geary.Account? account);
|
||||
|
||||
private static GearyApplication _instance = null;
|
||||
|
||||
private GearyController? controller = null;
|
||||
|
|
@ -484,5 +490,9 @@ along with Geary; if not, write to the Free Software Foundation, Inc.,
|
|||
|
||||
return 0; // on error
|
||||
}
|
||||
|
||||
public void notify_current_account_changed(Geary.Account? account) {
|
||||
current_account_changed(account);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -327,8 +327,6 @@ public class GearyController {
|
|||
account.email_sent.connect(on_sent);
|
||||
|
||||
main_window.folder_list.set_user_folders_root_name(account, _("Labels"));
|
||||
|
||||
update_search_placeholder_text();
|
||||
}
|
||||
|
||||
public async void disconnect_account_async(Geary.Account account, Cancellable? cancellable = null) {
|
||||
|
|
@ -373,8 +371,6 @@ public class GearyController {
|
|||
} catch (Error e) {
|
||||
message("Error enumerating accounts: %s", e.message);
|
||||
}
|
||||
|
||||
update_search_placeholder_text();
|
||||
}
|
||||
|
||||
// Returns the number of open accounts.
|
||||
|
|
@ -398,7 +394,6 @@ public class GearyController {
|
|||
// by other utility methods
|
||||
private void update_ui() {
|
||||
update_tooltips();
|
||||
update_search_placeholder_text();
|
||||
Gtk.Action delete_message = GearyApplication.instance.actions.get_action(ACTION_DELETE_MESSAGE);
|
||||
if (current_folder is Geary.FolderSupport.Archive) {
|
||||
delete_message.label = ARCHIVE_MESSAGE_LABEL;
|
||||
|
|
@ -473,7 +468,10 @@ public class GearyController {
|
|||
debug("switching to %s", folder.to_string());
|
||||
|
||||
current_folder = folder;
|
||||
current_account = folder.account;
|
||||
if (current_account != folder.account) {
|
||||
current_account = folder.account;
|
||||
GearyApplication.instance.notify_current_account_changed(current_account);
|
||||
}
|
||||
|
||||
if (!(current_folder is Geary.SearchFolder))
|
||||
previous_non_search_folder = current_folder;
|
||||
|
|
@ -1492,11 +1490,5 @@ public class GearyController {
|
|||
|
||||
main_window.folder_list.set_search(folder);
|
||||
}
|
||||
|
||||
private void update_search_placeholder_text() {
|
||||
main_window.main_toolbar.set_search_placeholder_text(
|
||||
current_account == null || GearyApplication.instance.get_num_accounts() == 1 ?
|
||||
_("Search") : _("Search %s account").printf(current_account.information.nickname));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
// Draws the main toolbar.
|
||||
public class MainToolbar : Gtk.Box {
|
||||
private const string ICON_CLEAR_NAME = "edit-clear-symbolic";
|
||||
private const string DEFAULT_SEARCH_TEXT = _("Search");
|
||||
|
||||
private Gtk.Toolbar toolbar;
|
||||
public FolderMenu copy_folder_menu { get; private set; }
|
||||
|
|
@ -14,13 +15,18 @@ public class MainToolbar : Gtk.Box {
|
|||
|
||||
private GtkUtil.ToggleToolbarDropdown mark_menu_dropdown;
|
||||
private GtkUtil.ToggleToolbarDropdown app_menu_dropdown;
|
||||
private Gtk.ToolItem search_container;
|
||||
private Gtk.Entry search_entry;
|
||||
private Geary.ProgressMonitor? search_upgrade_progress_monitor = null;
|
||||
private MonitoredProgressBar search_upgrade_progress_bar = new MonitoredProgressBar();
|
||||
|
||||
public signal void search_text_changed(string search_text);
|
||||
|
||||
public MainToolbar() {
|
||||
Object(orientation: Gtk.Orientation.VERTICAL, spacing: 0);
|
||||
|
||||
|
||||
GearyApplication.instance.current_account_changed.connect(on_account_changed);
|
||||
|
||||
Gtk.Builder builder = GearyApplication.instance.create_builder("toolbar.glade");
|
||||
toolbar = builder.get_object("toolbar") as Gtk.Toolbar;
|
||||
|
||||
|
|
@ -61,6 +67,7 @@ public class MainToolbar : Gtk.Box {
|
|||
mark_menu_dropdown.attach(mark_menu_button);
|
||||
|
||||
// Search bar.
|
||||
search_container = (Gtk.ToolItem) builder.get_object("search_container");
|
||||
search_entry = (Gtk.Entry) builder.get_object("search_entry");
|
||||
search_entry.changed.connect(on_search_entry_changed);
|
||||
search_entry.icon_release.connect(on_search_entry_icon_release);
|
||||
|
|
@ -84,7 +91,11 @@ public class MainToolbar : Gtk.Box {
|
|||
|
||||
toolbar.get_style_context().add_class("primary-toolbar");
|
||||
|
||||
search_upgrade_progress_bar.show_text = true;
|
||||
search_upgrade_progress_bar.margin_top = search_upgrade_progress_bar.margin_bottom = 3;
|
||||
|
||||
add(toolbar);
|
||||
set_search_placeholder_text(DEFAULT_SEARCH_TEXT);
|
||||
}
|
||||
|
||||
private Gtk.ToolButton set_toolbutton_action(Gtk.Builder builder, string action) {
|
||||
|
|
@ -119,5 +130,41 @@ public class MainToolbar : Gtk.Box {
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void on_search_upgrade_start() {
|
||||
search_container.remove(search_container.get_child());
|
||||
search_container.add(search_upgrade_progress_bar);
|
||||
search_upgrade_progress_bar.show();
|
||||
}
|
||||
|
||||
private void on_search_upgrade_finished() {
|
||||
search_container.remove(search_container.get_child());
|
||||
search_container.add(search_entry);
|
||||
}
|
||||
|
||||
private void on_account_changed(Geary.Account? account) {
|
||||
on_search_upgrade_finished(); // Reset search box.
|
||||
|
||||
if (search_upgrade_progress_monitor != null) {
|
||||
search_upgrade_progress_monitor.start.disconnect(on_search_upgrade_start);
|
||||
search_upgrade_progress_monitor.finish.disconnect(on_search_upgrade_finished);
|
||||
search_upgrade_progress_monitor = null;
|
||||
}
|
||||
|
||||
if (account != null) {
|
||||
search_upgrade_progress_monitor = account.search_upgrade_monitor;
|
||||
search_upgrade_progress_bar.set_progress_monitor(search_upgrade_progress_monitor);
|
||||
|
||||
search_upgrade_progress_monitor.start.connect(on_search_upgrade_start);
|
||||
search_upgrade_progress_monitor.finish.connect(on_search_upgrade_finished);
|
||||
if (search_upgrade_progress_monitor.is_in_progress)
|
||||
on_search_upgrade_start(); // Remove search box, we're already in progress.
|
||||
}
|
||||
|
||||
search_upgrade_progress_bar.text = _("Indexing %s account").printf(account.information.nickname);
|
||||
|
||||
set_search_placeholder_text(account == null || GearyApplication.instance.get_num_accounts() == 1 ?
|
||||
DEFAULT_SEARCH_TEXT : _("Search %s account").printf(account.information.nickname));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
34
src/client/ui/monitored-progress-bar.vala
Normal file
34
src/client/ui/monitored-progress-bar.vala
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/* Copyright 2013 Yorba Foundation
|
||||
*
|
||||
* This software is licensed under the GNU Lesser General Public License
|
||||
* (version 2.1 or later). See the COPYING file in this distribution.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Adapts a progress bar to automatically display progress of a Geary.ProgressMonitor.
|
||||
*/
|
||||
public class MonitoredProgressBar : Gtk.ProgressBar {
|
||||
private Geary.ProgressMonitor? monitor = null;
|
||||
|
||||
public void set_progress_monitor(Geary.ProgressMonitor monitor) {
|
||||
this.monitor = monitor;
|
||||
monitor.start.connect(on_start);
|
||||
monitor.finish.connect(on_finish);
|
||||
monitor.update.connect(on_update);
|
||||
|
||||
fraction = monitor.progress;
|
||||
}
|
||||
|
||||
private void on_start() {
|
||||
fraction = 0.0;
|
||||
}
|
||||
|
||||
private void on_update(double total_progress, double change, Geary.ProgressMonitor monitor) {
|
||||
fraction = total_progress;
|
||||
}
|
||||
|
||||
private void on_finish() {
|
||||
fraction = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
public abstract class Geary.AbstractAccount : BaseObject, Geary.Account {
|
||||
public Geary.AccountInformation information { get; protected set; }
|
||||
public Geary.ProgressMonitor search_upgrade_monitor { get; protected set; }
|
||||
|
||||
private string name;
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ public interface Geary.Account : BaseObject {
|
|||
|
||||
public abstract Geary.AccountInformation information { get; protected set; }
|
||||
|
||||
public abstract Geary.ProgressMonitor search_upgrade_monitor { get; protected set; }
|
||||
|
||||
public signal void opened();
|
||||
|
||||
public signal void closed();
|
||||
|
|
|
|||
205
src/engine/api/geary-progress-monitor.vala
Normal file
205
src/engine/api/geary-progress-monitor.vala
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
/* Copyright 2013 Yorba Foundation
|
||||
*
|
||||
* This software is licensed under the GNU Lesser General Public License
|
||||
* (version 2.1 or later). See the COPYING file in this distribution.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Type of progress monitor.
|
||||
*/
|
||||
public enum Geary.ProgressType {
|
||||
AGGREGATED,
|
||||
ACTIVITY,
|
||||
DB_UPGRADE,
|
||||
SEARCH_INDEX
|
||||
}
|
||||
|
||||
/**
|
||||
* Base class for progress monitoring.
|
||||
*/
|
||||
public abstract class Geary.ProgressMonitor : BaseObject {
|
||||
public const double MIN = 0.0;
|
||||
public const double MAX = 1.0;
|
||||
|
||||
public double progress { get; protected set; default = MIN; }
|
||||
public bool is_in_progress { get; protected set; default = false; }
|
||||
public Geary.ProgressType progress_type { get; protected set; }
|
||||
|
||||
/**
|
||||
* The start signal is fired just before progress begins. It will not fire again until after
|
||||
* {@link finish} has fired.
|
||||
*/
|
||||
public signal void start();
|
||||
|
||||
/**
|
||||
* Notifies the user of existing progress. Note that monitor refers to the monitor that
|
||||
* invoked this update, which may not be the same as this object.
|
||||
*/
|
||||
public signal void update(double total_progress, double change, Geary.ProgressMonitor monitor);
|
||||
|
||||
/**
|
||||
* Finish is fired when progress has completed.
|
||||
*/
|
||||
public signal void finish();
|
||||
|
||||
/**
|
||||
* Users must call this before calling update. Must not be called again until
|
||||
* {@link notify_finish()} has been called.
|
||||
*/
|
||||
public virtual void notify_start() {
|
||||
assert(!is_in_progress);
|
||||
progress = MIN;
|
||||
is_in_progress = true;
|
||||
|
||||
start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Users must call this when progress has completed. Must only be called after {@link notify_start()}
|
||||
*/
|
||||
public virtual void notify_finish() {
|
||||
assert(is_in_progress);
|
||||
is_in_progress = false;
|
||||
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Captures the progress of a single action.
|
||||
*/
|
||||
public class Geary.SimpleProgressMonitor : Geary.ProgressMonitor {
|
||||
/**
|
||||
* Creates a new progress monitor of the given type.
|
||||
*/
|
||||
public SimpleProgressMonitor(ProgressType type) {
|
||||
this.progress_type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the progress by the given value. Must be between {@link MIN} and {@link MAX}. Must only
|
||||
* be called after {@link notify_start()} and before {@link notify_finish()}
|
||||
*/
|
||||
public void increment(double value) {
|
||||
assert(value > 0);
|
||||
assert(is_in_progress);
|
||||
|
||||
if (progress + value > MAX)
|
||||
value = MAX - progress;
|
||||
|
||||
progress += value;
|
||||
update(progress, value, this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Monitors the progress of a countable interval. Note that min and max are inclusive.
|
||||
*/
|
||||
public class Geary.IntervalProgressMonitor : Geary.ProgressMonitor {
|
||||
private int min_interval;
|
||||
private int max_interval;
|
||||
private int current = 0;
|
||||
|
||||
/**
|
||||
* Creates a new progress monitor with the given interval range.
|
||||
*/
|
||||
public IntervalProgressMonitor(ProgressType type, int min, int max) {
|
||||
this.progress_type = type;
|
||||
this.min_interval = min;
|
||||
this.max_interval = max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new interval. Must not be done while in progress.
|
||||
*/
|
||||
public void set_interval(int min, int max) {
|
||||
assert(!is_in_progress);
|
||||
this.min_interval = min;
|
||||
this.max_interval = max;
|
||||
}
|
||||
|
||||
public override void notify_start() {
|
||||
current = 0;
|
||||
base.notify_start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Incrememts the progress
|
||||
*/
|
||||
public void increment(int count = 1) {
|
||||
assert(is_in_progress);
|
||||
assert(count + progress >= min_interval);
|
||||
assert(count + progress <= max_interval);
|
||||
|
||||
current += count;
|
||||
|
||||
double new_progress = (1.0 * current - min_interval) / (1.0 * max_interval - min_interval);
|
||||
double change = new_progress - progress;
|
||||
progress = new_progress;
|
||||
|
||||
update(progress, change, this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Captures progress of multiple actions by composing
|
||||
* many progress monitors into one.
|
||||
*/
|
||||
public class Geary.AggregateProgressMonitor : Geary.ProgressMonitor {
|
||||
private Gee.HashSet<Geary.ProgressMonitor> monitors = new Gee.HashSet<Geary.ProgressMonitor>();
|
||||
|
||||
/**
|
||||
* Creates an aggregate progress monitor.
|
||||
*/
|
||||
public AggregateProgressMonitor() {
|
||||
this.progress_type = Geary.ProgressType.AGGREGATED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new progress monitor to this aggregate.
|
||||
*/
|
||||
public void add(Geary.ProgressMonitor pm) {
|
||||
// TODO: Handle the case where we add a new monitor during progress.
|
||||
monitors.add(pm);
|
||||
pm.start.connect(on_start);
|
||||
pm.update.connect(on_update);
|
||||
pm.finish.connect(on_finish);
|
||||
}
|
||||
|
||||
private void on_start() {
|
||||
if (!is_in_progress)
|
||||
notify_start();
|
||||
}
|
||||
|
||||
private void on_update(double total_progress, double change, ProgressMonitor monitor) {
|
||||
assert(is_in_progress);
|
||||
|
||||
double updated_progress = MIN;
|
||||
foreach(Geary.ProgressMonitor pm in monitors)
|
||||
updated_progress += pm.progress;
|
||||
|
||||
updated_progress /= monitors.size;
|
||||
|
||||
double aggregated_change = updated_progress - progress;
|
||||
if (aggregated_change < 0)
|
||||
aggregated_change = 0;
|
||||
|
||||
progress += updated_progress;
|
||||
|
||||
if (progress > MAX)
|
||||
progress = MAX;
|
||||
|
||||
update(progress, aggregated_change, monitor);
|
||||
}
|
||||
|
||||
private void on_finish() {
|
||||
// Only signal completion once all progress monitors are complete.
|
||||
foreach(Geary.ProgressMonitor pm in monitors) {
|
||||
if (pm.is_in_progress)
|
||||
return;
|
||||
}
|
||||
|
||||
notify_finish();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -26,6 +26,8 @@ private class Geary.ImapDB.Account : BaseObject {
|
|||
new Gee.HashMap<Geary.FolderPath, FolderReference>();
|
||||
private Cancellable? background_cancellable = null;
|
||||
public ImapEngine.ContactStore contact_store { get; private set; }
|
||||
public IntervalProgressMonitor search_index_monitor { get; private set;
|
||||
default = new IntervalProgressMonitor(ProgressType.SEARCH_INDEX, 0, 0); }
|
||||
|
||||
public Account(Geary.AccountInformation account_information) {
|
||||
this.account_information = account_information;
|
||||
|
|
@ -698,15 +700,35 @@ private class Geary.ImapDB.Account : BaseObject {
|
|||
debug("Deleted %d duplicate folders", count);
|
||||
}
|
||||
|
||||
public async int get_email_count_async(Cancellable? cancellable) throws Error {
|
||||
check_open();
|
||||
|
||||
int count = 0;
|
||||
yield db.exec_transaction_async(Db.TransactionType.RO, (cx) => {
|
||||
count = do_get_email_count(cx, cancellable);
|
||||
|
||||
return Db.TransactionOutcome.SUCCESS;
|
||||
}, cancellable);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
private async void populate_search_table_async(Cancellable? cancellable) {
|
||||
// TODO: send processing signal upwards.
|
||||
debug("Populating search table");
|
||||
try {
|
||||
int total = yield get_email_count_async(cancellable);
|
||||
search_index_monitor.set_interval(0, total);
|
||||
search_index_monitor.notify_start();
|
||||
|
||||
while (!yield populate_search_table_batch_async(100, cancellable))
|
||||
;
|
||||
} catch (Error e) {
|
||||
debug("Error populating search table: %s", e.message);
|
||||
}
|
||||
|
||||
if (search_index_monitor.is_in_progress)
|
||||
search_index_monitor.notify_finish();
|
||||
|
||||
debug("Done populating search table");
|
||||
}
|
||||
|
||||
|
|
@ -749,6 +771,8 @@ private class Geary.ImapDB.Account : BaseObject {
|
|||
}
|
||||
|
||||
++count;
|
||||
search_index_monitor.increment();
|
||||
|
||||
result.next(cancellable);
|
||||
}
|
||||
|
||||
|
|
@ -925,5 +949,17 @@ private class Geary.ImapDB.Account : BaseObject {
|
|||
|
||||
stmt.exec(cancellable);
|
||||
}
|
||||
|
||||
private int do_get_email_count(Db.Connection cx, Cancellable? cancellable)
|
||||
throws Error {
|
||||
Db.Statement stmt = cx.prepare(
|
||||
"SELECT COUNT(*) FROM MessageTable");
|
||||
|
||||
Db.Result results = stmt.exec(cancellable);
|
||||
if (results.finished)
|
||||
return 0;
|
||||
|
||||
return results.int_at(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.AbstractAccount {
|
|||
this.remote.login_failed.connect(on_login_failed);
|
||||
this.remote.email_sent.connect(on_email_sent);
|
||||
|
||||
search_upgrade_monitor = local.search_index_monitor;
|
||||
|
||||
if (inbox_path == null) {
|
||||
inbox_path = new Geary.FolderRoot(Imap.Account.INBOX_NAME, Imap.Account.ASSUMED_SEPARATOR,
|
||||
Imap.Folder.CASE_SENSITIVE);
|
||||
|
|
|
|||
|
|
@ -6,11 +6,9 @@
|
|||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="GearyNewMessage">
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes" comments="Button for creating a new email message">Start new conversation (Ctrl+N, N)</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="is_important">True</property>
|
||||
<property name="label" translatable="yes">New Message</property>
|
||||
<property name="use_underline">True</property>
|
||||
|
|
@ -18,15 +16,13 @@
|
|||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorToolItem" id="separator">
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
|
|
@ -34,11 +30,9 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="GearyReplyToMessage">
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Reply to last message in conversation (Ctrl+R, R)</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="is_important">True</property>
|
||||
<property name="label" translatable="yes">Reply</property>
|
||||
<property name="use_underline">True</property>
|
||||
|
|
@ -46,16 +40,14 @@
|
|||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="GearyReplyAllMessage">
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Reply to everyone in last message of conversation (Ctrl+Shift+R, Shift+R)</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="is_important">True</property>
|
||||
<property name="label" translatable="yes">Reply All</property>
|
||||
<property name="use_underline">True</property>
|
||||
|
|
@ -63,16 +55,14 @@
|
|||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="GearyForwardMessage">
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Send copy of last message in conversation (Ctrl+L, F)</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="is_important">True</property>
|
||||
<property name="label" translatable="yes">Forward</property>
|
||||
<property name="use_underline">True</property>
|
||||
|
|
@ -80,15 +70,13 @@
|
|||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorToolItem" id="separator2">
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
|
|
@ -96,52 +84,44 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleToolButton" id="GearyMarkAsMenuButton">
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="label" translatable="yes">Mark</property>
|
||||
<property name="icon_name">edit-mark</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleToolButton" id="GearyCopyMenuButton">
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="label" translatable="yes">Label as</property>
|
||||
<property name="icon_name">tag-new</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleToolButton" id="GearyMoveMenuButton">
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="label" translatable="yes">Move to</property>
|
||||
<property name="icon_name">mail-move</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorToolItem" id="separator3">
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
|
|
@ -156,15 +136,13 @@
|
|||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolItem" id="filler">
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
|
|
@ -177,12 +155,13 @@
|
|||
<object class="GtkToolItem" id="search_container">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<child>
|
||||
<object class="GtkEntry" id="search_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="invisible_char">•</property>
|
||||
<property name="width_chars">35</property>
|
||||
<property name="primary_icon_name">edit-find-symbolic</property>
|
||||
<property name="secondary_icon_name">edit-clear-symbolic</property>
|
||||
<property name="primary_icon_sensitive">False</property>
|
||||
|
|
@ -190,23 +169,21 @@
|
|||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleToolButton" id="GearyGearMenuButton">
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_action_appearance">False</property>
|
||||
<property name="label" translatable="yes">Menu</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="icon_name">application-menu</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue