Append new log records to the inspector and scroll to them

This commit is contained in:
Michael Gratton 2019-04-07 11:32:38 +10:00 committed by Michael James Gratton
parent fc119ebb78
commit 6dc8b278f0
3 changed files with 62 additions and 16 deletions

View file

@ -36,6 +36,9 @@ public class Components.Inspector : Gtk.Window {
[GtkChild]
private Gtk.SearchEntry search_entry;
[GtkChild]
private Gtk.ScrolledWindow logs_scroller;
[GtkChild]
private Gtk.TreeView logs_view;
@ -58,6 +61,8 @@ public class Components.Inspector : Gtk.Window {
private string details;
private bool autoscroll = true;
public Inspector(GearyApplication app) {
this.title = this.header_bar.title = _("Inspector");
@ -81,15 +86,14 @@ public class Components.Inspector : Gtk.Window {
}
this.details = details.str;
// Log a marker for when the inspector was opened
debug("---- 8< ---- %s ---- 8< ----", this.header_bar.title);
enable_log_updates(true);
Gtk.ListStore logs_store = this.logs_store;
Geary.Logging.Record? logs = Geary.Logging.get_logs();
int index = 0;
while (logs != null) {
Gtk.TreeIter iter;
logs_store.append(out iter);
logs_store.insert(out iter, index++);
logs_store.set_value(iter, COL_MESSAGE, logs.format());
logs = logs.get_next();
}
@ -117,6 +121,13 @@ public class Components.Inspector : Gtk.Window {
this.logs_view.set_model(this.logs_filter);
}
public override void destroy() {
// Don't use enable_log_updates() here because we don't want a
// marker logged.
Geary.Logging.set_log_listener(null);
base.destroy();
}
public override bool key_press_event(Gdk.EventKey event) {
bool ret = this.search_bar.handle_event(event);
if (ret == Gdk.EVENT_PROPAGATE) {
@ -125,6 +136,16 @@ public class Components.Inspector : Gtk.Window {
return ret;
}
private void enable_log_updates(bool enabled) {
// Log a marker it indicate when it was toggled
debug("---- 8< ---- %s ---- 8< ----", this.header_bar.title);
if (enabled) {
Geary.Logging.set_log_listener(this.on_log_record);
} else {
Geary.Logging.set_log_listener(null);
}
}
private async void save(string path,
GLib.Cancellable? cancellable)
throws GLib.Error {
@ -167,11 +188,22 @@ public class Components.Inspector : Gtk.Window {
this.search_button.set_visible(logs_visible);
}
private void update_scrollbar() {
Gtk.Adjustment adj = this.logs_scroller.get_vadjustment();
adj.set_value(adj.upper - adj.page_size);
}
private void update_logs_filter() {
this.logs_filter_terms = this.search_entry.text.split(" ");
this.logs_filter.refilter();
}
private void append_record(Geary.Logging.Record record) {
Gtk.TreeIter inserted_iter;
this.logs_store.append(out inserted_iter);
this.logs_store.set_value(inserted_iter, COL_MESSAGE, record.format());
}
[GtkCallback]
private void on_visible_child_changed() {
update_ui();
@ -240,6 +272,13 @@ public class Components.Inspector : Gtk.Window {
this.search_bar.set_search_mode(!this.search_bar.get_search_mode());
}
[GtkCallback]
private void on_logs_size_allocate() {
if (this.autoscroll) {
update_scrollbar();
}
}
[GtkCallback]
private void on_logs_selection_changed() {
update_ui();
@ -250,9 +289,16 @@ public class Components.Inspector : Gtk.Window {
update_logs_filter();
}
[GtkCallback]
private void on_destroy() {
destroy();
private void on_log_record(Geary.Logging.Record record) {
if (GLib.MainContext.default() ==
GLib.MainContext.get_thread_default()) {
append_record(record);
} else {
GLib.Idle.add(() => {
append_record(record);
return GLib.Source.REMOVE;
});
}
}
}

View file

@ -95,9 +95,9 @@ private class Geary.ImapDB.Attachment : Geary.Attachment {
save_file(part, attachments_dir, cancellable);
update_db(cx, cancellable);
} catch (Error err) {
// Don't honour the cancellable here, we need to delete
// it.
this.delete(cx, cancellable);
// Don't honour the cancellable here, it needs to be
// deleted
this.delete(cx, null);
throw err;
}
}
@ -161,10 +161,8 @@ private class Geary.ImapDB.Attachment : Geary.Attachment {
// create directory, but don't throw exception if already exists
try {
target.get_parent().make_directory_with_parents(cancellable);
} catch (IOError ioe) {
// fall through if already exists
if (!(ioe is IOError.EXISTS))
throw ioe;
} catch (IOError.EXISTS err) {
// All good
}
// Delete any existing file now since we might not be creating

View file

@ -18,7 +18,6 @@
<property name="can_focus">False</property>
<property name="default_width">750</property>
<property name="default_height">500</property>
<signal name="destroy" handler="on_destroy" swapped="no"/>
<child type="titlebar">
<object class="GtkHeaderBar" id="header_bar">
<property name="visible">True</property>
@ -50,6 +49,8 @@
<object class="GtkButton" id="save_as_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes"
comments="Tooltip for inspector button">Save logs and details to a file</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="on_save_as_clicked" swapped="no"/>
<child>
@ -69,13 +70,13 @@
<object class="GtkButton" id="copy_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes" comments="Tooltip for inspector button">Copy selected rows</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="on_copy_clicked" swapped="no"/>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="tooltip_text" translatable="yes" comments="Tooltip for inspector button">Copy selected rows</property>
<property name="icon_name">edit-copy-symbolic</property>
</object>
</child>
@ -119,7 +120,7 @@
</packing>
</child>
<child>
<object class="GtkScrolledWindow">
<object class="GtkScrolledWindow" id="logs_scroller">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="vexpand">True</property>
@ -132,6 +133,7 @@
<property name="headers_visible">False</property>
<property name="enable_search">False</property>
<property name="show_expanders">False</property>
<signal name="size-allocate" handler="on_logs_size_allocate" swapped="no"/>
<child internal-child="selection">
<object class="GtkTreeSelection">
<property name="mode">multiple</property>