201 lines
5.0 KiB
C
201 lines
5.0 KiB
C
/*
|
|
* Copyright (C) 2012 - Juan Ferrer Toribio
|
|
*
|
|
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "vn-image.h"
|
|
#include <db/db.h>
|
|
|
|
#define set_default_image(obj) g_object_set (obj->image, \
|
|
"icon-name", "dialog-question", "icon-size", GTK_ICON_SIZE_DIALOG, NULL)
|
|
|
|
/**
|
|
* SECTION:vn-image
|
|
* @Short_description: an image widget
|
|
* @Title: VnImage
|
|
* @See_also: #VnField
|
|
* @Image: image.png
|
|
*
|
|
* An image widget that allows to set a new image with a double click.
|
|
*/
|
|
G_DEFINE_TYPE (VnImage, vn_image, VN_TYPE_FIELD);
|
|
|
|
/**
|
|
* vn_image_new:
|
|
*
|
|
* Creates a new #VnImage
|
|
*
|
|
* Return value: a #VnImage
|
|
**/
|
|
VnField * vn_image_new ()
|
|
{
|
|
return g_object_new (VN_TYPE_IMAGE, NULL);
|
|
}
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Private
|
|
|
|
static void vn_image_set_value (VnImage * obj, const GValue * value)
|
|
{
|
|
GBytes * bytes = NULL;
|
|
|
|
if (!gvn_value_is_null (value)
|
|
&& G_VALUE_TYPE (value) == G_TYPE_BYTES)
|
|
bytes = g_value_get_boxed (value);
|
|
|
|
if (bytes)
|
|
{
|
|
gsize size;
|
|
const guchar * data;
|
|
GError * err = NULL;
|
|
GdkPixbufLoader * loader;
|
|
|
|
loader = gdk_pixbuf_loader_new ();
|
|
data = g_bytes_get_data (bytes, &size);
|
|
|
|
if (gdk_pixbuf_loader_write (loader, data, size, &err)
|
|
&& gdk_pixbuf_loader_close (loader, &err))
|
|
{
|
|
GdkPixbuf * pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
|
|
gtk_image_set_from_pixbuf (obj->image, pixbuf);
|
|
}
|
|
else
|
|
{
|
|
g_warning ("%s",err->message);
|
|
g_error_free (err);
|
|
set_default_image (obj);
|
|
}
|
|
|
|
g_object_unref (loader);
|
|
}
|
|
else
|
|
set_default_image (obj);
|
|
}
|
|
|
|
static void vn_image_cb_update_preview (GtkFileChooser * chooser, GtkImage * image)
|
|
{
|
|
char *filename;
|
|
GdkPixbuf *pixbuf;
|
|
|
|
filename = gtk_file_chooser_get_preview_filename (chooser);
|
|
|
|
if (filename)
|
|
{
|
|
pixbuf = gdk_pixbuf_new_from_file_at_size (filename, 128, 128, NULL);
|
|
g_free (filename);
|
|
|
|
if (pixbuf)
|
|
{
|
|
gtk_image_set_from_pixbuf (image, pixbuf);
|
|
g_object_unref (pixbuf);
|
|
}
|
|
}
|
|
else
|
|
pixbuf = NULL;
|
|
|
|
gtk_file_chooser_set_preview_widget_active (chooser, pixbuf != NULL);
|
|
}
|
|
|
|
static gboolean vn_image_cb_event (VnField * field, GdkEvent * event, VnImage * obj)
|
|
{
|
|
if (event->type != GDK_2BUTTON_PRESS)
|
|
return FALSE;
|
|
|
|
GtkWidget * image;
|
|
GtkWidget * toplevel;
|
|
GtkFileChooser * chooser;
|
|
GtkFileFilter * filter;
|
|
|
|
filter = gtk_file_filter_new ();
|
|
gtk_file_filter_add_mime_type (filter, "image/png");
|
|
gtk_file_filter_add_mime_type (filter, "image/jpeg");
|
|
gtk_file_filter_add_mime_type (filter, "image/gif");
|
|
gtk_file_filter_add_mime_type (filter, "image/bmp");
|
|
gtk_file_filter_add_mime_type (filter, "image/svg+xml");
|
|
|
|
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (obj));
|
|
|
|
if (!gtk_widget_is_toplevel (toplevel))
|
|
toplevel = NULL;
|
|
|
|
chooser = GTK_FILE_CHOOSER (gtk_file_chooser_dialog_new (
|
|
_("Select the image")
|
|
,GTK_WINDOW (toplevel)
|
|
,GTK_FILE_CHOOSER_ACTION_OPEN
|
|
,"Cancel", GTK_RESPONSE_CANCEL
|
|
,"Open", GTK_RESPONSE_ACCEPT
|
|
,NULL
|
|
));
|
|
gtk_file_chooser_set_filter (chooser, filter);
|
|
|
|
image = gtk_image_new ();
|
|
gtk_file_chooser_set_preview_widget (chooser, image);
|
|
g_signal_connect (chooser, "update-preview",
|
|
G_CALLBACK (vn_image_cb_update_preview), image);
|
|
|
|
if (gtk_dialog_run (GTK_DIALOG (chooser)) == GTK_RESPONSE_ACCEPT)
|
|
{
|
|
gsize len;
|
|
gchar * data;
|
|
gchar * filename;
|
|
GError * err = NULL;
|
|
|
|
filename = gtk_file_chooser_get_filename (chooser);
|
|
|
|
if (g_file_get_contents (filename, &data, &len, &err))
|
|
{
|
|
GValue value = {0};
|
|
g_value_init (&value, G_TYPE_BYTES);
|
|
g_value_take_boxed (&value, g_bytes_new_take (data, len));
|
|
|
|
VN_FIELD_GET_CLASS (obj)->value_changed (VN_FIELD (obj), &value);
|
|
vn_image_set_value (obj, &value);
|
|
g_value_unset (&value);
|
|
}
|
|
else
|
|
{
|
|
g_warning ("%s", err->message);
|
|
g_error_free (err);
|
|
}
|
|
|
|
g_free (filename);
|
|
}
|
|
|
|
gtk_widget_destroy (GTK_WIDGET (chooser));
|
|
return FALSE;
|
|
}
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Class
|
|
|
|
static void vn_image_init (VnImage * obj)
|
|
{
|
|
obj->image = GTK_IMAGE (gtk_image_new ());
|
|
g_signal_connect (obj, "event",
|
|
G_CALLBACK (vn_image_cb_event), obj);
|
|
set_default_image (obj);
|
|
gtk_container_add (GTK_CONTAINER (obj), GTK_WIDGET (obj->image));
|
|
VN_FIELD (obj)->field = GTK_WIDGET (obj->image);
|
|
}
|
|
|
|
static void vn_image_finalize (VnImage * obj)
|
|
{
|
|
G_OBJECT_CLASS (vn_image_parent_class)->finalize (G_OBJECT (obj));
|
|
}
|
|
|
|
static void vn_image_class_init (VnImageClass * klass)
|
|
{
|
|
G_OBJECT_CLASS (klass)->finalize = (GObjectFinalizeFunc) vn_image_finalize;
|
|
VN_FIELD_CLASS (klass)->set_value = (VnFieldSetValueFunc) vn_image_set_value;
|
|
}
|