[Xfce4-commits] <xfce4-panel:devel> More working version of the launcher code

Nick Schermer nick at xfce.org
Tue Aug 11 20:26:43 CEST 2009


Updating branch refs/heads/devel
         to cf5ffb883c9c6d238b34e0b1e14b9b678979902e (commit)
       from bb581443f94cbed2ff2b6d6fd7d4228661c4d459 (commit)

commit cf5ffb883c9c6d238b34e0b1e14b9b678979902e
Author: Nick Schermer <nick at xfce.org>
Date:   Tue Feb 10 22:22:16 2009 +0100

    More working version of the launcher code
    
    This version add more code to the launcher and makes it actually
    work again. Possible to add new launcher (not custom ones yet)
    and move and delete them. Editing is not working yet.

 panel/panel-preferences-dialog.c       |   22 ++--
 plugins/launcher/launcher-dialog.c     |  295 ++++++++++++++++++++++++++-----
 plugins/launcher/launcher-dialog.glade |   31 ++++
 plugins/launcher/launcher.c            |  159 ++++++++++++-----
 plugins/launcher/launcher.h            |    5 +-
 5 files changed, 405 insertions(+), 107 deletions(-)

diff --git a/panel/panel-preferences-dialog.c b/panel/panel-preferences-dialog.c
index 1f013dc..15bcbac 100644
--- a/panel/panel-preferences-dialog.c
+++ b/panel/panel-preferences-dialog.c
@@ -94,7 +94,7 @@ struct _PanelPreferencesDialog
 
   /* store for the items list */
   GtkListStore     *store;
-  
+
   gulong            changed_handler_id;
 };
 
@@ -140,7 +140,7 @@ panel_preferences_dialog_init (PanelPreferencesDialog *dialog)
   window = gtk_builder_get_object (GTK_BUILDER (dialog), "dialog");
   panel_application_take_dialog (dialog->application, GTK_WINDOW (window));
   g_signal_connect (G_OBJECT (window), "response", G_CALLBACK (panel_preferences_dialog_response), dialog);
-  
+
 #define connect_signal(name,detail_signal,c_handler) \
   object = gtk_builder_get_object (GTK_BUILDER (dialog), name); \
   panel_return_if_fail (G_IS_OBJECT (object)); \
@@ -225,8 +225,8 @@ panel_preferences_dialog_finalize (GObject *object)
 
 
 static void
-panel_preferences_dialog_response (GtkWidget              *window, 
-                                   gint                    response_id, 
+panel_preferences_dialog_response (GtkWidget              *window,
+                                   gint                    response_id,
                                    PanelPreferencesDialog *dialog)
 {
   GError    *error = NULL;
@@ -326,7 +326,7 @@ panel_preferences_dialog_panel_combobox_changed (GtkComboBox            *combobo
 
   panel_return_if_fail (GTK_IS_COMBO_BOX (combobox));
   panel_return_if_fail (PANEL_IS_PREFERENCES_DIALOG (dialog));
-  
+
   /* disconnect signal we used to monitor changes in the itembar */
   if (dialog->changed_handler_id != 0)
     {
@@ -337,11 +337,11 @@ panel_preferences_dialog_panel_combobox_changed (GtkComboBox            *combobo
   /* set the selected window */
   nth = gtk_combo_box_get_active (combobox);
   dialog->active = panel_application_get_window (dialog->application, nth);
-  
-  
+
+
   itembar = gtk_bin_get_child (GTK_BIN (dialog->active));
-  dialog->changed_handler_id = g_signal_connect_swapped (G_OBJECT (itembar), "notify::changed", 
-                                                               G_CALLBACK (panel_preferences_dialog_item_store_rebuild), 
+  dialog->changed_handler_id = g_signal_connect_swapped (G_OBJECT (itembar), "notify::changed",
+                                                               G_CALLBACK (panel_preferences_dialog_item_store_rebuild),
                                                                dialog);
 
   /* rebind the dialog bindings */
@@ -564,7 +564,7 @@ panel_preferences_dialog_item_move (GtkWidget              *button,
         {
           /* block the changed signal */
           g_signal_handler_block (G_OBJECT (itembar), dialog->changed_handler_id);
-          
+
           /* move the item on the panel */
           panel_itembar_reorder_child (PANEL_ITEMBAR (itembar),
                                        GTK_WIDGET (provider),
@@ -640,7 +640,7 @@ panel_preferences_dialog_item_remove (GtkWidget              *button,
         {
           /* hide the dialog */
           gtk_widget_hide (widget);
-          
+
           /* send signal */
           xfce_panel_plugin_provider_emit_signal (provider, PROVIDER_SIGNAL_REMOVE_PLUGIN);
         }
diff --git a/plugins/launcher/launcher-dialog.c b/plugins/launcher/launcher-dialog.c
index c0456dc..080e826 100644
--- a/plugins/launcher/launcher-dialog.c
+++ b/plugins/launcher/launcher-dialog.c
@@ -26,6 +26,7 @@
 #include <exo/exo.h>
 #include <libxfce4ui/libxfce4ui.h>
 #include <libxfce4menu/libxfce4menu.h>
+#include <libxfce4util/libxfce4util.h>
 #include <common/panel-private.h>
 
 #include "launcher.h"
@@ -39,6 +40,7 @@ typedef struct
   LauncherPlugin *plugin;
   GtkBuilder     *builder;
   guint           idle_populate_id;
+  XfconfChannel  *channel;
 }
 LauncherPluginDialog;
 
@@ -51,6 +53,11 @@ enum
 
 
 
+static void launcher_dialog_entries_insert_item (GtkListStore *store, GtkTreeIter *iter, const gchar *filename);
+static void launcher_dialog_entries_changed (XfconfChannel *channel, const gchar *property_name, const GValue *value, LauncherPluginDialog *dialog);
+
+
+
 static gboolean
 launcher_dialog_add_visible_function (GtkTreeModel *model,
                                       GtkTreeIter  *iter,
@@ -108,7 +115,7 @@ launcher_dialog_add_store_insert (gpointer filename,
 
   panel_return_if_fail (XFCE_IS_MENU_ITEM (item));
   panel_return_if_fail (GTK_IS_LIST_STORE (user_data));
-  
+
   /* TODO get rid of this and support absolute paths too */
   icon_name = xfce_menu_item_get_icon_name (item);
   if (icon_name != NULL
@@ -120,7 +127,7 @@ launcher_dialog_add_store_insert (gpointer filename,
   gtk_list_store_append (store, &iter);
   gtk_list_store_set (store, &iter,
                       COL_ADD_ICON, icon_name,
-                      COL_ADD_NAME, xfce_menu_item_get_name (item), 
+                      COL_ADD_NAME, xfce_menu_item_get_name (item),
                       COL_ADD_FILENAME, xfce_menu_item_get_filename (item),
                       -1);
 }
@@ -202,6 +209,48 @@ launcher_dialog_add_populate_model (LauncherPluginDialog *dialog)
 
 
 
+static gboolean
+launcher_dialog_tree_save_foreach (GtkTreeModel *model,
+                                   GtkTreePath  *path,
+                                   GtkTreeIter  *iter,
+                                   gpointer      user_data)
+{
+  GPtrArray *array = user_data;
+  GValue    *value;
+  gchar     *filename;
+
+  /* get the filename of the entry from the store */
+  gtk_tree_model_get (model, iter, COL_ADD_FILENAME, &filename, -1);
+
+  /* create a value with the filename */
+  value = g_new0 (GValue, 1);
+  g_value_init (value, G_TYPE_STRING);
+  g_value_take_string (value, filename);
+
+  /* put it in the array */
+  g_ptr_array_add (array, value);
+
+  return FALSE;
+}
+
+
+
+static void
+launcher_dialog_tree_save (LauncherPluginDialog *dialog)
+{
+  GObject   *store;
+  GPtrArray *array;
+
+  store = gtk_builder_get_object (dialog->builder, "entry-store");
+
+  array = g_ptr_array_new ();
+  gtk_tree_model_foreach (GTK_TREE_MODEL (store), launcher_dialog_tree_save_foreach, array);
+  xfconf_channel_set_arrayv (dialog->channel, "/entries", array);
+  xfconf_array_free (array);
+}
+
+
+
 static void
 launcher_dialog_tree_selection_changed (GtkTreeSelection     *selection,
                                         LauncherPluginDialog *dialog)
@@ -228,16 +277,16 @@ launcher_dialog_tree_selection_changed (GtkTreeSelection     *selection,
 
   /* update the sensitivity of the buttons */
   object = gtk_builder_get_object (dialog->builder, "entry-remove");
-  gtk_widget_set_sensitive (GTK_WIDGET (object), n_children > 1);
+  gtk_widget_set_sensitive (GTK_WIDGET (object), !!(n_children > 0));
 
   object = gtk_builder_get_object (dialog->builder, "entry-move-up");
-  gtk_widget_set_sensitive (GTK_WIDGET (object), position > 0);
+  gtk_widget_set_sensitive (GTK_WIDGET (object), !!(position > 0 && position <= n_children));
 
   object = gtk_builder_get_object (dialog->builder, "entry-move-down");
-  gtk_widget_set_sensitive (GTK_WIDGET (object), n_children > position);
+  gtk_widget_set_sensitive (GTK_WIDGET (object), !!(position >= 0 && position < n_children - 1));
 
   object = gtk_builder_get_object (dialog->builder, "entry-edit");
-  gtk_widget_set_sensitive (GTK_WIDGET (object), position >= 0 /* TODO custom only */);
+  gtk_widget_set_sensitive (GTK_WIDGET (object), !!(position >= 0 && n_children > 0) /* TODO custom only */);
 }
 
 
@@ -246,9 +295,14 @@ static void
 launcher_dialog_entry_button_clicked (GtkWidget            *button,
                                       LauncherPluginDialog *dialog)
 {
-  const gchar *name;
-  GObject     *object;
-  GtkWidget   *window;
+  const gchar      *name;
+  GObject          *object;
+  GtkWidget        *window;
+  GObject          *treeview;
+  GtkTreeSelection *selection;
+  GtkTreeModel     *model;
+  GtkTreeIter       iter_a, iter_b;
+  GtkTreePath      *path;
 
   panel_return_if_fail (GTK_IS_BUILDABLE (button));
   panel_return_if_fail (GTK_IS_BUILDER (dialog->builder));
@@ -262,38 +316,58 @@ launcher_dialog_entry_button_clicked (GtkWidget            *button,
       launcher_dialog_add_populate_model (dialog);
       gtk_widget_show (GTK_WIDGET (object));
     }
-  else if (exo_str_is_equal (name, "entry-remove"))
+  else
     {
-      /* create question dialog */
-      window = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (button)),
-                                       GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
-                                       GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE,
-                                       _("Are you sure you want to remove \"%s\"?"), "TODO");
-      gtk_dialog_add_buttons (GTK_DIALOG (window), GTK_STOCK_REMOVE, GTK_RESPONSE_ACCEPT,
-                              GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);
-      gtk_dialog_set_default_response (GTK_DIALOG (window), GTK_RESPONSE_ACCEPT);
-
-      /* run the dialog */
-      if (gtk_dialog_run (GTK_DIALOG (window)) == GTK_RESPONSE_ACCEPT)
-        {
+      /* get the selected item in the tree, leave if none is found */
+      treeview = gtk_builder_get_object (dialog->builder, "entry-treeview");
+      selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
+      if (!gtk_tree_selection_get_selected (selection, &model, &iter_a))
+        return;
 
+      if (exo_str_is_equal (name, "entry-remove"))
+        {
+          /* create question dialog */
+          window = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (button)),
+                                           GTK_DIALOG_DESTROY_WITH_PARENT,
+                                           GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE,
+                                           _("Are you sure you want to remove \"%s\"?"), "TODO");
+          gtk_dialog_add_buttons (GTK_DIALOG (window), GTK_STOCK_REMOVE, GTK_RESPONSE_ACCEPT,
+                                  GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);
+          gtk_dialog_set_default_response (GTK_DIALOG (window), GTK_RESPONSE_ACCEPT);
+
+          /* run the dialog */
+          if (gtk_dialog_run (GTK_DIALOG (window)) == GTK_RESPONSE_ACCEPT)
+            gtk_list_store_remove (GTK_LIST_STORE (model), &iter_a);
+
+          /* destroy */
+          gtk_widget_destroy (window);
+        }
+      else if (exo_str_is_equal (name, "entry-edit"))
+        {
+          object = gtk_builder_get_object (dialog->builder, "dialog-editor");
+          gtk_widget_show (GTK_WIDGET (object));
+        }
+      else if (exo_str_is_equal (name, "entry-move-up"))
+        {
+          path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter_a);
+          if (gtk_tree_path_prev (path)
+              && gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter_b, path))
+            gtk_list_store_swap (GTK_LIST_STORE (model), &iter_a, &iter_b);
+          gtk_tree_path_free (path);
+        }
+      else
+        {
+          panel_return_if_fail (exo_str_is_equal (name, "entry-move-down"));
+          iter_b = iter_a;
+          if (gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &iter_b))
+            gtk_list_store_swap (GTK_LIST_STORE (model), &iter_a, &iter_b);
         }
 
-      /* destroy */
-      gtk_widget_destroy (window);
-    }
-  else if (exo_str_is_equal (name, "entry-move-up"))
-    {
-
-    }
-  else if (exo_str_is_equal (name, "entry-move-down"))
-    {
+      /* store the new settings */
+      launcher_dialog_tree_save (dialog);
 
-    }
-  else /* entry-edit */
-    {
-      object = gtk_builder_get_object (dialog->builder, "dialog-editor");
-      gtk_widget_show (GTK_WIDGET (object));
+      /* emit a changed signal to update the button states */
+      launcher_dialog_tree_selection_changed (selection, dialog);
     }
 }
 
@@ -322,6 +396,11 @@ launcher_dialog_response (GtkWidget            *widget,
       gtk_widget_destroy (widget);
       g_object_unref (G_OBJECT (dialog->builder));
 
+      /* disconnect signal */
+      g_signal_handlers_disconnect_by_func (G_OBJECT (dialog->channel),
+                                            launcher_dialog_entries_changed,
+                                            dialog);
+
       /* unblock plugin menu */
       xfce_panel_plugin_unblock_menu (XFCE_PANEL_PLUGIN (dialog->plugin));
 
@@ -351,15 +430,15 @@ launcher_dialog_add_response (GtkWidget            *widget,
                               gint                  response_id,
                               LauncherPluginDialog *dialog)
 {
-  GObject          *treeview, *store;
-  GtkTreeSelection *selection;
-  GtkTreeModel     *model;
-  GtkTreeIter       iter;
-  gchar            *filename;
+  GObject           *treeview, *store;
+  GtkTreeSelection  *selection;
+  GtkTreeModel      *model;
+  GtkTreeIter        iter, sibling;
+  gchar             *filename;
 
   panel_return_if_fail (GTK_IS_DIALOG (widget));
   panel_return_if_fail (XFCE_IS_LAUNCHER_PLUGIN (dialog->plugin));
-  
+
   if (response_id != 0)
     {
       /* set the selected item in the treeview */
@@ -367,12 +446,31 @@ launcher_dialog_add_response (GtkWidget            *widget,
       selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
       if (gtk_tree_selection_get_selected (selection, &model, &iter))
         {
+          /* get the selected file in the add dialog */
           gtk_tree_model_get (model, &iter, COL_ADD_FILENAME, &filename, -1);
-          
+
+          /* get the selected item in the entry treeview */
+          treeview = gtk_builder_get_object (dialog->builder, "entry-treeview");
+          selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
+          if (gtk_tree_selection_get_selected (selection, &model, &sibling))
+            gtk_list_store_insert_after (GTK_LIST_STORE (model), &iter, &sibling);
+          else
+            gtk_list_store_append (GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (treeview))), &iter);
+
+          /* insert the item */
+          launcher_dialog_entries_insert_item (GTK_LIST_STORE (model), &iter, filename);
+
+          /* cleanup */
           g_free (filename);
+
+          /* write the model to xfconf */
+          launcher_dialog_tree_save (dialog);
+
+          /* update the selection */
+          launcher_dialog_tree_selection_changed (selection, dialog);
         }
     }
-  
+
   /* empty the store */
   store = gtk_builder_get_object (dialog->builder, "add-store");
   gtk_list_store_clear (GTK_LIST_STORE (store));
@@ -383,6 +481,96 @@ launcher_dialog_add_response (GtkWidget            *widget,
 
 
 
+static void
+launcher_dialog_entries_insert_item (GtkListStore *store,
+                                     GtkTreeIter  *iter,
+                                     const gchar  *filename)
+{
+  XfceRc *rc;
+
+  panel_return_if_fail (GTK_IS_LIST_STORE (store));
+  panel_return_if_fail (IS_STRING (filename));
+
+  rc = xfce_rc_simple_open (filename, TRUE);
+  if (G_LIKELY (rc != NULL))
+    {
+      xfce_rc_set_group (rc, "Desktop Entry");
+
+      gtk_list_store_set (GTK_LIST_STORE (store), iter,
+                          COL_ADD_ICON, xfce_rc_read_entry_untranslated (rc, "Icon", NULL),
+                          COL_ADD_NAME, xfce_rc_read_entry (rc, "Name", NULL),
+                          COL_ADD_FILENAME, filename,
+                          -1);
+      xfce_rc_close (rc);
+    }
+}
+
+
+
+static void
+launcher_dialog_entries_changed (XfconfChannel        *channel,
+                                 const gchar          *property_name,
+                                 const GValue         *value,
+                                 LauncherPluginDialog *dialog)
+{
+  gchar       **filenames;
+  gchar        *filename;
+  guint         i;
+  GObject      *store;
+  GtkTreeIter   iter;
+  gboolean      update = FALSE;
+  gint          n_children;
+
+  /* only handle something when the entries changes */
+  if (!exo_str_is_equal (property_name, "/entries"))
+    return;
+
+  /* get the store and clear it */
+  store = gtk_builder_get_object (dialog->builder, "entry-store");
+
+  filenames = xfconf_channel_get_string_list (channel, "/entries");
+  if (G_LIKELY (filenames != NULL))
+    {
+      /* compare if the number of items is different */
+      n_children = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL);
+      update = g_strv_length (filenames) != (guint) n_children;
+
+      /* if not, compare the model and the array if there are differences */
+      if (!update && gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter))
+        {
+          for (i = 0; filenames[i] != NULL; i++)
+            {
+              gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, COL_ADD_FILENAME, &filename, -1);
+              update = !exo_str_is_equal (filenames[i], filename);
+              if (G_UNLIKELY (update))
+                break;
+
+              if (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter))
+                break;
+            }
+        }
+
+      if (update == TRUE)
+        {
+          gtk_list_store_clear (GTK_LIST_STORE (store));
+          for (i = 0; update && filenames[i] != NULL; i++)
+            {
+              gtk_list_store_append (GTK_LIST_STORE (store), &iter);
+              launcher_dialog_entries_insert_item (GTK_LIST_STORE (store), &iter, filenames[i]);
+            }
+        }
+
+      g_strfreev (filenames);
+    }
+  else if (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) > 0)
+    {
+      /* model is not empty but the channel is */
+      gtk_list_store_clear (GTK_LIST_STORE (store));
+    }
+}
+
+
+
 void
 launcher_dialog_show (LauncherPlugin *plugin)
 {
@@ -402,6 +590,10 @@ launcher_dialog_show (LauncherPlugin *plugin)
       dialog = g_slice_new0 (LauncherPluginDialog);
       dialog->builder = builder;
       dialog->plugin = plugin;
+      dialog->channel = launcher_plugin_get_channel (plugin);
+
+      /* monitor the channel for any changes */
+      g_signal_connect (G_OBJECT (dialog->channel), "property-changed", G_CALLBACK (launcher_dialog_entries_changed), dialog);
 
       /* block plugin menu */
       xfce_panel_plugin_block_menu (XFCE_PANEL_PLUGIN (plugin));
@@ -427,16 +619,16 @@ launcher_dialog_show (LauncherPlugin *plugin)
 
       /* connect binding to the advanced properties */
       object = gtk_builder_get_object (builder, "disable-tooltips");
-      xfconf_g_property_bind (plugin->channel, "/disable-tooltips", G_TYPE_BOOLEAN, object, "active");
+      //TODOxfconf_g_property_bind (plugin->channel, "/disable-tooltips", G_TYPE_BOOLEAN, object, "active");
 
       object = gtk_builder_get_object (builder, "show-labels");
-      xfconf_g_property_bind (plugin->channel, "/show-labels", G_TYPE_BOOLEAN, object, "active");
+      //xfconf_g_property_bind (plugin->channel, "/show-labels", G_TYPE_BOOLEAN, object, "active");
 
       object = gtk_builder_get_object (builder, "move-first");
-      xfconf_g_property_bind (plugin->channel, "/move-first", G_TYPE_BOOLEAN, object, "active");
+      //xfconf_g_property_bind (plugin->channel, "/move-first", G_TYPE_BOOLEAN, object, "active");
 
       object = gtk_builder_get_object (builder, "arrow-position");
-      xfconf_g_property_bind (plugin->channel, "/arrow-position", G_TYPE_UINT, object, "active");
+      //xfconf_g_property_bind (plugin->channel, "/arrow-position", G_TYPE_UINT, object, "active");
 
       /* setup responses for the other dialogs */
       object = gtk_builder_get_object (builder, "dialog-editor");
@@ -460,6 +652,13 @@ launcher_dialog_show (LauncherPlugin *plugin)
       object = gtk_builder_get_object (builder, "addrenderericon");
       g_object_set (G_OBJECT (object), "stock-size", GTK_ICON_SIZE_DND, NULL);
 
+      /* setup the icon size */
+      object = gtk_builder_get_object (builder, "entryrenderericon");
+      g_object_set (G_OBJECT (object), "stock-size", GTK_ICON_SIZE_DND, NULL);
+
+      /* load the launchers */
+      launcher_dialog_entries_changed (dialog->channel, "/entries", NULL, dialog);
+
       /* show the dialog */
       gtk_widget_show (GTK_WIDGET (window));
     }
diff --git a/plugins/launcher/launcher-dialog.glade b/plugins/launcher/launcher-dialog.glade
index ad98233..7b28bf2 100644
--- a/plugins/launcher/launcher-dialog.glade
+++ b/plugins/launcher/launcher-dialog.glade
@@ -39,6 +39,16 @@
       <column type="gchararray"/>
     </columns>
   </object>
+  <object class="GtkListStore" id="entry-store">
+    <columns>
+      <!-- column-name icon -->
+      <column type="gchararray"/>
+      <!-- column-name name -->
+      <column type="gchararray"/>
+      <!-- column-name filename -->
+      <column type="gchararray"/>
+    </columns>
+  </object>
   <object class="GtkTreeModelFilter" id="add-store-filter">
     <property name="child_model">add-store</property>
   </object>
@@ -74,6 +84,27 @@
                       <object class="GtkTreeView" id="entry-treeview">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
+                        <property name="model">entry-store</property>
+                        <property name="headers_visible">False</property>
+                        <property name="rules_hint">True</property>
+                        <property name="enable_search">False</property>
+                        <child>
+                          <object class="GtkTreeViewColumn" id="treeviewcolumn2">
+                            <property name="spacing">2</property>
+                            <child>
+                              <object class="GtkCellRendererPixbuf" id="entryrenderericon"/>
+                              <attributes>
+                                <attribute name="icon-name">0</attribute>
+                              </attributes>
+                            </child>
+                            <child>
+                              <object class="GtkCellRendererText" id="entryrenderername"/>
+                              <attributes>
+                                <attribute name="text">1</attribute>
+                              </attributes>
+                            </child>
+                          </object>
+                        </child>
                       </object>
                     </child>
                   </object>
diff --git a/plugins/launcher/launcher.c b/plugins/launcher/launcher.c
index 7c64ba7..27833f0 100644
--- a/plugins/launcher/launcher.c
+++ b/plugins/launcher/launcher.c
@@ -19,10 +19,15 @@
 #include <config.h>
 #endif
 
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
 #include <exo/exo.h>
-#include <xfconf/xfconf.h>
+
 #include <libxfce4util/libxfce4util.h>
 #include <libxfce4ui/libxfce4ui.h>
+#include <common/panel-private.h>
 
 #include "launcher.h"
 #include "launcher-dialog.h"
@@ -37,10 +42,11 @@ static void launcher_plugin_save (XfcePanelPlugin *panel_plugin);
 static void launcher_plugin_configure_plugin (XfcePanelPlugin *panel_plugin);
 static void launcher_plugin_screen_position_changed (XfcePanelPlugin *panel_plugin, gint position);
 
+static void launcher_plugin_button_set_icon (LauncherPlugin *plugin);
 static void launcher_plugin_button_state_changed (GtkWidget *button_a, GtkStateType state, GtkWidget *button_b);
 static gboolean launcher_plugin_button_press_event (GtkWidget *button, GdkEventButton *event, LauncherPlugin *plugin);
 static gboolean launcher_plugin_button_release_event (GtkWidget *button, GdkEventButton *event, LauncherPlugin *plugin);
-static gboolean launcher_plugin_icon_button_query_tooltip (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip, LauncherPlugin *plugin);
+static gboolean launcher_plugin_button_query_tooltip (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip, LauncherPlugin *plugin);
 static void launcher_plugin_button_drag_data_received (GtkWidget *widget,GdkDragContext *context, gint x,gint y,GtkSelectionData *selection_data, guint info, guint drag_time, LauncherPlugin *plugin);
 
 static void launcher_plugin_entries_load (LauncherPlugin *plugin);
@@ -48,9 +54,9 @@ static gboolean launcher_plugin_entry_query_tooltip (GtkWidget *widget, gint x,
 static LauncherEntry *launcher_plugin_entry_new_from_filename (const gchar *filename);
 static void launcher_plugin_entry_free (LauncherEntry *entry);
 
-static gboolean launcher_plugin_entry_exec_on_screen (LauncherEntry *entry, GdkScreen *screen, GSList *uri_list);
-static void launcher_plugin_entry_exec (LauncherEntry *entry, GdkScreen *screen, GSList *uri_list);
-static void launcher_plugin_entry_exec_from_clipboard (LauncherEntry *entry, GdkScreen *screen);
+static gboolean launcher_plugin_entry_exec_on_screen (LauncherEntry *entry, guint32 event_time, GdkScreen *screen, GSList *uri_list);
+static void launcher_plugin_entry_exec (LauncherEntry *entry, guint32 event_time, GdkScreen *screen, GSList *uri_list);
+static void launcher_plugin_entry_exec_from_clipboard (LauncherEntry *entry, guint32 event_time, GdkScreen *screen);
 static void launcher_plugin_exec_append_quoted (GString *string, const gchar *unquoted);
 static gboolean launcher_plugin_exec_parse (LauncherEntry *entry, GSList *uri_list, gboolean terminal, gint *argc, gchar ***argv, GError **error);
 
@@ -72,7 +78,7 @@ struct _LauncherPlugin
   GtkWidget *arrow;
   GtkWidget *image;
 
-  GSList *items;
+  GSList *entries;
 
   guint disable_tooltips : 1;
 };
@@ -152,6 +158,9 @@ launcher_plugin_property_changed (XfconfChannel  *channel,
 
       /* load the new entries */
       launcher_plugin_entries_load (plugin);
+
+      /* update the icon */
+      launcher_plugin_button_set_icon (plugin);
     }
 }
 
@@ -188,7 +197,7 @@ launcher_plugin_construct (XfcePanelPlugin *panel_plugin)
                     G_CALLBACK (launcher_plugin_button_drag_data_received), plugin);
 
   plugin->image = xfce_scaled_image_new ();
-  gtk_container_add (GTK_CONTAINER (plugin->icon_button), plugin->image);
+  gtk_container_add (GTK_CONTAINER (plugin->button), plugin->image);
   gtk_widget_show (plugin->image);
 
   plugin->arrow = xfce_arrow_button_new (GTK_ARROW_UP);
@@ -209,6 +218,9 @@ launcher_plugin_construct (XfcePanelPlugin *panel_plugin)
 
   /* load the entries */
   launcher_plugin_entries_load (plugin);
+
+  /* update the icon */
+  launcher_plugin_button_set_icon (plugin);
 }
 
 
@@ -244,6 +256,8 @@ static gboolean
 launcher_plugin_size_changed (XfcePanelPlugin *panel_plugin,
                               gint             size)
 {
+  gtk_widget_set_size_request (GTK_WIDGET (panel_plugin), size, size);
+
   return TRUE;
 }
 
@@ -271,7 +285,8 @@ launcher_plugin_save (XfcePanelPlugin *panel_plugin)
           filenames[i++] = entry->filename;
 
       /* store the list of filenames */
-      xfconf_channel_set_string_list (plugin->channel, "/entries", filenames);
+      xfconf_channel_set_string_list (plugin->channel, "/entries",
+                                      (const gchar **) filenames);
 
       /* cleanup */
       g_free (filenames);
@@ -299,6 +314,39 @@ launcher_plugin_screen_position_changed (XfcePanelPlugin *panel_plugin,
 
 
 static void
+launcher_plugin_button_set_icon (LauncherPlugin *plugin)
+{
+  LauncherEntry *entry;
+
+  panel_return_if_fail (XFCE_IS_LAUNCHER_PLUGIN (plugin));
+  panel_return_if_fail (XFCE_IS_SCALED_IMAGE (plugin->image));
+
+  if (G_LIKELY (plugin->entries != NULL))
+    {
+      entry = plugin->entries->data;
+
+      if (IS_STRING (entry->icon))
+        {
+          if (g_path_is_absolute (entry->icon))
+            xfce_scaled_image_set_from_file (XFCE_SCALED_IMAGE (plugin->image),
+                                             entry->icon);
+          else
+            xfce_scaled_image_set_from_icon_name (XFCE_SCALED_IMAGE (plugin->image),
+                                                  entry->icon);
+          /* TODO some more name checking */
+        }
+    }
+  else
+    {
+      /* set missing image icon */
+      xfce_scaled_image_set_from_icon_name (XFCE_SCALED_IMAGE (plugin->image),
+                                            GTK_STOCK_MISSING_IMAGE);
+    }
+}
+
+
+
+static void
 launcher_plugin_button_state_changed (GtkWidget    *button_a,
                                       GtkStateType  state,
                                       GtkWidget    *button_b)
@@ -316,13 +364,12 @@ launcher_plugin_button_press_event (GtkWidget      *button,
                                     LauncherPlugin *plugin)
 {
   panel_return_val_if_fail (XFCE_IS_LAUNCHER_PLUGIN (plugin), FALSE);
-  panel_return_val_if_fail (plugin->entries != NULL, FALSE);
-  
+
   /* do nothing on anything else then a single click */
   if (event->type != GDK_BUTTON_PRESS)
     return FALSE;
-    
-    
+
+  return FALSE;
 }
 
 
@@ -332,31 +379,38 @@ launcher_plugin_button_release_event (GtkWidget      *button,
                                       GdkEventButton *event,
                                       LauncherPlugin *plugin)
 {
+  LauncherEntry *entry;
+  GdkScreen     *screen;
+
   panel_return_val_if_fail (XFCE_IS_LAUNCHER_PLUGIN (plugin), FALSE);
-  panel_return_val_if_fail (plugin->entries != NULL, FALSE);
-  
+
+  if (G_UNLIKELY (plugin->entries == NULL))
+    return FALSE;
+
+  entry = plugin->entries->data;
+  screen = gtk_widget_get_screen (button);
+
   if (event->button == 1)
-    launcher_plugin_entry_exec (entry, gtk_widget_get_screen (button), NULL);
+    launcher_plugin_entry_exec (entry, event->time, screen, NULL);
   else if (event->button == 2)
-    launcher_plugin_entry_exec_from_clipboard (entry, gtk_widget_get_screen (button));
+    launcher_plugin_entry_exec_from_clipboard (entry, event->time, screen);
   else
     return TRUE;
-    
+
   return FALSE;
 }
 
 
 
 static gboolean
-launcher_plugin_icon_button_query_tooltip (GtkWidget      *widget,
-                                           gint            x,
-                                           gint            y,
-                                           gboolean        keyboard_mode,
-                                           GtkTooltip     *tooltip,
-                                           LauncherPlugin *plugin)
+launcher_plugin_button_query_tooltip (GtkWidget      *widget,
+                                      gint            x,
+                                      gint            y,
+                                      gboolean        keyboard_mode,
+                                      GtkTooltip     *tooltip,
+                                      LauncherPlugin *plugin)
 {
   panel_return_val_if_fail (XFCE_IS_LAUNCHER_PLUGIN (plugin), FALSE);
-  panel_return_val_if_fail (plugin->entries != NULL, FALSE);
 
   /* check if we show tooltips */
   if (plugin->entries == NULL || plugin->entries->data == NULL
@@ -369,18 +423,17 @@ launcher_plugin_icon_button_query_tooltip (GtkWidget      *widget,
 
 
 
-static void 
+static void
 launcher_plugin_button_drag_data_received (GtkWidget        *widget,
-                                           GdkDragContext   *context, 
+                                           GdkDragContext   *context,
                                            gint              x,
                                            gint              y,
-                                           GtkSelectionData *selection_data, 
-                                           guint             info, 
-                                           guint             drag_time, 
+                                           GtkSelectionData *selection_data,
+                                           guint             info,
+                                           guint             drag_time,
                                            LauncherPlugin   *plugin)
 {
   panel_return_if_fail (XFCE_IS_LAUNCHER_PLUGIN (plugin));
-  panel_return_if_fail (plugin->entries != NULL);
 
   gtk_drag_finish (context, TRUE, FALSE, drag_time);
 }
@@ -403,9 +456,9 @@ launcher_plugin_entries_load (LauncherPlugin *plugin)
       /* try to load all the entries */
       for (i = 0; filenames[i] != NULL; i++)
         {
-          entry = launcher_plugin_entry_from_filename (filenames[i]);
+          entry = launcher_plugin_entry_new_from_filename (filenames[i]);
           if (G_LIKELY (entry != NULL))
-            launcher->entries = g_slist_append (launcher->entries, entry);
+            plugin->entries = g_slist_append (plugin->entries, entry);
         }
 
       /* cleanup */
@@ -508,13 +561,14 @@ launcher_plugin_entry_free (LauncherEntry *entry)
 
 static gboolean
 launcher_plugin_entry_exec_on_screen (LauncherEntry *entry,
+                                      guint32        event_time,
                                       GdkScreen     *screen,
                                       GSList        *uri_list)
 {
   GError    *error = NULL;
   gchar    **argv;
   gboolean   succeed = FALSE;
-  
+
   /* parse the execute command */
   if (launcher_plugin_exec_parse (entry, uri_list, entry->terminal,
                                   NULL, &argv, &error))
@@ -522,19 +576,19 @@ launcher_plugin_entry_exec_on_screen (LauncherEntry *entry,
       /* launch the command on the screen */
       succeed = xfce_execute_argv_on_screen (screen, entry->path, argv, NULL,
                                              G_SPAWN_SEARCH_PATH, entry->startup_notify,
-                                             entry->icon, &error);
-                                             
+                                             event_time, entry->icon, &error);
+
       /* cleanup */
       g_strfreev (argv);
     }
-    
+
   if (G_UNLIKELY (succeed == FALSE))
     {
       /* TODO */
       g_message ("Failed to launch.... (%s)", error->message);
       g_error_free (error);
     }
-    
+
   return succeed;
 }
 
@@ -542,34 +596,35 @@ launcher_plugin_entry_exec_on_screen (LauncherEntry *entry,
 
 static void
 launcher_plugin_entry_exec (LauncherEntry *entry,
+                            guint32        event_time,
                             GdkScreen     *screen,
                             GSList        *uri_list)
 {
   GSList   *li, fake;
   gboolean  proceed = TRUE;
-  
+
   panel_return_if_fail (entry != NULL);
-  
+
   /* leave when there is nothing to execute */
   if (!IS_STRING (entry->exec))
     return;
-  
+
   if (G_UNLIKELY (uri_list != NULL
-      && g_strstr (entry->exec, "%F") == NULL
-      && g_strstr (entry->exec, "%U") == NULL))
+      && strstr (entry->exec, "%F") == NULL
+      && strstr (entry->exec, "%U") == NULL))
     {
       fake.next = NULL;
-      
+
       /* run an instance for each file, break on the first error */
       for (li = uri_list; li != NULL && proceed; li = li->next)
         {
           fake.data = li->data;
-          proceed = launcher_plugin_entry_exec_on_screen (entry, screen, &fake);
+          proceed = launcher_plugin_entry_exec_on_screen (entry, event_time, screen, &fake);
         }
     }
   else
     {
-      launcher_plugin_entry_exec_on_screen (entry, screen, uri_list);
+      launcher_plugin_entry_exec_on_screen (entry, event_time, screen, uri_list);
     }
 }
 
@@ -577,10 +632,11 @@ launcher_plugin_entry_exec (LauncherEntry *entry,
 
 static void
 launcher_plugin_entry_exec_from_clipboard (LauncherEntry *entry,
+                                           guint32        event_time,
                                            GdkScreen     *screen)
 {
   panel_return_if_fail (entry != NULL);
-  
+
   /* TODO */
 }
 
@@ -623,7 +679,7 @@ launcher_plugin_exec_parse (LauncherEntry   *entry,
   if (G_UNLIKELY (terminal))
     g_string_append (string, "exo-open --launch TerminalEmulator ");
 
-  for (p = exec; *p != '\0'; ++p)
+  for (p = entry->exec; *p != '\0'; ++p)
     {
       if (p[0] == '%' && p[1] != '\0')
         {
@@ -692,3 +748,12 @@ launcher_plugin_exec_parse (LauncherEntry   *entry,
 
   return result;
 }
+
+
+
+XfconfChannel *
+launcher_plugin_get_channel (LauncherPlugin *plugin)
+{
+  panel_return_val_if_fail (XFCE_IS_LAUNCHER_PLUGIN (plugin), NULL);
+  return plugin->channel;
+}
diff --git a/plugins/launcher/launcher.h b/plugins/launcher/launcher.h
index b87023d..3bc2fe6 100644
--- a/plugins/launcher/launcher.h
+++ b/plugins/launcher/launcher.h
@@ -19,6 +19,7 @@
 #define __LAUNCHER_H__
 
 #include <gtk/gtk.h>
+#include <xfconf/xfconf.h>
 #include <libxfce4panel/libxfce4panel.h>
 
 G_BEGIN_DECLS
@@ -34,7 +35,9 @@ typedef struct _LauncherEntry          LauncherEntry;
 #define XFCE_IS_LAUNCHER_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XFCE_TYPE_LAUNCHER_PLUGIN))
 #define XFCE_LAUNCHER_PLUGIN_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), XFCE_TYPE_LAUNCHER_PLUGIN, LauncherPluginClass))
 
-GType      launcher_plugin_get_type (void) G_GNUC_CONST;
+GType          launcher_plugin_get_type    (void) G_GNUC_CONST;
+
+XfconfChannel *launcher_plugin_get_channel (LauncherPlugin *plugin);
 
 G_END_DECLS
 



More information about the Xfce4-commits mailing list