diff --git a/configure.ac.in b/configure.ac.in index 550d654..1b14c0d 100644 --- a/configure.ac.in +++ b/configure.ac.in @@ -31,7 +31,7 @@ dnl *************************** dnl *** Initialize automake *** dnl *************************** AM_INIT_AUTOMAKE([1.8 no-dist-gzip dist-bzip2]) -AM_CONFIG_HEADER([config.h]) +AC_CONFIG_HEADERS([config.h]) AM_MAINTAINER_MODE() m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) @@ -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/menu.c b/panel-plugin/menu.c index 41a4f1a..a6dad9f 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" @@ -70,6 +74,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 +89,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 +104,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 +279,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 +333,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 (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)) + { + 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) @@ -478,3 +546,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; + gchar *pixel; + unsigned char *data; + + qrcode = QRcode_encodeData(strlen(text), 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