From 179fa413b047bede6e32109e2ce82437c5fb8d34 Mon Sep 17 00:00:00 2001 From: MenTaLguY Date: Mon, 16 Jan 2006 02:36:01 +0000 Subject: moving trunk for module inkscape (bzr r1) --- src/ui/widget/imageicon.cpp | 442 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 442 insertions(+) create mode 100644 src/ui/widget/imageicon.cpp (limited to 'src/ui/widget/imageicon.cpp') diff --git a/src/ui/widget/imageicon.cpp b/src/ui/widget/imageicon.cpp new file mode 100644 index 000000000..6a817e30d --- /dev/null +++ b/src/ui/widget/imageicon.cpp @@ -0,0 +1,442 @@ +/* + * A simple image display widget, using Inkscape's own rendering engine + * + * Authors: + * Bob Jamison + * Other dudes from The Inkscape Organization + * + * Copyright (C) 2004 The Inkscape Organization + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + + + +#include "imageicon.h" +#include +#include "svg-view-widget.h" +#include "document.h" +#include "inkscape.h" + + +namespace Inkscape +{ +namespace UI +{ +namespace Widget +{ + + + +typedef enum { + SVG_TYPES, + IMPORT_TYPES, + EXPORT_TYPES + } FileDialogType; + + +/*######################################################################### +### ImageIcon widget +#########################################################################*/ + + +/** + * Constructor + */ +ImageIcon::ImageIcon() +{ + init(); +} + +/** + * Construct from a file name + */ +ImageIcon::ImageIcon(const Glib::ustring &fileName) +{ + init(); + showSvgFile(fileName); +} + +/** + * Copy Constructor + */ +ImageIcon::ImageIcon(const ImageIcon &other) + : sigc::trackable(), Glib::ObjectBase(), Gtk::VBox() +{ + init(); + document = other.document; + viewerGtkmm = other.viewerGtkmm; + showingBrokenImage = other.showingBrokenImage; +} + +/** + * Destructor + */ +ImageIcon::~ImageIcon() +{ + if (document) + sp_document_unref(document); +} + + +/** + * basic initialization, called by the various constructors + */ +void ImageIcon::init() +{ + if (!INKSCAPE) + inkscape_application_init("",false); + document = NULL; + viewerGtkmm = NULL; + //set_size_request(150,150); + showingBrokenImage = false; +} + + +bool ImageIcon::showSvgDocument(const SPDocument *docArg) +{ + + if (document) + sp_document_unref(document); + + SPDocument *doc = (SPDocument *)docArg; + + sp_document_ref(doc); + document = doc; + + //This should remove it from the box, and free resources + //if (viewerGtkmm) + // viewerGtkmm->destroy(); + + GtkWidget *viewerGtk = sp_svg_view_widget_new(doc); + viewerGtkmm = Glib::wrap(viewerGtk); + + viewerGtkmm->show(); + pack_start(*viewerGtkmm, TRUE, TRUE, 0); + + //GtkWidget *vbox = (GtkWidget *)gobj(); + //gtk_box_pack_start(GTK_BOX(vbox), viewerGtk, TRUE, TRUE, 0); + + return true; +} + +bool ImageIcon::showSvgFile(const Glib::ustring &theFileName) +{ + Glib::ustring fileName = theFileName; + + fileName = Glib::filename_to_utf8(fileName); + + SPDocument *doc = sp_document_new (fileName.c_str(), 0); + if (!doc) { + g_warning("SVGView: error loading document '%s'\n", fileName.c_str()); + return false; + } + + showSvgDocument(doc); + + sp_document_unref(doc); + + return true; +} + + + +bool ImageIcon::showSvgFromMemory(const char *xmlBuffer) +{ + if (!xmlBuffer) + return false; + + gint len = (gint)strlen(xmlBuffer); + SPDocument *doc = sp_document_new_from_mem(xmlBuffer, len, 0); + if (!doc) { + g_warning("SVGView: error loading buffer '%s'\n",xmlBuffer); + return false; + } + + showSvgDocument(doc); + + sp_document_unref(doc); + + return true; +} + + + +bool ImageIcon::showBitmap(const Glib::ustring &theFileName) +{ + Glib::ustring fileName = theFileName; + + + /*##################################### + # LET'S HAVE SOME FUN WITH SVG! + # Instead of just loading an image, why + # don't we make a lovely little svg and + # display it nicely? + #####################################*/ + + //Arbitrary size of svg doc -- rather 'portrait' shaped + gint previewWidth = 400; + gint previewHeight = 600; + + //Get some image info. Smart pointer does not need to be deleted + Glib::RefPtr img = Gdk::Pixbuf::create_from_file(fileName); + gint imgWidth = img->get_width(); + gint imgHeight = img->get_height(); + + //Find the minimum scale to fit the image inside the preview area + double scaleFactorX = (0.9 *(double)previewWidth) / ((double)imgWidth); + double scaleFactorY = (0.9 *(double)previewHeight) / ((double)imgHeight); + double scaleFactor = scaleFactorX; + if (scaleFactorX > scaleFactorY) + scaleFactor = scaleFactorY; + + //Now get the resized values + gint scaledImgWidth = (int) (scaleFactor * (double)imgWidth); + gint scaledImgHeight = (int) (scaleFactor * (double)imgHeight); + + //center the image on the area + gint imgX = (previewWidth - scaledImgWidth) / 2; + gint imgY = (previewHeight - scaledImgHeight) / 2; + + //wrap a rectangle around the image + gint rectX = imgX-1; + gint rectY = imgY-1; + gint rectWidth = scaledImgWidth +2; + gint rectHeight = scaledImgHeight+2; + + //Our template. Modify to taste + gchar const *xformat = + "\n" + "\n" + "\n" + "\n" + "\n" + "\n\n"; + + //if (!Glib::get_charset()) //If we are not utf8 + fileName = Glib::filename_to_utf8(fileName); + + //Fill in the template + /* FIXME: Do proper XML quoting for fileName. */ + gchar *xmlBuffer = g_strdup_printf(xformat, + previewWidth, previewHeight, + imgX, imgY, scaledImgWidth, scaledImgHeight, + fileName.c_str(), + rectX, rectY, rectWidth, rectHeight); + + //g_message("%s\n", xmlBuffer); + + //now show it! + showSvgFromMemory(xmlBuffer); + g_free(xmlBuffer); + + return true; +} + + + +void ImageIcon::showBrokenImage(const Glib::ustring &errorMessage) +{ + //Are we already showing it? + if (showingBrokenImage) + return; + + //Our template. Modify to taste + gchar const *xformat = + "" + "" + "" + " " + " " + " " + " " + " " + " " + " %s" + ""; + + //Fill in the template + char *cErrorMessage = (char *)errorMessage.c_str(); + gchar *xmlBuffer = g_strdup_printf(xformat, cErrorMessage); + + //g_message("%s\n", xmlBuffer); + + //now show it! + showSvgFromMemory(xmlBuffer); + g_free(xmlBuffer); + showingBrokenImage = true; + +} + + + +static bool +hasSuffix(const Glib::ustring &str, Glib::ustring &ext) +{ + int strLen = str.length(); + int extLen = ext.length(); + if (extLen > strLen) + { + return false; + } + int strpos = strLen-1; + for (int extpos = extLen-1 ; extpos>=0 ; extpos--, strpos--) + { + Glib::ustring::value_type ch = str[strpos]; + if (ch != ext[extpos]) + { + if ( ((ch & 0xff80) != 0) || + static_cast( g_ascii_tolower( static_cast(0x07f & ch) ) ) != ext[extpos] ) + { + return false; + } + } + } + return true; +} + + +/** + * Return true if the image is loadable by Gdk, else false + */ +static bool +isValidImageIconFile(const Glib::ustring &fileName) +{ + std::vectorformats = Gdk::Pixbuf::get_formats(); + for (unsigned int i=0; iextensions = format.get_extensions(); + for (unsigned int j=0; j 0x150000L) + { + Glib::ustring err = "File too large"; + showBrokenImage(err); + return false; + } + } + + Glib::ustring svg = ".svg"; + Glib::ustring svgz = ".svgz"; + + if (hasSuffix(fileName, svg) || hasSuffix(fileName, svgz) ) + { + if (!showSvgFile(fileName)) + { + showBrokenImage(bitmapError); + return false; + } + return true; + } + else if (isValidImageIconFile(fileName)) + { + if (!showBitmap(fileName)) + { + showBrokenImage(bitmapError); + return false; + } + return true; + } + else + { + showBrokenImage("unsupported file type"); + return false; + } +} + + + + + + + +} // namespace Widget +} // namespace UI +} // namespace Inkscape + + +/*######################################################################### +### E N D O F F I L E +#########################################################################*/ + + + -- cgit v1.2.3