Code

Pot and Dutch translation update
[inkscape.git] / src / extension / internal / gdkpixbuf-input.cpp
1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4 #include <glib/gprintf.h>
5 #include <glibmm/i18n.h>
6 #include "document-private.h"
7 #include <dir-util.h>
8 #include "extension/input.h"
9 #include "extension/system.h"
10 #include "gdkpixbuf-input.h"
11 #include "selection-chemistry.h"
12 #include "sp-image.h"
14 namespace Inkscape {
16 namespace IO {
17 GdkPixbuf* pixbuf_new_from_file( char const *utf8name, GError **error );
18 }
20 namespace Extension {
21 namespace Internal {
23 static std::set<Glib::ustring> create_lossy_set()
24 {
25     std::set<Glib::ustring> lossy;
26     lossy.insert(".jpg");
27     lossy.insert(".jpeg");
28     return lossy;
29 }
31 SPDocument *
32 GdkpixbufInput::open(Inkscape::Extension::Input *mod, char const *uri)
33 {
34     bool embed = (strcmp(mod->get_param_optiongroup("link"), "embed") == 0);
36     SPDocument *doc = NULL;
37     GdkPixbuf *pb = Inkscape::IO::pixbuf_new_from_file( uri, NULL );
38     static std::set<Glib::ustring> lossy = create_lossy_set();
40     if (pb) {         /* We are readable */
41         bool is_lossy;
42         Glib::ustring mime_type, ext;
43         Glib::ustring u = uri;
44         std::size_t dotpos = u.rfind('.');
45         if (dotpos != Glib::ustring::npos) {
46             ext = u.substr(dotpos, Glib::ustring::npos);
47         }
49         // HACK: replace with something better based on GIO
50         if (!ext.empty() && lossy.find(ext) != lossy.end()) {
51             is_lossy = true;
52             mime_type = "image/jpeg";
53         } else {
54             is_lossy = false;
55             mime_type = "image/png";
56         }
58         doc = sp_document_new(NULL, TRUE, TRUE);
59         bool saved = sp_document_get_undo_sensitive(doc);
60         sp_document_set_undo_sensitive(doc, false); // no need to undo in this temporary document
62         double width = gdk_pixbuf_get_width(pb);
63         double height = gdk_pixbuf_get_height(pb);
64         gchar const *str = gdk_pixbuf_get_option( pb, "Inkscape::DpiX" );
65         if ( str ) {
66             gint dpi = atoi(str);
67             if ( dpi > 0 && dpi != 72 ) {
68                 double scale = 72.0 / (double)dpi;
69                 width *= scale;
70             }
71         }
72         str = gdk_pixbuf_get_option( pb, "Inkscape::DpiY" );
73         if ( str ) {
74             gint dpi = atoi(str);
75             if ( dpi > 0 && dpi != 72 ) {
76                 double scale = 72.0 / (double)dpi;
77                 height *= scale;
78             }
79         }
81         // Create image node
82         Inkscape::XML::Document *xml_doc = sp_document_repr_doc(doc);
83         Inkscape::XML::Node *image_node = xml_doc->createElement("svg:image");
84         sp_repr_set_svg_double(image_node, "width", width);
85         sp_repr_set_svg_double(image_node, "height", height);
87         if (embed) {
88             sp_embed_image(image_node, pb, mime_type);
89         } else {
90             // convert filename to uri
91             gchar* _uri = g_filename_to_uri(uri, NULL, NULL);
92             if(_uri) {
93                 image_node->setAttribute("xlink:href", _uri);
94                 g_free(_uri);
95             } else {
96                 image_node->setAttribute("xlink:href", uri);
97             }
98         }
100         g_object_unref(pb);
102         // Add it to the current layer
103         SP_DOCUMENT_ROOT(doc)->appendChildRepr(image_node);
104         Inkscape::GC::release(image_node);
105         fit_canvas_to_drawing(doc);
106         // restore undo, as now this document may be shown to the user if a bitmap was opened
107         sp_document_set_undo_sensitive(doc, saved);
108     } else {
109         printf("GdkPixbuf loader failed\n");
110     }
112     return doc;
115 #include "clear-n_.h"
117 void
118 GdkpixbufInput::init(void)
120     GSList * formatlist, * formatlisthead;
122     /* \todo I'm not sure if I need to free this list */
123     for (formatlist = formatlisthead = gdk_pixbuf_get_formats();
124          formatlist != NULL;
125          formatlist = g_slist_next(formatlist)) {
127         GdkPixbufFormat *pixformat = (GdkPixbufFormat *)formatlist->data;
129         gchar *name =        gdk_pixbuf_format_get_name(pixformat);
130         gchar *description = gdk_pixbuf_format_get_description(pixformat);
131         gchar **extensions =  gdk_pixbuf_format_get_extensions(pixformat);
132         gchar **mimetypes =   gdk_pixbuf_format_get_mime_types(pixformat);
134         for (int i = 0; extensions[i] != NULL; i++) {
135         for (int j = 0; mimetypes[j] != NULL; j++) {
137             /* thanks but no thanks, we'll handle SVG extensions... */
138             if (strcmp(extensions[i], "svg") == 0) {
139                 continue;
140             }
141             if (strcmp(extensions[i], "svgz") == 0) {
142                 continue;
143             }
144             if (strcmp(extensions[i], "svg.gz") == 0) {
145                 continue;
146             }
147             gchar *caption = g_strdup_printf(_("%s GDK pixbuf Input"), name);
148             gchar *xmlString = g_strdup_printf(
149                 "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
150                     "<name>%s</name>\n"
151                     "<id>org.inkscape.input.gdkpixbuf.%s</id>\n"
152                     "<param name='link' type='optiongroup'  appearance='full' _gui-text='" N_("Link or embed image:") "' >\n"
153                         "<_option value='embed'>" N_("embed") "</_option>\n"
154                         "<_option value='link'>" N_("link") "</_option>\n"
155                     "</param>\n"
156                     "<_param name='help' type='description'>" N_("Embed results in stand-alone, larger SVG files. Link references a file outside this SVG document and all files must be moved together.") "</_param>\n"
157                     "<input>\n"
158                         "<extension>.%s</extension>\n"
159                         "<mimetype>%s</mimetype>\n"
160                         "<filetypename>%s (*.%s)</filetypename>\n"
161                         "<filetypetooltip>%s</filetypetooltip>\n"
162                     "</input>\n"
163                 "</inkscape-extension>",
164                 caption,
165                 extensions[i],
166                 extensions[i],
167                 mimetypes[j],
168                 name,
169                 extensions[i],
170                 description
171                 );
173             Inkscape::Extension::build_from_mem(xmlString, new GdkpixbufInput());
174             g_free(xmlString);
175             g_free(caption);
176         }}
178         g_free(name);
179         g_free(description);
180         g_strfreev(mimetypes);
181         g_strfreev(extensions);
182     }
184     g_slist_free(formatlisthead);
187 } } }  /* namespace Inkscape, Extension, Implementation */
189 /*
190   Local Variables:
191   mode:c++
192   c-file-style:"stroustrup"
193   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
194   indent-tabs-mode:nil
195   fill-column:99
196   End:
197 */
198 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :