summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Kang <jonathankang@gnome.org>2020-02-21 14:53:11 +0800
committerJonathan Kang <jonathankang@gnome.org>2020-02-21 14:53:11 +0800
commit938cb8996f4fe9e4c26097e19522f628bdf1ba9f (patch)
tree4e607179e87e277a240aab395f4754e9883484a9
parent2a2b6ec5e26f96a1625f550a9f2d68bfb8cb6ff6 (diff)
downloadgnome-logs-journal-from-file.tar.gz
application: Add the ability to open journal filesjournal-from-file
You can use the command "gnome-logs $path-to-journal-files" to view logs from those journal files. https://gitlab.gnome.org/GNOME/gnome-logs/issues/45
-rw-r--r--src/gl-application.c55
-rw-r--r--src/gl-journal-model.c12
-rw-r--r--src/gl-journal-model.h3
-rw-r--r--src/gl-journal.c107
-rw-r--r--src/gl-journal.h2
-rw-r--r--src/gl-window.c60
-rw-r--r--src/gl-window.h2
7 files changed, 197 insertions, 44 deletions
diff --git a/src/gl-application.c b/src/gl-application.c
index c20052c..f2d9eaa 100644
--- a/src/gl-application.c
+++ b/src/gl-application.c
@@ -24,6 +24,8 @@
#include "gl-categorylist.h"
#include "gl-eventtoolbar.h"
#include "gl-eventviewlist.h"
+#include "gl-journal.h"
+#include "gl-journal-model.h"
#include "gl-util.h"
#include "gl-window.h"
@@ -35,6 +37,7 @@ struct _GlApplication
typedef struct
{
+ GlJournal *journal;
GSettings *desktop;
GSettings *settings;
gchar *monospace_font;
@@ -54,10 +57,13 @@ on_new_window (GSimpleAction *action,
{
GtkApplication *application;
GtkWidget *window;
+ GlApplicationPrivate *priv;
application = GTK_APPLICATION (user_data);
+ priv = gl_application_get_instance_private (GL_APPLICATION (application));
window = gl_window_new (GTK_APPLICATION (application));
+ gl_window_load_journal (GL_WINDOW (window), priv->journal);
gtk_widget_show (window);
}
@@ -199,26 +205,37 @@ gl_application_startup (GApplication *application)
}
static void
-gl_application_activate (GApplication *application)
+launch_window (GApplication *application)
{
GtkWidget *window;
GlApplicationPrivate *priv;
const gchar * const close_accel[] = { "<Primary>w", NULL };
const gchar * const search_accel[] = { "<Primary>f", NULL };
+ priv = gl_application_get_instance_private (GL_APPLICATION (application));
+
window = gl_window_new (GTK_APPLICATION (application));
+ gl_window_load_journal (GL_WINDOW (window), priv->journal);
gtk_widget_show (window);
gtk_application_set_accels_for_action (GTK_APPLICATION (application),
"win.close", close_accel);
gtk_application_set_accels_for_action (GTK_APPLICATION (application),
"win.search", search_accel);
- priv = gl_application_get_instance_private (GL_APPLICATION (application));
-
on_monospace_font_name_changed (priv->desktop, DESKTOP_MONOSPACE_FONT_NAME,
priv);
}
+static void
+gl_application_activate (GApplication *application)
+{
+ GlApplicationPrivate *priv;
+
+ priv = gl_application_get_instance_private (GL_APPLICATION (application));
+ priv->journal = gl_journal_new (NULL);
+ launch_window (application);
+}
+
static const GOptionEntry options[] =
{
{ "version", 'v', 0, G_OPTION_ARG_NONE, NULL,
@@ -240,6 +257,33 @@ gl_application_handle_local_options (GApplication *application,
}
static void
+gl_application_open (GApplication *application,
+ GFile **files,
+ gint n_files,
+ const gchar *hint)
+{
+ gint i;
+ GPtrArray *array;
+ GlApplicationPrivate *priv;
+
+ priv = gl_application_get_instance_private (GL_APPLICATION (application));
+
+ array = g_ptr_array_new ();
+ for (i = 0; i < n_files; i++)
+ {
+ GFile *file;
+
+ file = files[i];
+ g_ptr_array_add (array, g_file_get_path (file));
+ }
+
+ g_ptr_array_add (array, NULL);
+
+ priv->journal = gl_journal_new (array);
+ launch_window (application);
+}
+
+static void
gl_application_finalize (GObject *object)
{
GlApplication *application;
@@ -252,6 +296,8 @@ gl_application_finalize (GObject *object)
g_clear_object (&priv->settings);
g_clear_pointer (&priv->monospace_font, g_free);
+ g_clear_object (&priv->journal);
+
G_OBJECT_CLASS (gl_application_parent_class)->finalize (object);
}
@@ -262,6 +308,8 @@ gl_application_init (GlApplication *application)
gchar *changed_font;
GAction *action;
+ g_application_set_flags (G_APPLICATION (application), G_APPLICATION_HANDLES_OPEN);
+
priv = gl_application_get_instance_private (application);
priv->monospace_font = NULL;
@@ -297,6 +345,7 @@ gl_application_class_init (GlApplicationClass *klass)
app_class = G_APPLICATION_CLASS (klass);
app_class->activate = gl_application_activate;
+ app_class->open = gl_application_open;
app_class->startup = gl_application_startup;
app_class->handle_local_options = gl_application_handle_local_options;
}
diff --git a/src/gl-journal-model.c b/src/gl-journal-model.c
index b1a54ec..a2fe03a 100644
--- a/src/gl-journal-model.c
+++ b/src/gl-journal-model.c
@@ -254,11 +254,8 @@ static void
gl_journal_model_init (GlJournalModel *model)
{
model->batch_size = 50;
- model->journal = gl_journal_new ();
model->entries = g_ptr_array_new_with_free_func (g_object_unref);
model->export = FALSE;
-
- gl_journal_model_fetch_more_entries (model, FALSE);
}
static void
@@ -309,7 +306,6 @@ gl_journal_model_dispose (GObject *object)
model->entries = NULL;
}
- g_clear_object (&model->journal);
if (model->token_array != NULL)
{
g_ptr_array_free (model->token_array, TRUE);
@@ -1211,6 +1207,14 @@ gl_journal_model_fetch_more_entries (GlJournalModel *model,
}
}
+void
+gl_journal_model_load_journal (GlJournalModel *model,
+ GlJournal *journal)
+{
+ model->journal = journal;
+ gl_journal_model_fetch_more_entries (model, FALSE);
+}
+
GlRowEntry *
gl_row_entry_new (void)
{
diff --git a/src/gl-journal-model.h b/src/gl-journal-model.h
index 49818b8..52a2945 100644
--- a/src/gl-journal-model.h
+++ b/src/gl-journal-model.h
@@ -79,6 +79,9 @@ gboolean gl_journal_model_get_loading (GlJourn
void gl_journal_model_fetch_more_entries (GlJournalModel *model,
gboolean all);
+void gl_journal_model_load_journal (GlJournalModel *model,
+ GlJournal *journal);
+
GArray * gl_journal_model_get_boot_ids (GlJournalModel *model);
gchar * gl_journal_model_get_boot_time (GlJournalModel *model,
diff --git a/src/gl-journal.c b/src/gl-journal.c
index 3aebab8..da0b2b6 100644
--- a/src/gl-journal.c
+++ b/src/gl-journal.c
@@ -25,6 +25,13 @@
#include <stdlib.h>
#include <systemd/sd-journal.h>
+enum
+{
+ PROP_0,
+ PROP_FILES,
+ N_PROPERTIES
+};
+
struct _GlJournalEntry
{
GObject parent_instance;
@@ -48,6 +55,8 @@ struct _GlJournalEntry
G_DEFINE_TYPE (GlJournalEntry, gl_journal_entry, G_TYPE_OBJECT);
+static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
+
typedef struct
{
sd_journal *journal;
@@ -55,6 +64,7 @@ typedef struct
guint source_id;
gchar **mandatory_fields;
GArray *boot_ids;
+ GPtrArray *files;
} GlJournalPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (GlJournal, gl_journal, G_TYPE_OBJECT)
@@ -323,6 +333,46 @@ on_journal_changed (gint fd,
}
static void
+gl_journal_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GlJournal *self = GL_JOURNAL (object);
+ GlJournalPrivate *priv = gl_journal_get_instance_private (self);
+
+ switch (prop_id)
+ {
+ case PROP_FILES:
+ g_value_set_pointer (value, priv->files);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gl_journal_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GlJournal *self = GL_JOURNAL (object);
+ GlJournalPrivate *priv = gl_journal_get_instance_private (self);
+
+ switch (prop_id)
+ {
+ case PROP_FILES:
+ priv->files = g_value_get_pointer (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
gl_journal_finalize (GObject *object)
{
guint i;
@@ -347,24 +397,31 @@ gl_journal_finalize (GObject *object)
}
static void
-gl_journal_class_init (GlJournalClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- gobject_class->finalize = gl_journal_finalize;
-}
-
-static void
-gl_journal_init (GlJournal *self)
+gl_journal_constructed (GObject *object)
{
+ GlJournal *self;
GlJournalPrivate *priv;
sd_journal *journal;
gint ret;
+ self = GL_JOURNAL (object);
priv = gl_journal_get_instance_private (self);
- ret = sd_journal_open (&journal, 0);
- priv->journal = journal;
+ if (priv->files == NULL)
+ {
+ ret = sd_journal_open (&journal, 0);
+ priv->journal = journal;
+ }
+ else
+ {
+ gchar **paths;
+
+ paths = (gchar **) g_ptr_array_free (priv->files, FALSE);
+ ret = sd_journal_open_files (&journal, (const gchar **) paths, 0);
+ priv->journal = journal;
+
+ g_clear_pointer (&paths, g_strfreev);
+ }
if (ret < 0)
{
@@ -412,6 +469,28 @@ gl_journal_init (GlJournal *self)
gl_journal_get_boots (self);
}
+static void
+gl_journal_class_init (GlJournalClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->constructed = gl_journal_constructed;
+ gobject_class->get_property = gl_journal_get_property;
+ gobject_class->set_property = gl_journal_set_property;
+ gobject_class->finalize = gl_journal_finalize;
+
+ obj_properties[PROP_FILES] = g_param_spec_pointer ("files", "Files",
+ "Journal Files",
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY);
+ g_object_class_install_properties (gobject_class, N_PROPERTIES, obj_properties);
+}
+
+static void
+gl_journal_init (GlJournal *self)
+{
+}
+
static GlJournalEntry *
_gl_journal_query_entry (GlJournal *self)
{
@@ -730,9 +809,11 @@ gl_journal_previous (GlJournal *journal)
}
GlJournal *
-gl_journal_new (void)
+gl_journal_new (GPtrArray *files)
{
- return g_object_new (GL_TYPE_JOURNAL, NULL);
+ return g_object_new (GL_TYPE_JOURNAL,
+ "files", files,
+ NULL);
}
static void
diff --git a/src/gl-journal.h b/src/gl-journal.h
index 9ddfb06..bea8758 100644
--- a/src/gl-journal.h
+++ b/src/gl-journal.h
@@ -75,7 +75,7 @@ void gl_journal_set_matches (GlJournal *journal, GPtrArray *matches);
void gl_journal_set_start_position (GlJournal *journal, guint64 until_timestamp);
GArray * gl_journal_get_boot_ids (GlJournal *journal);
GlJournalEntry * gl_journal_previous (GlJournal *journal);
-GlJournal * gl_journal_new (void);
+GlJournal * gl_journal_new (GPtrArray *files);
gchar * gl_journal_get_boot_time (GlJournal *journal,
const gchar *boot_match);
diff --git a/src/gl-window.c b/src/gl-window.c
index 3b3716a..2ebd758 100644
--- a/src/gl-window.c
+++ b/src/gl-window.c
@@ -383,21 +383,52 @@ enable_export (GlWindow *window)
g_simple_action_set_enabled (G_SIMPLE_ACTION (action_export), TRUE);
}
+void
+gl_window_load_journal (GlWindow *window,
+ GlJournal *journal)
+{
+ gchar *boot_match;
+ GAction *action_view_boot;
+ GArray *boot_ids;
+ GVariant *variant;
+ GlJournalBootID *boot_id;
+ GlEventViewList *event_list;
+ GlEventToolbar *toolbar;
+ GlJournalModel *journal_model;
+ GlWindowPrivate *priv;
+
+ priv = gl_window_get_instance_private (window);
+ toolbar = GL_EVENT_TOOLBAR (priv->event_toolbar);
+ event_list = GL_EVENT_VIEW_LIST (priv->event_list);
+
+ journal_model = gl_event_view_list_get_journal_model (event_list);
+ gl_journal_model_load_journal (journal_model, journal);
+
+ boot_ids = gl_event_view_list_get_boot_ids (event_list);
+ gl_event_toolbar_add_boots (toolbar, boot_ids);
+
+ if (boot_ids->len > 0)
+ {
+ boot_id = &g_array_index (boot_ids, GlJournalBootID,
+ boot_ids->len - 1);
+ boot_match = boot_id->boot_match;
+
+ action_view_boot = g_action_map_lookup_action (G_ACTION_MAP (window),
+ "view-boot");
+ variant = g_variant_new_string (boot_match);
+ g_action_change_state (action_view_boot, variant);
+ }
+}
+
static void
gl_window_init (GlWindow *window)
{
GtkCssProvider *provider;
GdkScreen *screen;
GlWindowPrivate *priv;
- GlEventToolbar *toolbar;
GlEventViewList *event_list;
GtkWidget *categories;
- GAction *action_view_boot;
- GArray *boot_ids;
GlJournalStorage storage_type;
- GlJournalBootID *boot_id;
- gchar *boot_match;
- GVariant *variant;
GSettings *settings;
gboolean ignore;
GlJournalModel *model;
@@ -413,27 +444,10 @@ gl_window_init (GlWindow *window)
priv = gl_window_get_instance_private (window);
event_list = GL_EVENT_VIEW_LIST (priv->event_list);
- toolbar = GL_EVENT_TOOLBAR (priv->event_toolbar);
-
- boot_ids = gl_event_view_list_get_boot_ids (event_list);
g_action_map_add_action_entries (G_ACTION_MAP (window), actions,
G_N_ELEMENTS (actions), window);
- gl_event_toolbar_add_boots (toolbar, boot_ids);
-
- if (boot_ids->len > 0)
- {
- boot_id = &g_array_index (boot_ids, GlJournalBootID,
- boot_ids->len - 1);
- boot_match = boot_id->boot_match;
-
- action_view_boot = g_action_map_lookup_action (G_ACTION_MAP (window),
- "view-boot");
- variant = g_variant_new_string (boot_match);
- g_action_change_state (action_view_boot, variant);
- }
-
categories = gl_event_view_list_get_category_list (event_list);
g_signal_connect (GL_CATEGORY_LIST (categories), "notify::category",
G_CALLBACK (on_category_list_changed), window);
diff --git a/src/gl-window.h b/src/gl-window.h
index 4744569..f8cffda 100644
--- a/src/gl-window.h
+++ b/src/gl-window.h
@@ -22,12 +22,14 @@
#include <gtk/gtk.h>
#include "gl-application.h"
+#include "gl-journal-model.h"
G_BEGIN_DECLS
#define GL_TYPE_WINDOW (gl_window_get_type ())
G_DECLARE_FINAL_TYPE (GlWindow, gl_window, GL, WINDOW, GtkApplicationWindow)
+void gl_window_load_journal (GlWindow *window, GlJournal *journal);
GtkWidget * gl_window_new (GtkApplication *application);
void gl_window_set_sort_order (GlWindow *window, GlSortOrder sort_order);
void disable_export (GlWindow *window);