177 if(e->type != GDK_BUTTON_PRESS || e->button != GDK_BUTTON_SECONDARY)
return FALSE;
178 const char *uri = gtk_label_get_current_uri(GTK_LABEL(label));
181 if(!uri || !*uri) uri = (
const char *)g_object_get_data(G_OBJECT(label),
"own-hash");
182 if(!uri || !*uri)
return FALSE;
185 GtkWidget *mi = gtk_menu_item_new_with_label(_(
"Search for this hash"));
186 g_object_set_data_full(G_OBJECT(mi),
"uri", g_strdup(uri), g_free);
188 gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
189 gtk_widget_show_all(menu);
190 gtk_menu_popup_at_pointer(GTK_MENU(menu), (GdkEvent *)e);
234 GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
235 GtkWidget *hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4);
237 GtkWidget *toggle = gtk_toggle_button_new();
238 gtk_button_set_relief(GTK_BUTTON(toggle), GTK_RELIEF_NONE);
239 gtk_widget_set_focus_on_click(toggle,
FALSE);
240 GtkWidget *arrow = gtk_image_new_from_icon_name(expanded ?
"pan-down-symbolic" :
"pan-end-symbolic",
241 GTK_ICON_SIZE_BUTTON);
242 gtk_container_add(GTK_CONTAINER(toggle), arrow);
245 gtk_label_set_markup(GTK_LABEL(header), header_markup);
246 gtk_label_set_xalign(GTK_LABEL(header), 0.0);
249 GtkWidget *revealer = gtk_revealer_new();
250 gtk_revealer_set_reveal_child(GTK_REVEALER(revealer), expanded);
251 if(body) gtk_container_add(GTK_CONTAINER(revealer), body);
253 g_object_set_data(G_OBJECT(toggle),
"revealer", revealer);
254 g_object_set_data(G_OBJECT(toggle),
"arrow", arrow);
255 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle), expanded);
256 g_signal_connect(toggle,
"toggled", G_CALLBACK(
_on_toggle), NULL);
258 gtk_box_pack_start(GTK_BOX(hbox), toggle,
FALSE,
FALSE, 0);
259 gtk_box_pack_start(GTK_BOX(hbox), header,
TRUE,
TRUE, 0);
260 gtk_box_pack_start(GTK_BOX(vbox), hbox,
FALSE,
FALSE, 0);
261 gtk_box_pack_start(GTK_BOX(vbox), revealer,
FALSE,
FALSE, 0);
263 g_object_set_data(G_OBJECT(vbox),
"toggle", toggle);
264 g_object_set_data(G_OBJECT(vbox),
"header", header);
297 GtkWidget *detail = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4);
298 gtk_widget_set_margin_start(detail, 28);
299 gtk_widget_set_margin_bottom(detail, 6);
301 if(links && links->len)
303 GString *ls = g_string_new(NULL);
304 for(guint
i = 0;
i < links->len;
i++)
308 g_string_append_printf(ls,
"%s%s → <a href=\"%s\"><tt>%s</tt></a>",
i ?
" " :
"", lk->
label,
313 gtk_label_set_markup(GTK_LABEL(
lw), ls->str);
314 gtk_label_set_xalign(GTK_LABEL(
lw), 0.0);
316 gtk_box_pack_start(GTK_BOX(detail),
lw,
FALSE,
FALSE, 0);
317 g_string_free(ls,
TRUE);
321 gchar *escaped = g_markup_escape_text(pretty, -1);
322 gchar *mono = g_strdup_printf(
"<tt>%s</tt>", escaped);
324 gtk_label_set_markup(GTK_LABEL(body), mono);
325 gtk_label_set_xalign(GTK_LABEL(body), 0.0);
326 gtk_label_set_selectable(GTK_LABEL(body),
TRUE);
327 gtk_box_pack_start(GTK_BOX(detail), body,
FALSE,
FALSE, 0);
477 gchar *
t = g_markup_printf_escaped(
"<b>%s</b>", title);
478 gtk_label_set_markup(GTK_LABEL(hdr),
t);
479 gtk_label_set_xalign(GTK_LABEL(hdr), 0.0);
480 gtk_widget_set_margin_top(hdr, 8);
482 gtk_box_pack_start(GTK_BOX(box), hdr,
FALSE,
FALSE, 0);
484 const double frac =
max ? CLAMP((
double)cur / (
double)
max, 0.0, 1.0) : 0.0;
486 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(bar), frac);
487 gtk_progress_bar_set_show_text(GTK_PROGRESS_BAR(bar),
TRUE);
488 gchar *txt = g_strdup_printf(
"%.1f / %.1f MiB (%.0f%%)", cur / 1048576.0,
max / 1048576.0, frac * 100.0);
489 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(bar), txt);
491 gtk_box_pack_start(GTK_BOX(box), bar,
FALSE,
FALSE, 0);
500 gtk_label_set_markup(GTK_LABEL(lbl), markup);
501 gtk_label_set_xalign(GTK_LABEL(lbl), 0.0);
504 if(trailing && *trailing)
506 GtkWidget *
row = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8);
507 gtk_widget_set_margin_start(
row, 12);
508 gtk_box_pack_start(GTK_BOX(
row), lbl,
TRUE,
TRUE, 0);
510 gtk_label_set_markup(GTK_LABEL(tl), trailing);
511 gtk_label_set_xalign(GTK_LABEL(tl), 1.0);
517 gtk_widget_set_margin_start(lbl, 12);
518 gtk_box_pack_start(GTK_BOX(box), lbl,
FALSE,
FALSE, 0);
790 gtk_window_present(GTK_WINDOW(
_g.window));
794 _g.decl_map = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
795 _g.group_map = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
_group_free);
797 _g.window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
798 gtk_window_set_title(GTK_WINDOW(
_g.window), _(
"Event supervisor"));
799 gtk_window_set_default_size(GTK_WINDOW(
_g.window), 1000, 640);
801 g_signal_connect(
_g.window,
"destroy", G_CALLBACK(
_on_destroy), NULL);
803 GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
804 gtk_container_set_border_width(GTK_CONTAINER(vbox), 8);
805 gtk_container_add(GTK_CONTAINER(
_g.window), vbox);
808 GtkWidget *bar = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8);
809 gtk_box_pack_start(GTK_BOX(vbox), bar,
FALSE,
FALSE, 0);
811 GtkWidget *record = gtk_check_button_new_with_label(_(
"Record"));
812 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(record),
TRUE);
815 gtk_box_pack_start(GTK_BOX(bar), record,
FALSE,
FALSE, 0);
817 GtkWidget *refresh = gtk_button_new_with_label(_(
"Refresh"));
818 g_signal_connect(refresh,
"clicked", G_CALLBACK(
_on_refresh), NULL);
819 gtk_box_pack_start(GTK_BOX(bar), refresh,
FALSE,
FALSE, 0);
821 GtkWidget *clear = gtk_button_new_with_label(_(
"Clear"));
822 g_signal_connect(clear,
"clicked", G_CALLBACK(
_on_clear), NULL);
823 gtk_box_pack_start(GTK_BOX(bar), clear,
FALSE,
FALSE, 0);
825 gtk_box_pack_start(GTK_BOX(bar), gtk_label_new(_(
"Group by")),
FALSE,
FALSE, 0);
826 _g.groupby = gtk_combo_box_text_new();
827 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(
_g.groupby),
"domain");
828 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(
_g.groupby),
"thread");
829 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(
_g.groupby),
"op");
830 gtk_combo_box_set_active(GTK_COMBO_BOX(
_g.groupby), 0);
832 gtk_box_pack_start(GTK_BOX(bar),
_g.groupby,
FALSE,
FALSE, 0);
835 _g.search_entry = gtk_search_entry_new();
836 gtk_entry_set_placeholder_text(GTK_ENTRY(
_g.search_entry), _(
"search hash or text…"));
837 gtk_widget_set_size_request(
_g.search_entry, 220, -1);
839 gtk_box_pack_end(GTK_BOX(bar),
_g.search_entry,
FALSE,
FALSE, 0);
841 _g.count_label = gtk_label_new(
"");
842 gtk_box_pack_end(GTK_BOX(bar),
_g.count_label,
FALSE,
FALSE, 0);
845 _g.notebook = gtk_notebook_new();
847 gtk_box_pack_start(GTK_BOX(vbox),
_g.notebook,
TRUE,
TRUE, 0);
849 _g.timeline_list = gtk_list_box_new();
850 gtk_list_box_set_selection_mode(GTK_LIST_BOX(
_g.timeline_list), GTK_SELECTION_SINGLE);
851 _g.timeline_scroll = gtk_scrolled_window_new(NULL, NULL);
852 gtk_container_add(GTK_CONTAINER(
_g.timeline_scroll),
_g.timeline_list);
853 _g.page_timeline = gtk_notebook_append_page(GTK_NOTEBOOK(
_g.notebook),
_g.timeline_scroll,
854 gtk_label_new(_(
"Timeline")));
856 _g.grouped_list = gtk_list_box_new();
857 gtk_list_box_set_selection_mode(GTK_LIST_BOX(
_g.grouped_list), GTK_SELECTION_NONE);
858 GtkWidget *sw2 = gtk_scrolled_window_new(NULL, NULL);
859 gtk_container_add(GTK_CONTAINER(sw2),
_g.grouped_list);
860 _g.page_grouped = gtk_notebook_append_page(GTK_NOTEBOOK(
_g.notebook), sw2, gtk_label_new(_(
"Grouped")));
862 _g.mem_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 2);
863 gtk_container_set_border_width(GTK_CONTAINER(
_g.mem_box), 6);
864 GtkWidget *sw3 = gtk_scrolled_window_new(NULL, NULL);
865 gtk_container_add(GTK_CONTAINER(sw3),
_g.mem_box);
866 _g.page_memory = gtk_notebook_append_page(GTK_NOTEBOOK(
_g.notebook), sw3, gtk_label_new(_(
"Memory")));
868 _g.search_list = gtk_list_box_new();
869 gtk_list_box_set_selection_mode(GTK_LIST_BOX(
_g.search_list), GTK_SELECTION_NONE);
870 GtkWidget *sw4 = gtk_scrolled_window_new(NULL, NULL);
871 gtk_container_add(GTK_CONTAINER(sw4),
_g.search_list);
872 _g.page_search = gtk_notebook_append_page(GTK_NOTEBOOK(
_g.notebook), sw4, gtk_label_new(_(
"Search")));
875 GList *
pages = gtk_container_get_children(GTK_CONTAINER(
_g.notebook));
876 for(GList *l =
pages; l; l = l->next)
877 gtk_container_child_set(GTK_CONTAINER(
_g.notebook), GTK_WIDGET(l->data),
"tab-expand",
TRUE,
878 "tab-fill",
TRUE, NULL);
881 gtk_widget_show_all(
_g.window);