[sysprof/wip/chergert/sysprof-3] libsysprof-ui: start on new tabbed design
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [sysprof/wip/chergert/sysprof-3] libsysprof-ui: start on new tabbed design
- Date: Thu, 16 May 2019 07:00:27 +0000 (UTC)
commit 4fe6a6d6470ba6e6d5e4f01f52fa01eb9aecf74f
Author: Christian Hergert <chergert redhat com>
Date: Wed May 15 23:56:30 2019 -0700
libsysprof-ui: start on new tabbed design
src/libsysprof-ui/libsysprof-ui.gresource.xml | 2 +
src/libsysprof-ui/meson.build | 5 +
src/libsysprof-ui/sysprof-capture-view.c | 21 +-
src/libsysprof-ui/sysprof-display.c | 159 ++++
src/libsysprof-ui/sysprof-display.h | 45 ++
src/libsysprof-ui/sysprof-notebook.c | 167 ++++
src/libsysprof-ui/sysprof-notebook.h | 47 ++
src/libsysprof-ui/sysprof-tab.c | 152 ++++
src/libsysprof-ui/sysprof-tab.h | 35 +
src/libsysprof-ui/sysprof-ui.h | 2 +
src/libsysprof-ui/ui/sysprof-display.ui | 37 +
src/libsysprof-ui/ui/sysprof-tab.ui | 45 ++
src/sysprof/sysprof-application.c | 66 +-
src/sysprof/sysprof-window.c | 1017 ++-----------------------
src/sysprof/sysprof-window.h | 35 +-
src/sysprof/ui/sysprof-window.ui | 283 +------
16 files changed, 813 insertions(+), 1305 deletions(-)
---
diff --git a/src/libsysprof-ui/libsysprof-ui.gresource.xml b/src/libsysprof-ui/libsysprof-ui.gresource.xml
index 46ac5f8..849b877 100644
--- a/src/libsysprof-ui/libsysprof-ui.gresource.xml
+++ b/src/libsysprof-ui/libsysprof-ui.gresource.xml
@@ -11,6 +11,7 @@
<file preprocess="xml-stripblanks">ui/sysprof-callgraph-view.ui</file>
<file preprocess="xml-stripblanks">ui/sysprof-capture-view.ui</file>
+ <file preprocess="xml-stripblanks">ui/sysprof-display.ui</file>
<file preprocess="xml-stripblanks">ui/sysprof-details-view.ui</file>
<file preprocess="xml-stripblanks">ui/sysprof-empty-state-view.ui</file>
<file preprocess="xml-stripblanks">ui/sysprof-failed-state-view.ui</file>
@@ -18,6 +19,7 @@
<file preprocess="xml-stripblanks">ui/sysprof-process-model-row.ui</file>
<file preprocess="xml-stripblanks">ui/sysprof-profiler-menu-button.ui</file>
<file preprocess="xml-stripblanks">ui/sysprof-recording-state-view.ui</file>
+ <file preprocess="xml-stripblanks">ui/sysprof-tab.ui</file>
<file preprocess="xml-stripblanks">ui/sysprof-visualizer-view.ui</file>
</gresource>
</gresources>
diff --git a/src/libsysprof-ui/meson.build b/src/libsysprof-ui/meson.build
index e7c4645..29972b7 100644
--- a/src/libsysprof-ui/meson.build
+++ b/src/libsysprof-ui/meson.build
@@ -3,6 +3,7 @@ libsysprof_ui_public_sources = [
'sysprof-callgraph-view.c',
'sysprof-color-cycle.c',
'sysprof-cpu-visualizer-row.c',
+ 'sysprof-display.c',
'sysprof-empty-state-view.c',
'sysprof-failed-state-view.c',
'sysprof-line-visualizer-row.c',
@@ -11,6 +12,7 @@ libsysprof_ui_public_sources = [
'sysprof-mark-visualizer-row.c',
'sysprof-model-filter.c',
'sysprof-multi-paned.c',
+ 'sysprof-notebook.c',
'sysprof-process-model-row.c',
'sysprof-profiler-menu-button.c',
'sysprof-recording-state-view.c',
@@ -27,6 +29,7 @@ libsysprof_ui_private_sources = [
'sysprof-details-view.c',
'sysprof-cell-renderer-duration.c',
'sysprof-cell-renderer-percent.c',
+ 'sysprof-tab.c',
'sysprof-theme-manager.c',
'../stackstash.c',
]
@@ -36,6 +39,7 @@ libsysprof_ui_public_headers = [
'sysprof-callgraph-view.h',
'sysprof-cell-renderer-percent.h',
'sysprof-cpu-visualizer-row.h',
+ 'sysprof-display.h',
'sysprof-empty-state-view.h',
'sysprof-failed-state-view.h',
'sysprof-line-visualizer-row.h',
@@ -44,6 +48,7 @@ libsysprof_ui_public_headers = [
'sysprof-mark-visualizer-row.h',
'sysprof-model-filter.h',
'sysprof-multi-paned.h',
+ 'sysprof-notebook.h',
'sysprof-process-model-row.h',
'sysprof-profiler-menu-button.h',
'sysprof-recording-state-view.h',
diff --git a/src/libsysprof-ui/sysprof-capture-view.c b/src/libsysprof-ui/sysprof-capture-view.c
index 39a447a..0322fd8 100644
--- a/src/libsysprof-ui/sysprof-capture-view.c
+++ b/src/libsysprof-ui/sysprof-capture-view.c
@@ -226,7 +226,7 @@ sysprof_capture_view_scan_worker (GTask *task,
SysprofCaptureReader *reader = task_data;
SysprofCaptureFeatures features = {0};
SysprofCaptureFrame frame;
- SysprofCaptureStat st_buf = {0};
+ SysprofCaptureStat st_buf = {{0}};
g_assert (SYSPROF_IS_CAPTURE_VIEW (self));
g_assert (G_IS_TASK (task));
@@ -775,3 +775,22 @@ sysprof_capture_view_fit_to_width (SysprofCaptureView *self)
zoom = sysprof_zoom_manager_fit_zoom_for_duration (priv->zoom_manager, duration, width);
sysprof_zoom_manager_set_zoom (priv->zoom_manager, zoom);
}
+
+/**
+ * sysprof_capture_view_get_reader:
+ *
+ * Gets the reader for the view, if any.
+ *
+ * Returns: (transfer none): a #SysprofCaptureReader or %NULL
+ *
+ * Since: 3.34
+ */
+SysprofCaptureReader *
+sysprof_capture_view_get_reader (SysprofCaptureView *self)
+{
+ SysprofCaptureViewPrivate *priv = sysprof_capture_view_get_instance_private (self);
+
+ g_return_val_if_fail (SYSPROF_IS_CAPTURE_VIEW (self), NULL);
+
+ return priv->reader;
+}
diff --git a/src/libsysprof-ui/sysprof-display.c b/src/libsysprof-ui/sysprof-display.c
new file mode 100644
index 0000000..1a90c86
--- /dev/null
+++ b/src/libsysprof-ui/sysprof-display.c
@@ -0,0 +1,159 @@
+/* sysprof-display.c
+ *
+ * Copyright 2019 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#define G_LOG_DOMAIN "sysprof-display"
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+
+#include <sysprof-capture.h>
+#include <sysprof-ui.h>
+#include <sysprof.h>
+
+#include "sysprof-capture-view.h"
+#include "sysprof-display.h"
+#include "sysprof-empty-state-view.h"
+#include "sysprof-recording-state-view.h"
+
+typedef struct
+{
+ SysprofCaptureView *capture_view;
+ SysprofEmptyStateView *empty_view;
+ SysprofRecordingStateView *recording_view;
+} SysprofDisplayPrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (SysprofDisplay, sysprof_display, GTK_TYPE_BIN)
+
+enum {
+ PROP_0,
+ PROP_TITLE,
+ N_PROPS
+};
+
+static GParamSpec *properties [N_PROPS];
+
+/**
+ * sysprof_display_new:
+ *
+ * Create a new #SysprofDisplay.
+ *
+ * Returns: (transfer full): a newly created #SysprofDisplay
+ *
+ * Since: 3.34
+ */
+GtkWidget *
+sysprof_display_new (void)
+{
+ return g_object_new (SYSPROF_TYPE_DISPLAY, NULL);
+}
+
+static gchar *
+sysprof_display_dup_title (SysprofDisplay *self)
+{
+ SysprofDisplayPrivate *priv = sysprof_display_get_instance_private (self);
+ SysprofCaptureReader *reader;
+
+ g_return_val_if_fail (SYSPROF_IS_DISPLAY (self), NULL);
+
+ if ((reader = sysprof_capture_view_get_reader (priv->capture_view)))
+ {
+ const gchar *filename;
+
+ if ((filename = sysprof_capture_reader_get_filename (reader)))
+ return g_strdup (filename);
+
+ }
+
+ return g_strdup (_("Unsaved Session"));
+}
+
+static void
+sysprof_display_finalize (GObject *object)
+{
+ G_OBJECT_CLASS (sysprof_display_parent_class)->finalize (object);
+}
+
+static void
+sysprof_display_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ SysprofDisplay *self = (SysprofDisplay *)object;
+
+ switch (prop_id)
+ {
+ case PROP_TITLE:
+ g_value_take_string (value, sysprof_display_dup_title (self));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+sysprof_display_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (prop_id)
+ {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+sysprof_display_class_init (SysprofDisplayClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->finalize = sysprof_display_finalize;
+ object_class->get_property = sysprof_display_get_property;
+ object_class->set_property = sysprof_display_set_property;
+
+ properties [PROP_TITLE] =
+ g_param_spec_string ("title",
+ "Title",
+ "The title of the display",
+ NULL,
+ (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, N_PROPS, properties);
+
+ gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/sysprof/ui/sysprof-display.ui");
+ gtk_widget_class_bind_template_child_private (widget_class, SysprofDisplay , empty_view);
+ gtk_widget_class_bind_template_child_private (widget_class, SysprofDisplay , recording_view);
+ gtk_widget_class_bind_template_child_private (widget_class, SysprofDisplay , capture_view);
+
+ g_type_ensure (SYSPROF_TYPE_CAPTURE_VIEW);
+ g_type_ensure (SYSPROF_TYPE_EMPTY_STATE_VIEW);
+ g_type_ensure (SYSPROF_TYPE_RECORDING_STATE_VIEW);
+}
+
+static void
+sysprof_display_init (SysprofDisplay *self)
+{
+ gtk_widget_init_template (GTK_WIDGET (self));
+}
diff --git a/src/libsysprof-ui/sysprof-display.h b/src/libsysprof-ui/sysprof-display.h
new file mode 100644
index 0000000..0b6c735
--- /dev/null
+++ b/src/libsysprof-ui/sysprof-display.h
@@ -0,0 +1,45 @@
+/* sysprof-display.h
+ *
+ * Copyright 2019 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <gtk/gtk.h>
+
+#include "sysprof-version-macros.h"
+
+G_BEGIN_DECLS
+
+#define SYSPROF_TYPE_DISPLAY (sysprof_display_get_type())
+
+SYSPROF_AVAILABLE_IN_ALL
+G_DECLARE_DERIVABLE_TYPE (SysprofDisplay, sysprof_display, SYSPROF, DISPLAY, GtkBin)
+
+struct _SysprofDisplayClass
+{
+ GtkBinClass parent_class;
+
+ /*< private >*/
+ gpointer _reserved[16];
+} __attribute__((aligned(8)));
+
+SYSPROF_AVAILABLE_IN_ALL
+GtkWidget *sysprof_display_new (void);
+
+G_END_DECLS
diff --git a/src/libsysprof-ui/sysprof-notebook.c b/src/libsysprof-ui/sysprof-notebook.c
new file mode 100644
index 0000000..0be4977
--- /dev/null
+++ b/src/libsysprof-ui/sysprof-notebook.c
@@ -0,0 +1,167 @@
+/* sysprof-notebook.c
+ *
+ * Copyright 2019 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#define G_LOG_DOMAIN "sysprof-notebook"
+
+#include "config.h"
+
+#include "sysprof-display.h"
+#include "sysprof-notebook.h"
+#include "sysprof-tab.h"
+
+typedef struct
+{
+ void *dummy;
+} SysprofNotebookPrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (SysprofNotebook, sysprof_notebook, GTK_TYPE_NOTEBOOK)
+
+enum {
+ PROP_0,
+ N_PROPS
+};
+
+static GParamSpec *properties [N_PROPS];
+
+/**
+ * sysprof_notebook_new:
+ *
+ * Create a new #SysprofNotebook.
+ *
+ * Returns: (transfer full): a newly created #SysprofNotebook
+ *
+ * Since: 3.34
+ */
+GtkWidget *
+sysprof_notebook_new (void)
+{
+ return g_object_new (SYSPROF_TYPE_NOTEBOOK, NULL);
+}
+
+static void
+sysprof_notebook_page_added (GtkNotebook *notebook,
+ GtkWidget *child,
+ guint page_num)
+{
+ g_assert (SYSPROF_IS_NOTEBOOK (notebook));
+ g_assert (GTK_IS_WIDGET (child));
+
+ if (SYSPROF_IS_DISPLAY (child))
+ {
+ GtkWidget *tab = sysprof_tab_new (SYSPROF_DISPLAY (child));
+
+ gtk_notebook_set_tab_label (notebook, child, tab);
+ gtk_notebook_set_tab_reorderable (notebook, child, TRUE);
+ }
+
+ gtk_notebook_set_show_tabs (notebook,
+ gtk_notebook_get_n_pages (notebook) > 1);
+}
+
+static void
+sysprof_notebook_page_removed (GtkNotebook *notebook,
+ GtkWidget *child,
+ guint page_num)
+{
+ g_assert (SYSPROF_IS_NOTEBOOK (notebook));
+ g_assert (GTK_IS_WIDGET (child));
+
+ if (gtk_notebook_get_n_pages (notebook) == 0)
+ {
+ child = sysprof_display_new ();
+ gtk_container_add (GTK_CONTAINER (notebook), child);
+ gtk_widget_show (child);
+ }
+
+ gtk_notebook_set_show_tabs (notebook,
+ gtk_notebook_get_n_pages (notebook) > 1);
+}
+
+static void
+sysprof_notebook_finalize (GObject *object)
+{
+ SysprofNotebook *self = (SysprofNotebook *)object;
+ SysprofNotebookPrivate *priv = sysprof_notebook_get_instance_private (self);
+
+ G_OBJECT_CLASS (sysprof_notebook_parent_class)->finalize (object);
+}
+
+static void
+sysprof_notebook_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ SysprofNotebook *self = SYSPROF_NOTEBOOK (object);
+
+ switch (prop_id)
+ {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+sysprof_notebook_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ SysprofNotebook *self = SYSPROF_NOTEBOOK (object);
+
+ switch (prop_id)
+ {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+sysprof_notebook_class_init (SysprofNotebookClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkNotebookClass *notebook_class = GTK_NOTEBOOK_CLASS (klass);
+
+ object_class->finalize = sysprof_notebook_finalize;
+ object_class->get_property = sysprof_notebook_get_property;
+ object_class->set_property = sysprof_notebook_set_property;
+
+ notebook_class->page_added = sysprof_notebook_page_added;
+ notebook_class->page_removed = sysprof_notebook_page_removed;
+}
+
+static void
+sysprof_notebook_init (SysprofNotebook *self)
+{
+ gtk_notebook_set_show_border (GTK_NOTEBOOK (self), FALSE);
+ gtk_notebook_set_scrollable (GTK_NOTEBOOK (self), TRUE);
+ gtk_notebook_popup_enable (GTK_NOTEBOOK (self));
+}
+
+void
+sysprof_notebook_close_current (SysprofNotebook *self)
+{
+ gint page;
+
+ g_return_if_fail (SYSPROF_IS_NOTEBOOK (self));
+
+ if ((page = gtk_notebook_get_current_page (GTK_NOTEBOOK (self))) >= 0)
+ gtk_widget_destroy (gtk_notebook_get_nth_page (GTK_NOTEBOOK (self), page));
+}
diff --git a/src/libsysprof-ui/sysprof-notebook.h b/src/libsysprof-ui/sysprof-notebook.h
new file mode 100644
index 0000000..7a06439
--- /dev/null
+++ b/src/libsysprof-ui/sysprof-notebook.h
@@ -0,0 +1,47 @@
+/* sysprof-notebook.h
+ *
+ * Copyright 2019 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <gtk/gtk.h>
+
+#include "sysprof-version-macros.h"
+
+G_BEGIN_DECLS
+
+#define SYSPROF_TYPE_NOTEBOOK (sysprof_notebook_get_type())
+
+SYSPROF_AVAILABLE_IN_ALL
+G_DECLARE_DERIVABLE_TYPE (SysprofNotebook, sysprof_notebook, SYSPROF, NOTEBOOK, GtkNotebook)
+
+struct _SysprofNotebookClass
+{
+ GtkNotebookClass parent_class;
+
+ /*< private >*/
+ gpointer _reserved[16];
+};
+
+SYSPROF_AVAILABLE_IN_ALL
+GtkWidget *sysprof_notebook_new (void);
+SYSPROF_AVAILABLE_IN_ALL
+void sysprof_notebook_close_current (SysprofNotebook *self);
+
+G_END_DECLS
diff --git a/src/libsysprof-ui/sysprof-tab.c b/src/libsysprof-ui/sysprof-tab.c
new file mode 100644
index 0000000..45c9254
--- /dev/null
+++ b/src/libsysprof-ui/sysprof-tab.c
@@ -0,0 +1,152 @@
+/* sysprof-tab.c
+ *
+ * Copyright 2019 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#define G_LOG_DOMAIN "sysprof-tab"
+
+#include "config.h"
+
+#include "sysprof-display.h"
+#include "sysprof-tab.h"
+
+struct _SysprofTab
+{
+ GtkBox parent_instance;
+
+ GtkButton *close_button;
+ GtkLabel *title;
+
+ SysprofDisplay *display;
+};
+
+G_DEFINE_TYPE (SysprofTab, sysprof_tab, GTK_TYPE_BOX)
+
+enum {
+ PROP_0,
+ PROP_DISPLAY,
+ N_PROPS
+};
+
+static GParamSpec *properties [N_PROPS];
+
+GtkWidget *
+sysprof_tab_new (SysprofDisplay *display)
+{
+ return g_object_new (SYSPROF_TYPE_TAB,
+ "display", display,
+ NULL);
+}
+
+static void
+sysprof_tab_close_clicked (SysprofTab *self,
+ GtkButton *button)
+{
+ g_assert (SYSPROF_IS_TAB (self));
+ g_assert (GTK_IS_BUTTON (button));
+
+ if (self->display != NULL)
+ gtk_widget_destroy (GTK_WIDGET (self->display));
+}
+
+static void
+sysprof_tab_finalize (GObject *object)
+{
+ SysprofTab *self = (SysprofTab *)object;
+
+ g_clear_weak_pointer (&self->display);
+
+ G_OBJECT_CLASS (sysprof_tab_parent_class)->finalize (object);
+}
+
+static void
+sysprof_tab_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ SysprofTab *self = SYSPROF_TAB (object);
+
+ switch (prop_id)
+ {
+ case PROP_DISPLAY:
+ g_value_set_object (value, self->display);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+sysprof_tab_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ SysprofTab *self = SYSPROF_TAB (object);
+
+ switch (prop_id)
+ {
+ case PROP_DISPLAY:
+ g_set_weak_pointer (&self->display, g_value_get_object (value));
+ g_object_bind_property (self->display, "title",
+ self->title, "label",
+ G_BINDING_SYNC_CREATE);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+sysprof_tab_class_init (SysprofTabClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->finalize = sysprof_tab_finalize;
+ object_class->get_property = sysprof_tab_get_property;
+ object_class->set_property = sysprof_tab_set_property;
+
+ gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/sysprof/ui/sysprof-tab.ui");
+ gtk_widget_class_bind_template_child (widget_class, SysprofTab, close_button);
+ gtk_widget_class_bind_template_child (widget_class, SysprofTab, title);
+
+ properties [PROP_DISPLAY] =
+ g_param_spec_object ("display",
+ "Display",
+ "The display widget for the tab",
+ SYSPROF_TYPE_DISPLAY,
+ (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, N_PROPS, properties);
+}
+
+static void
+sysprof_tab_init (SysprofTab *self)
+{
+ gtk_widget_init_template (GTK_WIDGET (self));
+
+ g_signal_connect_object (self->close_button,
+ "clicked",
+ G_CALLBACK (sysprof_tab_close_clicked),
+ self,
+ G_CONNECT_SWAPPED);
+}
diff --git a/src/libsysprof-ui/sysprof-tab.h b/src/libsysprof-ui/sysprof-tab.h
new file mode 100644
index 0000000..1762244
--- /dev/null
+++ b/src/libsysprof-ui/sysprof-tab.h
@@ -0,0 +1,35 @@
+/* sysprof-tab.h
+ *
+ * Copyright 2019 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <gtk/gtk.h>
+
+#include "sysprof-display.h"
+
+G_BEGIN_DECLS
+
+#define SYSPROF_TYPE_TAB (sysprof_tab_get_type())
+
+G_DECLARE_FINAL_TYPE (SysprofTab, sysprof_tab, SYSPROF, TAB, GtkBox)
+
+GtkWidget *sysprof_tab_new (SysprofDisplay *display);
+
+G_END_DECLS
diff --git a/src/libsysprof-ui/sysprof-ui.h b/src/libsysprof-ui/sysprof-ui.h
index 52a3af8..51cbb5b 100644
--- a/src/libsysprof-ui/sysprof-ui.h
+++ b/src/libsysprof-ui/sysprof-ui.h
@@ -30,6 +30,7 @@ G_BEGIN_DECLS
# include "sysprof-capture-view.h"
# include "sysprof-cell-renderer-percent.h"
# include "sysprof-cpu-visualizer-row.h"
+# include "sysprof-display.h"
# include "sysprof-empty-state-view.h"
# include "sysprof-failed-state-view.h"
# include "sysprof-line-visualizer-row.h"
@@ -38,6 +39,7 @@ G_BEGIN_DECLS
# include "sysprof-mark-visualizer-row.h"
# include "sysprof-model-filter.h"
# include "sysprof-multi-paned.h"
+# include "sysprof-notebook.h"
# include "sysprof-process-model-row.h"
# include "sysprof-profiler-menu-button.h"
# include "sysprof-recording-state-view.h"
diff --git a/src/libsysprof-ui/ui/sysprof-display.ui b/src/libsysprof-ui/ui/sysprof-display.ui
new file mode 100644
index 0000000..1392b5a
--- /dev/null
+++ b/src/libsysprof-ui/ui/sysprof-display.ui
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <template class="SysprofDisplay" parent="GtkBin">
+ <child>
+ <object class="GtkStack" id="stack">
+ <property name="homogeneous">false</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="SysprofEmptyStateView" id="empty_view">
+ <property name="title" translatable="yes">Welcome to Sysprof</property>
+ <property name="subtitle" translatable="yes">Start profiling your system with the
<b>Record</b> button above.</property>
+ <property name="visible">true</property>
+ </object>
+ <packing>
+ <property name="name">empty</property>
+ </packing>
+ </child>
+ <child>
+ <object class="SysprofCaptureView" id="capture_view">
+ <property name="visible">true</property>
+ </object>
+ <packing>
+ <property name="name">capture</property>
+ </packing>
+ </child>
+ <child>
+ <object class="SysprofRecordingStateView" id="recording_view">
+ <property name="visible">true</property>
+ </object>
+ <packing>
+ <property name="name">recording</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/src/libsysprof-ui/ui/sysprof-tab.ui b/src/libsysprof-ui/ui/sysprof-tab.ui
new file mode 100644
index 0000000..7f63472
--- /dev/null
+++ b/src/libsysprof-ui/ui/sysprof-tab.ui
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.0 -->
+<interface>
+ <requires lib="gtk+" version="3.0"/>
+ <template class="SysprofTab" parent="GtkBox">
+ <property name="can_focus">False</property>
+ <property name="hexpand">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="title">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="close_button">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="receives_default">False</property>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">window-close-symbolic</property>
+ </object>
+ </child>
+ <style>
+ <class name="flat"/>
+ <class name="small-button"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </template>
+</interface>
diff --git a/src/sysprof/sysprof-application.c b/src/sysprof/sysprof-application.c
index 4405a6b..24e6cd7 100644
--- a/src/sysprof/sysprof-application.c
+++ b/src/sysprof/sysprof-application.c
@@ -36,9 +36,20 @@ struct {
const gchar *action_name;
const gchar *accels[12];
} default_accels[] = {
- { "zoom.zoom-in", { "<Primary>plus", "<Primary>KP_Add", "<Primary>equal", "ZoomIn", NULL } },
- { "zoom.zoom-out", { "<Primary>minus", "<Primary>KP_Subtract", "ZoomOut", NULL } },
- { "zoom.zoom-one", { "<Primary>0", "<Primary>KP_0", NULL } },
+ { "zoom.zoom-in", { "<Primary>plus", "<Primary>KP_Add", "<Primary>equal", "ZoomIn", NULL } },
+ { "zoom.zoom-out", { "<Primary>minus", "<Primary>KP_Subtract", "ZoomOut", NULL } },
+ { "zoom.zoom-one", { "<Primary>0", "<Primary>KP_0", NULL } },
+ { "win.new-tab", { "<Primary>t", NULL } },
+ { "win.close-tab", { "<Primary>w", NULL } },
+ { "win.switch-tab(1)", { "<Alt>1", NULL } },
+ { "win.switch-tab(2)", { "<Alt>2", NULL } },
+ { "win.switch-tab(3)", { "<Alt>3", NULL } },
+ { "win.switch-tab(4)", { "<Alt>4", NULL } },
+ { "win.switch-tab(5)", { "<Alt>5", NULL } },
+ { "win.switch-tab(6)", { "<Alt>6", NULL } },
+ { "win.switch-tab(7)", { "<Alt>7", NULL } },
+ { "win.switch-tab(8)", { "<Alt>8", NULL } },
+ { "win.switch-tab(9)", { "<Alt>9", NULL } },
{ NULL }
};
@@ -70,29 +81,23 @@ sysprof_application_activate (GApplication *app)
static void
sysprof_application_open (GApplication *app,
- GFile **files,
- gint n_files,
- const gchar *hint)
+ GFile **files,
+ gint n_files,
+ const gchar *hint)
{
- guint opened = 0;
- gint i;
+ GtkWidget *window;
g_assert (SYSPROF_IS_APPLICATION (app));
g_assert (files != NULL || n_files == 0);
- for (i = 0; i < n_files; i++)
- {
- SysprofWindow *window;
+ window = sysprof_window_new (SYSPROF_APPLICATION (app));
- window = g_object_new (SYSPROF_TYPE_WINDOW,
- "application", app,
- NULL);
- sysprof_window_open (window, files [i]);
- gtk_window_present (GTK_WINDOW (window));
- opened++;
- }
+ for (gint i = 0; i < n_files; i++)
+ sysprof_window_open (SYSPROF_WINDOW (window), files[i]);
+
+ gtk_window_present (GTK_WINDOW (window));
- if (opened == 0)
+ if (n_files == 0)
sysprof_application_activate (app);
}
@@ -246,7 +251,6 @@ sysprof_open_capture (GSimpleAction *action,
gpointer user_data)
{
GtkApplication *app = user_data;
- GtkWidget *window;
GList *list;
g_assert (G_IS_APPLICATION (app));
@@ -257,29 +261,11 @@ sysprof_open_capture (GSimpleAction *action,
for (; list != NULL; list = list->next)
{
- window = list->data;
+ GtkWindow *window = list->data;
if (SYSPROF_IS_WINDOW (window))
- {
- SysprofWindowState state;
-
- state = sysprof_window_get_state (SYSPROF_WINDOW (window));
-
- if (state == SYSPROF_WINDOW_STATE_EMPTY)
- {
- sysprof_window_open_from_dialog (SYSPROF_WINDOW (window));
- return;
- }
- }
+ sysprof_window_open_from_dialog (SYSPROF_WINDOW (window));
}
-
- window = g_object_new (SYSPROF_TYPE_WINDOW,
- "application", app,
- NULL);
-
- gtk_window_present (GTK_WINDOW (window));
-
- sysprof_window_open_from_dialog (SYSPROF_WINDOW (window));
}
static void
diff --git a/src/sysprof/sysprof-window.c b/src/sysprof/sysprof-window.c
index ca950ba..249637b 100644
--- a/src/sysprof/sysprof-window.c
+++ b/src/sysprof/sysprof-window.c
@@ -1,6 +1,6 @@
/* sysprof-window.c
*
- * Copyright 2016 Christian Hergert <chergert redhat com>
+ * Copyright 2016-2019 Christian Hergert <chergert redhat com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -14,791 +14,84 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*/
#define G_LOG_DOMAIN "sysprof-window"
#include "config.h"
-#include <errno.h>
-#include <glib/gi18n.h>
-#include <math.h>
#include <sysprof-ui.h>
-#include "sysprof-application.h"
#include "sysprof-window.h"
-#include "sysprof-window-settings.h"
struct _SysprofWindow
{
GtkApplicationWindow parent_instance;
-
- SysprofWindowState state;
-
- SysprofProfiler *profiler;
- SysprofCaptureReader *reader;
-
- GCancellable *refilter_cancellable;
-
- /* Gtk widget template children */
- SysprofCallgraphView *callgraph_view;
- SysprofEmptyStateView *empty_view;
- GtkMenuButton *gear_menu_button;
- GtkInfoBar *info_bar;
- GtkLabel *info_bar_label;
- GtkRevealer *info_bar_revealer;
- SysprofMarksView *marks_view;
- GtkPaned *paned;
- SysprofProfilerMenuButton *profiler_menu_button;
- SysprofRecordingStateView *recording_view;
- GtkButton *record_button;
- GtkLabel *subtitle;
- GtkLabel *stat_label;
- GtkLabel *title;
- GtkStack *view_stack;
- SysprofVisualizerView *visualizers;
- SysprofZoomManager *zoom_manager;
- GtkLabel *zoom_one_label;
-
- guint stats_handler;
-
- guint closing : 1;
+ SysprofNotebook *notebook;
};
G_DEFINE_TYPE (SysprofWindow, sysprof_window, GTK_TYPE_APPLICATION_WINDOW)
-static void sysprof_window_set_state (SysprofWindow *self,
- SysprofWindowState state);
-
-enum {
- START_RECORDING,
- STOP_RECORDING,
- N_SIGNALS
-};
-
-static guint signals [N_SIGNALS];
-
-static void sysprof_window_set_profiler (SysprofWindow *self,
- SysprofProfiler *profiler);
-
-static G_GNUC_PRINTF(3, 4) void
-sysprof_window_notify_user (SysprofWindow *self,
- GtkMessageType message_type,
- const gchar *format,
- ...)
-{
- g_autofree gchar *str = NULL;
- va_list args;
-
- g_assert (SYSPROF_IS_WINDOW (self));
- g_assert (format != NULL);
-
- va_start (args, format);
- str = g_strdup_vprintf (format, args);
- va_end (args);
-
- gtk_info_bar_set_message_type (self->info_bar, message_type);
- gtk_label_set_label (self->info_bar_label, str);
- gtk_revealer_set_reveal_child (self->info_bar_revealer, TRUE);
-}
-
-static void
-sysprof_window_action_set (SysprofWindow *self,
- const gchar *action_name,
- const gchar *first_property,
- ...)
-{
- gpointer action;
- va_list args;
-
- g_assert (SYSPROF_IS_WINDOW (self));
- g_assert (action_name != NULL);
-
- action = g_action_map_lookup_action (G_ACTION_MAP (self), action_name);
-
- if (action == NULL)
- {
- g_warning ("Failed to locate action \"%s\"", action_name);
- return;
- }
-
- va_start (args, first_property);
- g_object_set_valist (action, first_property, args);
- va_end (args);
-}
-
-static gboolean
-sysprof_window_update_stats (gpointer data)
-{
- SysprofWindow *self = data;
-
- g_assert (SYSPROF_IS_WINDOW (self));
-
- if (self->profiler != NULL)
- {
- SysprofCaptureWriter *writer;
-
- if (NULL != (writer = sysprof_profiler_get_writer (self->profiler)))
- {
- g_autofree gchar *str = NULL;
- SysprofCaptureStat stbuf;
- guint count;
-
- sysprof_capture_writer_stat (writer, &stbuf);
-
- count = stbuf.frame_count[SYSPROF_CAPTURE_FRAME_SAMPLE];
- /* Translators: %u is the number (amount) of samples. */
- str = g_strdup_printf (_("Samples: %u"), count);
- gtk_label_set_label (self->stat_label, str);
- }
- }
-
- return G_SOURCE_CONTINUE;
-}
-
-
-static void
-sysprof_window_update_subtitle (SysprofWindow *self)
-{
- g_autofree gchar *relative = NULL;
- const gchar *filename;
- const gchar *date;
- GTimeVal tv;
-
- g_assert (SYSPROF_IS_WINDOW (self));
- g_assert (self->reader != NULL);
-
- if (NULL != (filename = sysprof_capture_reader_get_filename (self->reader)))
- {
- g_autoptr(GFile) home = NULL;
- g_autoptr(GFile) file = NULL;
-
- file = g_file_new_for_path (filename);
- home = g_file_new_for_path (g_get_home_dir ());
-
- if (g_file_has_prefix (file, home))
- filename = relative = g_file_get_relative_path (home, file);
- }
-
- if (filename == NULL)
- filename = _("[Memory Capture]");
-
- date = sysprof_capture_reader_get_time (self->reader);
-
- if (g_time_val_from_iso8601 (date, &tv))
- {
- g_autoptr(GDateTime) dt = NULL;
- g_autofree gchar *str = NULL;
- g_autofree gchar *label = NULL;
-
- dt = g_date_time_new_from_timeval_local (&tv);
- str = g_date_time_format (dt, "%x %X");
-
- /* Translators: The first %s is a file name, the second is the date and time. */
- label = g_strdup_printf (_("%s — %s"), filename, str);
-
- gtk_label_set_label (self->subtitle, label);
- }
- else
- gtk_label_set_label (self->subtitle, filename);
-}
-
-static void
-sysprof_window_build_profile_cb (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
-{
- SysprofProfile *profile = (SysprofProfile *)object;
- g_autoptr(SysprofWindow) self = user_data;
- g_autoptr(GError) error = NULL;
-
- g_assert (SYSPROF_IS_CALLGRAPH_PROFILE (profile));
- g_assert (SYSPROF_IS_WINDOW (self));
- g_assert (G_IS_ASYNC_RESULT (result));
-
- gtk_widget_set_sensitive (GTK_WIDGET (self->record_button), TRUE);
-
- if (!sysprof_profile_generate_finish (profile, result, &error))
- {
- /* If we were cancelled while updating the selection, ignore the failure */
- if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) &&
- (self->state == SYSPROF_WINDOW_STATE_BROWSING))
- return;
- sysprof_window_notify_user (self, GTK_MESSAGE_ERROR, "%s", error->message);
- sysprof_window_set_state (self, SYSPROF_WINDOW_STATE_EMPTY);
- return;
- }
-
- sysprof_callgraph_view_set_profile (self->callgraph_view, SYSPROF_CALLGRAPH_PROFILE (profile));
- if (sysprof_callgraph_view_get_n_functions (self->callgraph_view) == 0)
- sysprof_window_notify_user (self,
- GTK_MESSAGE_WARNING,
- _("Not enough samples were collected to generate a callgraph"));
-
- sysprof_visualizer_view_set_reader (self->visualizers, self->reader);
-
- sysprof_window_set_state (self, SYSPROF_WINDOW_STATE_BROWSING);
-}
-
-static void
-sysprof_window_build_profile (SysprofWindow *self)
-{
- g_autoptr(SysprofProfile) profile = NULL;
- SysprofSelection *selection;
-
- g_assert (SYSPROF_IS_WINDOW (self));
- g_assert (self->reader != NULL);
-
- if (self->refilter_cancellable != NULL)
- {
- if (!g_cancellable_is_cancelled (self->refilter_cancellable))
- g_cancellable_cancel (self->refilter_cancellable);
- g_clear_object (&self->refilter_cancellable);
- }
-
- selection = sysprof_visualizer_view_get_selection (self->visualizers);
-
- profile = sysprof_callgraph_profile_new_with_selection (selection);
- sysprof_profile_set_reader (profile, self->reader);
-
- self->refilter_cancellable = g_cancellable_new ();
-
- gtk_widget_set_sensitive (GTK_WIDGET (self->record_button), FALSE);
-
- sysprof_profile_generate (profile,
- self->refilter_cancellable,
- sysprof_window_build_profile_cb,
- g_object_ref (self));
-
- sysprof_marks_view_load_async (self->marks_view, self->reader, selection, NULL, NULL, NULL);
-}
-
-static void
-add_class (gpointer widget,
- const gchar *name)
-{
- g_assert (GTK_IS_WIDGET (widget));
-
- gtk_style_context_add_class (gtk_widget_get_style_context (widget), name);
-}
-
-static void
-remove_class (gpointer widget,
- const gchar *name)
-{
- g_assert (GTK_IS_WIDGET (widget));
-
- gtk_style_context_remove_class (gtk_widget_get_style_context (widget), name);
-}
-
-static void
-sysprof_window_set_state (SysprofWindow *self,
- SysprofWindowState state)
-{
- g_autoptr(SysprofProfiler) profiler = NULL;
-
- g_assert (SYSPROF_IS_WINDOW (self));
-
- if (self->state == state)
- return;
-
- self->state = state;
-
- switch (state)
- {
- case SYSPROF_WINDOW_STATE_EMPTY:
- case SYSPROF_WINDOW_STATE_FAILED:
- /* Translators: This is a button. */
- gtk_button_set_label (self->record_button, _("Record"));
- gtk_widget_set_sensitive (GTK_WIDGET (self->record_button), TRUE);
- add_class (self->record_button, "suggested-action");
- remove_class (self->record_button, "destructive-action");
- if (state == SYSPROF_WINDOW_STATE_FAILED)
- gtk_stack_set_visible_child_name (self->view_stack, "failed");
- else
- gtk_stack_set_visible_child_name (self->view_stack, "empty");
- gtk_label_set_label (self->subtitle, _("Not running"));
- sysprof_callgraph_view_set_profile (self->callgraph_view, NULL);
- gtk_widget_set_visible (GTK_WIDGET (self->stat_label), FALSE);
- g_clear_pointer (&self->reader, sysprof_capture_reader_unref);
- sysprof_window_action_set (self, "close-capture", "enabled", FALSE, NULL);
- sysprof_window_action_set (self, "save-capture", "enabled", FALSE, NULL);
- sysprof_window_action_set (self, "screenshot", "enabled", FALSE, NULL);
- profiler = sysprof_local_profiler_new ();
- sysprof_window_set_profiler (self, profiler);
- break;
-
- case SYSPROF_WINDOW_STATE_RECORDING:
- /* Translators: This is a button. */
- gtk_button_set_label (self->record_button, _("Stop"));
- gtk_widget_set_sensitive (GTK_WIDGET (self->record_button), TRUE);
- remove_class (self->record_button, "suggested-action");
- add_class (self->record_button, "destructive-action");
- gtk_stack_set_visible_child_name (self->view_stack, "recording");
- gtk_label_set_label (self->subtitle, _("Recording…"));
- gtk_widget_set_visible (GTK_WIDGET (self->stat_label), TRUE);
- g_clear_pointer (&self->reader, sysprof_capture_reader_unref);
- sysprof_callgraph_view_set_profile (self->callgraph_view, NULL);
- sysprof_window_action_set (self, "close-capture", "enabled", FALSE, NULL);
- sysprof_window_action_set (self, "save-capture", "enabled", FALSE, NULL);
- sysprof_window_action_set (self, "screenshot", "enabled", FALSE, NULL);
- break;
-
- case SYSPROF_WINDOW_STATE_PROCESSING:
- gtk_widget_set_sensitive (GTK_WIDGET (self->record_button), FALSE);
- gtk_label_set_label (self->subtitle, _("Building profile…"));
- sysprof_window_action_set (self, "close-capture", "enabled", FALSE, NULL);
- sysprof_window_action_set (self, "save-capture", "enabled", FALSE, NULL);
- sysprof_window_action_set (self, "screenshot", "enabled", FALSE, NULL);
- sysprof_window_build_profile (self);
- break;
-
- case SYSPROF_WINDOW_STATE_BROWSING:
- /* Translators: This is a button. */
- gtk_button_set_label (self->record_button, _("Record"));
- gtk_widget_set_sensitive (GTK_WIDGET (self->record_button), TRUE);
- add_class (self->record_button, "suggested-action");
- remove_class (self->record_button, "destructive-action");
- gtk_widget_set_visible (GTK_WIDGET (self->stat_label), TRUE);
- gtk_stack_set_visible_child_name (self->view_stack, "browsing");
- sysprof_window_update_stats (self);
- sysprof_window_update_subtitle (self);
- sysprof_window_action_set (self, "close-capture", "enabled", TRUE, NULL);
- sysprof_window_action_set (self, "save-capture", "enabled", TRUE, NULL);
- sysprof_window_action_set (self, "screenshot", "enabled", TRUE, NULL);
- profiler = sysprof_local_profiler_new ();
- sysprof_window_set_profiler (self, profiler);
- break;
-
- case SYSPROF_WINDOW_STATE_0:
- default:
- g_warning ("Unknown state: %0d", state);
- break;
- }
-}
-
-static void
-sysprof_window_enable_stats (SysprofWindow *self)
-{
- g_assert (SYSPROF_IS_WINDOW (self));
-
- if (self->stats_handler == 0)
- self->stats_handler =
- g_timeout_add_seconds (1, sysprof_window_update_stats, self);
-}
-
-static void
-sysprof_window_disable_stats (SysprofWindow *self)
-{
- g_assert (SYSPROF_IS_WINDOW (self));
-
- if (self->stats_handler != 0)
- {
- g_source_remove (self->stats_handler);
- self->stats_handler = 0;
- }
-}
-
-static void
-sysprof_window_add_sources (SysprofWindow *window,
- SysprofProfiler *profiler)
-{
-#ifdef __linux__
- g_autoptr(SysprofSource) host_source = NULL;
- g_autoptr(SysprofSource) proc_source = NULL;
- g_autoptr(SysprofSource) perf_source = NULL;
- g_autoptr(SysprofSource) memory_source = NULL;
-
- g_assert (SYSPROF_IS_WINDOW (window));
- g_assert (SYSPROF_IS_PROFILER (profiler));
-
- proc_source = sysprof_proc_source_new ();
- sysprof_profiler_add_source (profiler, proc_source);
-
- perf_source = sysprof_perf_source_new ();
- sysprof_profiler_add_source (profiler, perf_source);
-
- host_source = sysprof_hostinfo_source_new ();
- sysprof_profiler_add_source (profiler, host_source);
-
- memory_source = sysprof_memory_source_new ();
- sysprof_profiler_add_source (profiler, memory_source);
-#endif
-}
-
-static void
-sysprof_window_start_recording (SysprofWindow *self)
-{
- g_assert (SYSPROF_IS_WINDOW (self));
-
- if ((self->state == SYSPROF_WINDOW_STATE_EMPTY) ||
- (self->state == SYSPROF_WINDOW_STATE_FAILED) ||
- (self->state == SYSPROF_WINDOW_STATE_BROWSING))
- {
- gtk_revealer_set_reveal_child (self->info_bar_revealer, FALSE);
- sysprof_window_add_sources (self, self->profiler);
- sysprof_window_set_state (self, SYSPROF_WINDOW_STATE_RECORDING);
- sysprof_window_enable_stats (self);
- sysprof_profiler_start (self->profiler);
- return;
- }
-}
-
-static void
-sysprof_window_stop_recording (SysprofWindow *self)
-{
- g_assert (SYSPROF_IS_WINDOW (self));
-
- if (self->state == SYSPROF_WINDOW_STATE_RECORDING)
- {
- if (self->profiler != NULL)
- {
- /* SysprofProfiler::stopped will move us to generating */
- gtk_label_set_label (self->subtitle, _("Stopping…"));
- /*
- * In case that ::stopped takes a while to execute,
- * disable record button immediately.
- */
- gtk_widget_set_sensitive (GTK_WIDGET (self->record_button), FALSE);
- sysprof_profiler_stop (self->profiler);
- }
- }
-}
-
-static void
-sysprof_window_hide_info_bar_revealer (SysprofWindow *self)
-{
- g_assert (SYSPROF_IS_WINDOW (self));
-
- gtk_revealer_set_reveal_child (self->info_bar_revealer, FALSE);
-}
-
-static void
-sysprof_window_profiler_stopped (SysprofWindow *self,
- SysprofProfiler *profiler)
-{
- g_autoptr(SysprofCaptureReader) reader = NULL;
- g_autoptr(GError) error = NULL;
- SysprofCaptureWriter *writer;
-
- g_assert (SYSPROF_IS_WINDOW (self));
- g_assert (SYSPROF_IS_PROFILER (profiler));
-
- sysprof_window_disable_stats (self);
-
- if (self->closing)
- {
- gtk_window_close (GTK_WINDOW (self));
- return;
- }
-
- if (self->state == SYSPROF_WINDOW_STATE_FAILED)
- return;
-
- writer = sysprof_profiler_get_writer (profiler);
- reader = sysprof_capture_writer_create_reader (writer, &error);
-
- if (reader == NULL)
- {
- sysprof_window_notify_user (self, GTK_MESSAGE_ERROR, "%s", error->message);
- sysprof_window_set_state (self, SYSPROF_WINDOW_STATE_EMPTY);
- return;
- }
-
- g_clear_pointer (&self->reader, sysprof_capture_reader_unref);
- self->reader = g_steal_pointer (&reader);
-
- sysprof_window_build_profile (self);
-}
-
-static void
-sysprof_window_profiler_failed (SysprofWindow *self,
- const GError *reason,
- SysprofProfiler *profiler)
-{
- g_assert (SYSPROF_IS_WINDOW (self));
- g_assert (reason != NULL);
- g_assert (SYSPROF_IS_PROFILER (profiler));
-
- sysprof_window_notify_user (self, GTK_MESSAGE_ERROR, "%s", reason->message);
- sysprof_window_set_state (self, SYSPROF_WINDOW_STATE_FAILED);
-}
-
-static void
-sysprof_window_set_profiler (SysprofWindow *self,
- SysprofProfiler *profiler)
+/**
+ * sysprof_window_new:
+ *
+ * Create a new #SysprofWindow.
+ *
+ * Returns: (transfer full): a newly created #SysprofWindow
+ */
+GtkWidget *
+sysprof_window_new (SysprofApplication *application)
{
- g_assert (SYSPROF_IS_WINDOW (self));
- g_assert (SYSPROF_IS_PROFILER (profiler));
-
- if (self->profiler != profiler)
- {
- if (self->profiler != NULL)
- {
- if (sysprof_profiler_get_is_running (self->profiler))
- sysprof_profiler_stop (self->profiler);
- sysprof_profiler_menu_button_set_profiler (self->profiler_menu_button, NULL);
- sysprof_recording_state_view_set_profiler (self->recording_view, NULL);
- g_clear_object (&self->profiler);
- }
-
- if (profiler != NULL)
- {
- if (!sysprof_profiler_get_is_mutable (profiler))
- {
- g_warning ("Ignoring attempt to set profiler to an already running session!");
- return;
- }
-
- self->profiler = g_object_ref (profiler);
-
- g_signal_connect_object (profiler,
- "stopped",
- G_CALLBACK (sysprof_window_profiler_stopped),
- self,
- G_CONNECT_SWAPPED);
-
- g_signal_connect_object (profiler,
- "failed",
- G_CALLBACK (sysprof_window_profiler_failed),
- self,
- G_CONNECT_SWAPPED);
-
- sysprof_profiler_menu_button_set_profiler (self->profiler_menu_button, profiler);
- sysprof_recording_state_view_set_profiler (self->recording_view, profiler);
- }
- }
+ return g_object_new (SYSPROF_TYPE_WINDOW,
+ "application", application,
+ NULL);
}
static void
-sysprof_window_open_capture (GSimpleAction *action,
- GVariant *variant,
- gpointer user_data)
+new_tab_cb (GSimpleAction *action,
+ GVariant *param,
+ gpointer user_data)
{
SysprofWindow *self = user_data;
- g_assert (G_IS_SIMPLE_ACTION (action));
- g_assert (variant == NULL);
- g_assert (SYSPROF_IS_WINDOW (self));
-
- sysprof_window_open_from_dialog (self);
-}
-
-static void
-sysprof_window_save_capture (GSimpleAction *action,
- GVariant *variant,
- gpointer user_data)
-{
- g_autoptr(SysprofCaptureReader) reader = NULL;
- SysprofWindow *self = user_data;
- GtkFileChooserNative *dialog;
- gint response;
-
- g_assert (G_IS_SIMPLE_ACTION (action));
- g_assert (variant == NULL);
- g_assert (SYSPROF_IS_WINDOW (self));
-
- if (self->reader == NULL)
- {
- g_warning ("Save called without a capture open, ignoring");
- return;
- }
-
- reader = sysprof_capture_reader_ref (self->reader);
-
- /* Translators: This is a window title. */
- dialog = gtk_file_chooser_native_new (_("Save Capture As…"),
- GTK_WINDOW (self),
- GTK_FILE_CHOOSER_ACTION_SAVE,
- /* Translators: This is a button. */
- _("Save"),
- /* Translators: This is a button. */
- _("Cancel"));
-
- gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (dialog), TRUE);
-
- response = gtk_native_dialog_run (GTK_NATIVE_DIALOG (dialog));
-
- if (response == GTK_RESPONSE_ACCEPT)
- {
- g_autofree gchar *filename = NULL;
- g_autoptr(GError) error = NULL;
-
- filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
-
- if (filename == NULL)
- goto failure;
-
- if (!g_str_has_suffix (filename, ".syscap"))
- {
- gchar *tmp;
-
- tmp = g_strdup_printf ("%s.syscap", filename);
- g_free (filename);
- filename = tmp;
- }
-
- /* this should really be done outside the main loop. */
- if (!sysprof_capture_reader_save_as (reader, filename, &error))
- {
- sysprof_window_notify_user (self,
- GTK_MESSAGE_ERROR,
- /* Translators: %s is the error message. */
- _("An error occurred while attempting to save your capture: %s"),
- error->message);
- goto failure;
- }
- }
+ g_return_if_fail (SYSPROF_IS_WINDOW (self));
-failure:
- gtk_native_dialog_destroy (GTK_NATIVE_DIALOG (dialog));
+ sysprof_window_new_tab (self);
}
static void
-sysprof_window_close_capture (GSimpleAction *action,
- GVariant *variant,
- gpointer user_data)
+switch_tab_cb (GSimpleAction *action,
+ GVariant *param,
+ gpointer user_data)
{
SysprofWindow *self = user_data;
+ gint page;
- g_assert (G_IS_SIMPLE_ACTION (action));
- g_assert (variant == NULL);
- g_assert (SYSPROF_IS_WINDOW (self));
-
- sysprof_window_set_state (self, SYSPROF_WINDOW_STATE_EMPTY);
-}
-
-static void
-sysprof_window_record_button_clicked (SysprofWindow *self,
- GtkButton *button)
-{
- g_assert (SYSPROF_IS_WINDOW (self));
- g_assert (GTK_IS_BUTTON (button));
+ g_return_if_fail (SYSPROF_IS_WINDOW (self));
+ g_return_if_fail (g_variant_is_of_type (param, G_VARIANT_TYPE_INT32));
- if (self->state == SYSPROF_WINDOW_STATE_RECORDING)
- sysprof_window_stop_recording (self);
- else
- sysprof_window_start_recording (self);
+ page = g_variant_get_int32 (param);
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (self->notebook), page - 1);
}
static void
-sysprof_window_screenshot (GSimpleAction *action,
- GVariant *variant,
- gpointer user_data)
+close_tab_cb (GSimpleAction *action,
+ GVariant *param,
+ gpointer user_data)
{
SysprofWindow *self = user_data;
- g_autofree gchar *str = NULL;
- GtkWindow *window;
- GtkScrolledWindow *scroller;
- GtkTextView *text_view;
-
- g_assert (G_IS_SIMPLE_ACTION (action));
- g_assert (SYSPROF_IS_WINDOW (self));
-
- if (NULL == (str = sysprof_callgraph_view_screenshot (self->callgraph_view)))
- return;
-
- window = g_object_new (GTK_TYPE_WINDOW,
- "title", "Sysprof",
- "default-width", 800,
- "default-height", 600,
- "transient-for", self,
- NULL);
-
- scroller = g_object_new (GTK_TYPE_SCROLLED_WINDOW,
- "visible", TRUE,
- NULL);
- gtk_container_add (GTK_CONTAINER (window), GTK_WIDGET (scroller));
-
- text_view = g_object_new (GTK_TYPE_TEXT_VIEW,
- "editable", FALSE,
- "monospace", TRUE,
- "visible", TRUE,
- NULL);
- gtk_container_add (GTK_CONTAINER (scroller), GTK_WIDGET (text_view));
-
- gtk_text_buffer_set_text (gtk_text_view_get_buffer (text_view), str, -1);
-
- gtk_window_present (window);
-}
-
-static gboolean
-sysprof_window_delete_event (GtkWidget *widget,
- GdkEventAny *event)
-{
- SysprofWindow *self = (SysprofWindow *)widget;
- g_assert (SYSPROF_IS_WINDOW (self));
- g_assert (event != NULL);
-
- if (self->state == SYSPROF_WINDOW_STATE_RECORDING)
- {
- if (self->profiler != NULL)
- {
- if (self->closing == FALSE)
- {
- self->closing = TRUE;
- sysprof_profiler_stop (self->profiler);
- return GDK_EVENT_STOP;
- }
- }
- }
-
- return GDK_EVENT_PROPAGATE;
-}
-
-static gboolean
-zoom_level_to_string (GBinding *binding,
- const GValue *from_value,
- GValue *to_value,
- gpointer user_data)
-{
- gdouble percent = 100.0 * g_value_get_double (from_value);
- g_value_take_string (to_value, g_strdup_printf ("%u%%", (guint)floor (percent)));
- return TRUE;
-}
-
-static void
-sysprof_window_visualizers_selection_changed (SysprofWindow *self,
- SysprofSelection *selection)
-{
- g_assert (SYSPROF_IS_WINDOW (self));
- g_assert (SYSPROF_IS_SELECTION (selection));
-
- sysprof_window_build_profile (self);
-}
-
-static void
-sysprof_window_destroy (GtkWidget *widget)
-{
- SysprofWindow *self = (SysprofWindow *)widget;
-
- if (self->refilter_cancellable != NULL)
- {
- if (!g_cancellable_is_cancelled (self->refilter_cancellable))
- g_cancellable_cancel (self->refilter_cancellable);
- g_clear_object (&self->refilter_cancellable);
- }
-
- g_clear_object (&self->profiler);
- g_clear_pointer (&self->reader, sysprof_capture_reader_unref);
- sysprof_window_disable_stats (self);
+ g_return_if_fail (SYSPROF_IS_WINDOW (self));
- GTK_WIDGET_CLASS (sysprof_window_parent_class)->destroy (widget);
+ sysprof_notebook_close_current (self->notebook);
}
static void
-sysprof_window_constructed (GObject *object)
+sysprof_window_finalize (GObject *object)
{
- SysprofWindow *self = (SysprofWindow *)object;
- g_autoptr(SysprofProfiler) profiler = NULL;
-
- G_OBJECT_CLASS (sysprof_window_parent_class)->constructed (object);
-
- profiler = sysprof_local_profiler_new ();
- sysprof_window_set_profiler (self, profiler);
-
- sysprof_window_set_state (self, SYSPROF_WINDOW_STATE_EMPTY);
+ G_OBJECT_CLASS (sysprof_window_parent_class)->finalize (object);
}
static void
@@ -806,255 +99,61 @@ sysprof_window_class_init (SysprofWindowClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
- GtkBindingSet *binding_set;
-
- object_class->constructed = sysprof_window_constructed;
-
- widget_class->delete_event = sysprof_window_delete_event;
- widget_class->destroy = sysprof_window_destroy;
-
- signals [START_RECORDING] =
- g_signal_new_class_handler ("start-recording",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
- G_CALLBACK (sysprof_window_start_recording),
- NULL, NULL, NULL, G_TYPE_NONE, 0);
-
- signals [STOP_RECORDING] =
- g_signal_new_class_handler ("stop-recording",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
- G_CALLBACK (sysprof_window_stop_recording),
- NULL, NULL, NULL, G_TYPE_NONE, 0);
- binding_set = gtk_binding_set_by_class (klass);
- gtk_binding_entry_add_signal (binding_set, GDK_KEY_Escape, 0, "stop-recording", 0);
+ object_class->finalize = sysprof_window_finalize;
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/sysprof/ui/sysprof-window.ui");
- gtk_widget_class_bind_template_child (widget_class, SysprofWindow, callgraph_view);
- gtk_widget_class_bind_template_child (widget_class, SysprofWindow, empty_view);
- gtk_widget_class_bind_template_child (widget_class, SysprofWindow, gear_menu_button);
- gtk_widget_class_bind_template_child (widget_class, SysprofWindow, info_bar);
- gtk_widget_class_bind_template_child (widget_class, SysprofWindow, info_bar_label);
- gtk_widget_class_bind_template_child (widget_class, SysprofWindow, info_bar_revealer);
- gtk_widget_class_bind_template_child (widget_class, SysprofWindow, marks_view);
- gtk_widget_class_bind_template_child (widget_class, SysprofWindow, paned);
- gtk_widget_class_bind_template_child (widget_class, SysprofWindow, profiler_menu_button);
- gtk_widget_class_bind_template_child (widget_class, SysprofWindow, record_button);
- gtk_widget_class_bind_template_child (widget_class, SysprofWindow, recording_view);
- gtk_widget_class_bind_template_child (widget_class, SysprofWindow, stat_label);
- gtk_widget_class_bind_template_child (widget_class, SysprofWindow, subtitle);
- gtk_widget_class_bind_template_child (widget_class, SysprofWindow, title);
- gtk_widget_class_bind_template_child (widget_class, SysprofWindow, view_stack);
- gtk_widget_class_bind_template_child (widget_class, SysprofWindow, visualizers);
- gtk_widget_class_bind_template_child (widget_class, SysprofWindow, zoom_manager);
- gtk_widget_class_bind_template_child (widget_class, SysprofWindow, zoom_one_label);
+ gtk_widget_class_bind_template_child (widget_class, SysprofWindow , notebook);
- g_type_ensure (SYSPROF_TYPE_MARKS_VIEW);
+ g_type_ensure (SYSPROF_TYPE_PROFILER_MENU_BUTTON);
+ g_type_ensure (SYSPROF_TYPE_NOTEBOOK);
+ g_type_ensure (SYSPROF_TYPE_DISPLAY);
}
static void
sysprof_window_init (SysprofWindow *self)
{
- static GActionEntry action_entries[] = {
- { "close-capture", sysprof_window_close_capture },
- { "open-capture", sysprof_window_open_capture },
- { "save-capture", sysprof_window_save_capture },
- { "screenshot", sysprof_window_screenshot },
+ static GActionEntry actions[] = {
+ { "close-tab", close_tab_cb },
+ { "new-tab", new_tab_cb },
+ { "switch-tab", switch_tab_cb, "i" },
};
- SysprofSelection *selection;
- g_autoptr(GtkWindowGroup) window_group = NULL;
gtk_widget_init_template (GTK_WIDGET (self));
-#ifdef DEVELOPMENT_BUILD
- gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (self)), "development-version");
-#endif
-
- /*
- * Hookup widget signals.
- */
-
- g_signal_connect_object (self->info_bar,
- "response",
- G_CALLBACK (sysprof_window_hide_info_bar_revealer),
- self,
- G_CONNECT_SWAPPED);
-
- g_signal_connect_object (self->info_bar,
- "close",
- G_CALLBACK (sysprof_window_hide_info_bar_revealer),
- self,
- G_CONNECT_SWAPPED);
-
- g_signal_connect_object (self->record_button,
- "clicked",
- G_CALLBACK (sysprof_window_record_button_clicked),
- self,
- G_CONNECT_SWAPPED);
-
- g_object_bind_property_full (self->zoom_manager, "zoom", self->zoom_one_label, "label",
- G_BINDING_SYNC_CREATE,
- zoom_level_to_string, NULL, NULL, NULL);
-
- /*
- * Wire up selections for visualizers to update callgraph.
- */
-
- selection = sysprof_visualizer_view_get_selection (self->visualizers);
-
- g_signal_connect_object (selection,
- "changed",
- G_CALLBACK (sysprof_window_visualizers_selection_changed),
- self,
- G_CONNECT_SWAPPED);
-
- /*
- * Setup actions for the window.
- */
g_action_map_add_action_entries (G_ACTION_MAP (self),
- action_entries,
- G_N_ELEMENTS (action_entries),
+ actions,
+ G_N_ELEMENTS (actions),
self);
- gtk_widget_insert_action_group (GTK_WIDGET (self), "zoom", G_ACTION_GROUP (self->zoom_manager));
-
- /*
- * Restore previous window settings.
- */
- sysprof_window_settings_register (GTK_WINDOW (self));
-
- /*
- * Set default focus to the record button for quick workflow of
- * launch, enter, escape, view.
- */
- gtk_window_set_focus (GTK_WINDOW (self), GTK_WIDGET (self->record_button));
-
- /*
- * Prevent grabs (e.g. modal dialogs) from affecting multiple windows.
- */
- window_group = gtk_window_group_new ();
- gtk_window_group_add_window (window_group, GTK_WINDOW (self));
-}
-
-static void
-sysprof_window_open_cb (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
-{
- SysprofWindow *self = (SysprofWindow *)object;
- g_autoptr(SysprofCaptureReader) reader = NULL;
- g_autoptr(GError) error = NULL;
-
- g_assert (SYSPROF_IS_WINDOW (self));
- g_assert (G_IS_TASK (result));
-
- if (!(reader = g_task_propagate_pointer (G_TASK (result), &error)))
- {
- sysprof_window_notify_user (self,
- GTK_MESSAGE_ERROR,
- "%s", error->message);
- return;
- }
-
- g_clear_pointer (&self->reader, sysprof_capture_reader_unref);
- self->reader = g_steal_pointer (&reader);
-
- sysprof_window_set_state (self, SYSPROF_WINDOW_STATE_PROCESSING);
-}
-
-static void
-sysprof_window_open_worker (GTask *task,
- gpointer source_object,
- gpointer task_data,
- GCancellable *cancellable)
-{
- g_autofree gchar *path = NULL;
- g_autoptr(GError) error = NULL;
- SysprofCaptureReader *reader;
- GFile *file = task_data;
-
- g_assert (G_IS_TASK (task));
- g_assert (SYSPROF_IS_WINDOW (source_object));
- g_assert (G_IS_FILE (file));
-
- path = g_file_get_path (file);
-
- if (!(reader = sysprof_capture_reader_new (path, &error)))
- g_task_return_error (task, g_steal_pointer (&error));
- else
- g_task_return_pointer (task,
- g_steal_pointer (&reader),
- (GDestroyNotify)sysprof_capture_reader_unref);
}
void
sysprof_window_open (SysprofWindow *self,
GFile *file)
{
- g_autoptr(GTask) task = NULL;
-
g_return_if_fail (SYSPROF_IS_WINDOW (self));
g_return_if_fail (G_IS_FILE (file));
- if (!g_file_is_native (file))
- {
- sysprof_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, sysprof_window_open_cb, NULL);
- g_task_set_task_data (task, g_object_ref (file), g_object_unref);
- g_task_run_in_thread (task, sysprof_window_open_worker);
}
-SysprofWindowState
-sysprof_window_get_state (SysprofWindow *self)
+void
+sysprof_window_open_from_dialog (SysprofWindow *self)
{
- g_return_val_if_fail (SYSPROF_IS_WINDOW (self), SYSPROF_WINDOW_STATE_0);
-
- return self->state;
+ g_return_if_fail (SYSPROF_IS_WINDOW (self));
}
void
-sysprof_window_open_from_dialog (SysprofWindow *self)
+sysprof_window_new_tab (SysprofWindow *self)
{
- GtkFileChooserNative *dialog;
- GtkFileFilter *filter;
- gint response;
-
- g_assert (SYSPROF_IS_WINDOW (self));
-
- /* Translators: This is a window title. */
- dialog = gtk_file_chooser_native_new (_("Open Capture…"),
- GTK_WINDOW (self),
- GTK_FILE_CHOOSER_ACTION_OPEN,
- /* Translators: This is a button. */
- _("Open"),
- /* Translators: This is a button. */
- _("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);
+ GtkWidget *display;
+ gint page;
- 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)
- {
- g_autoptr(GFile) file = NULL;
+ g_return_if_fail (SYSPROF_IS_WINDOW (self));
- file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
- sysprof_window_open (self, file);
- }
+ display = sysprof_display_new ();
+ page = gtk_notebook_insert_page (GTK_NOTEBOOK (self->notebook), display, NULL, -1);
+ gtk_widget_show (display);
- gtk_native_dialog_destroy (GTK_NATIVE_DIALOG (dialog));
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (self->notebook), page);
}
diff --git a/src/sysprof/sysprof-window.h b/src/sysprof/sysprof-window.h
index ca0ceb9..1b88aea 100644
--- a/src/sysprof/sysprof-window.h
+++ b/src/sysprof/sysprof-window.h
@@ -1,6 +1,6 @@
/* sysprof-window.h
*
- * Copyright 2016 Christian Hergert <chergert redhat com>
+ * Copyright 2016-2019 Christian Hergert <chergert redhat com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -14,39 +14,26 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
*/
-#ifndef SYSPROF_WINDOW_H
-#define SYSPROF_WINDOW_H
+#pragma once
#include <gtk/gtk.h>
+#include "sysprof-application.h"
+
G_BEGIN_DECLS
#define SYSPROF_TYPE_WINDOW (sysprof_window_get_type())
G_DECLARE_FINAL_TYPE (SysprofWindow, sysprof_window, SYSPROF, WINDOW, GtkApplicationWindow)
-typedef enum
-{
- SYSPROF_WINDOW_STATE_0,
- SYSPROF_WINDOW_STATE_EMPTY,
- SYSPROF_WINDOW_STATE_FAILED,
- SYSPROF_WINDOW_STATE_RECORDING,
- SYSPROF_WINDOW_STATE_PROCESSING,
- SYSPROF_WINDOW_STATE_BROWSING,
-} SysprofWindowState;
-
-SysprofWindowState sysprof_window_get_state (SysprofWindow *self);
-gboolean sysprof_window_get_recording (SysprofWindow *self);
-GFile *sysprof_window_get_capture_file (SysprofWindow *self);
-void sysprof_window_set_capture_file (SysprofWindow *self,
- GFile *capture_file);
-void sysprof_window_open (SysprofWindow *self,
- GFile *file);
-void sysprof_window_open_from_dialog (SysprofWindow *self);
+GtkWidget *sysprof_window_new (SysprofApplication *application);
+void sysprof_window_new_tab (SysprofWindow *self);
+void sysprof_window_open (SysprofWindow *self,
+ GFile *file);
+void sysprof_window_open_from_dialog (SysprofWindow *self);
G_END_DECLS
-
-#endif /* SYSPROF_WINDOW_H */
-
diff --git a/src/sysprof/ui/sysprof-window.ui b/src/sysprof/ui/sysprof-window.ui
index b92247d..a5e85db 100644
--- a/src/sysprof/ui/sysprof-window.ui
+++ b/src/sysprof/ui/sysprof-window.ui
@@ -70,296 +70,17 @@
<property name="position">1</property>
</packing>
</child>
- <child>
- <object class="GtkMenuButton" id="gear_menu_button">
- <property name="popover">gear_popover</property>
- <property name="visible">true</property>
- <style>
- <class name="image-button"/>
- </style>
- <child>
- <object class="GtkImage">
- <property name="icon-name">open-menu-symbolic</property>
- <property name="visible">true</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="pack-type">end</property>
- <property name="position">0</property>
- </packing>
- </child>
</object>
</child>
<child>
- <object class="GtkBox">
- <property name="orientation">vertical</property>
+ <object class="SysprofNotebook" id="notebook">
<property name="visible">true</property>
<child>
- <object class="GtkRevealer" id="info_bar_revealer">
+ <object class="SysprofDisplay">
<property name="visible">true</property>
- <property name="reveal-child">false</property>
- <child>
- <object class="GtkInfoBar" id="info_bar">
- <property name="visible">true</property>
- <child internal-child="content_area">
- <object class="GtkBox">
- <child>
- <object class="GtkLabel" id="info_bar_label">
- <property name="hexpand">true</property>
- <property name="label">Failure</property>
- <property name="visible">true</property>
- <property name="wrap">true</property>
- <property name="xalign">0</property>
- </object>
- </child>
- <child>
- <object class="GtkButton" id="close_info_button">
- <property name="label" translatable="yes" comments="Translators: This is a
button.">_Close</property>
- <property name="use-underline">true</property>
- <property name="visible">true</property>
- <property name="width-request">100</property>
- </object>
- </child>
- </object>
- </child>
- <action-widgets>
- <action-widget response="0">close_info_button</action-widget>
- </action-widgets>
- </object>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkStack" id="view_stack">
- <property name="expand">true</property>
- <property name="transition-duration">400</property>
- <property name="transition-type">crossfade</property>
- <property name="visible">true</property>
- <child>
- <object class="SysprofEmptyStateView" id="empty_view">
- <property name="visible">true</property>
- </object>
- <packing>
- <property name="name">empty</property>
- </packing>
- </child>
- <child>
- <object class="SysprofFailedStateView" id="failed_view">
- <property name="visible">true</property>
- </object>
- <packing>
- <property name="name">failed</property>
- </packing>
- </child>
- <child>
- <object class="SysprofRecordingStateView" id="recording_view">
- <property name="visible">true</property>
- </object>
- <packing>
- <property name="name">recording</property>
- </packing>
- </child>
- <child>
- <object class="SysprofMultiPaned" id="paned">
- <property name="orientation">vertical</property>
- <property name="visible">true</property>
- <property name="vexpand">true</property>
- <child>
- <object class="SysprofVisualizerView" id="visualizers">
- <property name="visible">true</property>
- <property name="zoom-manager">zoom_manager</property>
- </object>
- </child>
- <child>
- <object class="GtkNotebook" id="notebook">
- <property name="vexpand">true</property>
- <property name="visible">true</property>
- <child>
- <object class="SysprofCallgraphView" id="callgraph_view">
- <property name="visible">true</property>
- <property name="vexpand">true</property>
- </object>
- <packing>
- <property name="tab-label" translatable="yes">Callgraph</property>
- </packing>
- </child>
- <child>
- <object class="SysprofMarksView" id="marks_view">
- <property name="visible">true</property>
- <property name="vexpand">true</property>
- </object>
- <packing>
- <property name="tab-label" translatable="yes">Marks</property>
- </packing>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="name">browsing</property>
- </packing>
- </child>
</object>
</child>
</object>
</child>
</template>
- <object class="SysprofZoomManager" id="zoom_manager">
- <property name="min-zoom">0.01</property>
- </object>
- <object class="GtkPopover" id="gear_popover">
- <property name="border-width">12</property>
- <property name="width-request">225</property>
- <child>
- <object class="GtkBox">
- <property name="orientation">vertical</property>
- <property name="visible">true</property>
- <child>
- <object class="GtkBox">
- <property name="hexpand">true</property>
- <property name="orientation">horizontal</property>
- <property name="visible">true</property>
- <style>
- <class name="linked"/>
- </style>
- <child>
- <object class="GtkButton">
- <property name="action-name">zoom.zoom-out</property>
- <property name="hexpand">true</property>
- <property name="tooltip-text" translatable="yes" comments="Translators: This is a
tooltip.">Zoom out (Ctrl+-)</property>
- <property name="visible">true</property>
- <style>
- <class name="image-button"/>
- </style>
- <child>
- <object class="GtkImage">
- <property name="icon-name">zoom-out-symbolic</property>
- <property name="visible">true</property>
- </object>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkButton">
- <property name="action-name">zoom.zoom-one</property>
- <property name="tooltip-text" translatable="yes" comments="Translators: This is a
tooltip.">Reset zoom level (Ctrl+0)</property>
- <property name="visible">true</property>
- <child>
- <object class="GtkLabel" id="zoom_one_label">
- <property name="width-chars">5</property>
- <property name="visible">true</property>
- </object>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkButton">
- <property name="action-name">zoom.zoom-in</property>
- <property name="hexpand">true</property>
- <property name="tooltip-text" translatable="yes" comments="Translators: This is a
tooltip.">Zoom in (Ctrl++)</property>
- <property name="visible">true</property>
- <style>
- <class name="image-button"/>
- </style>
- <child>
- <object class="GtkImage">
- <property name="icon-name">zoom-in-symbolic</property>
- <property name="visible">true</property>
- </object>
- </child>
- </object>
- </child>
- </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">app.new-window</property>
- <property name="text" translatable="yes" comments="Translators: This is a menu label.">New
Window</property>
- <property name="visible">true</property>
- </object>
- </child>
- <child>
- <object class="GtkSeparator">
- <property name="orientation">horizontal</property>
- <property name="visible">true</property>
- </object>
- </child>
- <child>
- <object class="GtkModelButton">
- <property name="action-name">win.open-capture</property>
- <property name="text" translatable="yes" context="menu label" comments="Translators: This is a
menu label.">Open Capture…</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" comments="Translators: This is a menu label.">Save
As…</property>
- <property name="visible">true</property>
- </object>
- </child>
- <child>
- <object class="GtkSeparator">
- <property name="orientation">horizontal</property>
- <property name="visible">true</property>
- </object>
- </child>
- <child>
- <object class="GtkModelButton">
- <property name="action-name">win.screenshot</property>
- <property name="text" translatable="yes" comments="Translators: This is a menu
label.">Screenshot</property>
- <property name="visible">true</property>
- </object>
- </child>
- <child>
- <object class="GtkSeparator">
- <property name="orientation">horizontal</property>
- <property name="visible">true</property>
- </object>
- </child>
- <child>
- <object class="GtkModelButton">
- <property name="action-name">win.close-capture</property>
- <property name="text" translatable="yes" comments="Translators: This is a menu
label.">Close</property>
- <property name="visible">true</property>
- </object>
- </child>
- <child>
- <object class="GtkSeparator">
- <property name="orientation">horizontal</property>
- <property name="visible">true</property>
- </object>
- </child>
- <child>
- <object class="GtkModelButton">
- <property name="action-name">app.show-help-overlay</property>
- <property name="text" translatable="yes">Keyboard Shortcuts</property>
- <property name="visible">true</property>
- </object>
- </child>
- <child>
- <object class="GtkModelButton">
- <property name="action-name">app.help</property>
- <property name="text" translatable="yes">Help</property>
- <property name="visible">true</property>
- </object>
- </child>
- <child>
- <object class="GtkModelButton">
- <property name="action-name">app.about</property>
- <property name="text" translatable="yes">About Sysprof</property>
- <property name="visible">true</property>
- </object>
- </child>
- </object>
- </child>
- </object>
</interface>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]