[Xfce4-commits] <design:master> Add more stuff.
Nick Schermer
noreply at xfce.org
Sat Jun 4 21:42:01 CEST 2011
Updating branch refs/heads/master
to 9c4ad5588c3f0c0fcd20247a2e1829797a846b0c (commit)
from 35a2ac670e98fc991545b857355f68cf5e5c5f20 (commit)
commit 9c4ad5588c3f0c0fcd20247a2e1829797a846b0c
Author: Nick Schermer <nick at xfce.org>
Date: Sat Jun 4 21:41:02 2011 +0200
Add more stuff.
.../merge-with-xfrun/demo-code/c/appfinder-model.c | 157 ++++++++++++++----
.../merge-with-xfrun/demo-code/c/appfinder-model.h | 10 +-
.../demo-code/c/appfinder-window.c | 173 ++++++++++++++------
3 files changed, 256 insertions(+), 84 deletions(-)
diff --git a/xfce4-appfinder/merge-with-xfrun/demo-code/c/appfinder-model.c b/xfce4-appfinder/merge-with-xfrun/demo-code/c/appfinder-model.c
index b04acc2..26979ca 100644
--- a/xfce4-appfinder/merge-with-xfrun/demo-code/c/appfinder-model.c
+++ b/xfce4-appfinder/merge-with-xfrun/demo-code/c/appfinder-model.c
@@ -10,6 +10,10 @@
#include "appfinder-model.h"
+#define HISTORY_PATH "xfce4/xfce4-appfinder/history"
+#define ICON_SMALL 32
+#define ICON_LARGE 48
+
static void xfce_appfinder_model_tree_model_init (GtkTreeModelIface *iface);
@@ -61,7 +65,8 @@ struct _XfceAppfinderModel
GSList *items;
GarconMenu *menu;
- GdkPixbuf *command_icon;
+ GdkPixbuf *command_icon_small;
+ GdkPixbuf *command_icon_large;
gchar *filter_category;
gchar *filter_string;
@@ -77,12 +82,14 @@ struct _XfceAppfinderModel
typedef struct
{
GarconMenuItem *item;
- GdkPixbuf *pixbuf;
gchar *key;
gchar *abstract;
gchar *category;
gchar *command;
guint visible : 1;
+
+ GdkPixbuf *icon_small;
+ GdkPixbuf *icon_large;
}
ModelItem;
@@ -128,7 +135,8 @@ xfce_appfinder_model_init (XfceAppfinderModel *model)
{
/* generate a unique stamp */
model->stamp = g_random_int ();
- model->command_icon = xfce_appfinder_model_load_pixbuf (GTK_STOCK_EXECUTE, 32);
+ model->command_icon_small = xfce_appfinder_model_load_pixbuf (GTK_STOCK_EXECUTE, ICON_SMALL);
+ model->command_icon_large = xfce_appfinder_model_load_pixbuf (GTK_STOCK_EXECUTE, ICON_LARGE);
model->menu = garcon_menu_new_applications ();
model->collect_thread = g_thread_create (xfce_appfinder_model_collect_thread, model, TRUE, NULL);
@@ -181,8 +189,8 @@ xfce_appfinder_model_finalize (GObject *object)
g_free (model->filter_category);
g_free (model->filter_string);
- if (model->command_icon != NULL)
- g_object_unref (G_OBJECT (model->command_icon));
+ g_object_unref (G_OBJECT (model->command_icon_large));
+ g_object_unref (G_OBJECT (model->command_icon_small));
g_message ("model cleared");
@@ -218,7 +226,7 @@ xfce_appfinder_model_get_column_type (GtkTreeModel *tree_model,
case XFCE_APPFINDER_MODEL_COLUMN_COMMAND:
return G_TYPE_STRING;
- case XFCE_APPFINDER_MODEL_COLUMN_ICON:
+ case XFCE_APPFINDER_MODEL_COLUMN_ICON_SMALL:
case XFCE_APPFINDER_MODEL_COLUMN_ICON_LARGE:
return GDK_TYPE_PIXBUF;
@@ -340,33 +348,28 @@ xfce_appfinder_model_get_value (GtkTreeModel *tree_model,
g_value_set_static_string (value, item->command);
break;
-
- case XFCE_APPFINDER_MODEL_COLUMN_ICON:
- if (item->pixbuf == NULL)
+ case XFCE_APPFINDER_MODEL_COLUMN_ICON_SMALL:
+ if (item->icon_small == NULL
+ && item->item != NULL)
{
- if (item->item != NULL)
- {
- name = garcon_menu_item_get_icon_name (item->item);
- item->pixbuf = xfce_appfinder_model_load_pixbuf (name, 32);
- }
- else if (item->command != NULL)
- {
- item->pixbuf = g_object_ref (G_OBJECT (model->command_icon));
- }
+ name = garcon_menu_item_get_icon_name (item->item);
+ item->icon_small = xfce_appfinder_model_load_pixbuf (name, ICON_SMALL);
}
g_value_init (value, GDK_TYPE_PIXBUF);
- g_value_set_object (value, item->pixbuf);
+ g_value_set_object (value, item->icon_small);
break;
case XFCE_APPFINDER_MODEL_COLUMN_ICON_LARGE:
- if (item->item != NULL)
- name = garcon_menu_item_get_icon_name (item->item);
- else
- name = GTK_STOCK_EXECUTE;
+ if (item->icon_large == NULL
+ && item->icon_large != NULL)
+ {
+ name = garcon_menu_item_get_icon_name (item->item);
+ item->icon_large = xfce_appfinder_model_load_pixbuf (name, ICON_LARGE);
+ }
g_value_init (value, GDK_TYPE_PIXBUF);
- g_value_take_object (value, xfce_appfinder_model_load_pixbuf (name, 48));
+ g_value_set_object (value, item->icon_large);
break;
case XFCE_APPFINDER_MODEL_COLUMN_URI:
@@ -578,8 +581,10 @@ xfce_appfinder_model_item_free (gpointer data)
{
ModelItem *item = data;
- if (item->pixbuf != NULL)
- g_object_unref (G_OBJECT (item->pixbuf));
+ if (item->icon_small != NULL)
+ g_object_unref (G_OBJECT (item->icon_small));
+ if (item->icon_large != NULL)
+ g_object_unref (G_OBJECT (item->icon_large));
g_free (item->abstract);
g_free (item->key);
g_free (item->category);
@@ -717,6 +722,8 @@ xfce_appfinder_model_collect_history (XfceAppfinderModel *model,
{
item = g_slice_new0 (ModelItem);
item->command = g_strndup (contents, len);
+ item->icon_small = g_object_ref (G_OBJECT (model->command_icon_small));
+ item->icon_large = g_object_ref (G_OBJECT (model->command_icon_large));
model->collect_items = g_slist_prepend (model->collect_items, item);
}
@@ -754,7 +761,7 @@ xfce_appfinder_model_collect_thread (gpointer user_data)
}
/* load command history */
- filename = xfce_resource_lookup (XFCE_RESOURCE_CACHE, "xfce4/xfce4-appfinder/history");
+ filename = xfce_resource_lookup (XFCE_RESOURCE_CACHE, HISTORY_PATH);
if (G_LIKELY (filename != NULL))
{
history = g_mapped_file_new (filename, FALSE, &error);
@@ -920,7 +927,7 @@ xfce_appfinder_model_filter_string (XfceAppfinderModel *model,
g_free (model->filter_string);
- if (seach_string != NULL && *seach_string != '\0')
+ if (IS_STRING (seach_string))
{
normalized = g_utf8_normalize (seach_string, -1, G_NORMALIZE_ALL);
model->filter_string = g_utf8_casefold (normalized, -1);
@@ -940,6 +947,7 @@ gboolean
xfce_appfinder_model_execute (XfceAppfinderModel *model,
GtkTreeIter *iter,
GdkScreen *screen,
+ gboolean *is_regular_command,
GError **error)
{
const gchar *command, *p;
@@ -955,10 +963,16 @@ xfce_appfinder_model_execute (XfceAppfinderModel *model,
mitem = ITER_GET_DATA (iter);
item = mitem->item;
+
+ /* leave if this is not a menu item */
+ *is_regular_command = (item == NULL);
+ if (item == NULL)
+ return FALSE;
+
g_return_val_if_fail (GARCON_IS_MENU_ITEM (item), FALSE);
command = garcon_menu_item_get_command (item);
- if (command == NULL || *command == '\0')
+ if (!IS_STRING (command))
{
g_set_error_literal (error, 0, 0, _("Application has no command"));
return FALSE;
@@ -1011,8 +1025,10 @@ GdkPixbuf *
xfce_appfinder_model_load_pixbuf (const gchar *icon_name,
gint size)
{
- GdkPixbuf *pixbuf = NULL;
- GdkPixbuf *scaled;
+ GdkPixbuf *pixbuf = NULL;
+ GdkPixbuf *scaled;
+
+ g_message ("load icon %s at %dpx", icon_name, size);
if (icon_name != NULL)
{
@@ -1046,3 +1062,82 @@ xfce_appfinder_model_load_pixbuf (const gchar *icon_name,
return pixbuf;
}
+
+
+
+gboolean
+xfce_appfinder_model_save_commands (XfceAppfinderModel *model,
+ GError **error)
+{
+ GSList *li;
+ GString *contents;
+ gboolean succeed = FALSE;
+ gchar *filename;
+ ModelItem *item;
+
+ g_return_val_if_fail (XFCE_IS_APPFINDER_MODEL (model), FALSE);
+
+ contents = g_string_new (NULL);
+
+ g_message ("saving history");
+
+ /* store all the custom commands */
+ for (li = model->items; li != NULL; li = li->next)
+ {
+ item = li->data;
+ if (item->item != NULL
+ || item->command == NULL)
+ continue;
+
+ g_string_append (contents, item->command);
+ g_string_append_c (contents, '\n');
+ }
+
+ if (contents->len > 0)
+ {
+ filename = xfce_resource_save_location (XFCE_RESOURCE_CACHE, HISTORY_PATH, TRUE);
+ if (G_LIKELY (filename != NULL))
+ succeed = g_file_set_contents (filename, contents->str, contents->len, error);
+ else
+ g_set_error_literal (error, 0, 0, "Unable to create history cache file");
+ g_free (filename);
+ }
+ else
+ {
+ succeed = TRUE;
+ }
+
+ g_string_free (contents, TRUE);
+
+ return succeed;
+}
+
+
+
+GdkPixbuf *
+xfce_appfinder_model_get_icon_for_text (XfceAppfinderModel *model,
+ const gchar *text)
+{
+ ModelItem *item;
+ GSList *li;
+
+ if (!IS_STRING (text))
+ return NULL;
+
+ for (li = model->items; li != NULL; li = li->next)
+ {
+ item = li->data;
+
+ if (item->command != NULL
+ && strcmp (item->command, text) == 0)
+ {
+ if (item->icon_large == NULL
+ && item->item != NULL)
+ item->icon_large = xfce_appfinder_model_load_pixbuf (garcon_menu_item_get_icon_name (item->item), ICON_LARGE);
+
+ return g_object_ref (G_OBJECT (item->icon_large));
+ }
+ }
+
+ return NULL;
+}
diff --git a/xfce4-appfinder/merge-with-xfrun/demo-code/c/appfinder-model.h b/xfce4-appfinder/merge-with-xfrun/demo-code/c/appfinder-model.h
index bca36d9..19ca402 100644
--- a/xfce4-appfinder/merge-with-xfrun/demo-code/c/appfinder-model.h
+++ b/xfce4-appfinder/merge-with-xfrun/demo-code/c/appfinder-model.h
@@ -21,11 +21,12 @@ G_STMT_START { \
(iter).stamp = iter_stamp; \
(iter).user_data = iter_data; \
} G_STMT_END
+#define IS_STRING(str) ((str) != NULL && *(str) != '\0')
enum
{
XFCE_APPFINDER_MODEL_COLUMN_ABSTRACT,
- XFCE_APPFINDER_MODEL_COLUMN_ICON,
+ XFCE_APPFINDER_MODEL_COLUMN_ICON_SMALL,
XFCE_APPFINDER_MODEL_COLUMN_ICON_LARGE,
XFCE_APPFINDER_MODEL_COLUMN_VISIBLE,
XFCE_APPFINDER_MODEL_COLUMN_COMMAND,
@@ -48,11 +49,18 @@ void xfce_appfinder_model_filter_string (XfceAppfinderMode
gboolean xfce_appfinder_model_execute (XfceAppfinderModel *model,
GtkTreeIter *iter,
GdkScreen *screen,
+ gboolean *is_regular_command,
GError **error);
GdkPixbuf *xfce_appfinder_model_load_pixbuf (const gchar *icon_name,
gint size) G_GNUC_MALLOC;
+gboolean xfce_appfinder_model_save_commands (XfceAppfinderModel *model,
+ GError **error);
+
+GdkPixbuf *xfce_appfinder_model_get_icon_for_text (XfceAppfinderModel *model,
+ const gchar *text);
+
G_END_DECLS
#endif /* !__XFCE_APPFINDER_MODEL_H__ */
diff --git a/xfce4-appfinder/merge-with-xfrun/demo-code/c/appfinder-window.c b/xfce4-appfinder/merge-with-xfrun/demo-code/c/appfinder-window.c
index 558c748..635adda 100644
--- a/xfce4-appfinder/merge-with-xfrun/demo-code/c/appfinder-window.c
+++ b/xfce4-appfinder/merge-with-xfrun/demo-code/c/appfinder-window.c
@@ -67,6 +67,8 @@ struct _XfceAppfinderWindow
GtkWidget *image;
GtkWidget *treeview;
+ GdkPixbuf *icon_find;
+
GtkWidget *bbox;
GtkWidget *button_launch;
GtkWidget *bin_collapsed;
@@ -148,7 +150,8 @@ xfce_appfinder_window_init (XfceAppfinderWindow *window)
gtk_box_pack_start (GTK_BOX (hbox), align, FALSE, FALSE, 0);
gtk_widget_show (align);
- window->image = image = gtk_image_new_from_stock (GTK_STOCK_FIND, GTK_ICON_SIZE_DIALOG);
+ window->icon_find = xfce_appfinder_model_load_pixbuf (GTK_STOCK_FIND, 48);
+ window->image = image = gtk_image_new_from_pixbuf (window->icon_find);
gtk_container_add (GTK_CONTAINER (align), image);
gtk_widget_show (image);
@@ -250,7 +253,7 @@ xfce_appfinder_window_init (XfceAppfinderWindow *window)
G_CALLBACK (xfce_appfinder_window_item_changed), window);
renderer = gtk_cell_renderer_pixbuf_new ();
- column = gtk_tree_view_column_new_with_attributes (NULL, renderer, "pixbuf", XFCE_APPFINDER_MODEL_COLUMN_ICON, NULL);
+ column = gtk_tree_view_column_new_with_attributes (NULL, renderer, "pixbuf", XFCE_APPFINDER_MODEL_COLUMN_ICON_SMALL, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), GTK_TREE_VIEW_COLUMN (column));
renderer = gtk_cell_renderer_text_new ();
@@ -295,6 +298,7 @@ xfce_appfinder_window_finalize (GObject *object)
g_object_unref (G_OBJECT (window->model));
g_object_unref (G_OBJECT (window->category_model));
g_object_unref (G_OBJECT (window->completion));
+ g_object_unref (G_OBJECT (window->icon_find));
(*G_OBJECT_CLASS (xfce_appfinder_window_parent_class)->finalize) (object);
}
@@ -328,6 +332,20 @@ xfce_appfinder_window_delete_event (GtkWidget *widget,
static void
+xfce_appfinder_window_update_image (XfceAppfinderWindow *window,
+ GdkPixbuf *pixbuf)
+{
+ if (pixbuf == NULL)
+ pixbuf = window->icon_find;
+
+ /* gtk doesn't check this */
+ if (gtk_image_get_pixbuf (GTK_IMAGE (window->image)) != pixbuf)
+ gtk_image_set_from_pixbuf (GTK_IMAGE (window->image), pixbuf);
+}
+
+
+
+static void
xfce_appfinder_window_set_padding (GtkWidget *entry,
GtkWidget *align)
{
@@ -344,13 +362,23 @@ static void
xfce_appfinder_window_entry_changed (XfceAppfinderWindow *window)
{
const gchar *text;
+ GdkPixbuf *pixbuf;
text = gtk_entry_get_text (GTK_ENTRY (window->entry));
if (gtk_widget_get_visible (window->paned))
- xfce_appfinder_model_filter_string (window->model, text);
+ {
+ xfce_appfinder_model_filter_string (window->model, text);
+ }
else
- gtk_widget_set_sensitive (window->button_launch, text != NULL && *text != '\0');
+ {
+ gtk_widget_set_sensitive (window->button_launch, IS_STRING (text));
+
+ pixbuf = xfce_appfinder_model_get_icon_for_text (window->model, text);
+ xfce_appfinder_window_update_image (window, pixbuf);
+ if (pixbuf != NULL)
+ g_object_unref (G_OBJECT (pixbuf));
+ }
}
@@ -384,10 +412,16 @@ xfce_appfinder_window_entry_key_press_event (GtkWidget *entry,
GdkEventKey *event,
XfceAppfinderWindow *window)
{
- gboolean expand;
+ gboolean expand;
+ const gchar *text;
if (event->keyval == GDK_KEY_Up || event->keyval == GDK_KEY_Down)
{
+ /* only switch modes when there is no text in the entry */
+ text = gtk_entry_get_text (GTK_ENTRY (window->entry));
+ if (IS_STRING (text))
+ return FALSE;
+
expand = (event->keyval == GDK_KEY_Down);
if (gtk_widget_get_visible (window->paned) != expand)
{
@@ -414,7 +448,7 @@ xfce_appfinder_window_drag_begin (GtkWidget *widget,
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (window->treeview));
if (gtk_tree_selection_get_selected (selection, &model, &iter))
{
- gtk_tree_model_get (model, &iter, XFCE_APPFINDER_MODEL_COLUMN_ICON, &pixbuf, -1);
+ gtk_tree_model_get (model, &iter, XFCE_APPFINDER_MODEL_COLUMN_ICON_SMALL, &pixbuf, -1);
if (G_LIKELY (pixbuf != NULL))
{
gtk_drag_set_icon_pixbuf (drag_context, pixbuf, 0, 0);
@@ -508,13 +542,17 @@ xfce_appfinder_window_item_changed (XfceAppfinderWindow *window)
if (can_launch)
{
- gtk_tree_model_get (model, &iter, XFCE_APPFINDER_MODEL_COLUMN_ICON_LARGE, &pixbuf, -1);
+ gtk_tree_model_get (model, &iter, XFCE_APPFINDER_MODEL_COLUMN_ICON_SMALL, &pixbuf, -1);
if (G_LIKELY (pixbuf != NULL))
{
- gtk_image_set_from_pixbuf (GTK_IMAGE (window->image), pixbuf);
+ xfce_appfinder_window_update_image (window, pixbuf);
g_object_unref (G_OBJECT (pixbuf));
}
}
+ else
+ {
+ xfce_appfinder_window_update_image (window, NULL);
+ }
}
}
@@ -529,6 +567,60 @@ xfce_appfinder_window_row_activated (XfceAppfinderWindow *window)
+static gboolean
+xfce_appfinder_window_execute_command (const gchar *cmd,
+ GdkScreen *screen,
+ GError **error)
+{
+ gboolean in_terminal;
+ gchar *cmdline, *exo_open;
+ const gchar *exo_open_prefix[] = { "file://", "http://", "https://" };
+ guint i;
+ gboolean result = FALSE;
+
+ if (g_str_has_prefix (cmd, "#"))
+ {
+ /* open manual page in the terminal */
+ cmdline = g_strconcat ("man ", cmd + 1, NULL);
+ in_terminal = TRUE;
+ }
+ else if (g_str_has_prefix (cmd, "$"))
+ {
+ /* open in the terminal */
+ cmdline = xfce_expand_variables (cmd + 1, NULL);
+ in_terminal = TRUE;
+ }
+ else
+ {
+ cmdline = xfce_expand_variables (cmd, NULL);
+ in_terminal = FALSE;
+ }
+
+ result = xfce_spawn_command_line_on_screen (screen, cmdline, in_terminal, FALSE, error);
+ if (!result)
+ {
+ /* TODO instead check the exo exit code */
+ /* check if this is something exo-open can handle */
+ for (i = 0; !result && i < G_N_ELEMENTS (exo_open_prefix); i++)
+ if (g_str_has_prefix (cmdline, exo_open_prefix[i]))
+ result = TRUE;
+
+ if (result)
+ {
+ /* try to spawn again */
+ exo_open = g_strconcat ("exo-open ", cmdline, NULL);
+ result = xfce_spawn_command_line_on_screen (screen, exo_open, FALSE, FALSE, error);
+ g_free (exo_open);
+ }
+ }
+
+ g_free (cmdline);
+
+ return result;
+}
+
+
+
static void
xfce_appfinder_window_execute (XfceAppfinderWindow *window)
{
@@ -539,10 +631,8 @@ xfce_appfinder_window_execute (XfceAppfinderWindow *window)
gboolean result = FALSE;
GdkScreen *screen;
const gchar *text;
- gboolean in_terminal;
- gchar *cmdline, *exo_open;
- const gchar *exo_open_prefix[] = { "file://", "http://", "https://" };
- guint i;
+ gchar *cmd;
+ gboolean regular_command = FALSE;
if (!gtk_widget_get_sensitive (window->button_launch))
return;
@@ -554,49 +644,20 @@ xfce_appfinder_window_execute (XfceAppfinderWindow *window)
if (gtk_tree_selection_get_selected (selection, &model, &iter))
{
gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &orig, &iter);
- result = xfce_appfinder_model_execute (window->model, &orig, screen, &error);
+ result = xfce_appfinder_model_execute (window->model, &orig, screen, ®ular_command, &error);
+
+ if (result == FALSE && regular_command == TRUE)
+ {
+ gtk_tree_model_get (model, &iter, XFCE_APPFINDER_MODEL_COLUMN_COMMAND, &cmd, -1);
+ result = xfce_appfinder_window_execute_command (cmd, screen, &error);
+ g_free (cmd);
+ }
}
}
else
{
text = gtk_entry_get_text (GTK_ENTRY (window->entry));
- if (g_str_has_prefix (text, "#"))
- {
- /* open manual page in the terminal */
- cmdline = g_strconcat ("man ", text + 1, NULL);
- in_terminal = TRUE;
- }
- else if (g_str_has_prefix (text, "$"))
- {
- /* open in the terminal */
- cmdline = xfce_expand_variables (text + 1, NULL);
- in_terminal = TRUE;
- }
- else
- {
- cmdline = xfce_expand_variables (text, NULL);
- in_terminal = FALSE;
- }
-
- result = xfce_spawn_command_line_on_screen (screen, cmdline, in_terminal, FALSE, &error);
- if (!result)
- {
- /* TODO instead check the exo exit code */
- /* check if this is something exo-open can handle */
- for (i = 0; !result && i < G_N_ELEMENTS (exo_open_prefix); i++)
- if (g_str_has_prefix (cmdline, exo_open_prefix[i]))
- result = TRUE;
-
- if (result)
- {
- /* try to spawn again */
- exo_open = g_strconcat ("exo-open ", cmdline, NULL);
- result = xfce_spawn_command_line_on_screen (screen, exo_open, FALSE, FALSE, &error);
- g_free (exo_open);
- }
- }
-
- g_free (cmdline);
+ result = xfce_appfinder_window_execute_command (text, screen, &error);
}
gtk_entry_set_icon_from_stock (GTK_ENTRY (window->entry), GTK_ENTRY_ICON_PRIMARY,
@@ -605,10 +666,18 @@ xfce_appfinder_window_execute (XfceAppfinderWindow *window)
error != NULL ? error->message : NULL);
if (error != NULL)
- g_error_free (error);
+ g_clear_error (&error);
if (result)
- gtk_main_quit ();
+ {
+ if (!xfce_appfinder_model_save_commands (window->model, &error))
+ {
+ g_warning ("Failed to save history: %s", error->message);
+ g_error_free (error);
+ }
+
+ gtk_main_quit ();
+ }
}
More information about the Xfce4-commits
mailing list