diff options
author | Jonathan Kang <jonathankang@gnome.org> | 2020-02-21 14:53:11 +0800 |
---|---|---|
committer | Jonathan Kang <jonathankang@gnome.org> | 2020-02-21 14:53:11 +0800 |
commit | 938cb8996f4fe9e4c26097e19522f628bdf1ba9f (patch) | |
tree | 4e607179e87e277a240aab395f4754e9883484a9 | |
parent | 2a2b6ec5e26f96a1625f550a9f2d68bfb8cb6ff6 (diff) | |
download | gnome-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.c | 55 | ||||
-rw-r--r-- | src/gl-journal-model.c | 12 | ||||
-rw-r--r-- | src/gl-journal-model.h | 3 | ||||
-rw-r--r-- | src/gl-journal.c | 107 | ||||
-rw-r--r-- | src/gl-journal.h | 2 | ||||
-rw-r--r-- | src/gl-window.c | 60 | ||||
-rw-r--r-- | src/gl-window.h | 2 |
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); |