[sysprof/wip/chergert/compare] wip: cost change calculation
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [sysprof/wip/chergert/compare] wip: cost change calculation
- Date: Sun, 4 Dec 2016 08:16:04 +0000 (UTC)
commit 50903553e2313feb4e329dd6a8d9a179d79e057d
Author: Christian Hergert <chergert redhat com>
Date: Sun Dec 4 00:15:09 2016 -0800
wip: cost change calculation
.gitignore | 1 +
Makefile.am | 1 +
lib/resources/ui/sp-callgraph-view.ui | 12 +++
lib/sp-callgraph-profile.c | 34 +++++--
lib/sp-callgraph-profile.h | 2 +
lib/sp-callgraph-view.c | 164 +++++++++++++++++++++++++++++----
lib/sp-callgraph-view.h | 2 +
lib/sp-cell-renderer-percent.c | 57 +++++++++++-
lib/sp-cell-renderer-percent.h | 13 ++-
src/resources/ui/sp-window.ui | 14 +++
src/sp-window.c | 161 +++++++++++++++++++++++++++-----
11 files changed, 401 insertions(+), 60 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index 3a11aad..bada439 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,6 +25,7 @@
/TAGS
/aclocal.m4
/autom4te.cache
+/build
/build-aux
/config
/config.cache
diff --git a/Makefile.am b/Makefile.am
index 3c8802c..bc7a60e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -35,6 +35,7 @@ GITIGNOREFILES = \
ABOUT-NLS \
aclocal.m4 \
build-aux \
+ build \
ChangeLog \
config \
config.h.in \
diff --git a/lib/resources/ui/sp-callgraph-view.ui b/lib/resources/ui/sp-callgraph-view.ui
index 67cb120..d6e11ab 100644
--- a/lib/resources/ui/sp-callgraph-view.ui
+++ b/lib/resources/ui/sp-callgraph-view.ui
@@ -149,6 +149,18 @@
</object>
</child>
<child>
+ <object class="GtkTreeViewColumn" id="change_column">
+ <property name="expand">false</property>
+ <property name="title" translatable="yes">Change</property>
+ <property name="visible">false</property>
+ <child>
+ <object class="SpCellRendererPercent" id="change_cell">
+ <property name="ignore-zero">true</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
<object class="GtkTreeViewColumn" id="descendants_self_column">
<property name="expand">false</property>
<property name="sizing">fixed</property>
diff --git a/lib/sp-callgraph-profile.c b/lib/sp-callgraph-profile.c
index 57b0939..703467f 100644
--- a/lib/sp-callgraph-profile.c
+++ b/lib/sp-callgraph-profile.c
@@ -54,19 +54,19 @@
struct _SpCallgraphProfile
{
- GObject parent_instance;
+ GObject parent_instance;
- SpCaptureReader *reader;
- SpSelection *selection;
- StackStash *stash;
- GStringChunk *symbols;
- GHashTable *tags;
+ SpCaptureReader *reader;
+ SpSelection *selection;
+ StackStash *stash;
+ GStringChunk *symbols;
+ GHashTable *tags;
};
typedef struct
{
- SpCaptureReader *reader;
- SpSelection *selection;
+ SpCaptureReader *reader;
+ SpSelection *selection;
} Generate;
static void profile_iface_init (SpProfileInterface *iface);
@@ -504,3 +504,21 @@ sp_callgraph_profile_get_tag (SpCallgraphProfile *self,
return GPOINTER_TO_SIZE (g_hash_table_lookup (self->tags, symbol));
}
+
+gpointer
+sp_callgraph_profile_resolve_name (SpCallgraphProfile *self,
+ const gchar *name)
+{
+ GHashTable *const_table;
+
+ g_return_val_if_fail (SP_IS_CALLGRAPH_PROFILE (self), 0);
+
+ /*
+ * XXX: This is a total hack until we implement string chunk
+ * with our own fronting hsahtable. But we know the hashtable
+ * is the first field of the structure.
+ */
+ const_table = *(GHashTable **)self->symbols;
+
+ return g_hash_table_lookup (const_table, name);
+}
diff --git a/lib/sp-callgraph-profile.h b/lib/sp-callgraph-profile.h
index e034748..98eeac5 100644
--- a/lib/sp-callgraph-profile.h
+++ b/lib/sp-callgraph-profile.h
@@ -32,6 +32,8 @@ SpProfile *sp_callgraph_profile_new (void);
SpProfile *sp_callgraph_profile_new_with_selection (SpSelection *selection);
GQuark sp_callgraph_profile_get_tag (SpCallgraphProfile *self,
const gchar *symbol);
+gpointer sp_callgraph_profile_resolve_name (SpCallgraphProfile *self,
+ const gchar *name);
G_END_DECLS
diff --git a/lib/sp-callgraph-view.c b/lib/sp-callgraph-view.c
index 8ea1683..e5d6c25 100644
--- a/lib/sp-callgraph-view.c
+++ b/lib/sp-callgraph-view.c
@@ -43,16 +43,21 @@
typedef struct
{
- SpCallgraphProfile *profile;
+ SpCallgraphProfile *profile;
+ SpCallgraphProfile *compare_to;
- GtkTreeView *callers_view;
- GtkTreeView *functions_view;
- GtkTreeView *descendants_view;
- GtkTreeViewColumn *descendants_name_column;
+ GtkTreeView *callers_view;
+ GtkTreeView *functions_view;
+ GtkTreeView *descendants_view;
+ GtkTreeViewColumn *descendants_name_column;
- GQueue *history;
+ GtkTreeViewColumn *change_column;
+ SpCellRendererPercent *change_cell;
- guint profile_size;
+ GQueue *history;
+
+ guint profile_size;
+ guint compare_size;
} SpCallgraphViewPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (SpCallgraphView, sp_callgraph_view, GTK_TYPE_BIN)
@@ -109,6 +114,33 @@ sp_callgraph_view_get_profile_size (SpCallgraphView *self)
return size;
}
+static guint
+sp_callgraph_view_get_compare_to_size (SpCallgraphView *self)
+{
+ SpCallgraphViewPrivate *priv = sp_callgraph_view_get_instance_private (self);
+ StackStash *stash;
+ StackNode *node;
+ guint size = 0;
+
+ g_assert (SP_IS_CALLGRAPH_VIEW (self));
+
+ if (priv->compare_size != 0)
+ return priv->compare_size;
+
+ if (priv->compare_to == NULL)
+ return 0;
+
+ if (NULL == (stash = sp_callgraph_profile_get_stash (priv->compare_to)))
+ return 0;
+
+ for (node = stack_stash_get_root (stash); node != NULL; node = node->siblings)
+ size += node->total;
+
+ priv->compare_size = size;
+
+ return size;
+}
+
static void
build_functions_store (StackNode *node,
gpointer user_data)
@@ -750,9 +782,11 @@ sp_callgraph_view_class_init (SpCallgraphViewClass *klass)
"/org/gnome/sysprof/ui/sp-callgraph-view.ui");
gtk_widget_class_bind_template_child_private (widget_class, SpCallgraphView, callers_view);
- gtk_widget_class_bind_template_child_private (widget_class, SpCallgraphView, functions_view);
- gtk_widget_class_bind_template_child_private (widget_class, SpCallgraphView, descendants_view);
+ gtk_widget_class_bind_template_child_private (widget_class, SpCallgraphView, change_cell);
+ gtk_widget_class_bind_template_child_private (widget_class, SpCallgraphView, change_column);
gtk_widget_class_bind_template_child_private (widget_class, SpCallgraphView, descendants_name_column);
+ gtk_widget_class_bind_template_child_private (widget_class, SpCallgraphView, descendants_view);
+ gtk_widget_class_bind_template_child_private (widget_class, SpCallgraphView, functions_view);
bindings = gtk_binding_set_by_class (klass);
gtk_binding_entry_add_signal (bindings, GDK_KEY_Left, GDK_MOD1_MASK, "go-previous", 0);
@@ -965,19 +999,18 @@ sp_callgraph_view_update_descendants (SpCallgraphView *self,
G_TYPE_POINTER);
if (priv->profile != NULL)
- {
- StackStash *stash;
+ {
+ StackStash *stash = sp_callgraph_profile_get_stash (priv->profile);
- stash = sp_callgraph_profile_get_stash (priv->profile);
- if (stash != NULL)
- {
- Descendant *tree;
+ if (stash != NULL)
+ {
+ Descendant *tree;
- tree = build_tree (node);
- if (tree != NULL)
- append_to_tree_and_free (self, stash, store, tree, NULL);
- }
- }
+ tree = build_tree (node);
+ if (tree != NULL)
+ append_to_tree_and_free (self, stash, store, tree, NULL);
+ }
+ }
gtk_tree_view_set_model (priv->descendants_view, GTK_TREE_MODEL (store));
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store),
@@ -1081,3 +1114,94 @@ sp_callgraph_view_get_n_functions (SpCallgraphView *self)
return ret;
}
+
+static gboolean
+nodes_equal (StackNode *node,
+ StackNode *other)
+{
+ return TRUE;
+}
+
+static StackNode *
+find_compare_to_node (SpCallgraphView *self,
+ StackNode *node)
+{
+ SpCallgraphViewPrivate *priv = sp_callgraph_view_get_instance_private (self);
+ StackStash *other;
+ StackNode *iter;
+ gpointer resolved;
+
+ other = sp_callgraph_profile_get_stash (priv->compare_to);
+ resolved = sp_callgraph_profile_resolve_name (priv->compare_to, (const gchar *)node->data);
+
+ if (resolved == 0)
+ return NULL;
+
+ iter = stack_stash_find_node (other, resolved);
+
+ if (iter == NULL)
+ return NULL;
+
+ for (; iter != NULL; iter = iter->next)
+ {
+ if (nodes_equal (node, iter))
+ return iter;
+ }
+
+ return NULL;
+}
+
+static void
+compare_profiles_cell_data_func (GtkTreeViewColumn *tree_column,
+ GtkCellRenderer *cell,
+ GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer user_data)
+{
+ SpCallgraphView *self = user_data;
+ StackNode *node = NULL;
+ gdouble change = 0.0;
+ gdouble total = 0.0;
+
+ gtk_tree_model_get (model, iter,
+ COLUMN_POINTER, &node,
+ COLUMN_TOTAL, &total,
+ -1);
+
+ if G_LIKELY (node != NULL)
+ {
+ StackNode *compare_to_node = find_compare_to_node (self, node);
+ guint profile_size = sp_callgraph_view_get_compare_to_size (self);
+
+ if (compare_to_node != NULL)
+ {
+ gdouble other_total = 100 * compare_to_node->total / (gdouble)profile_size;
+
+ //g_print ("%lf %lf\n", total, other_total);
+
+ change = total - other_total;
+ }
+ }
+
+ sp_cell_renderer_percent_set_percent (SP_CELL_RENDERER_PERCENT (cell), change);
+}
+
+void
+sp_callgraph_view_compare_to (SpCallgraphView *self,
+ SpCallgraphProfile *compare_to)
+{
+ SpCallgraphViewPrivate *priv = sp_callgraph_view_get_instance_private (self);
+
+ g_return_if_fail (SP_IS_CALLGRAPH_VIEW (self));
+ g_return_if_fail (SP_IS_CALLGRAPH_PROFILE (compare_to));
+
+ if (g_set_object (&priv->compare_to, compare_to))
+ {
+ gtk_tree_view_column_set_visible (priv->change_column, TRUE);
+ gtk_tree_view_column_set_cell_data_func (priv->change_column,
+ GTK_CELL_RENDERER (priv->change_cell),
+ compare_profiles_cell_data_func,
+ self,
+ NULL);
+ }
+}
diff --git a/lib/sp-callgraph-view.h b/lib/sp-callgraph-view.h
index 40495ee..aed8277 100644
--- a/lib/sp-callgraph-view.h
+++ b/lib/sp-callgraph-view.h
@@ -42,6 +42,8 @@ GtkWidget *sp_callgraph_view_new (void);
SpCallgraphProfile *sp_callgraph_view_get_profile (SpCallgraphView *self);
void sp_callgraph_view_set_profile (SpCallgraphView *self,
SpCallgraphProfile *profile);
+void sp_callgraph_view_compare_to (SpCallgraphView *self,
+ SpCallgraphProfile *compare_to);
gchar *sp_callgraph_view_screenshot (SpCallgraphView *self);
guint sp_callgraph_view_get_n_functions (SpCallgraphView *self);
diff --git a/lib/sp-cell-renderer-percent.c b/lib/sp-cell-renderer-percent.c
index 4f5fe2b..178d00f 100644
--- a/lib/sp-cell-renderer-percent.c
+++ b/lib/sp-cell-renderer-percent.c
@@ -23,11 +23,13 @@
typedef struct
{
gdouble percent;
+ guint ignore_zero : 1;
} SpCellRendererPercentPrivate;
enum {
PROP_0,
PROP_PERCENT,
+ PROP_IGNORE_ZERO,
N_PROPS
};
@@ -49,6 +51,10 @@ sp_cell_renderer_percent_get_property (GObject *object,
g_value_set_double (value, sp_cell_renderer_percent_get_percent (self));
break;
+ case PROP_IGNORE_ZERO:
+ g_value_set_boolean (value, sp_cell_renderer_percent_get_ignore_zero (self));
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -68,6 +74,10 @@ sp_cell_renderer_percent_set_property (GObject *object,
sp_cell_renderer_percent_set_percent (self, g_value_get_double (value));
break;
+ case PROP_IGNORE_ZERO:
+ sp_cell_renderer_percent_set_ignore_zero (self, g_value_get_boolean (value));
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -90,6 +100,13 @@ sp_cell_renderer_percent_class_init (SpCellRendererPercentClass *klass)
0.0,
(G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+ properties [PROP_IGNORE_ZERO] =
+ g_param_spec_boolean ("ignore-zero",
+ "Ignore Zero",
+ "If Zero should be rendered as empty",
+ FALSE,
+ (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
g_object_class_install_properties (object_class, N_PROPS, properties);
}
@@ -116,7 +133,7 @@ sp_cell_renderer_percent_set_percent (SpCellRendererPercent *self,
SpCellRendererPercentPrivate *priv = sp_cell_renderer_percent_get_instance_private (self);
g_return_if_fail (SP_IS_CELL_RENDERER_PERCENT (self));
- g_return_if_fail (percent >= 0.0);
+ g_return_if_fail (percent >= -100.0);
g_return_if_fail (percent <= 100.0);
if (percent != priv->percent)
@@ -125,11 +142,45 @@ sp_cell_renderer_percent_set_percent (SpCellRendererPercent *self,
priv->percent = percent;
- g_snprintf (text, sizeof text, "%.2lf<span size='smaller'><span size='smaller'> </span>%%</span>",
percent);
- text [sizeof text - 1] = '\0';
+ if (priv->percent != 0.0 || !priv->ignore_zero)
+ {
+ g_snprintf (text, sizeof text, "%.2lf<span size='smaller'><span size='smaller'> </span>%%</span>",
percent);
+ text [sizeof text - 1] = '\0';
+ }
+ else
+ {
+ text[0] = '\0';
+ }
g_object_set (self, "markup", text, NULL);
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_PERCENT]);
}
}
+
+gboolean
+sp_cell_renderer_percent_get_ignore_zero (SpCellRendererPercent *self)
+{
+ SpCellRendererPercentPrivate *priv = sp_cell_renderer_percent_get_instance_private (self);
+
+ g_return_val_if_fail (SP_IS_CELL_RENDERER_PERCENT (self), FALSE);
+
+ return priv->ignore_zero;
+}
+
+void
+sp_cell_renderer_percent_set_ignore_zero (SpCellRendererPercent *self,
+ gboolean ignore_zero)
+{
+ SpCellRendererPercentPrivate *priv = sp_cell_renderer_percent_get_instance_private (self);
+
+ g_return_if_fail (SP_IS_CELL_RENDERER_PERCENT (self));
+
+ ignore_zero = !!ignore_zero;
+
+ if (ignore_zero != priv->ignore_zero)
+ {
+ priv->ignore_zero = ignore_zero;
+ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_IGNORE_ZERO]);
+ }
+}
diff --git a/lib/sp-cell-renderer-percent.h b/lib/sp-cell-renderer-percent.h
index 5a21fdc..7bbea75 100644
--- a/lib/sp-cell-renderer-percent.h
+++ b/lib/sp-cell-renderer-percent.h
@@ -46,11 +46,14 @@ struct _SpCellRendererPercentClass
gpointer padding[4];
};
-GType sp_cell_renderer_percent_get_type (void);
-GtkCellRenderer *sp_cell_renderer_percent_new (void);
-gdouble sp_cell_renderer_percent_get_percent (SpCellRendererPercent *self);
-void sp_cell_renderer_percent_set_percent (SpCellRendererPercent *self,
- gdouble percent);
+GType sp_cell_renderer_percent_get_type (void);
+GtkCellRenderer *sp_cell_renderer_percent_new (void);
+gboolean sp_cell_renderer_percent_get_ignore_zero (SpCellRendererPercent *self);
+void sp_cell_renderer_percent_set_ignore_zero (SpCellRendererPercent *self,
+ gboolean ignore_zero);
+gdouble sp_cell_renderer_percent_get_percent (SpCellRendererPercent *self);
+void sp_cell_renderer_percent_set_percent (SpCellRendererPercent *self,
+ gdouble percent);
G_END_DECLS
diff --git a/src/resources/ui/sp-window.ui b/src/resources/ui/sp-window.ui
index 005c31e..21689e4 100644
--- a/src/resources/ui/sp-window.ui
+++ b/src/resources/ui/sp-window.ui
@@ -280,6 +280,20 @@
</child>
<child>
<object class="GtkModelButton">
+ <property name="action-name">win.compare-capture</property>
+ <property name="text" translatable="yes">Open for comparison</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkSeparator">
+ <property name="orientation">horizontal</property>
+ <property name="margin-top">6</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkModelButton">
<property name="action-name">win.save-capture</property>
<property name="text" translatable="yes">Save As</property>
<property name="visible">true</property>
diff --git a/src/sp-window.c b/src/sp-window.c
index 9e1569f..b22dae6 100644
--- a/src/sp-window.c
+++ b/src/sp-window.c
@@ -76,8 +76,10 @@ enum {
static guint signals [N_SIGNALS];
-static void sp_window_set_profiler (SpWindow *self,
- SpProfiler *profiler);
+static void sp_window_set_profiler (SpWindow *self,
+ SpProfiler *profiler);
+static void sp_window_compare_to_file (SpWindow *self,
+ GFile *file);
static void
sp_window_notify_user (SpWindow *self,
@@ -153,6 +155,42 @@ sp_window_update_stats (gpointer data)
return G_SOURCE_CONTINUE;
}
+static GFile *
+sp_window_request_file (SpWindow *self,
+ const gchar *title)
+{
+ GtkFileChooserNative *dialog;
+ GtkFileFilter *filter;
+ GFile *ret = NULL;
+ gint response;
+
+ g_assert (SP_IS_WINDOW (self));
+
+ dialog = gtk_file_chooser_native_new (title,
+ GTK_WINDOW (self),
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ _("Open"),
+ _("Cancel"));
+
+ filter = gtk_file_filter_new ();
+ gtk_file_filter_set_name (filter, _("Sysprof Captures"));
+ gtk_file_filter_add_pattern (filter, "*.syscap");
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
+
+ filter = gtk_file_filter_new ();
+ gtk_file_filter_set_name (filter, _("All Files"));
+ gtk_file_filter_add_pattern (filter, "*");
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
+
+ response = gtk_native_dialog_run (GTK_NATIVE_DIALOG (dialog));
+
+ if (response == GTK_RESPONSE_ACCEPT)
+ ret = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
+
+ gtk_native_dialog_destroy (GTK_NATIVE_DIALOG (dialog));
+
+ return ret;
+}
static void
sp_window_update_subtitle (SpWindow *self)
@@ -315,6 +353,7 @@ sp_window_set_state (SpWindow *self,
gtk_widget_set_visible (GTK_WIDGET (self->stat_label), FALSE);
g_clear_pointer (&self->reader, sp_capture_reader_unref);
sp_window_action_set (self, "close-capture", "enabled", FALSE, NULL);
+ sp_window_action_set (self, "compare-capture", "enabled", FALSE, NULL);
sp_window_action_set (self, "save-capture", "enabled", FALSE, NULL);
sp_window_action_set (self, "screenshot", "enabled", FALSE, NULL);
profiler = sp_local_profiler_new ();
@@ -332,6 +371,7 @@ sp_window_set_state (SpWindow *self,
g_clear_pointer (&self->reader, sp_capture_reader_unref);
sp_callgraph_view_set_profile (self->callgraph_view, NULL);
sp_window_action_set (self, "close-capture", "enabled", FALSE, NULL);
+ sp_window_action_set (self, "compare-capture", "enabled", FALSE, NULL);
sp_window_action_set (self, "save-capture", "enabled", FALSE, NULL);
sp_window_action_set (self, "screenshot", "enabled", FALSE, NULL);
break;
@@ -340,6 +380,7 @@ sp_window_set_state (SpWindow *self,
gtk_widget_set_sensitive (GTK_WIDGET (self->record_button), FALSE);
gtk_label_set_label (self->subtitle, _("Building profileā¦"));
sp_window_action_set (self, "close-capture", "enabled", FALSE, NULL);
+ sp_window_action_set (self, "compare-capture", "enabled", FALSE, NULL);
sp_window_action_set (self, "save-capture", "enabled", FALSE, NULL);
sp_window_action_set (self, "screenshot", "enabled", FALSE, NULL);
sp_window_build_profile (self);
@@ -355,6 +396,7 @@ sp_window_set_state (SpWindow *self,
sp_window_update_stats (self);
sp_window_update_subtitle (self);
sp_window_action_set (self, "close-capture", "enabled", TRUE, NULL);
+ sp_window_action_set (self, "compare-capture", "enabled", TRUE, NULL);
sp_window_action_set (self, "save-capture", "enabled", TRUE, NULL);
sp_window_action_set (self, "screenshot", "enabled", TRUE, NULL);
profiler = sp_local_profiler_new ();
@@ -570,6 +612,23 @@ sp_window_open_capture (GSimpleAction *action,
}
static void
+sp_window_compare_capture (GSimpleAction *action,
+ GVariant *variant,
+ gpointer user_data)
+{
+ SpWindow *self = user_data;
+ g_autoptr(GFile) file = NULL;
+
+ g_assert (G_IS_SIMPLE_ACTION (action));
+ g_assert (variant == NULL);
+ g_assert (SP_IS_WINDOW (self));
+
+ file = sp_window_request_file (self, _("Open Capture for Comparison"));
+
+ sp_window_compare_to_file (self, file);
+}
+
+static void
sp_window_save_capture (GSimpleAction *action,
GVariant *variant,
gpointer user_data)
@@ -837,6 +896,7 @@ sp_window_init (SpWindow *self)
static GActionEntry action_entries[] = {
{ "close-capture", sp_window_close_capture },
{ "open-capture", sp_window_open_capture },
+ { "compare-capture", sp_window_compare_capture },
{ "save-capture", sp_window_save_capture },
{ "screenshot", sp_window_screenshot },
};
@@ -991,37 +1051,90 @@ sp_window_get_state (SpWindow *self)
void
sp_window_open_from_dialog (SpWindow *self)
{
- GtkFileChooserNative *dialog;
- GtkFileFilter *filter;
- gint response;
+ g_autoptr(GFile) file = NULL;
g_assert (SP_IS_WINDOW (self));
- dialog = gtk_file_chooser_native_new (_("Open Capture"),
- GTK_WINDOW (self),
- GTK_FILE_CHOOSER_ACTION_OPEN,
- _("Open"),
- _("Cancel"));
+ file = sp_window_request_file (self, _("Open Capture"));
- filter = gtk_file_filter_new ();
- gtk_file_filter_set_name (filter, _("Sysprof Captures"));
- gtk_file_filter_add_pattern (filter, "*.syscap");
- gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
+ if (file != NULL)
+ sp_window_open (self, file);
+}
- filter = gtk_file_filter_new ();
- gtk_file_filter_set_name (filter, _("All Files"));
- gtk_file_filter_add_pattern (filter, "*");
- gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
+static void
+sp_window_compare_to_generate_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ SpCallgraphProfile *profile = (SpCallgraphProfile *)object;
+ g_autoptr(SpWindow) self = user_data;
+ g_autoptr(GError) error = NULL;
- response = gtk_native_dialog_run (GTK_NATIVE_DIALOG (dialog));
+ g_assert (SP_IS_WINDOW (self));
+ g_assert (SP_IS_CALLGRAPH_PROFILE (profile));
- if (response == GTK_RESPONSE_ACCEPT)
+ if (!sp_profile_generate_finish (SP_PROFILE (profile), result, &error))
{
- g_autoptr(GFile) file = NULL;
+ sp_window_notify_user (self,
+ GTK_MESSAGE_ERROR,
+ "%s", error->message);
+ return;
+ }
+
+ sp_callgraph_view_compare_to (self->callgraph_view, SP_CALLGRAPH_PROFILE (profile));
+}
- file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
- sp_window_open (self, file);
+static void
+sp_window_compare_to_read_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ SpWindow *self = (SpWindow *)object;
+ g_autoptr(SpProfile) profile = NULL;
+ g_autoptr(SpCaptureReader) reader = NULL;
+ g_autoptr(GError) error = NULL;
+
+ g_assert (SP_IS_WINDOW (self));
+ g_assert (G_IS_TASK (result));
+
+ reader = g_task_propagate_pointer (G_TASK (result), &error);
+
+ if (reader == NULL)
+ {
+ sp_window_notify_user (self,
+ GTK_MESSAGE_ERROR,
+ "%s", error->message);
+ return;
}
- gtk_native_dialog_destroy (GTK_NATIVE_DIALOG (dialog));
+ profile = sp_callgraph_profile_new ();
+ sp_profile_set_reader (profile, reader);
+
+ sp_profile_generate (profile,
+ NULL,
+ sp_window_compare_to_generate_cb,
+ g_object_ref (self));
+}
+
+static void
+sp_window_compare_to_file (SpWindow *self,
+ GFile *file)
+{
+ g_autoptr(GTask) task = NULL;
+
+ g_return_if_fail (SP_IS_WINDOW (self));
+ g_return_if_fail (G_IS_FILE (file));
+
+ if (!g_file_is_native (file))
+ {
+ sp_window_notify_user (self,
+ GTK_MESSAGE_ERROR,
+ _("The file \"%s\" could not be opened. Only local files are supported."),
+ g_file_get_uri (file));
+ return;
+ }
+
+ task = g_task_new (self, NULL, sp_window_compare_to_read_cb, NULL);
+ g_task_set_task_data (task, g_object_ref (file), g_object_unref);
+ g_task_run_in_thread (task, sp_window_open_worker);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]