From 059e3dc5f9a07080b788c44236cb8cdf80cbb5e3 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Thu, 4 Jul 2013 22:43:39 +0200 Subject: [PATCH] add QR-Code support to clipman --- configure.ac.in | 11 +++ panel-plugin/Makefile.am | 2 + panel-plugin/common.h | 1 + panel-plugin/menu.c | 126 ++++++++++++++++++++++++++++++++++ panel-plugin/plugin.c | 5 ++ panel-plugin/settings-dialog.ui | 15 ++++ panel-plugin/xfce4-clipman-settings.c | 10 +++ 7 files changed, 170 insertions(+) diff --git a/configure.ac.in b/configure.ac.in index 550d654..87ce0f1 100644 --- a/configure.ac.in +++ b/configure.ac.in @@ -81,6 +81,16 @@ else enable_unique=no fi +dnl ***************************** +dnl *** Check for libqrencode *** +dnl ***************************** +XDT_CHECK_OPTIONAL_PACKAGE([QRENCODE], [libqrencode], [3.4.1], libqrencode, [QR Code support]) +if test x"$QRENCODE_FOUND" = x"yes"; then + enable_qrencode=yes +else + enable_qrencode=no +fi + dnl ******************************* dnl *** Check for documentation *** dnl ******************************* @@ -148,6 +158,7 @@ echo "Build Configuration:" echo echo " * Debug Support: $enable_debug" echo " * Unique: $enable_unique" +echo " * QR Code: $enable_qrencode" echo if test "x$USE_MAINTAINER_MODE" = "xyes" ; then echo "Enable Documentation: $enable_gen_doc" diff --git a/panel-plugin/Makefile.am b/panel-plugin/Makefile.am index d3c1259..554455a 100644 --- a/panel-plugin/Makefile.am +++ b/panel-plugin/Makefile.am @@ -115,6 +115,7 @@ xfce4_clipman_LDADD = \ @LIBXFCE4UTIL_LIBS@ \ @LIBXFCE4UI_LIBS@ \ @XFCONF_LIBS@ \ + @QRENCODE_LIBS@ \ $(NULL) # @@ -169,6 +170,7 @@ libclipman_la_LIBADD = \ @LIBXFCE4UI_LIBS@ \ @LIBXFCE4PANEL_LIBS@ \ @XFCONF_LIBS@ \ + @QRENCODE_LIBS@ $(NULL) # diff --git a/panel-plugin/common.h b/panel-plugin/common.h index 6b5fe0e..de5b17c 100644 --- a/panel-plugin/common.h +++ b/panel-plugin/common.h @@ -30,6 +30,7 @@ #define DEFAULT_REORDER_ITEMS TRUE #define DEFAULT_SKIP_ACTION_ON_KEY_DOWN FALSE #define DEFAULT_ADD_PRIMARY_CLIPBOARD FALSE +#define DEFAULT_SHOW_QR_CODE FALSE #define DEFAULT_HISTORY_IGNORE_PRIMARY_CLIPBOARD TRUE #define DEFAULT_ENABLE_ACTIONS FALSE diff --git a/panel-plugin/menu.c b/panel-plugin/menu.c index 41a4f1a..c78ce94 100644 --- a/panel-plugin/menu.c +++ b/panel-plugin/menu.c @@ -28,6 +28,10 @@ #include #include +#ifdef HAVE_QRENCODE +#include +#endif + #include "common.h" #include "collector.h" #include "history.h" @@ -49,6 +53,9 @@ struct _ClipmanMenuPrivate ClipmanHistory *history; GSList *list; gboolean reverse_order; +#ifdef HAVE_QRENCODE + gboolean show_qr_code; +#endif guint paste_on_activate; gboolean never_confirm_history_clear; }; @@ -56,6 +63,7 @@ struct _ClipmanMenuPrivate enum { REVERSE_ORDER = 1, + SHOW_QR_CODE, INHIBIT_MENU_ITEM, PASTE_ON_ACTIVATE, NEVER_CONFIRM_HISTORY_CLEAR, @@ -70,6 +78,10 @@ static void clipman_menu_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +#ifdef HAVE_QRENCODE +GdkPixbuf * clipman_menu_qrcode (char *text); +#endif + /* * Private methods declarations @@ -81,6 +93,10 @@ static void _clipman_menu_free_list (ClipmanMenu *menu); * Callbacks declarations */ +#ifdef HAVE_QRENCODE +static void cb_set_qrcode (GtkMenuItem *mi, + const GdkPixbuf *pixbuf); +#endif static void cb_set_clipboard (GtkMenuItem *mi, const ClipmanHistoryItem *item); static void cb_clear_history (ClipmanMenu *menu); @@ -92,6 +108,28 @@ static void cb_toggle_inhibit_mi (ClipmanMenu *menu); * Callbacks */ +#ifdef HAVE_QRENCODE +static void +cb_set_qrcode (GtkMenuItem *mi, const GdkPixbuf *pixbuf) +{ + GtkClipboard *clipboard; + ClipmanCollector *collector; + ClipmanHistory *history; + + collector = clipman_collector_get (); + clipman_collector_set_is_restoring (collector); + g_object_unref (collector); + + history = clipman_history_get (); + clipman_history_add_image (history, pixbuf); + + clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); + gtk_clipboard_set_image (clipboard, GDK_PIXBUF (pixbuf)); + + g_object_unref (history); +} +#endif + static void cb_set_clipboard (GtkMenuItem *mi, const ClipmanHistoryItem *item) { @@ -245,6 +283,9 @@ static void _clipman_menu_update_list (ClipmanMenu *menu) { GtkWidget *mi, *image; +#ifdef HAVE_QRENCODE + GdkPixbuf *pixbuf; +#endif ClipmanHistoryItem *item; const ClipmanHistoryItem *item_to_restore; GSList *list, *l; @@ -296,6 +337,37 @@ _clipman_menu_update_list (ClipmanMenu *menu) gtk_menu_shell_insert (GTK_MENU_SHELL (menu), mi, pos++); gtk_widget_show_all (mi); } + +#ifdef HAVE_QRENCODE + /* Draw QR Code if clipboard content is text */ + if (menu->priv->show_qr_code && item_to_restore && item_to_restore->type == CLIPMAN_HISTORY_TYPE_TEXT) + { + mi = gtk_separator_menu_item_new (); + menu->priv->list = g_slist_prepend (menu->priv->list, mi); + gtk_menu_shell_insert (GTK_MENU_SHELL (menu), mi, pos++); + gtk_widget_show_all (mi); + + if ((pixbuf = clipman_menu_qrcode (item_to_restore->content.text)) != NULL) + { + mi = gtk_image_menu_item_new (); + gtk_container_add (GTK_CONTAINER (mi), gtk_image_new_from_pixbuf (pixbuf)); + g_signal_connect (mi, "activate", G_CALLBACK (cb_set_qrcode), pixbuf); + menu->priv->list = g_slist_prepend (menu->priv->list, mi); + gtk_menu_shell_insert (GTK_MENU_SHELL (menu), mi, pos++); + gtk_widget_show_all (mi); + g_object_unref(pixbuf); + } + else + { + mi = gtk_menu_item_new_with_label (_("Could not generate QR-Code.")); + menu->priv->list = g_slist_prepend (menu->priv->list, mi); + gtk_menu_shell_insert (GTK_MENU_SHELL (menu), mi, pos++); + gtk_widget_set_sensitive (mi, FALSE); + gtk_widget_show (mi); + } + } +#endif + g_slist_free (list); if (pos == 0) @@ -357,6 +429,15 @@ clipman_menu_class_init (ClipmanMenuClass *klass) FALSE, G_PARAM_CONSTRUCT|G_PARAM_READWRITE)); +#ifdef HAVE_QRENCODE + g_object_class_install_property (object_class, SHOW_QR_CODE, + g_param_spec_boolean ("show-qr-code", + "ShowQrCode", + "Set to TRUE to display QR-Code in the menu", + FALSE, + G_PARAM_CONSTRUCT|G_PARAM_READWRITE)); +#endif + g_object_class_install_property (object_class, INHIBIT_MENU_ITEM, g_param_spec_boolean ("inhibit-menu-item", "InhibitMenuItem", @@ -429,6 +510,12 @@ clipman_menu_set_property (GObject *object, priv->reverse_order = g_value_get_boolean (value); break; +#ifdef HAVE_QRENCODE + case SHOW_QR_CODE: + priv->show_qr_code = g_value_get_boolean (value); + break; +#endif + case INHIBIT_MENU_ITEM: gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (priv->mi_inhibit), g_value_get_boolean (value)); @@ -478,3 +565,42 @@ clipman_menu_get_property (GObject *object, } } +#ifdef HAVE_QRENCODE +GdkPixbuf * +clipman_menu_qrcode (char *text) +{ + QRcode *qrcode; + GdkPixbuf *pixbuf, *pixbuf_scaled; + int i, j, k, rowstride, channels; + guchar *pixel; + unsigned char *data; + + qrcode = QRcode_encodeData(strlen(text), (unsigned char *)text, 0, QR_ECLEVEL_L); + + if (qrcode == NULL) + return NULL; + + data = qrcode->data; + + pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, qrcode->width + 2, qrcode->width + 2); + + pixel = gdk_pixbuf_get_pixels (pixbuf); + rowstride = gdk_pixbuf_get_rowstride (pixbuf); + channels = gdk_pixbuf_get_n_channels (pixbuf); + + gdk_pixbuf_fill(pixbuf, 0xffffffff); + for (i = 1; i <= qrcode->width; i++) + for (j = 1; j <= qrcode->width; j++) { + for (k = 0; k < channels; k++) + pixel[i * rowstride + j * channels + k] = !(*data & 0x1) * 0xff; + data++; + } + + pixbuf_scaled = gdk_pixbuf_scale_simple (pixbuf, (qrcode->width + 2) * 3, (qrcode->width + 2) * 3, GDK_INTERP_NEAREST); + + QRcode_free(qrcode); + g_object_unref(pixbuf); + + return pixbuf_scaled; +} +#endif diff --git a/panel-plugin/plugin.c b/panel-plugin/plugin.c index adeb054..387beed 100644 --- a/panel-plugin/plugin.c +++ b/panel-plugin/plugin.c @@ -113,6 +113,10 @@ plugin_register (void) /* ClipmanMenu */ plugin->menu = clipman_menu_new (); +#ifdef HAVE_QRENCODE + xfconf_g_property_bind (plugin->channel, "/settings/show-qr-code", + G_TYPE_BOOLEAN, plugin->menu, "show-qr-code"); +#endif xfconf_g_property_bind (plugin->channel, "/tweaks/reverse-menu-order", G_TYPE_BOOLEAN, plugin->menu, "reverse-order"); xfconf_g_property_bind (plugin->channel, "/tweaks/inhibit", @@ -323,6 +327,7 @@ plugin_about (MyPlugin *plugin) "", _("Contributors:"), "(c) 2008-2009 David Collins", + "(c) 2013 Christian Hesse", NULL, }; const gchar *documenters[] = { "Mike Massonnet", NULL, }; const gchar *license = diff --git a/panel-plugin/settings-dialog.ui b/panel-plugin/settings-dialog.ui index 946193c..9f4fc7d 100644 --- a/panel-plugin/settings-dialog.ui +++ b/panel-plugin/settings-dialog.ui @@ -70,6 +70,21 @@ 0 + + + Show _QR-Code + True + True + False + True + If checked, the menu shows a QR-Code of the corrently selected clipboard entry + True + True + + + 1 + + diff --git a/panel-plugin/xfce4-clipman-settings.c b/panel-plugin/xfce4-clipman-settings.c index 38e38be..9894100 100644 --- a/panel-plugin/xfce4-clipman-settings.c +++ b/panel-plugin/xfce4-clipman-settings.c @@ -87,6 +87,12 @@ prop_dialog_run (void) /* General settings */ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "add-selections")), DEFAULT_ADD_PRIMARY_CLIPBOARD); +#ifdef HAVE_QRENCODE + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "show-qr-code")), + DEFAULT_SHOW_QR_CODE); +#else + gtk_widget_hide(GTK_WIDGET (gtk_builder_get_object (builder, "show-qr-code"))); +#endif gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "history-ignore-selections")), DEFAULT_HISTORY_IGNORE_PRIMARY_CLIPBOARD); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "save-on-quit")), @@ -98,6 +104,10 @@ prop_dialog_run (void) xfconf_g_property_bind (xfconf_channel, "/settings/add-primary-clipboard", G_TYPE_BOOLEAN, gtk_builder_get_object (builder, "add-selections"), "active"); +#ifdef HAVE_QRENCODE + xfconf_g_property_bind (xfconf_channel, "/settings/show-qr-code", G_TYPE_BOOLEAN, + gtk_builder_get_object (builder, "show-qr-code"), "active"); +#endif xfconf_g_property_bind (xfconf_channel, "/settings/history-ignore-primary-clipboard", G_TYPE_BOOLEAN, gtk_builder_get_object (builder, "history-ignore-selections"), "active"); xfconf_g_property_bind (xfconf_channel, "/settings/save-on-quit", G_TYPE_BOOLEAN, -- 1.8.3.2