[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