[Xfce4-commits] <xfce-utils:completion> Add new object to handle history.
Jérôme Guelfucci
noreply at xfce.org
Wed Nov 3 21:04:02 CET 2010
Updating branch refs/heads/completion
to 899b7329bcfa26afabe324accfe812a2a9242858 (commit)
from 6f586a6fbcd2ee7e9c508ee854d3f8c409c900e0 (commit)
commit 899b7329bcfa26afabe324accfe812a2a9242858
Author: Jérôme Guelfucci <jeromeg at xfce.org>
Date: Sat Oct 30 11:12:40 2010 +0200
Add new object to handle history.
"In terminal" handling still needs to be added. Object not tested.
xfrun/xfrun-history.c | 465 +++++++++++++++++++++++++++++++++++++++++++++++++
xfrun/xfrun-history.h | 71 ++++++++
2 files changed, 536 insertions(+), 0 deletions(-)
diff --git a/xfrun/xfrun-history.c b/xfrun/xfrun-history.c
new file mode 100644
index 0000000..2b779c3
--- /dev/null
+++ b/xfrun/xfrun-history.c
@@ -0,0 +1,465 @@
+/*
+ * XfrunHistory - an object to handle history based completion of queries.
+ *
+ * Copyright (c) 2010 Jérôme Guelfucci <jeromeg at xfce.org>
+ *
+ * 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "xfrun-history.h"
+
+#include <glib.h>
+#include <libxfce4util/libxfce4util.h>
+#include <libxfce4ui/libxfce4ui.h>
+
+struct _XfrunHistoryPrivate
+{
+ GList *history;
+ GList *current_history;
+
+ GCompletion *full_completion;
+ GList *completion;
+ GList *current_completion;
+};
+
+
+
+G_DEFINE_TYPE (XfrunHistory, xfrun_history, G_TYPE_OBJECT);
+
+static void xfrun_history_finalize (GObject *gobject);
+static void xfrun_history_free_list (gpointer item,
+ gpointer user_data);
+static gchar **xfrun_history_get_file_content (void);
+static GList *xfrun_history_initialize_history (void);
+static GCompletion *xfrun_history_initialize_completion (GList *history);
+
+
+
+/* Private functions */
+
+static void xfrun_history_class_init (XfrunHistoryClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->finalize = xfrun_history_finalize;
+
+ g_type_class_add_private (klass, sizeof (XfrunHistoryPrivate));
+}
+
+static void
+xfrun_history_init (XfrunHistory *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, XFRUN_TYPE_HISTORY,
+ XfrunHistoryPrivate);
+
+ self->priv->history = xfrun_history_initialize_history ();
+ self->priv->current_history = NULL;
+
+ self->priv->full_completion = xfrun_history_initialize_completion (self->priv->history);
+ self->priv->completion = NULL;
+ self->priv->current_completion = NULL;
+}
+
+static void
+xfrun_history_finalize (GObject *gobject)
+{
+ XfrunHistory *self = XFRUN_HISTORY (gobject);
+
+ /* Free the history list */
+ if (self->priv->history)
+ {
+ g_list_foreach (self->priv->history, xfrun_history_free_list, NULL);
+ g_list_free (self->priv->history);
+ }
+
+ /* Free the completion stuff */
+ if (self->priv->full_completion)
+ g_completion_free (self->priv->full_completion);
+ if (self->priv->completion)
+ {
+ g_list_foreach (self->priv->completion, xfrun_history_free_list, NULL);
+ g_list_free (self->priv->completion);
+ }
+
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS (xfrun_history_parent_class)->finalize (gobject);
+}
+
+static void
+xfrun_history_free_list (gpointer item, gpointer user_data)
+{
+ g_free (item);
+}
+
+static gchar
+**xfrun_history_get_file_content (void)
+{
+ gchar **lines;
+ gchar *history_file;
+ gchar *contents;
+
+ lines = NULL;
+ contents = NULL;
+
+ history_file = xfce_resource_lookup (XFCE_RESOURCE_CACHE, "xfce4/xfrun4/history");
+
+ if (history_file && g_file_get_contents (history_file, &contents, NULL, NULL))
+ {
+ lines = g_strsplit (contents, "\n", -1);
+ g_free (contents);
+ }
+
+ g_free (history_file);
+
+ return lines;
+}
+
+static GList
+*xfrun_history_initialize_history (void)
+{
+ gchar **history_contents;
+ GList *list;
+ gint i;
+
+ history_contents = xfrun_history_get_file_content ();
+
+ if (history_contents == NULL)
+ return NULL;
+
+ list = NULL;
+
+ /* Add the lines to the history list */
+ for (i = 0; history_contents[i] != NULL; i++)
+ {
+ GString *string;
+
+ /* Remove leading and trailing white spaces */
+ string = g_string_new (g_strstrip (history_contents[i]));
+
+ /* Only add non-empty lines */
+ if (G_LIKELY (string->len > 0))
+ list = g_list_append (list, history_contents[i]);
+
+ g_string_free (string, FALSE);
+ }
+
+ g_strfreev (history_contents);
+
+ return list;
+}
+
+static GCompletion
+*xfrun_history_initialize_completion (GList *history)
+{
+ GCompletion *completion;
+
+ /* Create the completion and add the whole history list as
+ * completion items */
+ completion = g_completion_new (NULL);
+ g_completion_add_items (completion, history);
+
+ return completion;
+}
+
+/* Public functions */
+
+/**
+ * xfrun_history_get_next:
+ * @history: a #XfrunHistory
+ *
+ * Returns the next item in history, the same item if we are at the
+ * end of the history list or %NULL if the history is empty.
+ *
+ * When called for the first time, returns the first element of the list.
+ *
+ * Return value: a string that should not be modified/freed or %NULL.
+ **/
+gchar
+*xfrun_history_get_next (XfrunHistory *history)
+{
+ g_return_val_if_fail (XFRUN_IS_HISTORY (history), NULL);
+
+ /* Check if we have a loaded history */
+ if (history->priv->history == NULL)
+ return NULL;
+
+ if (history->priv->current_history)
+ {
+ /* We already started to cycle through history */
+ GList *next;
+
+ /* If the end was reached, stay at the end */
+ next = g_list_next (history->priv->current_history);
+ if (next)
+ history->priv->current_history = next;
+ }
+ else
+ /* Start to cycle through history */
+ history->priv->current_history = history->priv->history;
+
+ return history->priv->current_history->data;
+}
+
+/**
+ * xfrun_history_get_previous:
+ * @history: a #XfrunHistory
+ *
+ * Returns the previous item in history, the same item if we are at the
+ * beginning of the history list or %NULL if the history is empty.
+ *
+ * Return value: a string that should not be modified/freed or %NULL.
+ **/
+gchar
+*xfrun_history_get_previous (XfrunHistory *history)
+{
+ g_return_val_if_fail (XFRUN_IS_HISTORY (history), NULL);
+
+ /* Check if we have a loaded history */
+ if (history->priv->history == NULL)
+ return NULL;
+
+ if (history->priv->current_history)
+ {
+ /* We already started to cycle through history */
+ GList *previous;
+
+ /* If we are at the beginning, stay there */
+ previous = g_list_previous (history->priv->current_history);
+ if (previous)
+ history->priv->current_history = previous;
+ }
+
+ return history->priv->current_history->data;
+}
+
+/**
+ * xfrun_history_reset:
+ * @history: a #XfrunHistory
+ *
+ * Resets the history cycle to its initial value. Call
+ * xfrun_history_get_next to start a new cycle.
+ *
+ **/
+void
+xfrun_history_reset (XfrunHistory *history)
+{
+ g_return_if_fail (XFRUN_IS_HISTORY (history));
+
+ history->priv->current_history = NULL;
+}
+
+/**
+ * xfrun_history_completion_start:
+ * @history: a #XfrunHistory
+ * @pattern: the prefix to be completed using history.
+ *
+ * Complete prefix using the loaded history. Returns the first valid
+ * item if any or #NULL.
+ *
+ * The other valid items can be accessed using xfrun_history_completion_next
+ * and xfrun_history_completion_previous.
+ *
+ * xfrun_history_completion_reset should be called when the completion results
+ * are no longer needed.
+ *
+ * Return value: a string that should not be modified/freed or %NULL.
+ **/
+gchar
+*xfrun_history_completion_start (XfrunHistory *history,
+ const gchar *prefix)
+{
+ g_return_val_if_fail (XFRUN_IS_HISTORY (history), NULL);
+
+ if (history->priv->full_completion == NULL)
+ return NULL;
+
+ if (history->priv->completion)
+ /* Note: we don't have to free the items, they are owned by the completion stuff */
+ g_list_free (history->priv->completion);
+
+ /* Try to complete the given string and save the items */
+ history->priv->completion = g_completion_complete_utf8 (history->priv->full_completion,
+ prefix,
+ NULL);
+ history->priv->current_completion = history->priv->completion;
+
+ /* Return the first item if there is one */
+ if (history->priv->completion)
+ return history->priv->completion->data;
+ else
+ return NULL;
+}
+
+/**
+ * xfrun_history_completion_next:
+ * @history: a #XfrunHistory
+ *
+ * Returns the next completion item for current completion or %NULL
+ * if there is no history based completion at the moment.
+ *
+ * If the end of the completion list was reached, the same item is
+ * returned.
+ *
+ * xfrun_history_completion_start must be called once before using this
+ * function.
+ *
+ * Return value: a string that should not be modified/freed or %NULL.
+ **/
+gchar
+*xfrun_history_completion_next (XfrunHistory *history)
+{
+ GList *next;
+
+ g_return_val_if_fail (XFRUN_IS_HISTORY (history), NULL);
+
+ /* Check if a history completion was started */
+ if (history->priv->current_completion == NULL)
+ return NULL;
+
+ /* Get the next item */
+ next = g_list_next (history->priv->current_completion);
+
+ /* If we are at the end of the list, we stay there */
+ if (next)
+ history->priv->current_completion = next;
+
+ return history->priv->current_completion->data;
+}
+
+/**
+ * xfrun_history_completion_previous:
+ * @history: a #XfrunHistory
+ *
+ * Returns the previous completion item for current completion or %NULL
+ * if there is no history based completion at the moment.
+ *
+ * If the beginning of the completion list was reached, the same item is
+ * returned.
+ *
+ * xfrun_history_completion_start must be called once before using this
+ * function.
+ *
+ * Return value: a string that should not be modified/freed or %NULL.
+ **/
+gchar
+*xfrun_history_completion_previous (XfrunHistory *history)
+{
+ GList *previous;
+
+ g_return_val_if_fail (XFRUN_IS_HISTORY (history), NULL);
+
+ /* Check if a history completion was started */
+ if (history->priv->current_completion == NULL)
+ return NULL;
+
+ /* Get the previous item */
+ previous = g_list_previous (history->priv->current_completion);
+
+ /* If we are at the beginning of the list, we stay there */
+ if (previous)
+ history->priv->current_completion = previous;
+
+ return history->priv->current_completion->data;
+}
+
+/**
+ * xfrun_history_completion_reset:
+ * @history: a #XfrunHistory
+ *
+ * Clean the current completion. Should be called before starting a completion
+ * based on another prefix.
+ *
+ * Use xfrun_history_completion_start to start a new history based completion.
+ *
+ **/
+void
+xfrun_history_completion_reset (XfrunHistory *history)
+{
+ g_return_if_fail (XFRUN_IS_HISTORY (history));
+
+ if (history->priv->completion)
+ /* Note: we don't have to free the items, they are owned by the completion stuff */
+ g_list_free (history->priv->completion);
+
+ /* Reset the completion lists */
+ history->priv->completion = NULL;
+ history->priv->current_completion = NULL;
+}
+
+/**
+ * xfrun_history_add:
+ * @history; a #XfrunHistory
+ * @command: a string to be added to the history list.
+ *
+ * Add @command at the end of the history list.
+ *
+ **/
+void xfrun_history_add (XfrunHistory *history, gchar *command)
+{
+ GList *add;
+
+ g_return_if_fail (XFRUN_IS_HISTORY (history));
+
+ /* Add the command to the history list */
+ history->priv->history =
+ g_list_append (history->priv->history, command);
+
+ /* Add the command to the completion */
+ add = NULL;
+ add = g_list_append (add, command);
+ g_completion_add_items (history->priv->full_completion,
+ add);
+
+ g_list_free (add);
+}
+
+/**
+ * xfrun_history_save:
+ * @history: a #XfrunHistory
+ *
+ * Save the history list in the user ressource directory.
+ *
+ **/
+void xfrun_history_save (XfrunHistory *history)
+{
+ GError *error;
+ gchar *history_file;
+ gchar *contents;
+ GList *l;
+
+ g_return_if_fail (XFRUN_IS_HISTORY (history));
+
+ error = NULL;
+ contents = NULL;
+ history_file =
+ xfce_resource_lookup (XFCE_RESOURCE_CACHE, "xfce4/xfrun4/history");
+
+ for (l = history->priv->history; l != NULL; l = g_list_next (l))
+ {
+ contents = g_strconcat (contents, l->data, "\n", NULL);
+ }
+
+ if (!g_file_set_contents (history_file, contents, -1, &error))
+ {
+ xfce_dialog_show_error (NULL, error,
+ _("Error when writing history"));
+
+ g_error_free (error);
+ }
+
+ g_free (contents);
+ g_free (history_file);
+}
+
diff --git a/xfrun/xfrun-history.h b/xfrun/xfrun-history.h
new file mode 100644
index 0000000..84e53bd
--- /dev/null
+++ b/xfrun/xfrun-history.h
@@ -0,0 +1,71 @@
+/*
+ * XfrunHistory - an object to handle history based completion of queries.
+ *
+ * Copyright (c) 2010 Jérôme Guelfucci <jeromeg at xfce.org>
+ *
+ * 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Copyright/Licensing information.
+ */
+
+/* inclusion guard */
+#ifndef __XFRUN_HISTORY_H__
+#define __XFRUN_HISTORY_H__
+
+#include <glib-object.h>
+
+#define XFRUN_TYPE_HISTORY (xfrun_history_get_type ())
+#define XFRUN_HISTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XFRUN_TYPE_HISTORY, XfrunHistory))
+#define XFRUN_IS_HISTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XFRUN_TYPE_HISTORY))
+#define XFRUN_HISTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XFRUN_TYPE_HISTORY, XfrunHistoryClass))
+#define XFRUN_IS_HISTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XFRUN_TYPE_HISTORY))
+#define XFRUN_HISTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XFRUN_TYPE_HISTORY, XfrunHistoryClass))
+
+typedef struct _XfrunHistory XfrunHistory;
+typedef struct _XfrunHistoryClass XfrunHistoryClass;
+typedef struct _XfrunHistoryPrivate XfrunHistoryPrivate;
+
+struct _XfrunHistory
+{
+ GObject parent_instance;
+
+ XfrunHistoryPrivate *priv;
+};
+
+struct _XfrunHistoryClass
+{
+ GObjectClass parent_class;
+};
+
+GType xfrun_history_get_type (void);
+
+gchar *xfrun_history_get_next (XfrunHistory *history);
+gchar *xfrun_history_get_previous (XfrunHistory *history);
+void xfrun_history_reset (XfrunHistory *history);
+
+gchar *xfrun_history_completion_start (XfrunHistory *history,
+ const gchar *prefix);
+gchar *xfrun_history_completion_next (XfrunHistory *history);
+gchar *xfrun_history_completion_previous (XfrunHistory *history);
+void xfrun_history_completion_reset (XfrunHistory *history);
+
+void xfrun_history_add (XfrunHistory *history,
+ gchar *command);
+void xfrun_history_save (XfrunHistory *history);
+
+
+#endif /* __XFRUN_HISTORY_H__ */
More information about the Xfce4-commits
mailing list