Components.InspectorLogView: Add sidebar listing accounts & log domains
Adds a sidebar that displays accounts and logging domains, grouped into accounts, internal domains, and external domains.
This commit is contained in:
parent
d5e94a257d
commit
4b097b4542
3 changed files with 180 additions and 28 deletions
|
|
@ -15,6 +15,37 @@ public class Components.InspectorLogView : Gtk.Grid {
|
|||
private const int COL_MESSAGE = 0;
|
||||
|
||||
|
||||
private class SidebarRow : Gtk.ListBoxRow {
|
||||
|
||||
public enum RowType { ACCOUNT, INTERNAL_DOMAIN, EXTERNAL_DOMAIN }
|
||||
|
||||
|
||||
public RowType row_type { get; private set; }
|
||||
public string id { get; private set; }
|
||||
|
||||
internal Gtk.CheckButton enabled = new Gtk.CheckButton();
|
||||
|
||||
|
||||
public SidebarRow(RowType type, string label, string id) {
|
||||
this.row_type = type;
|
||||
this.id = id;
|
||||
|
||||
var label_widget = new Gtk.Label(label);
|
||||
label_widget.hexpand = true;
|
||||
label_widget.xalign = 0.0f;
|
||||
|
||||
var grid = new Gtk.Grid();
|
||||
grid.orientation = HORIZONTAL;
|
||||
grid.add(label_widget);
|
||||
grid.add(this.enabled);
|
||||
add(grid);
|
||||
|
||||
show_all();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/** Determines if the log record search user interface is shown. */
|
||||
public bool search_mode_enabled {
|
||||
get { return this.search_bar.search_mode_enabled; }
|
||||
|
|
@ -27,6 +58,9 @@ public class Components.InspectorLogView : Gtk.Grid {
|
|||
[GtkChild]
|
||||
private Gtk.SearchEntry search_entry { get; private set; }
|
||||
|
||||
[GtkChild]
|
||||
private Gtk.ListBox sidebar;
|
||||
|
||||
[GtkChild]
|
||||
private Gtk.ScrolledWindow logs_scroller;
|
||||
|
||||
|
|
@ -49,6 +83,10 @@ public class Components.InspectorLogView : Gtk.Grid {
|
|||
|
||||
private bool autoscroll = true;
|
||||
|
||||
private Gee.Set<string> seen_accounts = new Gee.HashSet<string>();
|
||||
|
||||
private Gee.Set<string> seen_domains = new Gee.HashSet<string>();
|
||||
|
||||
private Geary.AccountInformation? account_filter = null;
|
||||
|
||||
private bool listener_installed = false;
|
||||
|
|
@ -68,6 +106,7 @@ public class Components.InspectorLogView : Gtk.Grid {
|
|||
);
|
||||
|
||||
this.search_bar.connect_entry(this.search_entry);
|
||||
this.sidebar.set_header_func(this.sidebar_header_update);
|
||||
this.account_filter = filter_by;
|
||||
}
|
||||
|
||||
|
|
@ -210,8 +249,56 @@ public class Components.InspectorLogView : Gtk.Grid {
|
|||
}
|
||||
}
|
||||
|
||||
private void add_account(Geary.AccountInformation account) {
|
||||
if (this.seen_accounts.add(account.id)) {
|
||||
var row = new SidebarRow(ACCOUNT, account.display_name, account.id);
|
||||
for (int i = 0;; i++) {
|
||||
var existing = this.sidebar.get_row_at_index(i) as SidebarRow;
|
||||
if (existing == null ||
|
||||
existing.row_type != ACCOUNT ||
|
||||
existing.id.collate(row.id) > 0) {
|
||||
this.sidebar.insert(row, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void add_domain(string? domain) {
|
||||
var safe_domain = domain ?? "(none)";
|
||||
if (this.seen_domains.add(domain)) {
|
||||
var type = (
|
||||
safe_domain.down().has_prefix(Geary.Logging.DOMAIN.down())
|
||||
? SidebarRow.RowType.INTERNAL_DOMAIN
|
||||
: SidebarRow.RowType.EXTERNAL_DOMAIN
|
||||
);
|
||||
var row = new SidebarRow(type, safe_domain, safe_domain);
|
||||
int i = 0;
|
||||
for (;; i++) {
|
||||
var existing = this.sidebar.get_row_at_index(i) as SidebarRow;
|
||||
if (existing == null ||
|
||||
existing.row_type == type) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (;; i++) {
|
||||
var existing = this.sidebar.get_row_at_index(i) as SidebarRow;
|
||||
if (existing == null ||
|
||||
existing.row_type != type ||
|
||||
existing.id.collate(row.id) > 0) {
|
||||
this.sidebar.insert(row, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private inline bool should_append(Geary.Logging.Record record) {
|
||||
record.fill_well_known_sources();
|
||||
if (record.account != null) {
|
||||
add_account(record.account.information);
|
||||
}
|
||||
add_domain(record.domain);
|
||||
return (
|
||||
record.account == null ||
|
||||
this.account_filter == null ||
|
||||
|
|
@ -239,6 +326,18 @@ public class Components.InspectorLogView : Gtk.Grid {
|
|||
}
|
||||
}
|
||||
|
||||
private void sidebar_header_update(Gtk.ListBoxRow current_row,
|
||||
Gtk.ListBoxRow? previous_row) {
|
||||
Gtk.Widget? header = null;
|
||||
var current = current_row as SidebarRow;
|
||||
var previous = previous_row as SidebarRow;
|
||||
if (current != null &&
|
||||
(previous == null || current.row_type != previous.row_type)) {
|
||||
header = new Gtk.Separator(HORIZONTAL);
|
||||
}
|
||||
current_row.set_header(header);
|
||||
}
|
||||
|
||||
[GtkCallback]
|
||||
private void on_logs_size_allocate() {
|
||||
if (this.autoscroll) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.22.1 -->
|
||||
<!-- Generated with glade 3.22.2 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.20"/>
|
||||
<requires lib="libhandy" version="0.0"/>
|
||||
|
|
@ -33,45 +33,85 @@
|
|||
<signal name="search-changed" handler="on_logs_search_changed" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="logs_scroller">
|
||||
<object class="GtkGrid">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="logs_view">
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="model">logs_store</property>
|
||||
<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>
|
||||
<signal name="changed" handler="on_logs_selection_changed" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<property name="hscrollbar_policy">never</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="log_column">
|
||||
<property name="title">column</property>
|
||||
<object class="GtkViewport">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="log_renderer"/>
|
||||
<attributes>
|
||||
<attribute name="text">0</attribute>
|
||||
</attributes>
|
||||
<object class="GtkListBox" id="sidebar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">False</property>
|
||||
<property name="selection_mode">none</property>
|
||||
<style>
|
||||
<class name="sidebar"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="logs_scroller">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="logs_view">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="model">logs_store</property>
|
||||
<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>
|
||||
<signal name="changed" handler="on_logs_selection_changed" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="log_column">
|
||||
<property name="title">column</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="log_renderer"/>
|
||||
<attributes>
|
||||
<attribute name="text">0</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
|
|
@ -79,5 +119,8 @@
|
|||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<style>
|
||||
<class name="geary-inspector-log-viewer"/>
|
||||
</style>
|
||||
</template>
|
||||
</interface>
|
||||
|
|
|
|||
10
ui/geary.css
10
ui/geary.css
|
|
@ -327,3 +327,13 @@ treeview.sidebar:drop(active).into {
|
|||
border-top-style: solid;
|
||||
border-bottom-style: solid;
|
||||
}
|
||||
|
||||
/* Inspector */
|
||||
|
||||
.geary-inspector-log-viewer .sidebar row > grid {
|
||||
padding: 0 6px;
|
||||
}
|
||||
|
||||
.geary-inspector-log-viewer .sidebar row > grid * {
|
||||
margin: 4px;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue