/* * GChemPaint GOffice component * gchempaint.cc * * Copyright (C) 2005-2006 Jean Bréfort * * 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 2 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, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA */ #include "gchempaint-config.h" #include "gchempaint-priv.h" #include "gofficeapp.h" #include "lib/theme.h" #include #include #include #include #include #include #include gcpGOfficeApplication *app; extern "C" { extern GOPluginModuleDepend const go_plugin_depends [] = { { "goffice", GOFFICE_API_VERSION } }; extern GOPluginModuleHeader const go_plugin_header = { GOFFICE_MODULE_PLUGIN_MAGIC_NUMBER, G_N_ELEMENTS (go_plugin_depends) }; static GObjectClass *gogcp_parent_klass; static gboolean go_gchempaint_component_get_data (GOComponent *component, gpointer *data, int *length, void (**clearfunc) (gpointer), gpointer *user_data) { GOGChemPaintComponent *gogcp = GO_GCHEMPAINT_COMPONENT (component); xmlDocPtr xml = NULL; char *old_num_locale, *old_time_locale; bool result; if (!gogcp->document || !gogcp->document->HasChildren ()) { *data = NULL; *length = 0; * clearfunc = NULL; return true; } old_num_locale = g_strdup (setlocale (LC_NUMERIC, NULL)); setlocale(LC_NUMERIC, "C"); old_time_locale = g_strdup (setlocale (LC_TIME, NULL)); setlocale (LC_TIME, "C"); try { xml = gogcp->document->BuildXMLTree (); xmlChar *mem; int size; xmlDocDumpMemory (xml, &mem, &size); xmlFreeDoc (xml); *data = mem; *length = size; *clearfunc = xmlFree; result = true; } catch (int) { if (xml) xmlFreeDoc (xml); xml = NULL; // Error (SAVE); result = false; } setlocale (LC_NUMERIC, old_num_locale); g_free (old_num_locale); setlocale (LC_TIME, old_time_locale); g_free (old_time_locale); return result; } static void go_gchempaint_component_set_data (GOComponent *component) { GOGChemPaintComponent *gogcp = GO_GCHEMPAINT_COMPONENT (component); gogcp->document = app->ImportDocument (component->mime_type, component->data, component->length); gcpTheme *pTheme = gogcp->document->GetTheme (); GtkWidget *w = gogcp->document->GetWidget (); gnome_canvas_update_now (GNOME_CANVAS (w)); ArtDRect rect; gcpWidgetData *pData = (gcpWidgetData*)g_object_get_data(G_OBJECT(w), "data"); pData->GetObjectBounds (gogcp->document, &rect); double y = gogcp->document->GetYAlign (); y += gogcp->document->GetView ()->GetBaseLineOffset (); y *= pTheme->GetZoomFactor (); if (rect.x0 || rect.y0) gogcp->document->Move (- rect.x0 / pTheme->GetZoomFactor (), - rect.y0 / pTheme->GetZoomFactor ()); gogcp->document->GetView ()->Update (gogcp->document); if (y < rect.y0) y = rect.y1; component->ascent = (y - rect.y0) / 96.; component->descent = (rect.y1 - y) / 96.; component->width = (rect.x1 - rect.x0) / 96.; } static void go_gchempaint_component_draw (GOComponent *component, int width_pixels, int height_pixels) { GOGChemPaintComponent *gogcp = GO_GCHEMPAINT_COMPONENT (component); // GnomeCanvas does not support alpha channel, so we must use a 24bits pixbuf // and then copy the pixels. int i = gdk_pixbuf_get_width (component->pixbuf), j = gdk_pixbuf_get_height (component->pixbuf), k; GdkPixbuf *pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, false, 8, i, j); int srowstride = gdk_pixbuf_get_rowstride (pixbuf), drowstride = gdk_pixbuf_get_rowstride (component->pixbuf); guint32 *dest; guint8 *src, *sline, *dline = gdk_pixbuf_get_pixels (component->pixbuf); if (!gogcp->document) { gdk_pixbuf_fill (component->pixbuf, 0); return; } gdk_pixbuf_fill (pixbuf, 0xffffffff); GtkWidget *w = gogcp->document->GetWidget (); gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (w), (double) width_pixels / component->width / 96.); gnome_canvas_update_now (GNOME_CANVAS (w)); gcpWidgetData *pData = (gcpWidgetData*)g_object_get_data(G_OBJECT(w), "data"); GnomeCanvasBuf buf; buf.buf = sline = gdk_pixbuf_get_pixels (pixbuf); buf.rect.x0 = 0; buf.rect.x1 = i; buf.rect.y0 = 0; buf.rect.y1 = j; buf.buf_rowstride = gdk_pixbuf_get_rowstride (pixbuf); buf.bg_color = 0xffffff; buf.is_buf = 1; (* GNOME_CANVAS_ITEM_GET_CLASS (pData->Group)->render) (GNOME_CANVAS_ITEM (pData->Group), &buf); while (j-- > 0) { k = i; dest = (guint32*) dline; src = sline; while (k-- > 0) { *dest = *((guint32*) src); *dest |=0xff000000; dest++; src += 3; } sline += srowstride; dline += drowstride; } } static void go_gchempaint_component_print (GOComponent *component, GnomePrintContext *gpc, double width, double height) { GOGChemPaintComponent *gogcp = GO_GCHEMPAINT_COMPONENT (component); if (!gogcp->document) return; GtkWidget *w = gogcp->document->GetWidget (); gnome_canvas_update_now (GNOME_CANVAS (w)); gogcp->document->Print(gpc, width, height); } static gboolean go_gchempaint_component_edit (GOComponent *component) { GOGChemPaintComponent *gogcp = GO_GCHEMPAINT_COMPONENT (component); if (!gogcp->document) { component->ascent = 1.; component->descent = 0.; component->width = 1.; } if (gogcp->window) { gogcp->window->Show (); return true; } return app->EditDocument (gogcp); } static void go_gchempaint_component_finalize (GObject *obj) { GOGChemPaintComponent *gogcp = GO_GCHEMPAINT_COMPONENT (obj); if (gogcp->window) gogcp->window->Destroy (); G_OBJECT_CLASS (gogcp_parent_klass)->finalize (obj); } static void go_gchempaint_component_init (GOComponent *component) { component->resizable = false; component->editable = true; component->window = NULL; component->ascent = 1.; component->descent = 0.; component->width = 1.; } static void go_gchempaint_component_class_init (GOComponentClass *klass) { GObjectClass *obj_klass = (GObjectClass *) klass; obj_klass->finalize = go_gchempaint_component_finalize; gogcp_parent_klass = (GObjectClass*) g_type_class_peek_parent (klass); klass->get_data = go_gchempaint_component_get_data; klass->set_data = go_gchempaint_component_set_data; klass->draw = go_gchempaint_component_draw; klass->print = go_gchempaint_component_print; klass->edit = go_gchempaint_component_edit; } GSF_DYNAMIC_CLASS (GOGChemPaintComponent, go_gchempaint_component, go_gchempaint_component_class_init, go_gchempaint_component_init, GO_COMPONENT_TYPE) /*************************************************************************************/ G_MODULE_EXPORT void go_plugin_init (GOPlugin *plugin, GOCmdContext *cc) { bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); #ifdef ENABLE_NLS bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); #endif GTypeModule *module = go_plugin_get_type_module (plugin); go_gchempaint_component_register_type (module); go_components_set_mime_suffix ("application/x-gchempaint", "*.gchempaint"); app = new gcpGOfficeApplication (); } G_MODULE_EXPORT void go_plugin_shutdown (GOPlugin *plugin, GOCmdContext *cc) { delete app; } } // extern "C"