summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Kang <jonathan121537@gmail.com>2014-11-06 14:11:21 +0800
committerDavid King <davidk@gnome.org>2014-11-11 12:35:43 +0000
commitafda11b8d616ee84d901e5904435c67131dc3cf5 (patch)
tree846a0cc5b49e3b5475f2fb5086e230bf02e0e061
parentb19f65206028ae8b4bb6c89635128d8f12350931 (diff)
downloadgnome-logs-afda11b8d616ee84d901e5904435c67131dc3cf5.tar.gz
Hide sidebar while viewing event details
https://bugzilla.gnome.org/show_bug.cgi?id=726228
-rw-r--r--Makefile.am4
-rw-r--r--data/gl-eventview.ui10
-rw-r--r--data/gl-eventviewlist.ui45
-rw-r--r--data/gl-window.ui42
-rw-r--r--data/org.gnome.Logs.gresource.xml2
-rw-r--r--src/gl-application.c2
-rw-r--r--src/gl-categorylist.c124
-rw-r--r--src/gl-categorylist.h30
-rw-r--r--src/gl-eventview.c253
-rw-r--r--src/gl-eventview.h65
-rw-r--r--src/gl-eventviewlist.c394
-rw-r--r--src/gl-eventviewlist.h54
-rw-r--r--src/gl-window.c110
13 files changed, 723 insertions, 412 deletions
diff --git a/Makefile.am b/Makefile.am
index 45d3c47..b1feb39 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -27,6 +27,7 @@ gnome_logs_SOURCES = \
src/gl-application.c \
src/gl-categorylist.c \
src/gl-eventtoolbar.c \
+ src/gl-eventview.c \
src/gl-eventviewdetail.c \
src/gl-eventviewlist.c \
src/gl-eventviewrow.c \
@@ -44,8 +45,9 @@ enum_data = \
src/gl-enums.h
gnome_logs_enum_headers = \
+ $(srcdir)/src/gl-categorylist.h \
$(srcdir)/src/gl-eventtoolbar.h \
- $(srcdir)/src/gl-eventviewlist.h \
+ $(srcdir)/src/gl-eventview.h \
$(srcdir)/src/gl-eventviewrow.h \
$(srcdir)/src/gl-util.h
diff --git a/data/gl-eventview.ui b/data/gl-eventview.ui
new file mode 100644
index 0000000..dde128a
--- /dev/null
+++ b/data/gl-eventview.ui
@@ -0,0 +1,10 @@
+<interface domain="gnome-logs">
+ <template class="GlEventView" parent="GtkStack">
+ <property name="visible">True</property>
+ <child>
+ <object class="GlEventViewList" id="events">
+ <property name="visible">True</property>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/data/gl-eventviewlist.ui b/data/gl-eventviewlist.ui
new file mode 100644
index 0000000..1f7a9af
--- /dev/null
+++ b/data/gl-eventviewlist.ui
@@ -0,0 +1,45 @@
+<interface domain="gnome-logs">
+ <template class="GlEventViewList" parent="GtkBox">
+ <property name="orientation">horizontal</property>
+ <property name="visible">True</property>
+ <child>
+ <object class="GlCategoryList" id="categories">
+ <property name="visible">True</property>
+ <style>
+ <class name="categories"/>
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkSeparator" id="content_separator">
+ <property name="orientation">vertical</property>
+ <property name="visible">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkBox" id="event_view">
+ <property name="orientation">vertical</property>
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkSearchBar" id="event_search">
+ <property name="visible">True</property>
+ <signal name="notify::search-mode-enabled" handler="on_search_bar_notify_search_mode_enabled"/>
+ <child>
+ <object class="GtkSearchEntry" id="search_entry">
+ <property name="visible">True</property>
+ <property name="width-request">400</property>
+ <signal name="search-changed" handler="on_search_entry_changed" />
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkStack" id="event_stack">
+ <property name="visible">True</property>
+ <property name="expand">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/data/gl-window.ui b/data/gl-window.ui
index 4c67596..6f41df1 100644
--- a/data/gl-window.ui
+++ b/data/gl-window.ui
@@ -13,48 +13,8 @@
</object>
</child>
<child>
- <object class="GtkBox" id="content">
- <property name="orientation">horizontal</property>
+ <object class="GlEventView" id="event">
<property name="visible">True</property>
- <child>
- <object class="GlCategoryList" id="categories">
- <property name="visible">True</property>
- <style>
- <class name="categories"/>
- </style>
- </object>
- </child>
- <child>
- <object class="GtkSeparator" id="content_separator">
- <property name="orientation">vertical</property>
- <property name="visible">True</property>
- </object>
- </child>
- <child>
- <object class="GtkBox" id="event_view">
- <property name="orientation">vertical</property>
- <property name="visible">True</property>
- <child>
- <object class="GtkSearchBar" id="event_search">
- <property name="visible">True</property>
- <signal name="notify::search-mode-enabled" handler="on_gl_window_search_bar_notify_search_mode_enabled"/>
- <child>
- <object class="GtkSearchEntry" id="search_entry">
- <property name="visible">True</property>
- <property name="width-request">400</property>
- <signal name="search-changed" handler="on_gl_window_search_entry_changed" />
- </object>
- </child>
- </object>
- </child>
- <child>
- <object class="GlEventViewList" id="events">
- <property name="expand">True</property>
- <property name="visible">True</property>
- </object>
- </child>
- </object>
- </child>
</object>
</child>
</template>
diff --git a/data/org.gnome.Logs.gresource.xml b/data/org.gnome.Logs.gresource.xml
index 2b0ec8a..46d38a3 100644
--- a/data/org.gnome.Logs.gresource.xml
+++ b/data/org.gnome.Logs.gresource.xml
@@ -2,6 +2,8 @@
<gresources>
<gresource prefix='/org/gnome/Logs'>
<file preprocess='xml-stripblanks'>gl-categorylist.ui</file>
+ <file preprocess='xml-stripblanks'>gl-eventview.ui</file>
+ <file preprocess="xml-stripblanks">gl-eventviewlist.ui</file>
<file preprocess='xml-stripblanks'>gl-eventtoolbar.ui</file>
<file preprocess='xml-stripblanks'>gl-eventviewdetail.ui</file>
<file>gl-style.css</file>
diff --git a/src/gl-application.c b/src/gl-application.c
index 49ccaaa..8f3dcd0 100644
--- a/src/gl-application.c
+++ b/src/gl-application.c
@@ -23,6 +23,7 @@
#include "gl-categorylist.h"
#include "gl-eventtoolbar.h"
+#include "gl-eventview.h"
#include "gl-eventviewlist.h"
#include "gl-util.h"
#include "gl-window.h"
@@ -177,6 +178,7 @@ gl_application_startup (GApplication *application)
gl_window_get_type ();
gl_category_list_get_type ();
gl_event_toolbar_get_type ();
+ gl_event_view_get_type ();
gl_event_view_list_get_type ();
}
diff --git a/src/gl-categorylist.c b/src/gl-categorylist.c
index 4d7e20f..d17bb08 100644
--- a/src/gl-categorylist.c
+++ b/src/gl-categorylist.c
@@ -23,6 +23,13 @@
#include "gl-enums.h"
#include "gl-eventviewlist.h"
+enum
+{
+ PROP_0,
+ PROP_CATEGORY,
+ N_PROPERTIES
+};
+
typedef struct
{
GtkWidget *important;
@@ -35,10 +42,13 @@ typedef struct
GtkWidget *hardware;
GtkWidget *updates;
GtkWidget *usage;
+ GlCategoryListFilter category;
} GlCategoryListPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (GlCategoryList, gl_category_list, GTK_TYPE_LIST_BOX)
+static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
+
static gboolean
gl_category_list_focus (GtkWidget *listbox, GtkDirectionType direction)
{
@@ -75,86 +85,137 @@ on_gl_category_list_row_selected (GlCategoryList *listbox,
gpointer user_data)
{
GlCategoryListPrivate *priv;
- GtkWidget *toplevel;
- GActionMap *appwindow;
- GAction *category;
GEnumClass *eclass;
GEnumValue *evalue;
priv = gl_category_list_get_instance_private (listbox);
- toplevel = gtk_widget_get_toplevel (GTK_WIDGET (listbox));
-
- if (gtk_widget_is_toplevel (toplevel))
- {
- appwindow = G_ACTION_MAP (toplevel);
- category = g_action_map_lookup_action (appwindow, "category");
- }
- else
- {
- /* TODO: Investigate whether this only happens during dispose. */
- g_debug ("%s",
- "Category list row selected while not in a toplevel");
- return;
- }
-
- eclass = g_type_class_ref (GL_TYPE_EVENT_VIEW_LIST_FILTER);
+ eclass = g_type_class_ref (GL_TYPE_CATEGORY_LIST_FILTER);
if (row == GTK_LIST_BOX_ROW (priv->important))
{
- evalue = g_enum_get_value (eclass, GL_EVENT_VIEW_LIST_FILTER_IMPORTANT);
+ evalue = g_enum_get_value (eclass, GL_CATEGORY_LIST_FILTER_IMPORTANT);
}
else if (row == GTK_LIST_BOX_ROW (priv->alerts))
{
- evalue = g_enum_get_value (eclass, GL_EVENT_VIEW_LIST_FILTER_ALERTS);
+ evalue = g_enum_get_value (eclass, GL_CATEGORY_LIST_FILTER_ALERTS);
}
else if (row == GTK_LIST_BOX_ROW (priv->starred))
{
- evalue = g_enum_get_value (eclass, GL_EVENT_VIEW_LIST_FILTER_STARRED);
+ evalue = g_enum_get_value (eclass, GL_CATEGORY_LIST_FILTER_STARRED);
}
else if (row == GTK_LIST_BOX_ROW (priv->all))
{
- evalue = g_enum_get_value (eclass, GL_EVENT_VIEW_LIST_FILTER_ALL);
+ evalue = g_enum_get_value (eclass, GL_CATEGORY_LIST_FILTER_ALL);
}
else if (row == GTK_LIST_BOX_ROW (priv->applications))
{
- evalue = g_enum_get_value (eclass, GL_EVENT_VIEW_LIST_FILTER_APPLICATIONS);
+ evalue = g_enum_get_value (eclass, GL_CATEGORY_LIST_FILTER_APPLICATIONS);
}
else if (row == GTK_LIST_BOX_ROW (priv->system))
{
- evalue = g_enum_get_value (eclass, GL_EVENT_VIEW_LIST_FILTER_SYSTEM);
+ evalue = g_enum_get_value (eclass, GL_CATEGORY_LIST_FILTER_SYSTEM);
}
else if (row == GTK_LIST_BOX_ROW (priv->security))
{
- evalue = g_enum_get_value (eclass, GL_EVENT_VIEW_LIST_FILTER_SECURITY);
+ evalue = g_enum_get_value (eclass, GL_CATEGORY_LIST_FILTER_SECURITY);
}
else if (row == GTK_LIST_BOX_ROW (priv->hardware))
{
- evalue = g_enum_get_value (eclass, GL_EVENT_VIEW_LIST_FILTER_HARDWARE);
+ evalue = g_enum_get_value (eclass, GL_CATEGORY_LIST_FILTER_HARDWARE);
}
else if (row == GTK_LIST_BOX_ROW (priv->updates))
{
- evalue = g_enum_get_value (eclass, GL_EVENT_VIEW_LIST_FILTER_UPDATES);
+ evalue = g_enum_get_value (eclass, GL_CATEGORY_LIST_FILTER_UPDATES);
}
else if (row == GTK_LIST_BOX_ROW (priv->usage))
{
- evalue = g_enum_get_value (eclass, GL_EVENT_VIEW_LIST_FILTER_USAGE);
+ evalue = g_enum_get_value (eclass, GL_CATEGORY_LIST_FILTER_USAGE);
}
else
{
- g_assert_not_reached ();
+ /* This is only for the occasion when GlCategoryList is destroyed,
+ * in other words when there are no children for GlCategoryList */
+ return;
}
- g_action_activate (category, g_variant_new_string (evalue->value_nick));
+ priv->category = evalue->value;
+
+ g_object_notify_by_pspec (G_OBJECT (listbox),
+ obj_properties[PROP_CATEGORY]);
g_type_class_unref (eclass);
}
+GlCategoryListFilter
+gl_category_list_get_category (GlCategoryList *list)
+{
+ GlCategoryListPrivate *priv;
+
+ priv = gl_category_list_get_instance_private (list);
+
+ return priv->category;
+}
+
+static void
+gl_category_list_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GlCategoryList *list = GL_CATEGORY_LIST (object);
+ GlCategoryListPrivate *priv = gl_category_list_get_instance_private (list);
+
+ switch (prop_id)
+ {
+ case PROP_CATEGORY:
+ g_value_set_enum (value, priv->category);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gl_category_list_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GlCategoryList *list = GL_CATEGORY_LIST (object);
+ GlCategoryListPrivate *priv = gl_category_list_get_instance_private (list);
+
+ switch (prop_id)
+ {
+ case PROP_CATEGORY:
+ priv->category = g_value_get_enum (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
static void
gl_category_list_class_init (GlCategoryListClass *klass)
{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ gobject_class->get_property = gl_category_list_get_property;
+ gobject_class->set_property = gl_category_list_set_property;
widget_class->focus = gl_category_list_focus;
+
+ obj_properties[PROP_CATEGORY] = g_param_spec_enum ("category", "Category",
+ "Filter events by",
+ GL_TYPE_CATEGORY_LIST_FILTER,
+ GL_CATEGORY_LIST_FILTER_ALL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (gobject_class, N_PROPERTIES,
+ obj_properties);
+
gtk_widget_class_set_template_from_resource (widget_class,
"/org/gnome/Logs/gl-categorylist.ui");
gtk_widget_class_bind_template_child_private (widget_class, GlCategoryList,
@@ -201,6 +262,7 @@ gl_category_list_init (GlCategoryList *list)
GlCategoryListPrivate *priv;
gtk_widget_init_template (GTK_WIDGET (list));
+
priv = gl_category_list_get_instance_private (list);
gtk_list_box_set_header_func (GTK_LIST_BOX (list),
(GtkListBoxUpdateHeaderFunc)gl_category_list_header_func,
diff --git a/src/gl-categorylist.h b/src/gl-categorylist.h
index 3dd8cea..32f3b79 100644
--- a/src/gl-categorylist.h
+++ b/src/gl-categorylist.h
@@ -35,11 +35,41 @@ typedef struct
GtkListBoxClass parent_class;
} GlCategoryListClass;
+/*
+ * GlCategoryListFilter:
+ * @GL_CATEGORY_LIST_FILTER_IMPORTANT:
+ * @GL_CATEGORY_LIST_FILTER_ALERTS:
+ * @GL_CATEGORY_LIST_FILTER_STARRED:
+ * @GL_CATEGORY_LIST_FILTER_ALL:
+ * @GL_CATEGORY_LIST_FILTER_APPLICATIONS:
+ * @GL_CATEGORY_LIST_FILTER_SYSTEM:
+ * @GL_CATEGORY_LIST_FILTER_SECURITY:
+ * @GL_CATEGORY_LIST_FILTER_HARDWARE:
+ * @GL_CATEGORY_LIST_FILTER_UPDATES:
+ * @GL_CATEGORY_LIST_FILTER_USAGE:
+ *
+ * The category, selected in #GlCategoryList, to filter the events by.
+ */
+typedef enum
+{
+ GL_CATEGORY_LIST_FILTER_IMPORTANT,
+ GL_CATEGORY_LIST_FILTER_ALERTS,
+ GL_CATEGORY_LIST_FILTER_STARRED,
+ GL_CATEGORY_LIST_FILTER_ALL,
+ GL_CATEGORY_LIST_FILTER_APPLICATIONS,
+ GL_CATEGORY_LIST_FILTER_SYSTEM,
+ GL_CATEGORY_LIST_FILTER_SECURITY,
+ GL_CATEGORY_LIST_FILTER_HARDWARE,
+ GL_CATEGORY_LIST_FILTER_UPDATES,
+ GL_CATEGORY_LIST_FILTER_USAGE
+} GlCategoryListFilter;
+
#define GL_TYPE_CATEGORY_LIST (gl_category_list_get_type ())
#define GL_CATEGORY_LIST(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GL_TYPE_CATEGORY_LIST, GlCategoryList))
GType gl_category_list_get_type (void);
GtkWidget * gl_category_list_new (void);
+GlCategoryListFilter gl_category_list_get_category (GlCategoryList *list);
G_END_DECLS
diff --git a/src/gl-eventview.c b/src/gl-eventview.c
new file mode 100644
index 0000000..1df5148
--- /dev/null
+++ b/src/gl-eventview.c
@@ -0,0 +1,253 @@
+/*
+ * GNOME Logs - View and search logs
+ * Copyright (C) 2014 Red Hat, Inc.
+ * Copyright (C) 2014 Jonathan Kang
+ *
+ * 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/>.
+ */
+
+#include "gl-eventview.h"
+
+#include <glib/gi18n.h>
+#include <glib-unix.h>
+#include <stdlib.h>
+
+#include "gl-categorylist.h"
+#include "gl-enums.h"
+#include "gl-eventtoolbar.h"
+#include "gl-eventviewdetail.h"
+#include "gl-eventviewlist.h"
+#include "gl-journal.h"
+#include "gl-util.h"
+
+enum
+{
+ PROP_0,
+ PROP_MODE,
+ N_PROPERTIES
+};
+
+typedef struct
+{
+ GtkWidget *events;
+ GlJournalResult *result;
+ GlUtilClockFormat clock_format;
+ GlEventViewMode mode;
+} GlEventViewPrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (GlEventView, gl_event_view, GTK_TYPE_STACK)
+
+static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
+static const gchar DESKTOP_SCHEMA[] = "org.gnome.desktop.interface";
+static const gchar CLOCK_FORMAT[] = "clock-format";
+
+void
+gl_event_view_show_detail (GlEventView *view)
+{
+ GlEventViewList *events;
+ GlEventViewPrivate *priv;
+
+ g_return_if_fail (GL_EVENT_VIEW (view));
+
+ priv = gl_event_view_get_instance_private (view);
+ events = GL_EVENT_VIEW_LIST (priv->events);
+ priv->result = gl_event_view_list_get_detail_result (events);
+}
+
+gboolean
+gl_event_view_handle_search_event (GlEventView *view,
+ GAction *action,
+ GdkEvent *event)
+{
+ GlEventViewPrivate *priv;
+ GlEventViewList *events;
+
+ priv = gl_event_view_get_instance_private (view);
+ events = GL_EVENT_VIEW_LIST (priv->events);
+
+ if (gl_event_view_list_handle_search_event (events, action,
+ event) == GDK_EVENT_STOP)
+ {
+ return GDK_EVENT_STOP;
+ }
+
+ return GDK_EVENT_PROPAGATE;
+}
+
+void
+gl_event_view_set_search_mode (GlEventView *view,
+ gboolean state)
+{
+ GlEventViewPrivate *priv;
+ GlEventViewList *events;
+
+ g_return_if_fail (GL_EVENT_VIEW (view));
+
+ priv = gl_event_view_get_instance_private (view);
+ events = GL_EVENT_VIEW_LIST (priv->events);
+
+ gl_event_view_list_set_search_mode (events, state);
+}
+
+static void
+on_notify_mode (GlEventView *view,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ GlEventViewPrivate *priv;
+ GtkStack *stack;
+ GtkWidget *detail;
+
+ priv = gl_event_view_get_instance_private (view);
+ stack = GTK_STACK (view);
+
+ switch (priv->mode)
+ {
+ case GL_EVENT_VIEW_MODE_LIST:
+ {
+ GtkWidget *child;
+
+ child = gtk_stack_get_child_by_name (stack, "detail");
+
+ if (child)
+ {
+ gtk_container_remove (GTK_CONTAINER (stack), child);
+ }
+
+ gtk_stack_set_visible_child (stack, priv->events);
+ }
+ break;
+ case GL_EVENT_VIEW_MODE_DETAIL:
+ {
+ gl_event_view_show_detail (view);
+ detail = gl_event_view_detail_new (priv->result,
+ priv->clock_format);
+ gtk_widget_show_all (detail);
+ gtk_stack_add_named (stack, detail, "detail");
+ gtk_stack_set_visible_child_name (stack, "detail");
+ }
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+}
+
+static void
+gl_event_view_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GlEventView *view = GL_EVENT_VIEW (object);
+ GlEventViewPrivate *priv = gl_event_view_get_instance_private (view);
+
+ switch (prop_id)
+ {
+ case PROP_MODE:
+ g_value_set_enum (value, priv->mode);
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gl_event_view_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GlEventView *view = GL_EVENT_VIEW (object);
+ GlEventViewPrivate *priv = gl_event_view_get_instance_private (view);
+
+ switch (prop_id)
+ {
+ case PROP_MODE:
+ priv->mode = g_value_get_enum (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gl_event_view_class_init (GlEventViewClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ gobject_class->get_property = gl_event_view_get_property;
+ gobject_class->set_property = gl_event_view_set_property;
+
+ obj_properties[PROP_MODE] = g_param_spec_enum ("mode", "Mode",
+ "Event display mode",
+ GL_TYPE_EVENT_VIEW_MODE,
+ GL_EVENT_VIEW_MODE_LIST,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (gobject_class, N_PROPERTIES,
+ obj_properties);
+
+ gtk_widget_class_set_template_from_resource (widget_class,
+ "/org/gnome/Logs/gl-eventview.ui");
+ gtk_widget_class_bind_template_child_private (widget_class, GlEventView,
+ events);
+}
+
+static void
+gl_event_view_init (GlEventView *view)
+{
+ GlEventViewPrivate *priv;
+ GSettings *settings;
+
+ gtk_widget_init_template (GTK_WIDGET (view));
+
+ priv = gl_event_view_get_instance_private (view);
+
+ /* TODO: Monitor and propagate any GSettings changes. */
+ settings = g_settings_new (DESKTOP_SCHEMA);
+ priv->clock_format = g_settings_get_enum (settings, CLOCK_FORMAT);
+
+ g_object_unref (settings);
+
+ g_signal_connect (view, "notify::mode", G_CALLBACK (on_notify_mode),
+ NULL);
+}
+
+void
+gl_event_view_set_mode (GlEventView *view,
+ GlEventViewMode mode)
+{
+ GlEventViewPrivate *priv;
+
+ g_return_if_fail (GL_EVENT_VIEW (view));
+
+ priv = gl_event_view_get_instance_private (view);
+
+ if (priv->mode != mode)
+ {
+ priv->mode = mode;
+ g_object_notify_by_pspec (G_OBJECT (view),
+ obj_properties[PROP_MODE]);
+ }
+}
+
+GtkWidget *
+gl_event_view_new (void)
+{
+ return g_object_new (GL_TYPE_EVENT_VIEW, NULL);
+}
diff --git a/src/gl-eventview.h b/src/gl-eventview.h
new file mode 100644
index 0000000..67e6e1a
--- /dev/null
+++ b/src/gl-eventview.h
@@ -0,0 +1,65 @@
+/*
+ * GNOME Logs - View and search logs
+ * Copyright (C) 2014 Red Hat, Inc.
+ * Copyright (C) 2014 Jonathan Kang
+ *
+ * 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/>.
+ */
+
+#ifndef GL_EVENT_VIEW_H_
+#define GL_EVENT_VIEW_H_
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+typedef struct
+{
+ /*< private >*/
+ GtkStack parent_instance;
+} GlEventView;
+
+typedef struct
+{
+ /*< private >*/
+ GtkStackClass parent_class;
+} GlEventViewClass;
+
+/*
+ * GlEventViewMode:
+ * @GL_EVENT_VIEW_MODE_LIST:
+ * @GL_EVENT_VIEW_MODE_DETAIL:
+ *
+ * The mode, mirroring the GlEventToolbar mode, used to show events.
+ */
+typedef enum
+{
+ GL_EVENT_VIEW_MODE_LIST,
+ GL_EVENT_VIEW_MODE_DETAIL
+} GlEventViewMode;
+
+#define GL_TYPE_EVENT_VIEW (gl_event_view_get_type ())
+#define GL_EVENT_VIEW(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GL_TYPE_EVENT_VIEW, GlEventView))
+
+GType gl_event_view_get_type (void);
+GtkWidget * gl_event_view_new (void);
+void gl_event_view_search (GlEventView *view, const gchar *needle);
+void gl_event_view_set_mode (GlEventView *view, GlEventViewMode mode);
+void gl_event_view_show_detail (GlEventView *view);
+gboolean gl_event_view_handle_search_event (GlEventView *view, GAction *action, GdkEvent *event);
+void gl_event_view_set_search_mode (GlEventView *view, gboolean state);
+
+G_END_DECLS
+
+#endif /* GL_EVENT_VIEW_H_ */
diff --git a/src/gl-eventviewlist.c b/src/gl-eventviewlist.c
index 1c51190..0588536 100644
--- a/src/gl-eventviewlist.c
+++ b/src/gl-eventviewlist.c
@@ -22,28 +22,25 @@
#include <glib-unix.h>
#include <stdlib.h>
+#include "gl-categorylist.h"
#include "gl-enums.h"
#include "gl-eventtoolbar.h"
+#include "gl-eventview.h"
#include "gl-eventviewdetail.h"
#include "gl-eventviewrow.h"
#include "gl-journal.h"
#include "gl-util.h"
-enum
-{
- PROP_0,
- PROP_FILTER,
- PROP_MODE,
- N_PROPERTIES
-};
-
typedef struct
{
GlJournal *journal;
+ GlJournalResult *result;
GlUtilClockFormat clock_format;
- GlEventViewListFilter filter;
GtkListBox *active_listbox;
- GlEventViewMode mode;
+ GtkWidget *categories;
+ GtkWidget *event_search;
+ GtkWidget *event_stack;
+ GtkWidget *search_entry;
gchar *search_text;
GtkListBox *results_listbox;
@@ -52,9 +49,8 @@ typedef struct
guint insert_idle_id;
} GlEventViewListPrivate;
-G_DEFINE_TYPE_WITH_PRIVATE (GlEventViewList, gl_event_view_list, GTK_TYPE_STACK)
+G_DEFINE_TYPE_WITH_PRIVATE (GlEventViewList, gl_event_view_list, GTK_TYPE_BOX)
-static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
static const gssize N_RESULTS = -1;
static const gssize N_RESULTS_IDLE = 25;
static const gchar DESKTOP_SCHEMA[] = "org.gnome.desktop.interface";
@@ -171,20 +167,87 @@ on_listbox_row_activated (GtkListBox *listbox,
GlEventViewList *view)
{
GlEventViewListPrivate *priv;
- GlJournalResult *result;
- GtkWidget *detail;
- GtkStack *stack;
+ GtkWidget *toplevel;
priv = gl_event_view_list_get_instance_private (view);
- result = gl_event_view_row_get_result (GL_EVENT_VIEW_ROW (row));
+ priv->result = gl_event_view_row_get_result (GL_EVENT_VIEW_ROW (row));
+
+ toplevel = gtk_widget_get_toplevel (GTK_WIDGET (view));
+
+ if (gtk_widget_is_toplevel (toplevel))
+ {
+ GAction *mode;
+ GEnumClass *eclass;
+ GEnumValue *evalue;
+
+ mode = g_action_map_lookup_action (G_ACTION_MAP (toplevel), "view-mode");
+ eclass = g_type_class_ref (GL_TYPE_EVENT_VIEW_MODE);
+ evalue = g_enum_get_value (eclass, GL_EVENT_VIEW_MODE_DETAIL);
+
+ g_action_activate (mode, g_variant_new_string (evalue->value_nick));
+
+ g_type_class_unref (eclass);
+ }
+ else
+ {
+ g_debug ("Widget not in toplevel window, not switching toolbar mode");
+ }
+}
- detail = gl_event_view_detail_new (result, priv->clock_format);
+GlJournalResult *
+gl_event_view_list_get_detail_result (GlEventViewList *view)
+{
+ GlEventViewListPrivate *priv;
- gtk_widget_show_all (detail);
+ priv = gl_event_view_list_get_instance_private (view);
- stack = GTK_STACK (view);
- gtk_stack_add_named (stack, detail, "detail");
- gl_event_view_list_set_mode (view, GL_EVENT_VIEW_MODE_DETAIL);
+ return priv->result;
+}
+
+gboolean
+gl_event_view_list_handle_search_event (GlEventViewList *view,
+ GAction *action,
+ GdkEvent *event)
+{
+ GlEventViewListPrivate *priv;
+
+ priv = gl_event_view_list_get_instance_private (view);
+
+ if (g_action_get_enabled (action))
+ {
+ if (gtk_search_bar_handle_event (GTK_SEARCH_BAR (priv->event_search),
+ event) == GDK_EVENT_STOP)
+ {
+ g_action_change_state (action, g_variant_new_boolean (TRUE));
+
+ return GDK_EVENT_STOP;
+ }
+ }
+
+ return GDK_EVENT_PROPAGATE;
+}
+
+void
+gl_event_view_list_set_search_mode (GlEventViewList *view,
+ gboolean state)
+{
+ GlEventViewListPrivate *priv;
+
+ g_return_if_fail (GL_EVENT_VIEW_LIST (view));
+
+ priv = gl_event_view_list_get_instance_private (view);
+
+ gtk_search_bar_set_search_mode (GTK_SEARCH_BAR (priv->event_search), state);
+
+ if (state)
+ {
+ gtk_widget_grab_focus (priv->search_entry);
+ gtk_editable_set_position (GTK_EDITABLE (priv->search_entry), -1);
+ }
+ else
+ {
+ gtk_entry_set_text (GTK_ENTRY (priv->search_entry), "");
+ }
}
static GtkWidget *
@@ -238,7 +301,7 @@ gl_event_view_list_box_new (GlEventViewList *view)
gtk_list_box_set_selection_mode (GTK_LIST_BOX (listbox),
GTK_SELECTION_NONE);
g_signal_connect (listbox, "row-activated",
- G_CALLBACK (on_listbox_row_activated), GTK_STACK (view));
+ G_CALLBACK (on_listbox_row_activated), GTK_BOX (view));
return listbox;
}
@@ -583,7 +646,9 @@ gl_event_view_list_add_listbox_important (GlEventViewList *view)
NULL } };
GtkWidget *listbox;
GtkWidget *scrolled;
+ GlEventViewListPrivate *priv;
+ priv = gl_event_view_list_get_instance_private (view);
listbox = gl_event_view_list_box_new (view);
insert_journal_query_cmdline (view, &query,
@@ -592,27 +657,34 @@ gl_event_view_list_add_listbox_important (GlEventViewList *view)
scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_container_add (GTK_CONTAINER (scrolled), listbox);
gtk_widget_show_all (scrolled);
- gtk_stack_add_named (GTK_STACK (view), scrolled, "listbox-important");
+ gtk_stack_add_named (GTK_STACK (priv->event_stack), scrolled,
+ "listbox-important");
}
static void
gl_event_view_list_add_listbox_alerts (GlEventViewList *view)
{
GtkWidget *label;
+ GlEventViewListPrivate *priv;
+ priv = gl_event_view_list_get_instance_private (view);
label = gtk_label_new (_("Not implemented"));
gtk_widget_show_all (label);
- gtk_stack_add_named (GTK_STACK (view), label, "listbox-alerts");
+ gtk_stack_add_named (GTK_STACK (priv->event_stack), label,
+ "listbox-alerts");
}
static void
gl_event_view_list_add_listbox_starred (GlEventViewList *view)
{
GtkWidget *label;
+ GlEventViewListPrivate *priv;
+ priv = gl_event_view_list_get_instance_private (view);
label = gtk_label_new (_("Not implemented"));
gtk_widget_show_all (label);
- gtk_stack_add_named (GTK_STACK (view), label, "listbox-starred");
+ gtk_stack_add_named (GTK_STACK (priv->event_stack), label,
+ "listbox-starred");
}
static void
@@ -621,7 +693,9 @@ gl_event_view_list_add_listbox_all (GlEventViewList *view)
const GlJournalQuery query = { N_RESULTS, NULL };
GtkWidget *listbox;
GtkWidget *scrolled;
+ GlEventViewListPrivate *priv;
+ priv = gl_event_view_list_get_instance_private (view);
listbox = gl_event_view_list_box_new (view);
insert_journal_query_cmdline (view, &query, GTK_LIST_BOX (listbox));
@@ -629,7 +703,8 @@ gl_event_view_list_add_listbox_all (GlEventViewList *view)
scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_container_add (GTK_CONTAINER (scrolled), listbox);
gtk_widget_show_all (scrolled);
- gtk_stack_add_named (GTK_STACK (view), scrolled, "listbox-all");
+ gtk_stack_add_named (GTK_STACK (priv->event_stack), scrolled,
+ "listbox-all");
}
static void
@@ -639,7 +714,9 @@ gl_event_view_list_add_listbox_applications (GlEventViewList *view)
uid_t uid;
GtkWidget *listbox;
GtkWidget *scrolled;
+ GlEventViewListPrivate *priv;
+ priv = gl_event_view_list_get_instance_private (view);
listbox = gl_event_view_list_box_new (view);
creds = g_credentials_new ();
uid = g_credentials_get_unix_user (creds, NULL);
@@ -678,7 +755,8 @@ gl_event_view_list_add_listbox_applications (GlEventViewList *view)
scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_container_add (GTK_CONTAINER (scrolled), listbox);
gtk_widget_show_all (scrolled);
- gtk_stack_add_named (GTK_STACK (view), scrolled, "listbox-applications");
+ gtk_stack_add_named (GTK_STACK (priv->event_stack), scrolled,
+ "listbox-applications");
g_object_unref (creds);
}
@@ -690,7 +768,9 @@ gl_event_view_list_add_listbox_system (GlEventViewList *view)
(gchar *[2]){ "_TRANSPORT=kernel", NULL } };
GtkWidget *listbox;
GtkWidget *scrolled;
+ GlEventViewListPrivate *priv;
+ priv = gl_event_view_list_get_instance_private (view);
listbox = gl_event_view_list_box_new (view);
insert_journal_query_simple (view, &query, GTK_LIST_BOX (listbox));
@@ -698,7 +778,8 @@ gl_event_view_list_add_listbox_system (GlEventViewList *view)
scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_container_add (GTK_CONTAINER (scrolled), listbox);
gtk_widget_show_all (scrolled);
- gtk_stack_add_named (GTK_STACK (view), scrolled, "listbox-system");
+ gtk_stack_add_named (GTK_STACK (priv->event_stack), scrolled,
+ "listbox-system");
}
static void
@@ -708,7 +789,9 @@ gl_event_view_list_add_listbox_hardware (GlEventViewList *view)
(gchar *[2]){ "_TRANSPORT=kernel", NULL } };
GtkWidget *listbox;
GtkWidget *scrolled;
+ GlEventViewListPrivate *priv;
+ priv = gl_event_view_list_get_instance_private (view);
listbox = gl_event_view_list_box_new (view);
insert_journal_query_devices (view, &query, GTK_LIST_BOX (listbox));
@@ -716,7 +799,8 @@ gl_event_view_list_add_listbox_hardware (GlEventViewList *view)
scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_container_add (GTK_CONTAINER (scrolled), listbox);
gtk_widget_show_all (scrolled);
- gtk_stack_add_named (GTK_STACK (view), scrolled, "listbox-hardware");
+ gtk_stack_add_named (GTK_STACK (priv->event_stack), scrolled,
+ "listbox-hardware");
}
static void
@@ -725,7 +809,9 @@ gl_event_view_list_add_listbox_security (GlEventViewList *view)
const GlJournalQuery query = { N_RESULTS, NULL };
GtkWidget *listbox;
GtkWidget *scrolled;
+ GlEventViewListPrivate *priv;
+ priv = gl_event_view_list_get_instance_private (view);
listbox = gl_event_view_list_box_new (view);
insert_journal_query_security (view, &query, GTK_LIST_BOX (listbox));
@@ -733,41 +819,52 @@ gl_event_view_list_add_listbox_security (GlEventViewList *view)
scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_container_add (GTK_CONTAINER (scrolled), listbox);
gtk_widget_show_all (scrolled);
- gtk_stack_add_named (GTK_STACK (view), scrolled, "listbox-security");
+ gtk_stack_add_named (GTK_STACK (priv->event_stack), scrolled,
+ "listbox-security");
}
static void
gl_event_view_list_add_listbox_updates (GlEventViewList *view)
{
GtkWidget *label;
+ GlEventViewListPrivate *priv;
+ priv = gl_event_view_list_get_instance_private (view);
label = gtk_label_new (_("Not implemented"));
gtk_widget_show_all (label);
- gtk_stack_add_named (GTK_STACK (view), label, "listbox-updates");
+ gtk_stack_add_named (GTK_STACK (priv->event_stack), label,
+ "listbox-updates");
}
static void
gl_event_view_list_add_listbox_usage (GlEventViewList *view)
{
GtkWidget *label;
+ GlEventViewListPrivate *priv;
+ priv = gl_event_view_list_get_instance_private (view);
label = gtk_label_new (_("Not implemented"));
gtk_widget_show_all (label);
- gtk_stack_add_named (GTK_STACK (view), label, "listbox-usage");
+ gtk_stack_add_named (GTK_STACK (priv->event_stack), label,
+ "listbox-usage");
}
static void
-on_notify_filter (GlEventViewList *view,
- G_GNUC_UNUSED GParamSpec *pspec,
- G_GNUC_UNUSED gpointer user_data)
+on_notify_category (GlCategoryList *list,
+ GParamSpec *pspec,
+ gpointer user_data)
{
+ GlCategoryListFilter filter;
+ GlEventViewList *view;
GlEventViewListPrivate *priv;
GtkStack *stack;
GtkWidget *scrolled;
GtkWidget *viewport;
+ view = GL_EVENT_VIEW_LIST (user_data);
priv = gl_event_view_list_get_instance_private (view);
- stack = GTK_STACK (view);
+ stack = GTK_STACK (priv->event_stack);
+ filter = gl_category_list_get_category (list);
if (priv->active_listbox)
{
@@ -777,45 +874,45 @@ on_notify_filter (GlEventViewList *view,
gtk_widget_destroy (child);
}
- switch (priv->filter)
+ switch (filter)
{
- case GL_EVENT_VIEW_LIST_FILTER_IMPORTANT:
+ case GL_CATEGORY_LIST_FILTER_IMPORTANT:
gl_event_view_list_add_listbox_important (view);
gtk_stack_set_visible_child_name (stack, "listbox-important");
break;
- case GL_EVENT_VIEW_LIST_FILTER_ALERTS:
+ case GL_CATEGORY_LIST_FILTER_ALERTS:
gl_event_view_list_add_listbox_alerts (view);
gtk_stack_set_visible_child_name (stack, "listbox-alerts");
break;
- case GL_EVENT_VIEW_LIST_FILTER_STARRED:
+ case GL_CATEGORY_LIST_FILTER_STARRED:
gl_event_view_list_add_listbox_starred (view);
gtk_stack_set_visible_child_name (stack, "listbox-starred");
break;
- case GL_EVENT_VIEW_LIST_FILTER_ALL:
+ case GL_CATEGORY_LIST_FILTER_ALL:
gl_event_view_list_add_listbox_all (view);
gtk_stack_set_visible_child_name (stack, "listbox-all");
break;
- case GL_EVENT_VIEW_LIST_FILTER_APPLICATIONS:
+ case GL_CATEGORY_LIST_FILTER_APPLICATIONS:
gl_event_view_list_add_listbox_applications (view);
gtk_stack_set_visible_child_name (stack, "listbox-applications");
break;
- case GL_EVENT_VIEW_LIST_FILTER_SYSTEM:
+ case GL_CATEGORY_LIST_FILTER_SYSTEM:
gl_event_view_list_add_listbox_system (view);
gtk_stack_set_visible_child_name (stack, "listbox-system");
break;
- case GL_EVENT_VIEW_LIST_FILTER_HARDWARE:
+ case GL_CATEGORY_LIST_FILTER_HARDWARE:
gl_event_view_list_add_listbox_hardware (view);
gtk_stack_set_visible_child_name (stack, "listbox-hardware");
break;
- case GL_EVENT_VIEW_LIST_FILTER_SECURITY:
+ case GL_CATEGORY_LIST_FILTER_SECURITY:
gl_event_view_list_add_listbox_security (view);
gtk_stack_set_visible_child_name (stack, "listbox-security");
break;
- case GL_EVENT_VIEW_LIST_FILTER_UPDATES:
+ case GL_CATEGORY_LIST_FILTER_UPDATES:
gl_event_view_list_add_listbox_updates (view);
gtk_stack_set_visible_child_name (stack, "listbox-updates");
break;
- case GL_EVENT_VIEW_LIST_FILTER_USAGE:
+ case GL_CATEGORY_LIST_FILTER_USAGE:
gl_event_view_list_add_listbox_usage (view);
gtk_stack_set_visible_child_name (stack, "listbox-usage");
break;
@@ -826,70 +923,46 @@ on_notify_filter (GlEventViewList *view,
scrolled = gtk_stack_get_visible_child (stack);
viewport = gtk_bin_get_child (GTK_BIN (scrolled));
priv->active_listbox = GTK_LIST_BOX (gtk_bin_get_child (GTK_BIN (viewport)));
-
- gl_event_view_list_set_mode (view, GL_EVENT_VIEW_MODE_LIST);
}
static void
-on_notify_mode (GlEventViewList *view,
- GParamSpec *pspec,
- gpointer user_data)
+on_search_entry_changed (GtkSearchEntry *entry,
+ gpointer user_data)
{
GlEventViewListPrivate *priv;
- GtkStack *stack;
- GtkWidget *toplevel;
- priv = gl_event_view_list_get_instance_private (view);
- stack = GTK_STACK (view);
+ priv = gl_event_view_list_get_instance_private (GL_EVENT_VIEW_LIST (user_data));
- switch (priv->mode)
- {
- case GL_EVENT_VIEW_MODE_LIST:
- {
- GtkWidget *child;
- GtkWidget *viewport;
- GtkWidget *scrolled_window;
-
- child = gtk_stack_get_child_by_name (stack, "detail");
-
- if (child)
- {
- gtk_container_remove (GTK_CONTAINER (stack), child);
- }
+ gl_event_view_list_search (GL_EVENT_VIEW_LIST (user_data),
+ gtk_entry_get_text (GTK_ENTRY (priv->search_entry)));
+}
- viewport = gtk_widget_get_parent (GTK_WIDGET (priv->active_listbox));
- scrolled_window = gtk_widget_get_parent (viewport);
- gtk_stack_set_visible_child (stack, scrolled_window);
- }
- break;
- case GL_EVENT_VIEW_MODE_DETAIL:
- gtk_stack_set_visible_child_name (stack, "detail");
- break;
- default:
- g_assert_not_reached ();
- break;
- }
+static void
+on_search_bar_notify_search_mode_enabled (GtkSearchBar *search_bar,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ GAction *search;
+ GtkWidget *toplevel;
+ GActionMap *appwindow;
- toplevel = gtk_widget_get_toplevel (GTK_WIDGET (view));
+ toplevel = gtk_widget_get_toplevel (GTK_WIDGET (user_data));
if (gtk_widget_is_toplevel (toplevel))
{
- GAction *mode;
- GEnumClass *eclass;
- GEnumValue *evalue;
-
- mode = g_action_map_lookup_action (G_ACTION_MAP (toplevel), "view-mode");
- eclass = g_type_class_ref (GL_TYPE_EVENT_VIEW_MODE);
- evalue = g_enum_get_value (eclass, priv->mode);
-
- g_action_activate (mode, g_variant_new_string (evalue->value_nick));
-
- g_type_class_unref (eclass);
+ appwindow = G_ACTION_MAP (toplevel);
+ search = g_action_map_lookup_action (appwindow, "search");
}
else
{
- g_debug ("Widget not in toplevel window, not switching toolbar mode");
+ /* TODO: Investigate whether this only happens during dispose. */
+ g_debug ("%s",
+ "Search bar activated while not in a toplevel");
+ return;
}
+
+ g_action_change_state (search,
+ g_variant_new_boolean (gtk_search_bar_get_search_mode (search_bar)));
}
static void
@@ -908,102 +981,53 @@ gl_event_view_list_finalize (GObject *object)
}
static void
-gl_event_view_list_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GlEventViewList *view = GL_EVENT_VIEW_LIST (object);
- GlEventViewListPrivate *priv = gl_event_view_list_get_instance_private (view);
-
- switch (prop_id)
- {
- case PROP_FILTER:
- g_value_set_enum (value, priv->filter);
- break;
- case PROP_MODE:
- g_value_set_enum (value, priv->mode);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gl_event_view_list_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GlEventViewList *view = GL_EVENT_VIEW_LIST (object);
- GlEventViewListPrivate *priv = gl_event_view_list_get_instance_private (view);
-
- switch (prop_id)
- {
- case PROP_FILTER:
- priv->filter = g_value_get_enum (value);
- break;
- case PROP_MODE:
- priv->mode = g_value_get_enum (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
gl_event_view_list_class_init (GlEventViewListClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
gobject_class->finalize = gl_event_view_list_finalize;
- gobject_class->get_property = gl_event_view_list_get_property;
- gobject_class->set_property = gl_event_view_list_set_property;
-
- obj_properties[PROP_FILTER] = g_param_spec_enum ("filter", "Filter",
- "Filter events by",
- GL_TYPE_EVENT_VIEW_LIST_FILTER,
- GL_EVENT_VIEW_LIST_FILTER_IMPORTANT,
- G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS);
-
- obj_properties[PROP_MODE] = g_param_spec_enum ("mode", "Mode",
- "Event display mode",
- GL_TYPE_EVENT_VIEW_MODE,
- GL_EVENT_VIEW_MODE_LIST,
- G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS);
-
- g_object_class_install_properties (gobject_class, N_PROPERTIES,
- obj_properties);
+
+ gtk_widget_class_set_template_from_resource (widget_class,
+ "/org/gnome/Logs/gl-eventviewlist.ui");
+ gtk_widget_class_bind_template_child_private (widget_class, GlEventViewList,
+ categories);
+ gtk_widget_class_bind_template_child_private (widget_class, GlEventViewList,
+ event_search);
+ gtk_widget_class_bind_template_child_private (widget_class, GlEventViewList,
+ event_stack);
+ gtk_widget_class_bind_template_child_private (widget_class, GlEventViewList,
+ search_entry);
+
+ gtk_widget_class_bind_template_callback (widget_class,
+ on_search_entry_changed);
+ gtk_widget_class_bind_template_callback (widget_class,
+ on_search_bar_notify_search_mode_enabled);
}
static void
gl_event_view_list_init (GlEventViewList *view)
{
+ GlCategoryList *categories;
GlEventViewListPrivate *priv;
GSettings *settings;
+ gtk_widget_init_template (GTK_WIDGET (view));
+
priv = gl_event_view_list_get_instance_private (view);
priv->search_text = NULL;
priv->active_listbox = NULL;
priv->insert_idle_id = 0;
priv->journal = gl_journal_new ();
+ categories = GL_CATEGORY_LIST (priv->categories);
/* TODO: Monitor and propagate any GSettings changes. */
settings = g_settings_new (DESKTOP_SCHEMA);
priv->clock_format = g_settings_get_enum (settings, CLOCK_FORMAT);
g_object_unref (settings);
- g_signal_connect (view, "notify::filter", G_CALLBACK (on_notify_filter),
- NULL);
- g_signal_connect (view, "notify::mode", G_CALLBACK (on_notify_mode),
- NULL);
-
- /* Force an update of the active filter. */
- on_notify_filter (view, NULL, NULL);
+ g_signal_connect (categories, "notify::category", G_CALLBACK (on_notify_category),
+ view);
}
void
@@ -1022,42 +1046,6 @@ gl_event_view_list_search (GlEventViewList *view,
gtk_list_box_invalidate_filter (priv->active_listbox);
}
-void
-gl_event_view_list_set_filter (GlEventViewList *view,
- GlEventViewListFilter filter)
-{
- GlEventViewListPrivate *priv;
-
- g_return_if_fail (GL_EVENT_VIEW_LIST (view));
-
- priv = gl_event_view_list_get_instance_private (view);
-
- if (priv->filter != filter)
- {
- priv->filter = filter;
- g_object_notify_by_pspec (G_OBJECT (view),
- obj_properties[PROP_FILTER]);
- }
-}
-
-void
-gl_event_view_list_set_mode (GlEventViewList *view,
- GlEventViewMode mode)
-{
- GlEventViewListPrivate *priv;
-
- g_return_if_fail (GL_EVENT_VIEW_LIST (view));
-
- priv = gl_event_view_list_get_instance_private (view);
-
- if (priv->mode != mode)
- {
- priv->mode = mode;
- g_object_notify_by_pspec (G_OBJECT (view),
- obj_properties[PROP_MODE]);
- }
-}
-
GtkWidget *
gl_event_view_list_new (void)
{
diff --git a/src/gl-eventviewlist.h b/src/gl-eventviewlist.h
index d25cb57..22d50a0 100644
--- a/src/gl-eventviewlist.h
+++ b/src/gl-eventviewlist.h
@@ -20,71 +20,33 @@
#define GL_EVENT_VIEW_LIST_H_
#include <gtk/gtk.h>
+#include "gl-journal.h"
G_BEGIN_DECLS
typedef struct
{
/*< private >*/
- GtkListBox parent_instance;
+ GtkBox parent_instance;
} GlEventViewList;
typedef struct
{
/*< private >*/
- GtkListBoxClass parent_class;
+ GtkBoxClass parent_class;
} GlEventViewListClass;
-/*
- * GlEventViewListFilter:
- * @GL_EVENT_VIEW_LIST_FILTER_IMPORTANT:
- * @GL_EVENT_VIEW_LIST_FILTER_ALERTS:
- * @GL_EVENT_VIEW_LIST_FILTER_STARRED:
- * @GL_EVENT_VIEW_LIST_FILTER_ALL:
- * @GL_EVENT_VIEW_LIST_FILTER_APPLICATIONS:
- * @GL_EVENT_VIEW_LIST_FILTER_SYSTEM:
- * @GL_EVENT_VIEW_LIST_FILTER_SECURITY:
- * @GL_EVENT_VIEW_LIST_FILTER_HARDWARE:
- * @GL_EVENT_VIEW_LIST_FILTER_UPDATES:
- * @GL_EVENT_VIEW_LIST_FILTER_USAGE:
- *
- * The category, selected in #GlCategoryList, to filter the events by.
- */
-typedef enum
-{
- GL_EVENT_VIEW_LIST_FILTER_IMPORTANT,
- GL_EVENT_VIEW_LIST_FILTER_ALERTS,
- GL_EVENT_VIEW_LIST_FILTER_STARRED,
- GL_EVENT_VIEW_LIST_FILTER_ALL,
- GL_EVENT_VIEW_LIST_FILTER_APPLICATIONS,
- GL_EVENT_VIEW_LIST_FILTER_SYSTEM,
- GL_EVENT_VIEW_LIST_FILTER_SECURITY,
- GL_EVENT_VIEW_LIST_FILTER_HARDWARE,
- GL_EVENT_VIEW_LIST_FILTER_UPDATES,
- GL_EVENT_VIEW_LIST_FILTER_USAGE
-} GlEventViewListFilter;
-
-/*
- * GlEventViewMode:
- * @GL_EVENT_VIEW_MODE_LIST:
- * @GL_EVENT_VIEW_MODE_DETAIL:
- *
- * The mode, mirroring the GlEventToolbar mode, used to show events.
- */
-typedef enum
-{
- GL_EVENT_VIEW_MODE_LIST,
- GL_EVENT_VIEW_MODE_DETAIL
-} GlEventViewMode;
-
#define GL_TYPE_EVENT_VIEW_LIST (gl_event_view_list_get_type ())
#define GL_EVENT_VIEW_LIST(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GL_TYPE_EVENT_VIEW_LIST, GlEventViewList))
GType gl_event_view_list_get_type (void);
GtkWidget * gl_event_view_list_new (void);
void gl_event_view_list_search (GlEventViewList *view, const gchar *needle);
-void gl_event_view_list_set_filter (GlEventViewList *view, GlEventViewListFilter filter);
-void gl_event_view_list_set_mode (GlEventViewList *view, GlEventViewMode mode);
+GlJournalResult *gl_event_view_list_get_detail_result (GlEventViewList *view);
+gboolean gl_event_view_list_handle_search_event (GlEventViewList *view,
+ GAction *action,
+ GdkEvent *event);
+void gl_event_view_list_set_search_mode (GlEventViewList *view, gboolean state);
G_END_DECLS
diff --git a/src/gl-window.c b/src/gl-window.c
index fbd93ae..fc6f6b6 100644
--- a/src/gl-window.c
+++ b/src/gl-window.c
@@ -22,6 +22,7 @@
#include "gl-categorylist.h"
#include "gl-eventtoolbar.h"
+#include "gl-eventview.h"
#include "gl-eventviewlist.h"
#include "gl-enums.h"
#include "gl-util.h"
@@ -29,9 +30,7 @@
typedef struct
{
GtkWidget *event_toolbar;
- GtkWidget *event_search;
- GtkWidget *search_entry;
- GtkWidget *events;
+ GtkWidget *event;
} GlWindowPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (GlWindow, gl_window, GTK_TYPE_APPLICATION_WINDOW)
@@ -59,34 +58,7 @@ on_action_toggle (GSimpleAction *action,
}
static void
-on_category (GSimpleAction *action,
- GVariant *variant,
- gpointer user_data)
-{
- GlWindowPrivate *priv;
- const gchar *category;
- GlEventViewList *events;
- GEnumClass *eclass;
- GEnumValue *evalue;
-
- priv = gl_window_get_instance_private (GL_WINDOW (user_data));
- category = g_variant_get_string (variant, NULL);
- events = GL_EVENT_VIEW_LIST (priv->events);
- eclass = g_type_class_ref (GL_TYPE_EVENT_VIEW_LIST_FILTER);
- evalue = g_enum_get_value_by_nick (eclass, category);
-
- /* First switch the event view back to list mode if the category
- tab is clicked. */
- gl_event_view_list_set_mode (events, GL_EVENT_VIEW_MODE_LIST);
- gl_event_view_list_set_filter (events, evalue->value);
-
- g_simple_action_set_state (action, variant);
-
- g_type_class_unref (eclass);
-}
-
-static void
-on_close (GSimpleAction *action,
+on_close (GSimpleAction *action,
GVariant *variant,
gpointer user_data)
{
@@ -118,11 +90,11 @@ on_toolbar_mode (GSimpleAction *action,
{
/* Switch the event view back to list mode if the back button is
* clicked. */
- GlEventViewList *view;
+ GlEventView *view;
- view = GL_EVENT_VIEW_LIST (priv->events);
+ view = GL_EVENT_VIEW (priv->event);
- gl_event_view_list_set_mode (view, GL_EVENT_VIEW_MODE_LIST);
+ gl_event_view_set_mode (view, GL_EVENT_VIEW_MODE_LIST);
g_simple_action_set_enabled (G_SIMPLE_ACTION (search), TRUE);
}
@@ -145,11 +117,13 @@ on_view_mode (GSimpleAction *action,
GlWindowPrivate *priv;
const gchar *mode;
GlEventToolbar *toolbar;
+ GlEventView *event;
GEnumClass *eclass;
GEnumValue *evalue;
priv = gl_window_get_instance_private (GL_WINDOW (user_data));
mode = g_variant_get_string (variant, NULL);
+ event = GL_EVENT_VIEW (priv->event);
toolbar = GL_EVENT_TOOLBAR (priv->event_toolbar);
eclass = g_type_class_ref (GL_TYPE_EVENT_VIEW_MODE);
evalue = g_enum_get_value_by_nick (eclass, mode);
@@ -161,6 +135,7 @@ on_view_mode (GSimpleAction *action,
break;
case GL_EVENT_VIEW_MODE_DETAIL:
gl_event_toolbar_set_mode (toolbar, GL_EVENT_TOOLBAR_MODE_DETAIL);
+ gl_event_view_set_mode (event, GL_EVENT_VIEW_MODE_DETAIL);
break;
}
@@ -176,21 +151,13 @@ on_search (GSimpleAction *action,
{
gboolean state;
GlWindowPrivate *priv;
+ GlEventView *view;
state = g_variant_get_boolean (variant);
priv = gl_window_get_instance_private (GL_WINDOW (user_data));
+ view = GL_EVENT_VIEW (priv->event);
- gtk_search_bar_set_search_mode (GTK_SEARCH_BAR (priv->event_search), state);
-
- if (state)
- {
- gtk_widget_grab_focus (priv->search_entry);
- gtk_editable_set_position (GTK_EDITABLE (priv->search_entry), -1);
- }
- else
- {
- gtk_entry_set_text (GTK_ENTRY (priv->search_entry), "");
- }
+ gl_event_view_set_search_mode (view, state);
g_simple_action_set_state (action, variant);
}
@@ -201,6 +168,7 @@ on_gl_window_key_press_event (GlWindow *window,
gpointer user_data)
{
GlWindowPrivate *priv;
+ GlEventView *view;
GAction *action;
GVariant *variant;
const gchar *mode;
@@ -209,16 +177,11 @@ on_gl_window_key_press_event (GlWindow *window,
priv = gl_window_get_instance_private (window);
action = g_action_map_lookup_action (G_ACTION_MAP (window), "search");
+ view = GL_EVENT_VIEW (priv->event);
- if (g_action_get_enabled (action))
+ if (gl_event_view_handle_search_event (view, action, event) == GDK_EVENT_STOP)
{
- if (gtk_search_bar_handle_event (GTK_SEARCH_BAR (priv->event_search),
- event) == GDK_EVENT_STOP)
- {
- g_action_change_state (action, g_variant_new_boolean (TRUE));
-
- return GDK_EVENT_STOP;
- }
+ return GDK_EVENT_STOP;
}
action = g_action_map_lookup_action (G_ACTION_MAP (window), "view-mode");
@@ -238,10 +201,10 @@ on_gl_window_key_press_event (GlWindow *window,
(GdkEventKey*)event)
== GDK_EVENT_STOP)
{
- GlEventViewList *events;
+ GlEventView *view;
- events = GL_EVENT_VIEW_LIST (priv->events);
- gl_event_view_list_set_mode (events, GL_EVENT_VIEW_MODE_LIST);
+ view = GL_EVENT_VIEW (priv->event);
+ gl_event_view_set_mode (view, GL_EVENT_VIEW_MODE_LIST);
g_type_class_unref (eclass);
return GDK_EVENT_STOP;
@@ -254,32 +217,7 @@ on_gl_window_key_press_event (GlWindow *window,
return GDK_EVENT_PROPAGATE;
}
-static void
-on_gl_window_search_entry_changed (GtkSearchEntry *entry,
- gpointer user_data)
-{
- GlWindowPrivate *priv;
-
- priv = gl_window_get_instance_private (GL_WINDOW (user_data));
-
- gl_event_view_list_search (GL_EVENT_VIEW_LIST (priv->events),
- gtk_entry_get_text (GTK_ENTRY (priv->search_entry)));
-}
-
-static void
-on_gl_window_search_bar_notify_search_mode_enabled (GtkSearchBar *search_bar,
- GParamSpec *pspec,
- gpointer user_data)
-{
- GAction *search;
-
- search = g_action_map_lookup_action (G_ACTION_MAP (user_data), "search");
- g_action_change_state (search,
- g_variant_new_boolean (gtk_search_bar_get_search_mode (search_bar)));
-}
-
static GActionEntry actions[] = {
- { "category", on_action_radio, "s", "'important'", on_category },
{ "view-mode", on_action_radio, "s", "'list'", on_view_mode },
{ "toolbar-mode", on_action_radio, "s", "'list'", on_toolbar_mode },
{ "search", on_action_toggle, NULL, "false", on_search },
@@ -296,18 +234,10 @@ gl_window_class_init (GlWindowClass *klass)
gtk_widget_class_bind_template_child_private (widget_class, GlWindow,
event_toolbar);
gtk_widget_class_bind_template_child_private (widget_class, GlWindow,
- event_search);
- gtk_widget_class_bind_template_child_private (widget_class, GlWindow,
- search_entry);
- gtk_widget_class_bind_template_child_private (widget_class, GlWindow,
- events);
+ event);
gtk_widget_class_bind_template_callback (widget_class,
on_gl_window_key_press_event);
- gtk_widget_class_bind_template_callback (widget_class,
- on_gl_window_search_entry_changed);
- gtk_widget_class_bind_template_callback (widget_class,
- on_gl_window_search_bar_notify_search_mode_enabled);
}
static void