summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 0cc5b8d)
raw | patch | inline | side by side (parent: 0cc5b8d)
author | joncruz <joncruz@users.sourceforge.net> | |
Sat, 17 May 2008 22:34:59 +0000 (22:34 +0000) | ||
committer | joncruz <joncruz@users.sourceforge.net> | |
Sat, 17 May 2008 22:34:59 +0000 (22:34 +0000) |
src/sp-image.cpp | patch | blob | history | |
src/sp-image.h | patch | blob | history | |
src/ui/context-menu.cpp | patch | blob | history | |
src/widgets/desktop-widget.cpp | patch | blob | history |
diff --git a/src/sp-image.cpp b/src/sp-image.cpp
index 6ba348fbec094b2620b46ec747d3158778b2ec4e..7a1d3534d2863207be4891111b1f819e1a2aa622 100644 (file)
--- a/src/sp-image.cpp
+++ b/src/sp-image.cpp
//#include <gdk-pixbuf/gdk-pixbuf-io.h>
#include "display/nr-arena-image.h"
#include <display/curve.h>
+#include <glib/gstdio.h>
//Added for preserveAspectRatio support -- EAF
#include "enums.h"
static void sp_image_set_curve(SPImage *image);
-GdkPixbuf *sp_image_repr_read_image (const gchar *href, const gchar *absref, const gchar *base);
+static GdkPixbuf *sp_image_repr_read_image( time_t& modTime, gchar*& pixPath, const gchar *href, const gchar *absref, const gchar *base );
static GdkPixbuf *sp_image_pixbuf_force_rgba (GdkPixbuf * pixbuf);
static void sp_image_update_canvas_image (SPImage *image);
static GdkPixbuf * sp_image_repr_read_dataURI (const gchar * uri_data);
//g_message( "user_flush_data" );
}
-GdkPixbuf* pixbuf_new_from_file( const char *filename, GError **/*error*/ )
+static GdkPixbuf* pixbuf_new_from_file( const char *filename, time_t &modTime, gchar*& pixPath, GError **/*error*/ )
{
GdkPixbuf* buf = NULL;
PushPull youme;
gint dpiX = 0;
gint dpiY = 0;
+ modTime = 0;
+ if ( pixPath ) {
+ g_free(pixPath);
+ pixPath = 0;
+ }
//buf = gdk_pixbuf_new_from_file( filename, error );
dump_fopen_call( filename, "pixbuf_new_from_file" );
FILE* fp = fopen_utf8name( filename, "r" );
if ( fp )
{
+ {
+ struct stat st;
+ memset(&st, 0, sizeof(st));
+ int val = g_stat(filename, &st);
+ if ( !val ) {
+ modTime = st.st_mtime;
+ pixPath = g_strdup(filename);
+ }
+ }
+
GdkPixbufLoader *loader = gdk_pixbuf_loader_new();
if ( loader )
{
return buf;
}
+GdkPixbuf* pixbuf_new_from_file( const char *filename, GError **error )
+{
+ time_t modTime = 0;
+ gchar* pixPath = 0;
+ GdkPixbuf* result = pixbuf_new_from_file( filename, modTime, pixPath, error );
+ if (pixPath) {
+ g_free(pixPath);
+ }
+ return result;
+}
+
+
}
}
GType
sp_image_get_type (void)
{
- static GType image_type = 0;
- if (!image_type) {
- GTypeInfo image_info = {
- sizeof (SPImageClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) sp_image_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (SPImage),
- 16, /* n_preallocs */
- (GInstanceInitFunc) sp_image_init,
- NULL, /* value_table */
- };
- image_type = g_type_register_static (sp_item_get_type (), "SPImage", &image_info, (GTypeFlags)0);
- }
- return image_type;
+ static GType image_type = 0;
+ if (!image_type) {
+ GTypeInfo image_info = {
+ sizeof (SPImageClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) sp_image_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (SPImage),
+ 16, /* n_preallocs */
+ (GInstanceInitFunc) sp_image_init,
+ NULL, /* value_table */
+ };
+ image_type = g_type_register_static (sp_item_get_type (), "SPImage", &image_info, (GTypeFlags)0);
+ }
+ return image_type;
}
static void
sp_image_class_init (SPImageClass * klass)
{
- GObjectClass * gobject_class;
- SPObjectClass * sp_object_class;
- SPItemClass * item_class;
-
- gobject_class = (GObjectClass *) klass;
- sp_object_class = (SPObjectClass *) klass;
- item_class = (SPItemClass *) klass;
-
- parent_class = (SPItemClass*)g_type_class_ref (sp_item_get_type ());
-
- sp_object_class->build = sp_image_build;
- sp_object_class->release = sp_image_release;
- sp_object_class->set = sp_image_set;
- sp_object_class->update = sp_image_update;
- sp_object_class->write = sp_image_write;
-
- item_class->bbox = sp_image_bbox;
- item_class->print = sp_image_print;
- item_class->description = sp_image_description;
- item_class->show = sp_image_show;
- item_class->snappoints = sp_image_snappoints;
- item_class->set_transform = sp_image_set_transform;
+ GObjectClass * gobject_class;
+ SPObjectClass * sp_object_class;
+ SPItemClass * item_class;
+
+ gobject_class = (GObjectClass *) klass;
+ sp_object_class = (SPObjectClass *) klass;
+ item_class = (SPItemClass *) klass;
+
+ parent_class = (SPItemClass*)g_type_class_ref (sp_item_get_type ());
+
+ sp_object_class->build = sp_image_build;
+ sp_object_class->release = sp_image_release;
+ sp_object_class->set = sp_image_set;
+ sp_object_class->update = sp_image_update;
+ sp_object_class->write = sp_image_write;
+
+ item_class->bbox = sp_image_bbox;
+ item_class->print = sp_image_print;
+ item_class->description = sp_image_description;
+ item_class->show = sp_image_show;
+ item_class->snappoints = sp_image_snappoints;
+ item_class->set_transform = sp_image_set_transform;
}
-static void
-sp_image_init (SPImage *image)
+static void sp_image_init( SPImage *image )
{
- image->x.unset();
- image->y.unset();
- image->width.unset();
- image->height.unset();
- image->aspect_align = SP_ASPECT_NONE;
- image->curve = NULL;
+ image->x.unset();
+ image->y.unset();
+ image->width.unset();
+ image->height.unset();
+ image->aspect_align = SP_ASPECT_NONE;
+
+ image->trimx = 0;
+ image->trimy = 0;
+ image->trimwidth = 0;
+ image->trimheight = 0;
+ image->viewx = 0;
+ image->viewy = 0;
+ image->viewwidth = 0;
+ image->viewheight = 0;
+
+ image->curve = NULL;
+
+ image->href = 0;
+#if ENABLE_LCMS
+ image->color_profile = 0;
+#endif // ENABLE_LCMS
+ image->pixbuf = 0;
+ image->pixPath = 0;
+ image->lastMod = 0;
}
static void
@@ -591,38 +636,42 @@ sp_image_build (SPObject *object, SPDocument *document, Inkscape::XML::Node *rep
static void
sp_image_release (SPObject *object)
{
- SPImage *image;
-
- image = SP_IMAGE (object);
+ SPImage *image = SP_IMAGE(object);
- if (SP_OBJECT_DOCUMENT (object)) {
- /* Unregister ourselves */
- sp_document_remove_resource (SP_OBJECT_DOCUMENT (object), "image", SP_OBJECT (object));
- }
+ if (SP_OBJECT_DOCUMENT (object)) {
+ /* Unregister ourselves */
+ sp_document_remove_resource (SP_OBJECT_DOCUMENT (object), "image", SP_OBJECT (object));
+ }
- if (image->href) {
- g_free (image->href);
- image->href = NULL;
- }
+ if (image->href) {
+ g_free (image->href);
+ image->href = NULL;
+ }
- if (image->pixbuf) {
- gdk_pixbuf_unref (image->pixbuf);
- image->pixbuf = NULL;
- }
+ if (image->pixbuf) {
+ gdk_pixbuf_unref (image->pixbuf);
+ image->pixbuf = NULL;
+ }
#if ENABLE_LCMS
- if (image->color_profile) {
- g_free (image->color_profile);
- image->color_profile = NULL;
- }
+ if (image->color_profile) {
+ g_free (image->color_profile);
+ image->color_profile = NULL;
+ }
#endif // ENABLE_LCMS
+ if (image->pixPath) {
+ g_free(image->pixPath);
+ image->pixPath = 0;
+ }
+
if (image->curve) {
- image->curve = image->curve->unref();
- }
+ image->curve = image->curve->unref();
+ }
- if (((SPObjectClass *) parent_class)->release)
- ((SPObjectClass *) parent_class)->release (object);
+ if (((SPObjectClass *) parent_class)->release) {
+ ((SPObjectClass *) parent_class)->release (object);
+ }
}
static void
static void
sp_image_update (SPObject *object, SPCtx *ctx, unsigned int flags)
{
- SPImage *image;
-
- image = (SPImage *) object;
+ SPImage *image = SP_IMAGE(object);
SPDocument *doc = SP_OBJECT_DOCUMENT(object);
- if (((SPObjectClass *) (parent_class))->update)
- ((SPObjectClass *) (parent_class))->update (object, ctx, flags);
+ if (((SPObjectClass *) (parent_class))->update)
+ ((SPObjectClass *) (parent_class))->update (object, ctx, flags);
- if (flags & SP_IMAGE_HREF_MODIFIED_FLAG) {
- if (image->pixbuf) {
- gdk_pixbuf_unref (image->pixbuf);
- image->pixbuf = NULL;
- }
- if (image->href) {
- GdkPixbuf *pixbuf;
- pixbuf = sp_image_repr_read_image (
- object->repr->attribute("xlink:href"),
- object->repr->attribute("sodipodi:absref"),
- doc->base);
- if (pixbuf) {
- pixbuf = sp_image_pixbuf_force_rgba (pixbuf);
+ if (flags & SP_IMAGE_HREF_MODIFIED_FLAG) {
+ if (image->pixbuf) {
+ gdk_pixbuf_unref (image->pixbuf);
+ image->pixbuf = NULL;
+ }
+ if ( image->pixPath ) {
+ g_free(image->pixPath);
+ image->pixPath = 0;
+ }
+ image->lastMod = 0;
+ if (image->href) {
+ GdkPixbuf *pixbuf;
+ pixbuf = sp_image_repr_read_image (
+ image->lastMod,
+ image->pixPath,
+ object->repr->attribute("xlink:href"),
+ object->repr->attribute("sodipodi:absref"),
+ doc->base);
+ if (pixbuf) {
+ pixbuf = sp_image_pixbuf_force_rgba (pixbuf);
// BLIP
#if ENABLE_LCMS
if ( image->color_profile )
@@ -1105,12 +1159,16 @@ sp_image_show (SPItem *item, NRArena *arena, unsigned int /*key*/, unsigned int
*
*/
-GdkPixbuf *
-sp_image_repr_read_image (const gchar *href, const gchar *absref, const gchar *base)
+GdkPixbuf *sp_image_repr_read_image( time_t& modTime, char*& pixPath, const gchar *href, const gchar *absref, const gchar *base )
{
const gchar *filename, *docbase;
gchar *fullname;
GdkPixbuf *pixbuf;
+ modTime = 0;
+ if ( pixPath ) {
+ g_free(pixPath);
+ pixPath = 0;
+ }
filename = href;
if (filename != NULL) {
@@ -1118,7 +1176,7 @@ sp_image_repr_read_image (const gchar *href, const gchar *absref, const gchar *b
fullname = g_filename_from_uri(filename, NULL, NULL);
if (fullname) {
// TODO check this. Was doing a UTF-8 to filename conversion here.
- pixbuf = Inkscape::IO::pixbuf_new_from_file (fullname, NULL);
+ pixbuf = Inkscape::IO::pixbuf_new_from_file (fullname, modTime, pixPath, NULL);
if (pixbuf != NULL) return pixbuf;
}
} else if (strncmp (filename,"data:",5) == 0) {
@@ -1138,7 +1196,7 @@ sp_image_repr_read_image (const gchar *href, const gchar *absref, const gchar *b
// different dir) or unset (when doc is not saved yet), so we check for base+href existence first,
// and if it fails, we also try to use bare href regardless of its g_path_is_absolute
if (g_file_test (fullname, G_FILE_TEST_EXISTS) && !g_file_test (fullname, G_FILE_TEST_IS_DIR)) {
- pixbuf = Inkscape::IO::pixbuf_new_from_file( fullname, NULL );
+ pixbuf = Inkscape::IO::pixbuf_new_from_file( fullname, modTime, pixPath, NULL );
g_free (fullname);
if (pixbuf != NULL) return pixbuf;
}
@@ -1146,7 +1204,7 @@ sp_image_repr_read_image (const gchar *href, const gchar *absref, const gchar *b
/* try filename as absolute */
if (g_file_test (filename, G_FILE_TEST_EXISTS) && !g_file_test (filename, G_FILE_TEST_IS_DIR)) {
- pixbuf = Inkscape::IO::pixbuf_new_from_file( filename, NULL );
+ pixbuf = Inkscape::IO::pixbuf_new_from_file( filename, modTime, pixPath, NULL );
if (pixbuf != NULL) return pixbuf;
}
}
@@ -1161,7 +1219,7 @@ sp_image_repr_read_image (const gchar *href, const gchar *absref, const gchar *b
else
g_warning ("xlink:href did not resolve to a valid image file, now trying sodipodi:absref=\"%s\"", absref);
- pixbuf = Inkscape::IO::pixbuf_new_from_file( filename, NULL );
+ pixbuf = Inkscape::IO::pixbuf_new_from_file( filename, modTime, pixPath, NULL );
if (pixbuf != NULL) return pixbuf;
}
/* Nope: We do not find any valid pixmap file :-( */
return NULL;
}
+void sp_image_refresh_if_outdated( SPImage* image )
+{
+ if ( image->href && image->lastMod ) {
+ // It *might* change
+
+ struct stat st;
+ memset(&st, 0, sizeof(st));
+ int val = g_stat(image->pixPath, &st);
+ if ( !val ) {
+ // stat call worked. Check time now
+ if ( st.st_mtime != image->lastMod ) {
+ SPCtx *ctx = 0;
+ unsigned int flags = SP_IMAGE_HREF_MODIFIED_FLAG;
+ sp_image_update(image, ctx, flags);
+ }
+ }
+ }
+}
+
/*
Local Variables:
mode:c++
diff --git a/src/sp-image.h b/src/sp-image.h
index 75194174ef11f8bba8ce67ab3ab8d6819f0f7293..7b00e0da360601240f871a23e8d2027b360ed6d0 100644 (file)
--- a/src/sp-image.h
+++ b/src/sp-image.h
#define SP_IMAGE_HREF_MODIFIED_FLAG SP_OBJECT_USER_MODIFIED_FLAG_A
struct SPImage : public SPItem {
- SVGLength x;
- SVGLength y;
- SVGLength width;
- SVGLength height;
-
- // Added by EAF
- /* preserveAspectRatio */
- unsigned int aspect_align : 4;
- unsigned int aspect_clip : 1;
- int trimx, trimy, trimwidth, trimheight;
- double viewx, viewy, viewwidth, viewheight;
-
- SPCurve *curve; // This curve is at the image's boundary for snapping
-
- gchar *href;
+ SVGLength x;
+ SVGLength y;
+ SVGLength width;
+ SVGLength height;
+
+ // Added by EAF
+ /* preserveAspectRatio */
+ unsigned int aspect_align : 4;
+ unsigned int aspect_clip : 1;
+ int trimx, trimy, trimwidth, trimheight;
+ double viewx, viewy, viewwidth, viewheight;
+
+ SPCurve *curve; // This curve is at the image's boundary for snapping
+
+ gchar *href;
#if ENABLE_LCMS
- gchar *color_profile;
+ gchar *color_profile;
#endif // ENABLE_LCMS
- GdkPixbuf *pixbuf;
+ GdkPixbuf *pixbuf;
+ gchar *pixPath;
+ time_t lastMod;
};
struct SPImageClass {
- SPItemClass parent_class;
+ SPItemClass parent_class;
};
GType sp_image_get_type (void);
/* Return duplicate of curve or NULL */
SPCurve *sp_image_get_curve (SPImage *image);
+void sp_image_refresh_if_outdated( SPImage* image );
#endif
index bb18d7422be8b77b072193d4c84e0f3f7fade850..442eb5ef63593f873715fde04c48438ccd8eea56 100644 (file)
--- a/src/ui/context-menu.cpp
+++ b/src/ui/context-menu.cpp
#include "../xml/repr.h"
#include "desktop.h"
#include "document.h"
+#include "message-stack.h"
#include "ui/dialog/dialog-manager.h"
static void sp_object_type_menu(GType type, SPObject *object, SPDesktop *desktop, GtkMenu *menu);
/* Image */
static void sp_image_image_properties(GtkMenuItem *menuitem, SPAnchor *anchor);
+static void sp_image_image_edit(GtkMenuItem *menuitem, SPAnchor *anchor);
static void
sp_image_menu(SPObject *object, SPDesktop *desktop, GtkMenu *m)
{
- SPItem *item;
+ SPItem *item = SP_ITEM(object);
GtkWidget *w;
- item = (SPItem *) object;
-
/* Link dialog */
w = gtk_menu_item_new_with_mnemonic(_("Image _Properties"));
gtk_object_set_data(GTK_OBJECT(w), "desktop", desktop);
gtk_signal_connect(GTK_OBJECT(w), "activate", GTK_SIGNAL_FUNC(sp_image_image_properties), item);
gtk_widget_show(w);
gtk_menu_append(GTK_MENU(m), w);
+
+ w = gtk_menu_item_new_with_mnemonic(_("Edit Image..."));
+ gtk_object_set_data(GTK_OBJECT(w), "desktop", desktop);
+ gtk_signal_connect(GTK_OBJECT(w), "activate", GTK_SIGNAL_FUNC(sp_image_image_edit), item);
+ gtk_widget_show(w);
+ gtk_menu_append(GTK_MENU(m), w);
+ Inkscape::XML::Node *ir = SP_OBJECT_REPR(object);
+ const gchar *href = ir->attribute("xlink:href");
+ if ( (!href) || ((strncmp(href, "data:", 5) == 0)) ) {
+ gtk_widget_set_sensitive( w, FALSE );
+ }
}
static void
sp_object_attributes_dialog(SP_OBJECT(anchor), "Image");
}
+#define EDIT_APP "gimp"
+//#define EDIT_APP "krita"
+static void sp_image_image_edit(GtkMenuItem *menuitem, SPAnchor *anchor)
+{
+ SPObject* obj = SP_OBJECT(anchor);
+ Inkscape::XML::Node *ir = SP_OBJECT_REPR(obj);
+ const gchar *href = ir->attribute("xlink:href");
+
+ GError* errThing = 0;
+ gchar const* args[] = {EDIT_APP, href, 0};
+ g_spawn_async(0, // working dir
+ const_cast<gchar **>(args),
+ 0, //envp
+ G_SPAWN_SEARCH_PATH,
+ 0, // child_setup
+ 0, // user_data
+ 0, //GPid *child_pid
+ &errThing);
+ if ( errThing ) {
+ g_warning("Problem launching editor (%d). %s", errThing->code, errThing->message);
+ SPDesktop *desktop = (SPDesktop*)gtk_object_get_data(GTK_OBJECT(menuitem), "desktop");
+ desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, errThing->message);
+ g_error_free(errThing);
+ errThing = 0;
+ }
+}
+
/* SPShape */
static void
index df35f07f7eb7ff382f9da29d23c3a6a8a5bfb47f..3fd0e529ef54c544b2d13ad0d8166991ec5edea7 100644 (file)
#include "color-profile-fns.h"
#include "xml/node-observer.h"
#include "box3d-context.h"
+#include "sp-image.h"
#if defined (SOLARIS_2_8)
#include "round.h"
style = gtk_style_copy (GTK_WIDGET (dtw->canvas)->style);
style->bg[GTK_STATE_NORMAL] = style->white;
gtk_widget_set_style (GTK_WIDGET (dtw->canvas), style);
- if ( prefs_get_int_attribute ("options.useextinput", "value", 1) )
+ if ( prefs_get_int_attribute ("options.useextinput", "value", 1) )
gtk_widget_set_extension_events(GTK_WIDGET (dtw->canvas) , GDK_EXTENSION_EVENTS_ALL); //set extension events for tablets, unless disabled in preferences
g_signal_connect (G_OBJECT (dtw->canvas), "event", G_CALLBACK (sp_desktop_widget_event), dtw);
gtk_table_attach (GTK_TABLE (canvas_tbl), GTK_WIDGET(dtw->canvas), 1, 2, 1, 2, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), 0, 0);
{
/* The viewbox (in integers) must exactly match the size of SPCanvasbuf's pixel buffer.
* This is important because the former is being used for drawing the ruler, whereas
- * the latter is used for drawing e.g. the grids and guides. Only when the viewbox
+ * the latter is used for drawing e.g. the grids and guides. Only when the viewbox
* coincides with the pixel buffer, everything will line up nicely.
- */
+ */
NR::IRect viewbox = dtw->canvas->getViewboxIntegers();
-
+
double const scale = dtw->desktop->current_zoom();
double s = viewbox.min()[NR::X] / scale - dtw->ruler_origin[NR::X];
double e = viewbox.max()[NR::X] / scale - dtw->ruler_origin[NR::X];
{
/* The viewbox (in integers) must exactly match the size of SPCanvasbuf's pixel buffer.
* This is important because the former is being used for drawing the ruler, whereas
- * the latter is used for drawing e.g. the grids and guides. Only when the viewbox
+ * the latter is used for drawing e.g. the grids and guides. Only when the viewbox
* coincides with the pixel buffer, everything will line up nicely.
*/
NR::IRect viewbox = dtw->canvas->getViewboxIntegers();
-
+
double const scale = dtw->desktop->current_zoom();
double s = viewbox.min()[NR::Y] / -scale - dtw->ruler_origin[NR::Y];
double e = viewbox.max()[NR::Y] / -scale - dtw->ruler_origin[NR::Y];
@@ -1430,7 +1431,7 @@ sp_desktop_widget_adjustment_value_changed (GtkAdjustment */*adj*/, SPDesktopWid
sp_desktop_widget_update_rulers (dtw);
/* update perspective lines if we are in the 3D box tool (so that infinite ones are shown correctly) */
- sp_box3d_context_update_lines(dtw->desktop->event_context);
+ sp_box3d_context_update_lines(dtw->desktop->event_context);
dtw->update = 0;
}
@@ -1438,6 +1439,14 @@ sp_desktop_widget_adjustment_value_changed (GtkAdjustment */*adj*/, SPDesktopWid
/* we make the desktop window with focus active, signal is connected in interface.c */
bool SPDesktopWidget::onFocusInEvent(GdkEventFocus*)
{
+ {
+ GSList const *imageList = sp_document_get_resource_list(desktop->doc(), "image");
+ for (GSList const *p = imageList; p; p = p->next) {
+ SPImage* image = SP_IMAGE(p->data);
+ sp_image_refresh_if_outdated( image );
+ }
+ }
+
inkscape_activate_desktop (desktop);
return false;