summaryrefslogtreecommitdiff
path: root/logview/src/logview-prefs.c
diff options
context:
space:
mode:
Diffstat (limited to 'logview/src/logview-prefs.c')
-rw-r--r--logview/src/logview-prefs.c546
1 files changed, 546 insertions, 0 deletions
diff --git a/logview/src/logview-prefs.c b/logview/src/logview-prefs.c
new file mode 100644
index 00000000..0a2e0093
--- /dev/null
+++ b/logview/src/logview-prefs.c
@@ -0,0 +1,546 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
+/* logview-prefs.c - logview user preferences handling
+ *
+ * Copyright (C) 1998 Cesar Miquel <[email protected]>
+ * Copyright (C) 2004 Vincent Noel
+ * Copyright (C) 2006 Emmanuele Bassi
+ * Copyright (C) 2008 Cosimo Cecchi <[email protected]>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/stat.h>
+#include <string.h>
+#include <gtk/gtk.h>
+
+#include "logview-prefs.h"
+
+#define LOGVIEW_DEFAULT_HEIGHT 400
+#define LOGVIEW_DEFAULT_WIDTH 600
+
+/* logview settings */
+#define LOGVIEW_SCHEMA "org.mate.system-log"
+#define PREF_WIDTH "width"
+#define PREF_HEIGHT "height"
+#define PREF_LOGFILE "logfile"
+#define PREF_LOGFILES "logfiles"
+#define PREF_FONTSIZE "fontsize"
+#define PREF_FILTERS "filters"
+
+/* desktop-wide settings */
+#define MATE_MONOSPACE_FONT_NAME "monospace-font-name"
+#define MATE_MENUS_HAVE_TEAROFF "menus-have-tearoff"
+
+static LogviewPrefs *singleton = NULL;
+
+enum {
+ SYSTEM_FONT_CHANGED,
+ HAVE_TEAROFF_CHANGED,
+ LAST_SIGNAL
+};
+
+enum {
+ FILTER_NAME,
+ FILTER_INVISIBLE,
+ FILTER_FOREGROUND,
+ FILTER_BACKGROUND,
+ FILTER_REGEX,
+ MAX_TOKENS
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+#define GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), LOGVIEW_TYPE_PREFS, LogviewPrefsPrivate))
+
+struct _LogviewPrefsPrivate {
+ GSettings *logview_prefs;
+ GSettings *interface_prefs;
+
+ GHashTable *filters;
+};
+
+G_DEFINE_TYPE (LogviewPrefs, logview_prefs, G_TYPE_OBJECT);
+
+static void
+do_finalize (GObject *obj)
+{
+ LogviewPrefs *prefs = LOGVIEW_PREFS (obj);
+
+ g_hash_table_destroy (prefs->priv->filters);
+
+ g_object_unref (prefs->priv->logview_prefs);
+ g_object_unref (prefs->priv->interface_prefs);
+
+ G_OBJECT_CLASS (logview_prefs_parent_class)->finalize (obj);
+}
+
+static void
+logview_prefs_class_init (LogviewPrefsClass *klass)
+{
+ GObjectClass *oclass = G_OBJECT_CLASS (klass);
+
+ oclass->finalize = do_finalize;
+
+ signals[SYSTEM_FONT_CHANGED] = g_signal_new ("system-font-changed",
+ G_OBJECT_CLASS_TYPE (oclass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (LogviewPrefsClass, system_font_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
+ signals[HAVE_TEAROFF_CHANGED] = g_signal_new ("have-tearoff-changed",
+ G_OBJECT_CLASS_TYPE (oclass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (LogviewPrefsClass, have_tearoff_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE, 1,
+ G_TYPE_BOOLEAN);
+
+ g_type_class_add_private (klass, sizeof (LogviewPrefsPrivate));
+}
+
+static void
+have_tearoff_changed_cb (GSettings *settings,
+ gchar *key,
+ gpointer data)
+{
+ LogviewPrefs *prefs = data;
+ gboolean add_tearoffs;
+
+ add_tearoffs = g_settings_get_boolean (settings, key);
+ g_signal_emit (prefs, signals[HAVE_TEAROFF_CHANGED], 0, add_tearoffs, NULL);
+}
+
+static void
+monospace_font_changed_cb (GSettings *settings,
+ gchar *key,
+ gpointer data)
+{
+ LogviewPrefs *prefs = data;
+ gchar *monospace_font_name;
+
+ monospace_font_name = g_settings_get_string (settings, key);
+ g_signal_emit (prefs, signals[SYSTEM_FONT_CHANGED], 0, monospace_font_name, NULL);
+
+ g_free (monospace_font_name);
+}
+
+#define DELIMITER ":"
+
+static void
+load_filters (LogviewPrefs *prefs)
+{
+ gchar **filters;
+ gchar **tokens;
+ const gchar *str;
+ LogviewFilter *filter;
+ GtkTextTag *tag;
+ GdkColor color;
+ gint idx;
+
+ filters = g_settings_get_strv (prefs->priv->logview_prefs,
+ PREF_FILTERS);
+
+ prefs->priv->filters = g_hash_table_new_full (g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) g_object_unref);
+
+ for (idx = 0; filters[idx] != NULL; idx++) {
+ str = filters[idx];
+ tokens = g_strsplit (str, DELIMITER, MAX_TOKENS);
+ filter = logview_filter_new (tokens[FILTER_NAME], tokens[FILTER_REGEX]);
+ tag = gtk_text_tag_new (tokens[FILTER_NAME]);
+
+ g_object_set (tag, "invisible",
+ g_str_equal (tokens[FILTER_INVISIBLE], "1"), NULL);
+
+ if (strlen (tokens[FILTER_FOREGROUND])) {
+ gdk_color_parse (tokens[FILTER_FOREGROUND], &color);
+ g_object_set (tag, "foreground-gdk", &color,
+ "foreground-set", TRUE, NULL);
+ }
+
+ if (strlen (tokens[FILTER_BACKGROUND])) {
+ gdk_color_parse (tokens[FILTER_BACKGROUND], &color);
+ g_object_set (tag, "paragraph-background-gdk", &color,
+ "paragraph-background-set", TRUE, NULL);
+ }
+
+ g_object_set (filter, "texttag", tag, NULL);
+ g_hash_table_insert (prefs->priv->filters,
+ g_strdup(tokens[FILTER_NAME]),
+ filter);
+
+ g_object_ref (filter);
+ g_object_unref (tag);
+ g_strfreev (tokens);
+ }
+
+ g_strfreev (filters);
+}
+
+static void
+save_filter_foreach_func (gpointer key, gpointer value, gpointer user_data)
+{
+ GPtrArray *filters;
+ const gchar *name;
+ LogviewFilter *filter;
+ GdkColor *foreground;
+ gboolean foreground_set;
+ GdkColor *background;
+ gboolean background_set;
+ gchar *regex, *color;
+ gboolean invisible;
+ GtkTextTag *tag;
+ GString *prefs_string;
+
+ filters = user_data;
+ filter = LOGVIEW_FILTER (value);
+ name = key;
+ color = NULL;
+
+ prefs_string = g_string_new (name);
+ g_string_append (prefs_string, DELIMITER);
+
+ g_object_get (filter,
+ "regex", &regex,
+ "texttag", &tag,
+ NULL);
+ g_object_get (tag,
+ "foreground-gdk", &foreground,
+ "paragraph-background-gdk", &background,
+ "foreground-set", &foreground_set,
+ "paragraph-background-set", &background_set,
+ "invisible", &invisible, NULL);
+
+ if (invisible) {
+ g_string_append (prefs_string, "1" DELIMITER);
+ } else {
+ g_string_append (prefs_string, "0" DELIMITER);
+ }
+
+ if (foreground_set) {
+ color = gdk_color_to_string (foreground);
+ g_string_append (prefs_string, color);
+ g_free (color);
+ }
+
+ if (foreground) {
+ gdk_color_free (foreground);
+ }
+
+ g_string_append (prefs_string, DELIMITER);
+
+ if (background_set) {
+ color = gdk_color_to_string (background);
+ g_string_append (prefs_string, color);
+ g_free (color);
+ }
+
+ if (background) {
+ gdk_color_free (background);
+ }
+
+ g_string_append (prefs_string, DELIMITER);
+ g_string_append (prefs_string, regex);
+
+ g_free (regex);
+ g_object_unref (tag);
+
+ g_ptr_array_add (filters, g_string_free (prefs_string, FALSE));
+}
+
+static void
+save_filters (LogviewPrefs *prefs)
+{
+ GPtrArray *filters;
+ gchar **filters_strv;
+
+ filters = g_ptr_array_new ();
+ g_hash_table_foreach (prefs->priv->filters,
+ save_filter_foreach_func,
+ filters);
+ g_ptr_array_add (filters, NULL);
+
+ filters_strv = (gchar **) g_ptr_array_free (filters, FALSE);
+ g_settings_set_strv (prefs->priv->logview_prefs,
+ PREF_FILTERS,
+ (const gchar **) filters_strv);
+
+ g_strfreev (filters_strv);
+}
+
+static void
+get_filters_foreach (gpointer key, gpointer value, gpointer user_data)
+{
+ GList **list;
+ list = user_data;
+ *list = g_list_append (*list, value);
+}
+
+static void
+logview_prefs_init (LogviewPrefs *self)
+{
+ LogviewPrefsPrivate *priv;
+
+ priv = self->priv = GET_PRIVATE (self);
+
+ priv->logview_prefs = g_settings_new (LOGVIEW_SCHEMA);
+ priv->interface_prefs = g_settings_new ("org.mate.interface");
+
+ g_signal_connect (priv->interface_prefs, "changed::" MATE_MONOSPACE_FONT_NAME,
+ G_CALLBACK (monospace_font_changed_cb), self);
+ g_signal_connect (priv->interface_prefs, "changed::" MATE_MENUS_HAVE_TEAROFF,
+ G_CALLBACK (have_tearoff_changed_cb), self);
+
+ load_filters (self);
+}
+
+/* public methods */
+
+LogviewPrefs *
+logview_prefs_get ()
+{
+ if (!singleton)
+ singleton = g_object_new (LOGVIEW_TYPE_PREFS, NULL);
+
+ return singleton;
+}
+
+void
+logview_prefs_store_window_size (LogviewPrefs *prefs,
+ int width, int height)
+{
+ g_assert (LOGVIEW_IS_PREFS (prefs));
+
+ g_settings_set_int (prefs->priv->logview_prefs,
+ PREF_WIDTH, width);
+ g_settings_set_int (prefs->priv->logview_prefs,
+ PREF_HEIGHT, height);
+}
+
+void
+logview_prefs_get_stored_window_size (LogviewPrefs *prefs,
+ int *width, int *height)
+{
+ g_assert (LOGVIEW_IS_PREFS (prefs));
+
+ *width = g_settings_get_int (prefs->priv->logview_prefs,
+ PREF_WIDTH);
+ *height = g_settings_get_int (prefs->priv->logview_prefs,
+ PREF_HEIGHT);
+
+ if ((*width == 0) ^ (*height == 0)) {
+ /* if one of the two failed, return default for both */
+ *width = LOGVIEW_DEFAULT_WIDTH;
+ *height = LOGVIEW_DEFAULT_HEIGHT;
+ }
+}
+
+char *
+logview_prefs_get_monospace_font_name (LogviewPrefs *prefs)
+{
+ g_assert (LOGVIEW_IS_PREFS (prefs));
+
+ return (g_settings_get_string (prefs->priv->interface_prefs, MATE_MONOSPACE_FONT_NAME));
+}
+
+gboolean
+logview_prefs_get_have_tearoff (LogviewPrefs *prefs)
+{
+ g_assert (LOGVIEW_IS_PREFS (prefs));
+
+ return (g_settings_get_boolean (prefs->priv->interface_prefs, MATE_MENUS_HAVE_TEAROFF));
+}
+
+/* the elements should be freed with g_free () */
+
+gchar **
+logview_prefs_get_stored_logfiles (LogviewPrefs *prefs)
+{
+ g_assert (LOGVIEW_IS_PREFS (prefs));
+
+ return g_settings_get_strv (prefs->priv->logview_prefs,
+ PREF_LOGFILES);
+}
+
+void
+logview_prefs_store_log (LogviewPrefs *prefs, GFile *file)
+{
+ gchar **stored_logs;
+ GFile *stored;
+ gboolean found = FALSE;
+ gint idx, old_size;
+
+ g_assert (LOGVIEW_IS_PREFS (prefs));
+ g_assert (G_IS_FILE (file));
+
+ stored_logs = logview_prefs_get_stored_logfiles (prefs);
+
+ for (idx = 0; stored_logs[idx] != NULL; idx++) {
+ stored = g_file_parse_name (stored_logs[idx]);
+ if (g_file_equal (file, stored)) {
+ found = TRUE;
+ }
+
+ g_object_unref (stored);
+
+ if (found) {
+ break;
+ }
+ }
+
+ if (!found) {
+ old_size = g_strv_length (stored_logs);
+ stored_logs = g_realloc (stored_logs, (old_size + 2) * sizeof (gchar *));
+ stored_logs[old_size] = g_file_get_parse_name (file);
+ stored_logs[old_size + 1] = NULL;
+
+ g_settings_set_strv (prefs->priv->logview_prefs,
+ PREF_LOGFILES,
+ (const gchar **) stored_logs);
+ }
+
+ g_strfreev (stored_logs);
+}
+
+void
+logview_prefs_remove_stored_log (LogviewPrefs *prefs, GFile *target)
+{
+ gchar **stored_logs;
+ GFile *stored;
+ GPtrArray *new_value;
+ gint idx;
+ gboolean removed = FALSE;
+
+ g_assert (LOGVIEW_IS_PREFS (prefs));
+ g_assert (G_IS_FILE (target));
+
+ stored_logs = logview_prefs_get_stored_logfiles (prefs);
+ new_value = g_ptr_array_new ();
+
+ for (idx = 0; stored_logs[idx] != NULL; idx++) {
+ stored = g_file_parse_name (stored_logs[idx]);
+ if (!g_file_equal (stored, target)) {
+ g_ptr_array_add (new_value, g_strdup (stored_logs[idx]));
+ }
+
+ g_object_unref (stored);
+ }
+
+ g_ptr_array_add (new_value, NULL);
+ g_strfreev (stored_logs);
+ stored_logs = (gchar **) g_ptr_array_free (new_value, FALSE);
+
+ g_settings_set_strv (prefs->priv->logview_prefs,
+ PREF_LOGFILES,
+ (const gchar **) stored_logs);
+
+ g_strfreev (stored_logs);
+}
+
+void
+logview_prefs_store_fontsize (LogviewPrefs *prefs, int fontsize)
+{
+ g_assert (LOGVIEW_IS_PREFS (prefs));
+ g_assert (fontsize > 0);
+
+ g_settings_set_int (prefs->priv->logview_prefs, PREF_FONTSIZE, fontsize);
+}
+
+int
+logview_prefs_get_stored_fontsize (LogviewPrefs *prefs)
+{
+ g_assert (LOGVIEW_IS_PREFS (prefs));
+
+ return g_settings_get_int (prefs->priv->logview_prefs, PREF_FONTSIZE);
+}
+
+void
+logview_prefs_store_active_logfile (LogviewPrefs *prefs,
+ const char *filename)
+{
+ g_assert (LOGVIEW_IS_PREFS (prefs));
+
+ g_settings_set_string (prefs->priv->logview_prefs,
+ PREF_LOGFILE, filename);
+}
+
+char *
+logview_prefs_get_active_logfile (LogviewPrefs *prefs)
+{
+ g_assert (LOGVIEW_IS_PREFS (prefs));
+
+ return g_settings_get_string (prefs->priv->logview_prefs,
+ PREF_LOGFILE);
+}
+
+GList *
+logview_prefs_get_filters (LogviewPrefs *prefs)
+{
+ GList *filters = NULL;
+
+ g_assert (LOGVIEW_IS_PREFS (prefs));
+
+ g_hash_table_foreach (prefs->priv->filters,
+ get_filters_foreach,
+ &filters);
+
+ return filters;
+}
+
+void
+logview_prefs_remove_filter (LogviewPrefs *prefs,
+ const gchar *name)
+{
+ g_assert (LOGVIEW_IS_PREFS (prefs));
+
+ g_hash_table_remove (prefs->priv->filters,
+ name);
+
+ save_filters (prefs);
+}
+
+void
+logview_prefs_add_filter (LogviewPrefs *prefs,
+ LogviewFilter *filter)
+{
+ gchar* name;
+
+ g_assert (LOGVIEW_IS_PREFS (prefs));
+ g_assert (LOGVIEW_IS_FILTER (filter));
+
+ g_object_get (filter, "name", &name, NULL);
+ g_hash_table_insert (prefs->priv->filters, name, g_object_ref (filter));
+
+ save_filters (prefs);
+}
+
+LogviewFilter *
+logview_prefs_get_filter (LogviewPrefs *prefs,
+ const gchar *name)
+{
+ g_assert (LOGVIEW_IS_PREFS (prefs));
+
+ return g_hash_table_lookup (prefs->priv->filters, name);
+}
+