[Goodies-commits] r7174 - in xfce4-clipman-plugin/trunk: . panel-plugin
Mike Massonnet
mmassonnet at xfce.org
Mon Apr 13 09:55:32 CEST 2009
Author: mmassonnet
Date: 2009-04-13 07:55:32 +0000 (Mon, 13 Apr 2009)
New Revision: 7174
Added:
xfce4-clipman-plugin/trunk/panel-plugin/main.c
xfce4-clipman-plugin/trunk/xfce4-clipman-plugin.desktop.in
Removed:
xfce4-clipman-plugin/trunk/panel-plugin/panel-plugin.c
Modified:
xfce4-clipman-plugin/trunk/ChangeLog
xfce4-clipman-plugin/trunk/Makefile.am
xfce4-clipman-plugin/trunk/TODO
xfce4-clipman-plugin/trunk/configure.ac.in
xfce4-clipman-plugin/trunk/panel-plugin/Makefile.am
Log:
Make the plugin run as a standalone application
Modified: xfce4-clipman-plugin/trunk/ChangeLog
===================================================================
--- xfce4-clipman-plugin/trunk/ChangeLog 2009-04-12 20:54:39 UTC (rev 7173)
+++ xfce4-clipman-plugin/trunk/ChangeLog 2009-04-13 07:55:32 UTC (rev 7174)
@@ -1,4 +1,17 @@
2009-04-02 Mike Massonnet
+Make the plugin run as a standalone application
+
+ - panel-plugin/main.c:
+ Rename panel-plugin.c to main.c and use the Full register
+ function from libxfce4panel to check if the plugin is run from
+ the command line and build a status icon instead of the panel
+ plugin with a button.
+ - panel-plugin/Makefile.am:
+ Install the plugin to bindir.
+ - Makefile.am, xfce4-clipman-plugin.desktop.in:
+ Install a desktop entry file for the menu.
+
+2009-04-02 Mike Massonnet
Set Clipman the owner of a text content only on specific target
- panel-plugin/collector.c(cb_clipboard_owner_change):
Modified: xfce4-clipman-plugin/trunk/Makefile.am
===================================================================
--- xfce4-clipman-plugin/trunk/Makefile.am 2009-04-12 20:54:39 UTC (rev 7173)
+++ xfce4-clipman-plugin/trunk/Makefile.am 2009-04-13 07:55:32 UTC (rev 7174)
@@ -8,6 +8,11 @@
distclean-local:
rm -rf *.cache *~
+desktopdir = $(datadir)/applications
+desktop_in_files = xfce4-clipman-plugin.desktop.in
+desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
+ at INTLTOOL_DESKTOP_RULE@
+
EXTRA_DIST = \
AUTHORS \
ChangeLog \
Modified: xfce4-clipman-plugin/trunk/TODO
===================================================================
--- xfce4-clipman-plugin/trunk/TODO 2009-04-12 20:54:39 UTC (rev 7173)
+++ xfce4-clipman-plugin/trunk/TODO 2009-04-13 07:55:32 UTC (rev 7174)
@@ -1,6 +1,7 @@
Actions:
- A regex validator dialog
Collector:
-- As of the last "set clipman automatically the owner" change, for instance
-Thunar copy files has a special type but reported as utf8 string, it is
-necessary to have a proper filter on what is to be copied and not
+- Set ownership on the XAtom CLIPBOARD_MANAGER
+- Instead of getting ownership of the clipboard content only for text (plain
+and html) and images, replicate the clipboard content with the same
+SAVE_TARGETS so it works for everything
Modified: xfce4-clipman-plugin/trunk/configure.ac.in
===================================================================
--- xfce4-clipman-plugin/trunk/configure.ac.in 2009-04-12 20:54:39 UTC (rev 7173)
+++ xfce4-clipman-plugin/trunk/configure.ac.in 2009-04-13 07:55:32 UTC (rev 7174)
@@ -64,7 +64,7 @@
XDT_CHECK_PACKAGE([LIBXFCE4UTIL], [libxfce4util-1.0], [4.4.0])
XDT_CHECK_PACKAGE([LIBXFCEGUI4], [libxfcegui4-1.0], [4.4.0])
XDT_CHECK_PACKAGE([LIBXFCE4PANEL], [libxfce4panel-1.0], [4.4.0])
-XDT_CHECK_PACKAGE([XFCONF], [libxfconf-0], [4.6.0])
+XDT_CHECK_PACKAGE([XFCONF], [libxfconf-0], [4.5.0])
XDT_CHECK_PACKAGE([GLADE], [libglade-2.0], [2.6.0])
dnl ******************************
Modified: xfce4-clipman-plugin/trunk/panel-plugin/Makefile.am
===================================================================
--- xfce4-clipman-plugin/trunk/panel-plugin/Makefile.am 2009-04-12 20:54:39 UTC (rev 7173)
+++ xfce4-clipman-plugin/trunk/panel-plugin/Makefile.am 2009-04-13 07:55:32 UTC (rev 7174)
@@ -21,7 +21,7 @@
# Popup Command
#
-bin_PROGRAMS = xfce4-popup-clipman
+bin_PROGRAMS = xfce4-clipman-plugin xfce4-popup-clipman
xfce4_popup_clipman_SOURCES = \
xfce4-popup-clipman.c \
@@ -44,11 +44,8 @@
# Plugin
#
-plugindir = $(libexecdir)/xfce4/panel-plugins
-plugin_PROGRAMS = xfce4-clipman-plugin
-
xfce4_clipman_plugin_SOURCES = \
- panel-plugin.c \
+ main.c \
common.h \
actions.c actions.h \
collector.c collector.h \
@@ -102,6 +99,6 @@
@INTLTOOL_DESKTOP_RULE@
%.desktop.in: %.desktop.in.in
- sed -e "s^@EXTERNAL_PLUGIN_PATH@^$(libexecdir)/xfce4/panel-plugins^" \
+ sed -e "s^@EXTERNAL_PLUGIN_PATH@^$(bindir)^" \
$< > $@
Copied: xfce4-clipman-plugin/trunk/panel-plugin/main.c (from rev 7167, xfce4-clipman-plugin/trunk/panel-plugin/panel-plugin.c)
===================================================================
--- xfce4-clipman-plugin/trunk/panel-plugin/main.c (rev 0)
+++ xfce4-clipman-plugin/trunk/panel-plugin/main.c 2009-04-13 07:55:32 UTC (rev 7174)
@@ -0,0 +1,1162 @@
+/*
+ * Copyright (c) 2008-2009 Mike Massonnet <mmassonnet 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 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib/gstdio.h>
+#include <gtk/gtk.h>
+#include <libxfce4util/libxfce4util.h>
+#include <libxfcegui4/libxfcegui4.h>
+#include <libxfce4panel/xfce-panel-plugin.h>
+#include <libxfce4panel/xfce-panel-convenience.h>
+#include <xfconf/xfconf.h>
+#include <glade/glade.h>
+
+#include "common.h"
+#include "settings-dialog_glade.h"
+#include "actions.h"
+#include "collector.h"
+#include "history.h"
+#include "menu.h"
+
+
+
+/*
+ * MyPlugin structure
+ */
+
+typedef struct _MyPlugin MyPlugin;
+struct _MyPlugin
+{
+ XfcePanelPlugin *panel_plugin;
+ GtkStatusIcon *status_icon;
+ XfconfChannel *channel;
+ ClipmanActions *actions;
+ ClipmanCollector *collector;
+ ClipmanHistory *history;
+ GladeXML *gxml;
+ GtkWidget *button;
+ GtkWidget *image;
+ GtkWidget *menu;
+ GtkWidget *popup_menu;
+};
+
+/*
+ * Status Icon
+ */
+
+static MyPlugin* status_icon_register ();
+static gboolean cb_status_icon_is_embedded (GtkStatusIcon *status_icon);
+static void cb_status_icon_activate (MyPlugin *plugin);
+static void cb_status_icon_popup_menu (MyPlugin *plugin,
+ guint button,
+ guint activate_time);
+static gboolean cb_status_icon_set_size (MyPlugin *plugin,
+ gint size);
+
+/*
+ * Panel Plugin
+ */
+
+static void panel_plugin_register (XfcePanelPlugin *panel_plugin);
+static gboolean panel_plugin_set_size (MyPlugin *plugin,
+ gint size);
+
+/*
+ * Plugin Registration
+ */
+
+static gboolean plugin_preinit (gint argc,
+ gchar *argv[]);
+XFCE_PANEL_PLUGIN_REGISTER_EXTERNAL_FULL (panel_plugin_register, plugin_preinit, NULL);
+
+/*
+ * Plugin Functions
+ */
+
+static MyPlugin* plugin_register ();
+static void plugin_load (MyPlugin *plugin);
+static void plugin_save (MyPlugin *plugin);
+static void plugin_free (MyPlugin *plugin);
+static void plugin_configure (MyPlugin *plugin);
+static void cb_button_toggled (GtkToggleButton *button,
+ MyPlugin *plugin);
+static void cb_menu_deactivate (GtkMenuShell *menu,
+ MyPlugin *plugin);
+static void my_plugin_position_menu (GtkMenu *menu,
+ gint *x,
+ gint *y,
+ gboolean *push_in,
+ MyPlugin *plugin);
+
+/*
+ * X11 Selection for the popup command
+ */
+
+static gboolean my_plugin_set_selection (MyPlugin *plugin);
+static gboolean cb_message_received (MyPlugin *plugin,
+ GdkEventClient *ev);
+
+/*
+ * Settings Dialog
+ */
+
+static void setup_actions_treeview (GtkTreeView *treeview,
+ MyPlugin *plugin);
+static void refresh_actions_treeview (GtkTreeView *treeview,
+ MyPlugin *plugin);
+static void apply_action (const gchar *original_action_name,
+ MyPlugin *plugin);
+static void cb_actions_selection_changed (GtkTreeSelection *selection,
+ MyPlugin *plugin);
+static void cb_add_action (GtkButton *button,
+ MyPlugin *plugin);
+static void cb_edit_action (GtkButton *button,
+ MyPlugin *plugin);
+static void cb_actions_row_activated (GtkTreeView *treeview,
+ GtkTreePath *path,
+ GtkTreeViewColumn *column,
+ MyPlugin *plugin);
+static void cb_delete_action (GtkButton *button,
+ MyPlugin *plugin);
+static void setup_commands_treeview (GtkTreeView *treeview,
+ MyPlugin *plugin);
+static void entry_dialog_cleanup (GtkDialog *dialog,
+ MyPlugin *plugin);
+#if !GLIB_CHECK_VERSION(2,16,0)
+static void __foreach_command_fill_commands (gpointer key,
+ gpointer value,
+ gpointer user_data);
+#endif
+static void cb_commands_selection_changed (GtkTreeSelection *selection,
+ MyPlugin *plugin);
+static void cb_add_command (GtkButton *button,
+ MyPlugin *plugin);
+static void cb_refresh_command (GtkButton *button,
+ MyPlugin *plugin);
+static void cb_delete_command (GtkButton *button,
+ MyPlugin *plugin);
+static void cb_set_action_dialog_button_ok (GtkWidget *widget,
+ MyPlugin *plugin);
+
+
+
+/*
+ * Plugin Registration
+ */
+
+static gboolean
+plugin_preinit (gint argc,
+ gchar *argv[])
+{
+ MyPlugin *plugin;
+
+ if (argc == 1)
+ {
+ /*
+ * Consider the plugin to be run by command line
+ */
+ gtk_init (&argc, &argv);
+ plugin = status_icon_register ();
+ gtk_main ();
+ plugin_save (plugin);
+ plugin_free (plugin);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static MyPlugin *
+plugin_register ()
+{
+ /* MyPlugin */
+ MyPlugin *plugin = g_slice_new0 (MyPlugin);
+ plugin->panel_plugin = NULL;
+ plugin->status_icon = NULL;
+
+ /* Text Domain and Locale */
+ xfce_textdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR, "UTF-8");
+
+ /* Xfconf */
+ xfconf_init (NULL);
+ plugin->channel = xfconf_channel_new_with_property_base ("xfce4-panel", "/plugins/clipman");
+
+ /* ClipmanActions */
+ plugin->actions = clipman_actions_get ();
+
+ /* ClipmanHistory */
+ plugin->history = clipman_history_get ();
+ xfconf_g_property_bind (plugin->channel, "/settings/max-texts-in-history",
+ G_TYPE_UINT, plugin->history, "max-texts-in-history");
+ xfconf_g_property_bind (plugin->channel, "/settings/max-images-in-history",
+ G_TYPE_UINT, plugin->history, "max-images-in-history");
+ xfconf_g_property_bind (plugin->channel, "/settings/save-on-quit",
+ G_TYPE_BOOLEAN, plugin->history, "save-on-quit");
+
+ /* ClipmanCollector */
+ plugin->collector = clipman_collector_get ();
+ xfconf_g_property_bind (plugin->channel, "/settings/add-primary-clipboard",
+ G_TYPE_BOOLEAN, plugin->collector, "add-primary-clipboard");
+ xfconf_g_property_bind (plugin->channel, "/settings/enable-actions",
+ G_TYPE_BOOLEAN, plugin->collector, "enable-actions");
+
+ /* ClipmanMenu */
+ plugin->menu = clipman_menu_new ();
+
+ /* Load the data */
+ plugin_load (plugin);
+
+ /* Set the selection for the popup command */
+ my_plugin_set_selection (plugin);
+
+ return plugin;
+}
+
+/*
+ * Status Icon
+ */
+
+static MyPlugin *
+status_icon_register ()
+{
+ MyPlugin *plugin = plugin_register ();
+
+ /* Status Icon */
+ plugin->status_icon = gtk_status_icon_new_from_stock (GTK_STOCK_PASTE);
+ gtk_status_icon_set_tooltip (plugin->status_icon, _("Clipman"));
+ g_idle_add ((GSourceFunc)cb_status_icon_is_embedded, plugin->status_icon);
+
+ /* Signals */
+ g_signal_connect_swapped (plugin->status_icon, "activate",
+ G_CALLBACK (cb_status_icon_activate), plugin);
+ g_signal_connect_swapped (plugin->status_icon, "popup-menu",
+ G_CALLBACK (cb_status_icon_popup_menu), plugin);
+ g_signal_connect_swapped (plugin->status_icon, "size-changed",
+ G_CALLBACK (cb_status_icon_set_size), plugin);
+
+ return plugin;
+}
+
+static gboolean
+cb_status_icon_is_embedded (GtkStatusIcon *status_icon)
+{
+ if (!gtk_status_icon_is_embedded (status_icon))
+ gtk_main_quit ();
+ return FALSE;
+}
+
+static void
+cb_status_icon_activate (MyPlugin *plugin)
+{
+ gtk_menu_set_screen (GTK_MENU (plugin->menu), gtk_status_icon_get_screen (plugin->status_icon));
+ gtk_menu_popup (GTK_MENU (plugin->menu), NULL, NULL,
+ (GtkMenuPositionFunc)gtk_status_icon_position_menu, plugin->status_icon,
+ 0, gtk_get_current_event_time ());
+}
+
+static void
+cb_status_icon_popup_menu (MyPlugin *plugin, guint button, guint activate_time)
+{
+ GtkWidget *mi;
+
+ if (G_UNLIKELY (plugin->popup_menu == NULL))
+ {
+ plugin->popup_menu = gtk_menu_new ();
+ mi = gtk_menu_item_new_with_label (_("Clipman"));
+ gtk_widget_set_sensitive (mi, FALSE);
+ gtk_menu_shell_append (GTK_MENU_SHELL (plugin->popup_menu), mi);
+ mi = gtk_separator_menu_item_new ();
+ gtk_menu_shell_append (GTK_MENU_SHELL (plugin->popup_menu), mi);
+ mi = gtk_image_menu_item_new_from_stock (GTK_STOCK_PROPERTIES, NULL);
+ gtk_menu_shell_append (GTK_MENU_SHELL (plugin->popup_menu), mi);
+ g_signal_connect_swapped (mi, "activate", G_CALLBACK (plugin_configure), plugin);
+ mi = gtk_separator_menu_item_new ();
+ gtk_menu_shell_append (GTK_MENU_SHELL (plugin->popup_menu), mi);
+ mi = gtk_image_menu_item_new_from_stock (GTK_STOCK_REMOVE, NULL);
+ g_signal_connect (mi, "activate", G_CALLBACK (gtk_main_quit), NULL);
+ gtk_menu_shell_append (GTK_MENU_SHELL (plugin->popup_menu), mi);
+ gtk_widget_show_all (plugin->popup_menu);
+ }
+ gtk_menu_set_screen (GTK_MENU (plugin->popup_menu), gtk_status_icon_get_screen (plugin->status_icon));
+ gtk_menu_popup (GTK_MENU (plugin->popup_menu), NULL, NULL,
+ (GtkMenuPositionFunc)NULL, NULL,
+ 0, gtk_get_current_event_time ());
+}
+
+static gboolean
+cb_status_icon_set_size (MyPlugin *plugin, gint size)
+{
+ GdkPixbuf *pixbuf;
+
+ pixbuf = xfce_themed_icon_load (GTK_STOCK_PASTE, size);
+ gtk_status_icon_set_from_pixbuf (plugin->status_icon, pixbuf);
+ g_object_unref (G_OBJECT (pixbuf));
+
+ return TRUE;
+}
+
+/*
+ * Panel Plugin
+ */
+
+static void
+panel_plugin_register (XfcePanelPlugin *panel_plugin)
+{
+ MyPlugin *plugin = plugin_register ();
+
+ /* Panel Plugin */
+ plugin->panel_plugin = panel_plugin;
+#if GTK_CHECK_VERSION (2,12,0)
+ gtk_widget_set_tooltip_text (GTK_WIDGET (panel_plugin), _("Clipman"));
+#endif
+
+ /* Panel Button */
+ plugin->button = xfce_create_panel_toggle_button ();
+ /* The image is set through the set_size callback */
+ plugin->image = gtk_image_new ();
+ gtk_container_add (GTK_CONTAINER (plugin->button), plugin->image);
+ gtk_container_add (GTK_CONTAINER (panel_plugin), plugin->button);
+ xfce_panel_plugin_add_action_widget (panel_plugin, plugin->button);
+ g_signal_connect (plugin->button, "toggled",
+ G_CALLBACK (cb_button_toggled), plugin);
+
+ /* Signals */
+ g_signal_connect_swapped (panel_plugin, "size-changed",
+ G_CALLBACK (panel_plugin_set_size), plugin);
+ xfce_panel_plugin_menu_show_configure (panel_plugin);
+ g_signal_connect_swapped (panel_plugin, "configure-plugin",
+ G_CALLBACK (plugin_configure), plugin);
+ g_signal_connect_swapped (panel_plugin, "save",
+ G_CALLBACK (plugin_save), plugin);
+ g_signal_connect_swapped (panel_plugin, "free-data",
+ G_CALLBACK (plugin_free), plugin);
+ g_signal_connect (plugin->menu, "deactivate",
+ G_CALLBACK (cb_menu_deactivate), plugin);
+
+ gtk_widget_show_all (GTK_WIDGET (panel_plugin));
+}
+
+static gboolean
+panel_plugin_set_size (MyPlugin *plugin,
+ gint size)
+{
+ GdkPixbuf *pixbuf;
+
+ gtk_widget_set_size_request (plugin->button, size, size);
+
+ size -= 2 + 2 * MAX (plugin->button->style->xthickness,
+ plugin->button->style->ythickness);
+ pixbuf = xfce_themed_icon_load (GTK_STOCK_PASTE, size);
+ gtk_image_set_from_pixbuf (GTK_IMAGE (plugin->image), pixbuf);
+ g_object_unref (G_OBJECT (pixbuf));
+
+ return TRUE;
+}
+
+/*
+ * Plugin Functions
+ */
+
+static void
+plugin_load (MyPlugin *plugin)
+{
+ GtkClipboard *clipboard;
+ GKeyFile *keyfile;
+ gchar **texts = NULL;
+ gchar *filename;
+ GdkPixbuf *image;
+ gint i = 0;
+ gboolean save_on_quit;
+
+ /* Return if the history must not be saved */
+ g_object_get (plugin->history, "save-on-quit", &save_on_quit, NULL);
+ if (save_on_quit == FALSE)
+ return;
+
+ clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+
+ /* Load images */
+ while (TRUE)
+ {
+ filename = g_strdup_printf ("%s/xfce4/clipman/image%d.png", g_get_user_cache_dir (), i++);
+ DBG ("Loading image from cache file %s", filename);
+ image = gdk_pixbuf_new_from_file (filename, NULL);
+ g_unlink (filename);
+ g_free (filename);
+ if (image == NULL)
+ break;
+
+ clipman_history_add_image (plugin->history, image);
+ g_object_unref (image);
+ }
+
+ /* Load texts */
+ filename = g_strdup_printf ("%s/xfce4/clipman/textsrc", g_get_user_cache_dir ());
+ DBG ("Loading texts from cache file %s", filename);
+ keyfile = g_key_file_new ();
+ if (g_key_file_load_from_file (keyfile, filename, G_KEY_FILE_NONE, NULL))
+ {
+ texts = g_key_file_get_string_list (keyfile, "texts", "texts", NULL, NULL);
+ for (i = 0; texts != NULL && texts[i] != NULL; i++)
+ clipman_history_add_text (plugin->history, texts[i]);
+ g_unlink (filename);
+ }
+
+ g_key_file_free (keyfile);
+ g_strfreev (texts);
+ g_free (filename);
+
+ /* Set no current item */
+ clipman_history_set_item_to_restore (plugin->history, NULL);
+}
+
+static void
+plugin_save (MyPlugin *plugin)
+{
+ GSList *list, *l;
+ const ClipmanHistoryItem *item;
+ GKeyFile *keyfile;
+ const gchar **texts;
+ gchar *data;
+ gchar *filename;
+ gint n_texts, n_images;
+ gboolean save_on_quit;
+
+ /* Return if the history must not be saved */
+ g_object_get (plugin->history, "save-on-quit", &save_on_quit, NULL);
+ if (save_on_quit == FALSE)
+ return;
+
+ /* Create initial directory */
+ filename = xfce_resource_save_location (XFCE_RESOURCE_CACHE, "xfce4/clipman/", TRUE);
+ g_free (filename);
+
+ /* Save the history */
+ list = clipman_history_get_list (plugin->history);
+ list = g_slist_reverse (list);
+ if (list != NULL)
+ {
+ texts = g_malloc0 (g_slist_length (list) * sizeof (gchar *));
+ for (n_texts = n_images = 0, l = list; l != NULL; l = l->next)
+ {
+ item = l->data;
+
+ switch (item->type)
+ {
+ case CLIPMAN_HISTORY_TYPE_TEXT:
+ texts[n_texts++] = item->content.text;
+ break;
+
+ case CLIPMAN_HISTORY_TYPE_IMAGE:
+ filename = g_strdup_printf ("%s/xfce4/clipman/image%d.png", g_get_user_cache_dir (), n_images++);
+ if (!gdk_pixbuf_save (item->content.image, filename, "png", NULL, NULL))
+ g_warning ("Failed to save image to cache file %s", filename);
+ else
+ DBG ("Saved image to cache file %s", filename);
+ g_free (filename);
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+ }
+
+ if (n_texts > 0)
+ {
+ filename = g_strdup_printf ("%s/xfce4/clipman/textsrc", g_get_user_cache_dir ());
+ keyfile = g_key_file_new ();
+ g_key_file_set_string_list (keyfile, "texts", "texts", texts, n_texts);
+ data = g_key_file_to_data (keyfile, NULL, NULL);
+ g_file_set_contents (filename, data, -1, NULL);
+ DBG ("Saved texts to cache file %s", filename);
+
+ g_key_file_free (keyfile);
+ g_free (data);
+ g_free (filename);
+ }
+
+ g_free (texts);
+ g_slist_free (list);
+ }
+}
+
+static void
+plugin_free (MyPlugin *plugin)
+{
+ gtk_widget_destroy (plugin->menu);
+ g_object_unref (plugin->channel);
+ g_object_unref (plugin->actions);
+ g_object_unref (plugin->collector);
+ g_object_unref (plugin->history);
+
+ if (plugin->panel_plugin != NULL)
+ {
+ gtk_widget_destroy (plugin->button);
+ }
+ else if (plugin->status_icon != NULL)
+ {
+ gtk_widget_destroy (plugin->popup_menu);
+ }
+
+ g_slice_free (MyPlugin, plugin);
+ xfconf_shutdown ();
+}
+
+static void
+plugin_configure (MyPlugin *plugin)
+{
+ GtkWidget *dialog;
+ GtkWidget *action_dialog;
+ GtkWindowGroup *group;
+
+ /* GladeXML */
+ plugin->gxml = glade_xml_new_from_buffer (settings_dialog_glade, settings_dialog_glade_length, NULL, NULL);
+
+ /* Settings dialog */
+ dialog = glade_xml_get_widget (plugin->gxml, "settings-dialog");
+ if (plugin->panel_plugin != NULL)
+ gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (plugin->panel_plugin))));
+ group = gtk_window_group_new ();
+ gtk_window_group_add_window (group, GTK_WINDOW (dialog));
+
+ /* Action dialog */
+ action_dialog = glade_xml_get_widget (plugin->gxml, "action-dialog");
+ gtk_window_group_add_window (group, GTK_WINDOW (action_dialog));
+
+ /* General settings */
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (glade_xml_get_widget (plugin->gxml, "save-on-quit")),
+ DEFAULT_SAVE_ON_QUIT);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (glade_xml_get_widget (plugin->gxml, "add-selections")),
+ DEFAULT_ADD_PRIMARY_CLIPBOARD);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (glade_xml_get_widget (plugin->gxml, "store-an-image")),
+ (gboolean)DEFAULT_MAX_IMAGES_IN_HISTORY);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (glade_xml_get_widget (plugin->gxml, "max-texts-in-history")),
+ (gdouble)DEFAULT_MAX_TEXTS_IN_HISTORY);
+ xfconf_g_property_bind (plugin->channel, "/settings/save-on-quit", G_TYPE_BOOLEAN,
+ G_OBJECT (glade_xml_get_widget (plugin->gxml, "save-on-quit")), "active");
+ xfconf_g_property_bind (plugin->channel, "/settings/add-primary-clipboard", G_TYPE_BOOLEAN,
+ G_OBJECT (glade_xml_get_widget (plugin->gxml, "add-selections")), "active");
+ xfconf_g_property_bind (plugin->channel, "/settings/max-images-in-history", G_TYPE_UINT,
+ G_OBJECT (glade_xml_get_widget (plugin->gxml, "store-an-image")), "active");
+ xfconf_g_property_bind (plugin->channel, "/settings/max-texts-in-history", G_TYPE_UINT,
+ G_OBJECT (glade_xml_get_widget (plugin->gxml, "max-texts-in-history")), "value");
+
+ /* Actions tab and dialog */
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (glade_xml_get_widget (plugin->gxml, "enable-actions")),
+ DEFAULT_ENABLE_ACTIONS);
+ xfconf_g_property_bind (plugin->channel, "/settings/enable-actions", G_TYPE_BOOLEAN,
+ G_OBJECT (glade_xml_get_widget (plugin->gxml, "enable-actions")), "active");
+
+ glade_xml_signal_connect_data (plugin->gxml, "cb_add_action", G_CALLBACK (cb_add_action), plugin);
+ glade_xml_signal_connect_data (plugin->gxml, "cb_edit_action", G_CALLBACK (cb_edit_action), plugin);
+ glade_xml_signal_connect_data (plugin->gxml, "cb_delete_action", G_CALLBACK (cb_delete_action), plugin);
+ glade_xml_signal_connect_data (plugin->gxml, "cb_actions_row_activated", G_CALLBACK (cb_actions_row_activated), plugin);
+ glade_xml_signal_connect_data (plugin->gxml, "cb_add_command", G_CALLBACK (cb_add_command), plugin);
+ glade_xml_signal_connect_data (plugin->gxml, "cb_refresh_command", G_CALLBACK (cb_refresh_command), plugin);
+ glade_xml_signal_connect_data (plugin->gxml, "cb_delete_command", G_CALLBACK (cb_delete_command), plugin);
+
+ setup_actions_treeview (GTK_TREE_VIEW (glade_xml_get_widget (plugin->gxml, "actions")), plugin);
+ setup_commands_treeview (GTK_TREE_VIEW (glade_xml_get_widget (plugin->gxml, "commands")), plugin);
+
+ /* Callbacks for the OK button sensitivity in the actions dialog */
+ g_signal_connect_after (glade_xml_get_widget (plugin->gxml, "action-name"), "changed",
+ G_CALLBACK (cb_set_action_dialog_button_ok), plugin);
+ g_signal_connect_after (glade_xml_get_widget (plugin->gxml, "regex"), "changed",
+ G_CALLBACK (cb_set_action_dialog_button_ok), plugin);
+ g_signal_connect_after (glade_xml_get_widget (plugin->gxml, "button-add-command"), "clicked",
+ G_CALLBACK (cb_set_action_dialog_button_ok), plugin);
+ g_signal_connect_after (glade_xml_get_widget (plugin->gxml, "button-delete-command"), "clicked",
+ G_CALLBACK (cb_set_action_dialog_button_ok), plugin);
+
+ /* Run the dialog */
+ if (plugin->panel_plugin != NULL)
+ xfce_panel_plugin_block_menu (plugin->panel_plugin);
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ if (plugin->panel_plugin != NULL)
+ xfce_panel_plugin_unblock_menu (plugin->panel_plugin);
+
+ gtk_widget_destroy (action_dialog);
+ gtk_widget_destroy (dialog);
+ g_object_unref (group);
+ g_object_unref (plugin->gxml);
+ plugin->gxml = NULL;
+
+ /* Save the actions */
+ clipman_actions_save (plugin->actions);
+}
+
+static void
+cb_button_toggled (GtkToggleButton *button,
+ MyPlugin *plugin)
+{
+ if (gtk_toggle_button_get_active (button))
+ {
+ gtk_menu_set_screen (GTK_MENU (plugin->menu), gtk_widget_get_screen (plugin->button));
+ xfce_panel_plugin_register_menu (plugin->panel_plugin, GTK_MENU (plugin->menu));
+ gtk_menu_popup (GTK_MENU (plugin->menu), NULL, NULL,
+ (GtkMenuPositionFunc)my_plugin_position_menu, plugin,
+ 0, gtk_get_current_event_time ());
+ }
+}
+
+static void
+cb_menu_deactivate (GtkMenuShell *menu,
+ MyPlugin *plugin)
+{
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (plugin->button), FALSE);
+}
+
+static void
+my_plugin_position_menu (GtkMenu *menu,
+ gint *x,
+ gint *y,
+ gboolean *push_in,
+ MyPlugin *plugin)
+{
+ GtkWidget *button;
+ GtkRequisition requisition;
+ GtkOrientation orientation;
+
+ button = plugin->button;
+ orientation = xfce_panel_plugin_get_orientation (plugin->panel_plugin);
+ gtk_widget_size_request (GTK_WIDGET (menu), &requisition);
+ gdk_window_get_origin (button->window, x, y);
+
+ switch (orientation)
+ {
+ case GTK_ORIENTATION_HORIZONTAL:
+ if (*y + button->allocation.height + requisition.height > gdk_screen_height ())
+ /* Show menu above */
+ *y -= requisition.height;
+ else
+ /* Show menu below */
+ *y += button->allocation.height;
+
+ if (*x + requisition.width > gdk_screen_width ())
+ /* Adjust horizontal position */
+ *x = gdk_screen_width () - requisition.width;
+ break;
+
+ case GTK_ORIENTATION_VERTICAL:
+ if (*x + button->allocation.width + requisition.width > gdk_screen_width ())
+ /* Show menu on the right */
+ *x -= requisition.width;
+ else
+ /* Show menu on the left */
+ *x += button->allocation.width;
+
+ if (*y + requisition.height > gdk_screen_height ())
+ /* Adjust vertical position */
+ *y = gdk_screen_height () - requisition.height;
+ break;
+
+ default:
+ break;
+ }
+}
+
+/*
+ * X11 Selection for the popup command
+ */
+
+static gboolean
+my_plugin_set_selection (MyPlugin *plugin)
+{
+ GdkScreen *gscreen;
+ gchar *selection_name;
+ Atom selection_atom;
+ GtkWidget *win;
+ Window id;
+
+ win = gtk_invisible_new ();
+ gtk_widget_realize (win);
+ id = GDK_WINDOW_XID (GTK_WIDGET (win)->window);
+
+ gscreen = gtk_widget_get_screen (win);
+ selection_name = g_strdup_printf (XFCE_CLIPMAN_SELECTION"%d",
+ gdk_screen_get_number (gscreen));
+ selection_atom = XInternAtom (GDK_DISPLAY(), selection_name, FALSE);
+
+ if (XGetSelectionOwner (GDK_DISPLAY(), selection_atom))
+ {
+ gtk_widget_destroy (win);
+ return FALSE;
+ }
+
+ XSelectInput (GDK_DISPLAY(), id, PropertyChangeMask);
+ XSetSelectionOwner (GDK_DISPLAY(), selection_atom, id, GDK_CURRENT_TIME);
+
+ g_signal_connect_swapped (win, "client-event",
+ G_CALLBACK (cb_message_received), plugin);
+
+ return TRUE;
+}
+
+static gboolean
+cb_message_received (MyPlugin *plugin,
+ GdkEventClient *ev)
+{
+ if (G_LIKELY (ev->data_format == 8 && *(ev->data.b) != '\0'))
+ {
+ if (!g_ascii_strcasecmp (XFCE_CLIPMAN_MESSAGE, ev->data.b))
+ {
+ DBG ("Message received: %s", ev->data.b);
+
+ if (plugin->panel_plugin != NULL)
+ xfce_panel_plugin_set_panel_hidden (plugin->panel_plugin, FALSE);
+
+ while (gtk_events_pending ())
+ gtk_main_iteration ();
+
+ if (plugin->panel_plugin != NULL)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (plugin->button), TRUE);
+ else if (plugin->status_icon != NULL)
+ g_signal_emit_by_name (plugin->status_icon, "activate", NULL);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/*
+ * Settings Dialog
+ */
+
+/* Actions */
+static void
+setup_actions_treeview (GtkTreeView *treeview,
+ MyPlugin *plugin)
+{
+ GtkTreeSelection *selection;
+ GtkListStore *model;
+ GtkCellRenderer *cell;
+
+ /* Define the model */
+ model = gtk_list_store_new (2, G_TYPE_POINTER, G_TYPE_STRING);
+ gtk_tree_view_set_model (treeview, GTK_TREE_MODEL (model));
+ g_object_unref (model);
+
+ /* Define the columns */
+ cell = gtk_cell_renderer_text_new ();
+ g_object_set (cell, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
+ gtk_tree_view_insert_column_with_attributes (treeview, -1, "Action", cell, "markup", 1, NULL);
+
+ refresh_actions_treeview (treeview, plugin);
+
+ selection = gtk_tree_view_get_selection (treeview);
+ g_signal_connect (selection, "changed", G_CALLBACK (cb_actions_selection_changed), plugin);
+}
+
+static void
+refresh_actions_treeview (GtkTreeView *treeview,
+ MyPlugin *plugin)
+{
+ ClipmanActionsEntry *entry;
+ const GSList *entries;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gchar *title;
+
+ model = gtk_tree_view_get_model (treeview);
+ gtk_list_store_clear (GTK_LIST_STORE (model));
+
+ entries = clipman_actions_get_entries (plugin->actions);
+ for (; entries != NULL; entries = entries->next)
+ {
+ entry = entries->data;
+
+ title = g_strdup_printf ("<b>%s</b>\n<small>%s</small>", entry->action_name, g_regex_get_pattern (entry->regex));
+ gtk_list_store_append (GTK_LIST_STORE (model), &iter);
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, entry, 1, title, -1);
+ g_free (title);
+ }
+}
+
+static void
+apply_action (const gchar *original_action_name,
+ MyPlugin *plugin)
+{
+ GtkWidget *treeview;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ const gchar *action_name;
+ const gchar *regex;
+ gchar *command_name;
+ gchar *command;
+
+ action_name = gtk_entry_get_text (GTK_ENTRY (glade_xml_get_widget (plugin->gxml, "action-name")));
+ regex = gtk_entry_get_text (GTK_ENTRY (glade_xml_get_widget (plugin->gxml, "regex")));
+
+ treeview = glade_xml_get_widget (plugin->gxml, "commands");
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
+ if (!gtk_tree_model_get_iter_first (model, &iter))
+ return;
+
+ /* Remove the old actions */
+ if (original_action_name != NULL)
+ clipman_actions_remove (plugin->actions, original_action_name);
+
+ /* Add the new actions */
+ do
+ {
+ gtk_tree_model_get (model, &iter, 1, &command_name, 2, &command, -1);
+ clipman_actions_add (plugin->actions, action_name, regex, command_name, command);
+ g_free (command_name);
+ g_free (command);
+ }
+ while (gtk_tree_model_iter_next (model, &iter));
+
+ /* Refresh the actions treeview */
+ treeview = glade_xml_get_widget (plugin->gxml, "actions");
+ refresh_actions_treeview (GTK_TREE_VIEW (treeview), plugin);
+}
+
+static void
+cb_actions_selection_changed (GtkTreeSelection *selection,
+ MyPlugin *plugin)
+{
+ GtkTreeModel *model;
+ gboolean sensitive;
+
+ sensitive = gtk_tree_selection_get_selected (selection, &model, NULL);
+
+ gtk_widget_set_sensitive (glade_xml_get_widget (plugin->gxml, "button-edit-action"), sensitive);
+ gtk_widget_set_sensitive (glade_xml_get_widget (plugin->gxml, "button-delete-action"), sensitive);
+}
+
+static void
+cb_add_action (GtkButton *button,
+ MyPlugin *plugin)
+{
+ GtkWidget *dialog;
+ gint res;
+
+ dialog = glade_xml_get_widget (plugin->gxml, "action-dialog");
+ entry_dialog_cleanup (GTK_DIALOG (dialog), plugin);
+
+ res = gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_hide (dialog);
+
+ if (res == 1)
+ apply_action (NULL, plugin);
+}
+
+static void
+cb_edit_action (GtkButton *button,
+ MyPlugin *plugin)
+{
+ GtkWidget *treeview;
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GtkTreePath *path;
+ GtkTreeViewColumn *column;
+
+ treeview = glade_xml_get_widget (plugin->gxml, "actions");
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
+ if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+ {
+ g_critical ("Trying to edit an action but got no selection");
+ return;
+ }
+
+ path = gtk_tree_model_get_path (model, &iter);
+ column = gtk_tree_view_get_column (GTK_TREE_VIEW (treeview), 1);
+ gtk_tree_view_row_activated (GTK_TREE_VIEW (treeview), path, column);
+ gtk_tree_path_free (path);
+}
+
+static void
+cb_actions_row_activated (GtkTreeView *treeview,
+ GtkTreePath *path,
+ GtkTreeViewColumn *column,
+ MyPlugin *plugin)
+{
+ ClipmanActionsEntry *entry;
+ GtkTreeModel *actions_model, *commands_model;
+ GtkTreeIter iter;
+ GtkWidget *dialog;
+ gchar *title;
+ gint res;
+
+ dialog = glade_xml_get_widget (plugin->gxml, "action-dialog");
+ entry_dialog_cleanup (GTK_DIALOG (dialog), plugin);
+
+ actions_model = gtk_tree_view_get_model (treeview);
+ gtk_tree_model_get_iter (actions_model, &iter, path);
+ gtk_tree_model_get (actions_model, &iter, 0, &entry, -1);
+
+ commands_model = gtk_tree_view_get_model (GTK_TREE_VIEW (glade_xml_get_widget (plugin->gxml, "commands")));
+#if GLIB_CHECK_VERSION (2,16,0)
+ GHashTableIter hiter;
+ gpointer key, value;
+ g_hash_table_iter_init (&hiter, entry->commands);
+ while (g_hash_table_iter_next (&hiter, &key, &value))
+ {
+ title = g_strdup_printf ("<b>%s</b>\n<small>%s</small>", (gchar *)key, (gchar *)value);
+ gtk_list_store_append (GTK_LIST_STORE (commands_model), &iter);
+ gtk_list_store_set (GTK_LIST_STORE (commands_model), &iter, 0, title, 1, key, 2, value, -1);
+ g_free (title);
+ }
+#else
+ g_hash_table_foreach (entry->commands, (GHFunc)__foreach_command_fill_commands, commands_model);
+#endif
+
+ gtk_entry_set_text (GTK_ENTRY (glade_xml_get_widget (plugin->gxml, "action-name")), entry->action_name);
+ gtk_entry_set_text (GTK_ENTRY (glade_xml_get_widget (plugin->gxml, "regex")), g_regex_get_pattern (entry->regex));
+
+ res = gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_hide (dialog);
+
+ if (res == 1)
+ apply_action (entry->action_name, plugin);
+}
+
+static void
+cb_delete_action (GtkButton *button,
+ MyPlugin *plugin)
+{
+ ClipmanActionsEntry *entry;
+ GtkWidget *treeview;
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ treeview = glade_xml_get_widget (plugin->gxml, "actions");
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
+ if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+ {
+ g_critical ("Trying to remove an action but got no selection");
+ return;
+ }
+
+ gtk_tree_model_get (model, &iter, 0, &entry, -1);
+ clipman_actions_remove (plugin->actions, entry->action_name);
+ gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
+}
+
+/* Entry Dialog */
+static void
+setup_commands_treeview (GtkTreeView *treeview,
+ MyPlugin *plugin)
+{
+ GtkTreeSelection *selection;
+ GtkListStore *model;
+ GtkCellRenderer *cell;
+
+ /* Define the model */
+ model = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+ gtk_tree_view_set_model (treeview, GTK_TREE_MODEL (model));
+ g_object_unref (model);
+
+ /* Define the columns */
+ cell = gtk_cell_renderer_text_new ();
+ g_object_set (cell, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
+ gtk_tree_view_insert_column_with_attributes (treeview, -1, "Command", cell, "markup", 0, NULL);
+
+ selection = gtk_tree_view_get_selection (treeview);
+ g_signal_connect (selection, "changed", G_CALLBACK (cb_commands_selection_changed), plugin);
+}
+
+static void
+entry_dialog_cleanup (GtkDialog *dialog,
+ MyPlugin *plugin)
+{
+ GtkTreeModel *model;
+
+ gtk_widget_set_sensitive (glade_xml_get_widget (plugin->gxml, "action-dialog-button-ok"), FALSE);
+
+ gtk_entry_set_text (GTK_ENTRY (glade_xml_get_widget (plugin->gxml, "action-name")), "");
+ gtk_entry_set_text (GTK_ENTRY (glade_xml_get_widget (plugin->gxml, "regex")), "");
+
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (glade_xml_get_widget (plugin->gxml, "commands")));
+ gtk_list_store_clear (GTK_LIST_STORE (model));
+}
+
+#if !GLIB_CHECK_VERSION(2,16,0)
+static void
+__foreach_command_fill_commands (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ GtkTreeModel *model = user_data;
+ GtkTreeIter iter;
+ gchar *title;
+
+ title = g_strdup_printf ("<b>%s</b>\n<small>%s</small>", (gchar *)key, (gchar *)value);
+ gtk_list_store_append (GTK_LIST_STORE (_model), &iter);
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, title, 1, key, 2, value, -1);
+ g_free (title);
+}
+#endif
+
+static void
+cb_commands_selection_changed (GtkTreeSelection *selection,
+ MyPlugin *plugin)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gboolean sensitive;
+ gchar *command_name = NULL;
+ gchar *command = NULL;
+
+ sensitive = gtk_tree_selection_get_selected (selection, &model, &iter);
+
+ gtk_widget_set_sensitive (glade_xml_get_widget (plugin->gxml, "button-refresh-command"), sensitive);
+ gtk_widget_set_sensitive (glade_xml_get_widget (plugin->gxml, "button-delete-command"), sensitive);
+
+ if (sensitive)
+ {
+ gtk_tree_model_get (model, &iter, 1, &command_name, 2, &command, -1);
+ gtk_entry_set_text (GTK_ENTRY (glade_xml_get_widget (plugin->gxml, "command-name")), command_name);
+ gtk_entry_set_text (GTK_ENTRY (glade_xml_get_widget (plugin->gxml, "command")), command);
+ g_free (command_name);
+ g_free (command);
+ }
+ else
+ {
+ gtk_entry_set_text (GTK_ENTRY (glade_xml_get_widget (plugin->gxml, "command-name")), "");
+ gtk_entry_set_text (GTK_ENTRY (glade_xml_get_widget (plugin->gxml, "command")), "");
+ }
+}
+
+static void
+cb_add_command (GtkButton *button,
+ MyPlugin *plugin)
+{
+ GtkWidget *command_name;
+ GtkWidget *command;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gchar *title;
+
+ command_name = glade_xml_get_widget (plugin->gxml, "command-name");
+ command = glade_xml_get_widget (plugin->gxml, "command");
+
+ if (gtk_entry_get_text (GTK_ENTRY (command_name))[0] == '\0'
+ || gtk_entry_get_text (GTK_ENTRY (command))[0] == '\0')
+ return;
+
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (glade_xml_get_widget (plugin->gxml, "commands")));
+ title = g_strdup_printf ("<b>%s</b>\n<small>%s</small>",
+ gtk_entry_get_text (GTK_ENTRY (command_name)),
+ gtk_entry_get_text (GTK_ENTRY (command)));
+ gtk_list_store_append (GTK_LIST_STORE (model), &iter);
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, title,
+ 1, gtk_entry_get_text (GTK_ENTRY (command_name)),
+ 2, gtk_entry_get_text (GTK_ENTRY (command)), -1);
+ g_free (title);
+
+ gtk_entry_set_text (GTK_ENTRY (command_name), "");
+ gtk_entry_set_text (GTK_ENTRY (command), "");
+}
+
+static void
+cb_refresh_command (GtkButton *button,
+ MyPlugin *plugin)
+{
+ GtkWidget *treeview;
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GtkWidget *command_name;
+ GtkWidget *command;
+ gchar *title;
+
+ command_name = glade_xml_get_widget (plugin->gxml, "command-name");
+ command = glade_xml_get_widget (plugin->gxml, "command");
+
+ if (gtk_entry_get_text (GTK_ENTRY (command_name))[0] == '\0'
+ || gtk_entry_get_text (GTK_ENTRY (command))[0] == '\0')
+ return;
+
+ treeview = glade_xml_get_widget (plugin->gxml, "commands");
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
+ if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+ {
+ g_critical ("Trying to refresh a command but got no selection");
+ return;
+ }
+
+ title = g_strdup_printf ("<b>%s</b>\n<small>%s</small>",
+ gtk_entry_get_text (GTK_ENTRY (command_name)),
+ gtk_entry_get_text (GTK_ENTRY (command)));
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, title,
+ 1, gtk_entry_get_text (GTK_ENTRY (command_name)),
+ 2, gtk_entry_get_text (GTK_ENTRY (command)), -1);
+ g_free (title);
+
+ gtk_tree_selection_unselect_all (selection);
+}
+
+static void
+cb_delete_command (GtkButton *button,
+ MyPlugin *plugin)
+{
+ GtkWidget *treeview;
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ treeview = glade_xml_get_widget (plugin->gxml, "commands");
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
+ if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+ {
+ g_critical ("Trying to delete a command but got no selection");
+ return;
+ }
+
+ gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
+}
+
+static void
+cb_set_action_dialog_button_ok (GtkWidget *widget,
+ MyPlugin *plugin)
+{
+ const gchar *action_name;
+ const gchar *regex_pattern;
+ GRegex *regex;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gboolean has_commands;
+ gboolean sensitive = FALSE;
+
+ action_name = gtk_entry_get_text (GTK_ENTRY (glade_xml_get_widget (plugin->gxml, "action-name")));
+ regex_pattern = gtk_entry_get_text (GTK_ENTRY (glade_xml_get_widget (plugin->gxml, "regex")));
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (glade_xml_get_widget (plugin->gxml, "commands")));
+ has_commands = gtk_tree_model_get_iter_first (model, &iter);
+
+ if (action_name[0] != '\0' && regex_pattern[0] != '\0' && has_commands)
+ {
+ if (regex = g_regex_new (regex_pattern, 0, 0, NULL))
+ {
+ sensitive = TRUE;
+ g_regex_unref (regex);
+ }
+ }
+
+ gtk_widget_set_sensitive (glade_xml_get_widget (plugin->gxml, "action-dialog-button-ok"), sensitive);
+ return;
+}
+
Property changes on: xfce4-clipman-plugin/trunk/panel-plugin/main.c
___________________________________________________________________
Added: svn:mergeinfo
+
Added: xfce4-clipman-plugin/trunk/xfce4-clipman-plugin.desktop.in
===================================================================
--- xfce4-clipman-plugin/trunk/xfce4-clipman-plugin.desktop.in (rev 0)
+++ xfce4-clipman-plugin/trunk/xfce4-clipman-plugin.desktop.in 2009-04-13 07:55:32 UTC (rev 7174)
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Version=1.0
+Type=Application
+_Name=Clipman
+_Comment=Clipboards manager
+TryExec=xfce4-clipman-plugin
+Exec=xfce4-clipman-plugin
+Icon=gtk-paste
+Terminal=false
+Categories=GTK;Utility;TrayIcon;
+StartupNotify=true
More information about the Goodies-commits
mailing list