diff --git a/src/libsysprof-ui/sysprof-capture-view.c b/src/libsysprof-ui/sysprof-capture-view.c
index dd7e4776..2d36e79b 100644
--- a/src/libsysprof-ui/sysprof-capture-view.c
+++ b/src/libsysprof-ui/sysprof-capture-view.c
@@ -41,6 +41,7 @@ typedef struct
guint has_samples : 1;
guint has_counters : 1;
guint has_marks : 1;
+ guint can_replay : 1;
} SysprofCaptureFeatures;
typedef struct
@@ -64,6 +65,7 @@ typedef struct
guint busy;
+ guint can_replay : 1;
guint needs_fit : 1;
} SysprofCaptureViewPrivate;
@@ -318,7 +320,17 @@ sysprof_capture_view_scan_worker (GTask *task,
st_buf.frame_count[frame.type]++;
- if (frame.type == SYSPROF_CAPTURE_FRAME_MARK)
+ if (frame.type == SYSPROF_CAPTURE_FRAME_METADATA)
+ {
+ const SysprofCaptureMetadata *meta;
+
+ if ((meta = sysprof_capture_reader_read_metadata (reader)))
+ {
+ if (g_strcmp0 (meta->id, "local-profiler") == 0)
+ features.can_replay = TRUE;
+ }
+ }
+ else if (frame.type == SYSPROF_CAPTURE_FRAME_MARK)
{
const SysprofCaptureMark *mark;
@@ -997,3 +1009,13 @@ sysprof_capture_view_get_reader (SysprofCaptureView *self)
return priv->reader;
}
+
+gboolean
+sysprof_capture_view_get_can_replay (SysprofCaptureView *self)
+{
+ SysprofCaptureViewPrivate *priv = sysprof_capture_view_get_instance_private (self);
+
+ g_return_val_if_fail (SYSPROF_IS_CAPTURE_VIEW (self), FALSE);
+
+ return priv->features.can_replay;
+}
diff --git a/src/libsysprof-ui/sysprof-capture-view.h b/src/libsysprof-ui/sysprof-capture-view.h
index 3dad57df..dac9b10b 100644
--- a/src/libsysprof-ui/sysprof-capture-view.h
+++ b/src/libsysprof-ui/sysprof-capture-view.h
@@ -69,5 +69,7 @@ SYSPROF_AVAILABLE_IN_ALL
gboolean sysprof_capture_view_get_busy (SysprofCaptureView *self);
SYSPROF_AVAILABLE_IN_ALL
void sysprof_capture_view_fit_to_width (SysprofCaptureView *self);
+SYSPROF_AVAILABLE_IN_ALL
+gboolean sysprof_capture_view_get_can_replay (SysprofCaptureView *self);
G_END_DECLS
diff --git a/src/libsysprof-ui/sysprof-display.c b/src/libsysprof-ui/sysprof-display.c
index 1b7b2358..328d6ffb 100644
--- a/src/libsysprof-ui/sysprof-display.c
+++ b/src/libsysprof-ui/sysprof-display.c
@@ -53,6 +53,7 @@ G_DEFINE_TYPE_WITH_PRIVATE (SysprofDisplay, sysprof_display, GTK_TYPE_BIN)
enum {
PROP_0,
+ PROP_CAN_REPLAY,
PROP_CAN_SAVE,
PROP_RECORDING,
PROP_TITLE,
@@ -91,6 +92,7 @@ sysprof_display_load_cb (SysprofCaptureView *view,
if (!sysprof_capture_view_load_finish (view, result, &error))
g_warning ("Failed to load capture: %s", error->message);
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_CAN_REPLAY]);
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_CAN_SAVE]);
}
@@ -148,6 +150,7 @@ sysprof_display_profiler_stopped_cb (SysprofDisplay *self,
}
notify:
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_CAN_REPLAY]);
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_CAN_SAVE]);
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_RECORDING]);
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_TITLE]);
@@ -297,6 +300,10 @@ sysprof_display_get_property (GObject *object,
switch (prop_id)
{
+ case PROP_CAN_REPLAY:
+ g_value_set_boolean (value, sysprof_display_get_can_replay (self));
+ break;
+
case PROP_CAN_SAVE:
g_value_set_boolean (value, sysprof_display_get_can_save (self));
break;
@@ -325,6 +332,13 @@ sysprof_display_class_init (SysprofDisplayClass *klass)
widget_class->parent_set = sysprof_display_parent_set;
+ properties [PROP_CAN_REPLAY] =
+ g_param_spec_boolean ("can-replay",
+ "Can Replay",
+ "If the capture contains enough information to re-run the recording",
+ FALSE,
+ (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
properties [PROP_CAN_SAVE] =
g_param_spec_boolean ("can-save",
"Can Save",
@@ -593,3 +607,22 @@ _sysprof_display_focus_record (SysprofDisplay *self)
_sysprof_profiler_assistant_focus_record (priv->assistant);
}
+
+gboolean
+sysprof_display_get_can_replay (SysprofDisplay *self)
+{
+ SysprofDisplayPrivate *priv = sysprof_display_get_instance_private (self);
+
+ g_return_val_if_fail (SYSPROF_IS_DISPLAY (self), FALSE);
+
+ return !sysprof_display_is_empty (self) &&
+ sysprof_capture_view_get_can_replay (priv->capture_view);
+}
+
+SysprofDisplay *
+sysprof_display_replay (SysprofDisplay *self)
+{
+ g_return_val_if_fail (SYSPROF_IS_DISPLAY (self), NULL);
+
+ return NULL;
+}
diff --git a/src/libsysprof-ui/sysprof-display.h b/src/libsysprof-ui/sysprof-display.h
index fbfc6975..190f5363 100644
--- a/src/libsysprof-ui/sysprof-display.h
+++ b/src/libsysprof-ui/sysprof-display.h
@@ -57,5 +57,9 @@ SYSPROF_AVAILABLE_IN_ALL
gboolean sysprof_display_get_can_save (SysprofDisplay *self);
SYSPROF_AVAILABLE_IN_ALL
void sysprof_display_stop_recording (SysprofDisplay *self);
+SYSPROF_AVAILABLE_IN_ALL
+gboolean sysprof_display_get_can_replay (SysprofDisplay *self);
+SYSPROF_AVAILABLE_IN_ALL
+SysprofDisplay *sysprof_display_replay (SysprofDisplay *self);
G_END_DECLS
diff --git a/src/libsysprof-ui/sysprof-notebook.c b/src/libsysprof-ui/sysprof-notebook.c
index d1267b98..038bd3cc 100644
--- a/src/libsysprof-ui/sysprof-notebook.c
+++ b/src/libsysprof-ui/sysprof-notebook.c
@@ -31,6 +31,7 @@ G_DEFINE_TYPE (SysprofNotebook, sysprof_notebook, GTK_TYPE_NOTEBOOK)
enum {
PROP_0,
+ PROP_CAN_REPLAY,
PROP_CAN_SAVE,
PROP_CURRENT,
N_PROPS
@@ -64,6 +65,17 @@ sysprof_notebook_notify_can_save_cb (SysprofNotebook *self,
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_CAN_SAVE]);
}
+static void
+sysprof_notebook_notify_can_replay_cb (SysprofNotebook *self,
+ GParamSpec *pspec,
+ SysprofDisplay *display)
+{
+ g_assert (SYSPROF_IS_NOTEBOOK (self));
+ g_assert (SYSPROF_IS_DISPLAY (display));
+
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_CAN_REPLAY]);
+}
+
static void
sysprof_notebook_page_added (GtkNotebook *notebook,
GtkWidget *child,
@@ -82,12 +94,19 @@ sysprof_notebook_page_added (GtkNotebook *notebook,
gtk_notebook_set_tab_label (notebook, child, tab);
gtk_notebook_set_tab_reorderable (notebook, child, TRUE);
+ g_signal_connect_object (child,
+ "notify::can-replay",
+ G_CALLBACK (sysprof_notebook_notify_can_replay_cb),
+ notebook,
+ G_CONNECT_SWAPPED);
+
g_signal_connect_object (child,
"notify::can-save",
G_CALLBACK (sysprof_notebook_notify_can_save_cb),
notebook,
G_CONNECT_SWAPPED);
+ g_object_notify_by_pspec (G_OBJECT (notebook), properties [PROP_CAN_REPLAY]);
g_object_notify_by_pspec (G_OBJECT (notebook), properties [PROP_CAN_SAVE]);
g_object_notify_by_pspec (G_OBJECT (notebook), properties [PROP_CURRENT]);
@@ -116,6 +135,7 @@ sysprof_notebook_page_removed (GtkNotebook *notebook,
G_CALLBACK (sysprof_notebook_notify_can_save_cb),
notebook);
+ g_object_notify_by_pspec (G_OBJECT (notebook), properties [PROP_CAN_REPLAY]);
g_object_notify_by_pspec (G_OBJECT (notebook), properties [PROP_CAN_SAVE]);
g_object_notify_by_pspec (G_OBJECT (notebook), properties [PROP_CURRENT]);
}
@@ -134,6 +154,7 @@ sysprof_notebook_switch_page (GtkNotebook *notebook,
GTK_NOTEBOOK_CLASS (sysprof_notebook_parent_class)->switch_page (notebook, widget, page);
+ g_object_notify_by_pspec (G_OBJECT (notebook), properties [PROP_CAN_REPLAY]);
g_object_notify_by_pspec (G_OBJECT (notebook), properties [PROP_CAN_SAVE]);
g_object_notify_by_pspec (G_OBJECT (notebook), properties [PROP_CURRENT]);
}
@@ -148,6 +169,10 @@ sysprof_notebook_get_property (GObject *object,
switch (prop_id)
{
+ case PROP_CAN_REPLAY:
+ g_value_set_boolean (value, sysprof_notebook_get_can_replay (self));
+ break;
+
case PROP_CAN_SAVE:
g_value_set_boolean (value, sysprof_notebook_get_can_save (self));
break;
@@ -173,6 +198,13 @@ sysprof_notebook_class_init (SysprofNotebookClass *klass)
notebook_class->page_removed = sysprof_notebook_page_removed;
notebook_class->switch_page = sysprof_notebook_switch_page;
+ properties [PROP_CAN_REPLAY] =
+ g_param_spec_boolean ("can-replay",
+ "Can Replay",
+ "If the current display can replay a recording",
+ FALSE,
+ (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
properties [PROP_CAN_SAVE] =
g_param_spec_boolean ("can-save",
"Can Save",
@@ -293,3 +325,34 @@ sysprof_notebook_get_can_save (SysprofNotebook *self)
return FALSE;
}
+
+gboolean
+sysprof_notebook_get_can_replay (SysprofNotebook *self)
+{
+ SysprofDisplay *display;
+
+ g_return_val_if_fail (SYSPROF_IS_NOTEBOOK (self), FALSE);
+
+ if ((display = sysprof_notebook_get_current (self)))
+ return sysprof_display_get_can_replay (display);
+
+ return FALSE;
+}
+
+void
+sysprof_notebook_replay (SysprofNotebook *self)
+{
+ SysprofDisplay *display;
+ SysprofDisplay *replay;
+
+ g_return_if_fail (SYSPROF_IS_NOTEBOOK (self));
+
+ if (!(display = sysprof_notebook_get_current (self)) ||
+ !sysprof_display_get_can_replay (display) ||
+ !(replay = sysprof_display_replay (display)))
+ return;
+
+ g_return_if_fail (SYSPROF_IS_DISPLAY (replay));
+
+ gtk_container_add (GTK_CONTAINER (self), GTK_WIDGET (replay));
+}
diff --git a/src/libsysprof-ui/sysprof-notebook.h b/src/libsysprof-ui/sysprof-notebook.h
index ebf68c97..36aa1fe8 100644
--- a/src/libsysprof-ui/sysprof-notebook.h
+++ b/src/libsysprof-ui/sysprof-notebook.h
@@ -41,17 +41,21 @@ struct _SysprofNotebookClass
};
SYSPROF_AVAILABLE_IN_ALL
-GtkWidget *sysprof_notebook_new (void);
+GtkWidget *sysprof_notebook_new (void);
SYSPROF_AVAILABLE_IN_ALL
-SysprofDisplay *sysprof_notebook_get_current (SysprofNotebook *self);
+SysprofDisplay *sysprof_notebook_get_current (SysprofNotebook *self);
SYSPROF_AVAILABLE_IN_ALL
-void sysprof_notebook_close_current (SysprofNotebook *self);
+void sysprof_notebook_close_current (SysprofNotebook *self);
SYSPROF_AVAILABLE_IN_ALL
-void sysprof_notebook_open (SysprofNotebook *self,
- GFile *file);
+void sysprof_notebook_open (SysprofNotebook *self,
+ GFile *file);
SYSPROF_AVAILABLE_IN_ALL
-void sysprof_notebook_save (SysprofNotebook *self);
+void sysprof_notebook_save (SysprofNotebook *self);
SYSPROF_AVAILABLE_IN_ALL
-gboolean sysprof_notebook_get_can_save (SysprofNotebook *self);
+gboolean sysprof_notebook_get_can_save (SysprofNotebook *self);
+SYSPROF_AVAILABLE_IN_ALL
+void sysprof_notebook_replay (SysprofNotebook *self);
+SYSPROF_AVAILABLE_IN_ALL
+gboolean sysprof_notebook_get_can_replay (SysprofNotebook *self);
G_END_DECLS
diff --git a/src/sysprof/gtk/menus.ui b/src/sysprof/gtk/menus.ui
index d267eeb6..3e0a61f2 100644
--- a/src/sysprof/gtk/menus.ui
+++ b/src/sysprof/gtk/menus.ui
@@ -25,6 +25,13 @@
<primary>s
+