[Xfce4-commits] <xfce4-appfinder:master> Add action item editing.
Nick Schermer
noreply at xfce.org
Tue Sep 20 21:58:04 CEST 2011
Updating branch refs/heads/master
to f6290f1c16c175e65ef7837317342feb4efbb732 (commit)
from dbce37f8979ae6230c13438da1c21a8e53cb6091 (commit)
commit f6290f1c16c175e65ef7837317342feb4efbb732
Author: Nick Schermer <nick at xfce.org>
Date: Tue Sep 20 21:52:52 2011 +0200
Add action item editing.
src/appfinder-actions.c | 134 +++++++++++++++++++++++++++------
src/appfinder-actions.h | 14 ++--
src/appfinder-preferences.c | 154 +++++++++++++++++++++++++++++++++------
src/appfinder-preferences.glade | 1 +
4 files changed, 248 insertions(+), 55 deletions(-)
diff --git a/src/appfinder-actions.c b/src/appfinder-actions.c
index 01c1feb..3d57f4b 100644
--- a/src/appfinder-actions.c
+++ b/src/appfinder-actions.c
@@ -35,7 +35,8 @@
static void xfce_appfinder_actions_finalize (GObject *object);
static void xfce_appfinder_actions_free (XfceAppfinderAction *action);
-static void xfce_appfinder_actions_load (XfceAppfinderActions *actions);
+static void xfce_appfinder_actions_load (XfceAppfinderActions *actions,
+ gboolean steal);
static void xfce_appfinder_actions_save (XfceAppfinderActions *actions,
gboolean save_actions);
static void xfce_appfinder_actions_changed (XfconfChannel *channel,
@@ -57,6 +58,8 @@ struct _XfceAppfinderActions
XfconfChannel *channel;
gulong property_watch_id;
+ guint reload_idle_id;
+
GSList *actions;
};
@@ -100,7 +103,7 @@ xfce_appfinder_actions_init (XfceAppfinderActions *actions)
{
actions->channel = xfconf_channel_get ("xfce4-appfinder");
- xfce_appfinder_actions_load (actions);
+ xfce_appfinder_actions_load (actions, FALSE);
actions->property_watch_id =
g_signal_connect (G_OBJECT (actions->channel), "property-changed",
@@ -114,6 +117,9 @@ xfce_appfinder_actions_finalize (GObject *object)
{
XfceAppfinderActions *actions = XFCE_APPFINDER_ACTIONS (object);
+ if (actions->reload_idle_id != 0)
+ g_source_remove (actions->reload_idle_id);
+
g_signal_handler_disconnect (actions->channel, actions->property_watch_id);
g_slist_foreach (actions->actions, (GFunc) xfce_appfinder_actions_free, NULL);
@@ -197,7 +203,8 @@ xfce_appfinder_actions_sort (gconstpointer a,
static void
-xfce_appfinder_actions_load (XfceAppfinderActions *actions)
+xfce_appfinder_actions_load (XfceAppfinderActions *actions,
+ gboolean steal)
{
XfceAppfinderAction *action;
gchar prop[32];
@@ -207,6 +214,16 @@ xfce_appfinder_actions_load (XfceAppfinderActions *actions)
guint i;
gint unique_id;
GPtrArray *array;
+ GSList *li, *old_actions = NULL;
+
+ appfinder_return_if_fail (XFCE_IS_APPFINDER_ACTIONS (actions));
+ appfinder_return_if_fail (steal || actions->actions == NULL);
+
+ if (steal)
+ {
+ old_actions = actions->actions;
+ actions->actions = NULL;
+ }
if (xfconf_channel_has_property (actions->channel, "/actions"))
{
@@ -219,8 +236,26 @@ xfce_appfinder_actions_load (XfceAppfinderActions *actions)
appfinder_assert (value != NULL);
unique_id = g_value_get_int (value);
+ /* look for the id in the old actions */
+ for (li = old_actions; li != NULL; li = li->next)
+ {
+ action = li->data;
+ if (action->unique_id == unique_id)
+ break;
+ }
+
+ if (li != NULL)
+ {
+ /* use the old action */
+ old_actions = g_slist_delete_link (old_actions, li);
+ actions->actions = g_slist_prepend (actions->actions, action);
+
+ continue;
+ }
+
+ /* no usable actions was found, create a new one */
g_snprintf (prop, sizeof (prop), "/actions/action-%d/type", unique_id);
- type = xfconf_channel_get_int (actions->channel, prop, -1);
+ type = xfconf_channel_get_int (actions->channel, prop, XFCE_APPFINDER_ACTION_TYPE_PREFIX);
if (type < XFCE_APPFINDER_ACTION_TYPE_PREFIX
|| type > XFCE_APPFINDER_ACTION_TYPE_REGEX)
continue;
@@ -231,21 +266,13 @@ xfce_appfinder_actions_load (XfceAppfinderActions *actions)
g_snprintf (prop, sizeof (prop), "/actions/action-%d/command", unique_id);
command = xfconf_channel_get_string (actions->channel, prop, NULL);
- if (pattern != NULL && command != NULL)
- {
- action = g_slice_new0 (XfceAppfinderAction);
- action->type = type;
- action->unique_id = unique_id;
- action->pattern = pattern;
- action->command = command;
+ action = g_slice_new0 (XfceAppfinderAction);
+ action->type = type;
+ action->unique_id = unique_id;
+ action->pattern = pattern;
+ action->command = command;
- actions->actions = g_slist_prepend (actions->actions, action);
- }
- else
- {
- g_free (pattern);
- g_free (command);
- }
+ actions->actions = g_slist_prepend (actions->actions, action);
}
xfconf_array_free (array);
@@ -254,10 +281,15 @@ xfce_appfinder_actions_load (XfceAppfinderActions *actions)
else
{
xfce_appfinder_actions_load_defaults (actions);
-
xfce_appfinder_actions_save (actions, TRUE);
}
+ if (old_actions != NULL)
+ {
+ g_slist_foreach (old_actions, (GFunc) xfce_appfinder_actions_free, NULL);
+ g_slist_free (old_actions);
+ }
+
actions->actions = g_slist_sort (actions->actions, xfce_appfinder_actions_sort);
APPFINDER_DEBUG ("loaded %d actions", g_slist_length (actions->actions));
@@ -265,6 +297,23 @@ xfce_appfinder_actions_load (XfceAppfinderActions *actions)
+static gboolean
+xfce_appfinder_actions_reload_idle (gpointer data)
+{
+ xfce_appfinder_actions_load (XFCE_APPFINDER_ACTIONS (data), TRUE);
+ return FALSE;
+}
+
+
+
+static void
+xfce_appfinder_actions_reload_idle_destroyed (gpointer data)
+{
+ XFCE_APPFINDER_ACTIONS (data)->reload_idle_id = 0;
+}
+
+
+
static void
xfce_appfinder_actions_save (XfceAppfinderActions *actions,
gboolean save_actions)
@@ -275,8 +324,7 @@ xfce_appfinder_actions_save (XfceAppfinderActions *actions,
GPtrArray *array;
gchar prop[32];
- if (actions->property_watch_id > 0)
- g_signal_handler_block (actions->channel, actions->property_watch_id);
+ g_signal_handler_block (actions->channel, actions->property_watch_id);
array = g_ptr_array_new ();
@@ -306,12 +354,12 @@ xfce_appfinder_actions_save (XfceAppfinderActions *actions,
xfconf_array_free (array);
- if (actions->property_watch_id > 0)
- g_signal_handler_unblock (actions->channel, actions->property_watch_id);
+ g_signal_handler_unblock (actions->channel, actions->property_watch_id);
}
+
static void
xfce_appfinder_actions_changed (XfconfChannel *channel,
const gchar *prop_name,
@@ -328,7 +376,12 @@ xfce_appfinder_actions_changed (XfconfChannel *channel,
if (strcmp (prop_name, "/actions") == 0)
{
-
+ if (actions->reload_idle_id == 0)
+ {
+ actions->reload_idle_id = g_idle_add_full (G_PRIORITY_LOW,
+ xfce_appfinder_actions_reload_idle, actions,
+ xfce_appfinder_actions_reload_idle_destroyed);
+ }
}
else if (sscanf (prop_name, "/actions/action-%d/%30s",
&unique_id, field) == 2)
@@ -431,7 +484,6 @@ xfce_appfinder_actions_get (void)
{
actions = g_object_new (XFCE_TYPE_APPFINDER_ACTIONS, NULL);
g_object_add_weak_pointer (G_OBJECT (actions), (gpointer) &actions);
- APPFINDER_DEBUG ("allocate actions");
}
return actions;
@@ -439,6 +491,33 @@ xfce_appfinder_actions_get (void)
+gint
+xfce_appfinder_actions_get_unique_id (XfceAppfinderActions *actions)
+{
+ static gint unique_id = 1;
+ GSList *li;
+ XfceAppfinderAction *action;
+
+ appfinder_return_val_if_fail (XFCE_IS_APPFINDER_ACTIONS (actions), -1);
+
+ for (; unique_id < G_MAXINT; unique_id++)
+ {
+ for (li = actions->actions; li != NULL; li = li->next)
+ {
+ action = li->data;
+ if (action->unique_id == unique_id)
+ break;
+ }
+
+ if (li == NULL)
+ return unique_id;
+ }
+
+ return -1;
+}
+
+
+
XfceAppfinderActionsResult
xfce_appfinder_actions_execute (XfceAppfinderActions *actions,
const gchar *text,
@@ -464,6 +543,11 @@ xfce_appfinder_actions_execute (XfceAppfinderActions *actions,
{
action = li->data;
+ /* skip empty actions */
+ if (!IS_STRING (action->pattern)
+ || !IS_STRING (action->command))
+ continue;
+
switch (action->type)
{
case XFCE_APPFINDER_ACTION_TYPE_PREFIX:
diff --git a/src/appfinder-actions.h b/src/appfinder-actions.h
index 97ceb80..8f62003 100644
--- a/src/appfinder-actions.h
+++ b/src/appfinder-actions.h
@@ -43,14 +43,16 @@ typedef enum
}
XfceAppfinderActionsResult;
-GType xfce_appfinder_actions_get_type (void) G_GNUC_CONST;
+GType xfce_appfinder_actions_get_type (void) G_GNUC_CONST;
-XfceAppfinderActions *xfce_appfinder_actions_get (void) G_GNUC_MALLOC;
+XfceAppfinderActions *xfce_appfinder_actions_get (void) G_GNUC_MALLOC;
-XfceAppfinderActionsResult xfce_appfinder_actions_execute (XfceAppfinderActions *actions,
- const gchar *text,
- GdkScreen *screen,
- GError **error);
+gint xfce_appfinder_actions_get_unique_id (XfceAppfinderActions *actions);
+
+XfceAppfinderActionsResult xfce_appfinder_actions_execute (XfceAppfinderActions *actions,
+ const gchar *text,
+ GdkScreen *screen,
+ GError **error);
G_END_DECLS
diff --git a/src/appfinder-preferences.c b/src/appfinder-preferences.c
index e48f424..37a4c6b 100644
--- a/src/appfinder-preferences.c
+++ b/src/appfinder-preferences.c
@@ -32,6 +32,7 @@
#include <src/appfinder-preferences-ui.h>
#include <src/appfinder-model.h>
#include <src/appfinder-private.h>
+#include <src/appfinder-actions.h>
@@ -61,12 +62,14 @@ struct _XfceAppfinderPreferences
{
GtkBuilder __parent__;
- GObject *dialog;
+ GObject *dialog;
- XfconfChannel *channel;
+ XfconfChannel *channel;
- gulong bindings[3];
- gulong property_watch_id;
+ GtkTreeSelection *selection;
+
+ gulong bindings[3];
+ gulong property_watch_id;
};
enum
@@ -91,9 +94,8 @@ xfce_appfinder_preferences_class_init (XfceAppfinderPreferencesClass *klass)
static void
xfce_appfinder_preferences_init (XfceAppfinderPreferences *preferences)
{
- GObject *object;
- GtkTreeSelection *selection;
- GtkTreePath *path;
+ GObject *object;
+ GtkTreePath *path;
preferences->channel = xfconf_channel_get ("xfce4-appfinder");
@@ -126,17 +128,17 @@ xfce_appfinder_preferences_init (XfceAppfinderPreferences *preferences)
g_signal_connect (G_OBJECT (object), "clicked",
G_CALLBACK (xfce_appfinder_preferences_action_remove), preferences);
- xfce_appfinder_preferences_action_populate (preferences);
-
object = gtk_builder_get_object (GTK_BUILDER (preferences), "actions-treeview");
+ preferences->selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (object));
+
+ xfce_appfinder_preferences_action_populate (preferences);
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (object));
- gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
- g_signal_connect (G_OBJECT (selection), "changed",
+ gtk_tree_selection_set_mode (preferences->selection, GTK_SELECTION_BROWSE);
+ g_signal_connect (G_OBJECT (preferences->selection), "changed",
G_CALLBACK (xfce_appfinder_preferences_selection_changed), preferences);
path = gtk_tree_path_new_first ();
- gtk_tree_selection_select_path (selection, path);
+ gtk_tree_selection_select_path (preferences->selection, path);
gtk_tree_path_free (path);
preferences->property_watch_id =
@@ -182,10 +184,79 @@ xfce_appfinder_preferences_clear_history (XfceAppfinderPreferences *preferences)
+static gboolean
+xfce_appfinder_preferences_action_save_foreach (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ GPtrArray *array = data;
+ gint id;
+ GValue *value;
+
+ gtk_tree_model_get (model, iter, COLUMN_UNIQUE_ID, &id, -1);
+
+ value = g_new0 (GValue, 1);
+ g_value_init (value, G_TYPE_INT);
+ g_value_set_int (value, id);
+ g_ptr_array_add (array, value);
+
+ return FALSE;
+}
+
+
+
+static void
+xfce_appfinder_preferences_action_save (XfceAppfinderPreferences *preferences,
+ GtkTreeModel *model)
+{
+ GPtrArray *array;
+
+ appfinder_return_if_fail (GTK_IS_TREE_MODEL (model));
+ appfinder_return_if_fail (XFCE_IS_APPFINDER_PREFERENCES (preferences));
+
+ g_signal_handler_block (preferences->channel, preferences->property_watch_id);
+
+ array = g_ptr_array_new ();
+ gtk_tree_model_foreach (model, xfce_appfinder_preferences_action_save_foreach, array);
+ xfconf_channel_set_arrayv (preferences->channel, "/actions", array);
+ xfconf_array_free (array);
+
+ g_signal_handler_unblock (preferences->channel, preferences->property_watch_id);
+}
+
+
+
static void
xfce_appfinder_preferences_action_add (XfceAppfinderPreferences *preferences)
{
+ XfceAppfinderActions *actions;
+ gint id;
+ GObject *store;
+ GtkTreeIter iter;
+ gchar prop[32];
+
+ appfinder_return_if_fail (XFCE_IS_APPFINDER_PREFERENCES (preferences));
+
+ /* get an unused id */
+ actions = xfce_appfinder_actions_get ();
+ id = xfce_appfinder_actions_get_unique_id (actions);
+ g_object_unref (G_OBJECT (actions));
+ /* make sure property does not exist */
+ g_snprintf (prop, sizeof (prop), "/actions/action-%d", id);
+ xfconf_channel_reset_property (preferences->channel, prop, TRUE);
+
+ /* add new item to store */
+ store = gtk_builder_get_object (GTK_BUILDER (preferences), "actions-store");
+ gtk_list_store_append (GTK_LIST_STORE (store), &iter);
+ gtk_list_store_set (GTK_LIST_STORE (store), &iter, COLUMN_UNIQUE_ID, id, -1);
+
+ /* select item */
+ gtk_tree_selection_select_iter (preferences->selection, &iter);
+
+ /* save new id */
+ xfce_appfinder_preferences_action_save (preferences, GTK_TREE_MODEL (store));
}
@@ -194,17 +265,40 @@ static void
xfce_appfinder_preferences_action_remove (GtkWidget *button,
XfceAppfinderPreferences *preferences)
{
- GObject *object;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gchar *pattern;
+ gint id;
+ gchar prop[32];
+
+ appfinder_return_if_fail (GTK_IS_WIDGET (button));
+ appfinder_return_if_fail (XFCE_IS_APPFINDER_PREFERENCES (preferences));
+
+ if (!gtk_tree_selection_get_selected (preferences->selection, &model, &iter))
+ return;
+
+ gtk_tree_model_get (model, &iter,
+ COLUMN_PATTERN, &pattern,
+ COLUMN_UNIQUE_ID, &id,
+ -1);
- object = gtk_builder_get_object (GTK_BUILDER (preferences), "pattern");
if (xfce_dialog_confirm (GTK_WINDOW (gtk_widget_get_toplevel (button)),
GTK_STOCK_DELETE, NULL,
_("The custom action will be deleted permanently."),
_("Are you sure you want to delete pattern \"%s\"?"),
- gtk_entry_get_text (GTK_ENTRY (object))))
+ pattern))
{
+ gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
+ /* remove data from channel */
+ g_snprintf (prop, sizeof (prop), "/actions/action-%d", id);
+ xfconf_channel_reset_property (preferences->channel, prop, TRUE);
+
+ /* save */
+ xfce_appfinder_preferences_action_save (preferences, model);
}
+
+ g_free (pattern);
}
@@ -273,19 +367,25 @@ xfce_appfinder_preferences_action_changed (XfconfChannel *channel,
}
+
static void
xfce_appfinder_preferences_action_populate (XfceAppfinderPreferences *preferences)
{
GPtrArray *array;
- GObject *store;
+ GtkTreeModel *store;
const GValue *value;
gint unique_id;
gchar prop[32];
gchar *pattern, *command;
guint i;
+ gint restore_id = -1;
+ GtkTreeIter iter;
+
+ APPFINDER_DEBUG ("populate tree model");
+
+ if (gtk_tree_selection_get_selected (preferences->selection, &store, &iter))
+ gtk_tree_model_get (store, &iter, COLUMN_UNIQUE_ID, &restore_id, -1);
- store = gtk_builder_get_object (GTK_BUILDER (preferences), "actions-store");
- appfinder_assert (GTK_IS_LIST_STORE (store));
gtk_list_store_clear (GTK_LIST_STORE (store));
array = xfconf_channel_get_arrayv (preferences->channel, "/actions");
@@ -303,11 +403,14 @@ xfce_appfinder_preferences_action_populate (XfceAppfinderPreferences *preference
g_snprintf (prop, sizeof (prop), "/actions/action-%d/command", unique_id);
command = xfconf_channel_get_string (preferences->channel, prop, NULL);
- gtk_list_store_insert_with_values (GTK_LIST_STORE (store), NULL, i,
+ gtk_list_store_insert_with_values (GTK_LIST_STORE (store), &iter, i,
COLUMN_UNIQUE_ID, unique_id,
COLUMN_PATTERN, pattern,
-1);
+ if (restore_id == unique_id)
+ gtk_tree_selection_select_iter (preferences->selection, &iter);
+
g_free (pattern);
g_free (command);
}
@@ -369,6 +472,13 @@ xfce_appfinder_preferences_selection_changed (GtkTreeSelection *selectio
object = gtk_builder_get_object (GTK_BUILDER (preferences), objects[i].name);
appfinder_return_if_fail (GTK_IS_WIDGET (object));
gtk_widget_set_sensitive (GTK_WIDGET (object), unique_id != -1);
+
+ /* clear contents */
+ if (GTK_IS_ENTRY (object))
+ gtk_entry_set_text (GTK_ENTRY (object), "");
+ else if (GTK_IS_COMBO_BOX (object))
+ gtk_combo_box_set_active (GTK_COMBO_BOX (object), 0);
+
if (unique_id > -1)
{
g_snprintf (prop, sizeof (prop), "/actions/action-%d/%s", unique_id, objects[i].name);
@@ -376,10 +486,6 @@ xfce_appfinder_preferences_selection_changed (GtkTreeSelection *selectio
objects[i].prop_type, object,
objects[i].prop_name);
}
- else if (GTK_IS_ENTRY (object))
- {
- gtk_entry_set_text (GTK_ENTRY (object), "");
- }
}
object = gtk_builder_get_object (GTK_BUILDER (preferences), "button-remove");
diff --git a/src/appfinder-preferences.glade b/src/appfinder-preferences.glade
index 3eb3b02..3ae52e3 100644
--- a/src/appfinder-preferences.glade
+++ b/src/appfinder-preferences.glade
@@ -231,6 +231,7 @@
<property name="headers_clickable">False</property>
<property name="enable_search">False</property>
<property name="search_column">0</property>
+ <property name="rules_hint">True</property>
<child>
<object class="GtkTreeViewColumn" id="treeviewcolumn1">
<property name="title" translatable="yes">Pattern</property>
More information about the Xfce4-commits
mailing list