1 // -*- C++ -*-
2
3 /*
4 * Gnome Chemistry Utils
5 * gcu/loader.cc
6 *
7 * Copyright (C) 2007-2011 Jean Bréfort <jean.brefort@normalesup.org>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 3 of the
12 * License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
22 * USA
23 */
24
25 #include "config.h"
26 #include "application.h"
27 #include "cmd-context.h"
28 #include "document.h"
29 #include "loader.h"
30 #include <gsf/gsf-impl-utils.h>
31 #include <glib/gi18n-lib.h>
32 #include <cstring>
33
34 using namespace std;
35
36 namespace gcu {
37
38 static map<string, LoaderStruct> loaders;
39 static map<string, GOPluginService *> services;
40
41 #define GCU_PLUGIN_SERVICE_CHEMICAL_LOADER_TYPE (plugin_service_chemical_loader_get_type ())
42 #define GCU_PLUGIN_SERVICE_CHEMICAL_LOADER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GCU_PLUGIN_SERVICE_CHEMICAL_LOADER_TYPE, PluginServiceChemicalLoader))
43 #define IS_GCU_PLUGIN_SERVICE_CHEMICAL_LOADER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GCU_PLUGIN_SERVICE_CHEMICAL_LOADER_TYPE))
44
45 GType plugin_service_chemical_loader_get_type (void);
46 typedef struct {
47 GOPluginServiceSimple base;
48
49 } PluginServiceChemicalLoader;
50 typedef GOPluginServiceSimpleClass PluginServiceChemicalLoaderClass;
51
52 static void
plugin_service_chemical_loader_read_xml(GOPluginService * service,xmlNode * tree,GOErrorInfo ** ret_error)53 plugin_service_chemical_loader_read_xml (GOPluginService * service, xmlNode * tree,
54 GOErrorInfo ** ret_error)
55 {
56 xmlNode *ptr;
57
58 g_return_if_fail (service->id != NULL);
59
60 for (ptr = tree->xmlChildrenNode; ptr != NULL; ptr = ptr->next)
61 if (0 == xmlStrcmp (ptr->name, (xmlChar const *) "mime_type"))
62 {
63 char *name = (char *) xmlGetProp (ptr, (xmlChar const *) "name");
64 if (name) {
65 if (loaders.find (name) != loaders.end ()) {
66 *ret_error = go_error_info_new_printf ("Duplicate loader for mime type %s", name);
67 xmlFree (name);
68 return;
69 }
70 LoaderStruct l;
71 l.read = l.write = l.supports2D = l.supports3D = l.supportsCrystals = l.supportsSpectra = false;
72 l.loader = NULL;
73 char *prop = (char *) xmlGetProp (ptr, (xmlChar const *) "capabilities");
74 if (prop) {
75 if (strchr (prop, 'r') != NULL)
76 l.read = true;
77 if (strchr (prop, 'w') != NULL)
78 l.write = true;
79 xmlFree (prop);
80 }
81 prop = (char *) xmlGetProp (ptr, (xmlChar const *) "scope");
82 if (prop) {
83 if (strchr (prop, '2') != NULL)
84 l.supports2D = true;
85 if (strchr (prop, '3') != NULL)
86 l.supports3D = true;
87 if (strchr (prop, 'c') != NULL || strchr (prop, 'C') != NULL)
88 l.supportsCrystals = true;
89 if (strchr (prop, 's') != NULL || strchr (prop, 'S') != NULL)
90 l.supportsSpectra = true;
91 xmlFree (prop);
92 }
93 loaders[name] = l;
94 services[name] = service;
95 xmlFree (name);
96 }
97 }
98 }
99
100 static char *
plugin_service_chemical_loader_get_description(G_GNUC_UNUSED GOPluginService * service)101 plugin_service_chemical_loader_get_description (G_GNUC_UNUSED GOPluginService * service)
102 {
103 return g_strdup (_("Chemical file loader type."));
104 }
105
106 static void
plugin_service_chemical_loader_class_init(GObjectClass * gobject_class)107 plugin_service_chemical_loader_class_init (GObjectClass *gobject_class)
108 {
109 GOPluginServiceClass *plugin_service_class = GO_PLUGIN_SERVICE_CLASS (gobject_class);
110
111 plugin_service_class->read_xml = plugin_service_chemical_loader_read_xml;
112 plugin_service_class->get_description = plugin_service_chemical_loader_get_description;
113 }
114
115 static void
plugin_service_chemical_loader_init(G_GNUC_UNUSED PluginServiceChemicalLoader * s)116 plugin_service_chemical_loader_init (G_GNUC_UNUSED PluginServiceChemicalLoader *s)
117 {
118 }
119
GSF_CLASS(PluginServiceChemicalLoader,plugin_service_chemical_loader,plugin_service_chemical_loader_class_init,plugin_service_chemical_loader_init,GO_TYPE_PLUGIN_SERVICE_SIMPLE)120 GSF_CLASS (PluginServiceChemicalLoader, plugin_service_chemical_loader,
121 plugin_service_chemical_loader_class_init, plugin_service_chemical_loader_init,
122 GO_TYPE_PLUGIN_SERVICE_SIMPLE)
123
124 Loader::Loader ()
125 {
126 }
127
~Loader()128 Loader::~Loader ()
129 {
130 }
131
132 bool Loader::Inited = false;
133
Init(Application * app)134 void Loader::Init (Application *app)
135 {
136 if (Inited)
137 return;
138 go_plugin_service_define ("chemical_loader",
139 &plugin_service_chemical_loader_get_type);
140 go_plugin_loader_module_register_version ("gchemutils", VERSION);
141 char *plugins_dir = g_strdup (GCU_PLUGINS_DIR);
142 GSList *dirs = g_slist_prepend (NULL, plugins_dir);
143 go_plugins_init ((app->GetCmdContext ())? app->GetCmdContext ()->GetGOCmdContext (): NULL, NULL, NULL, dirs, true, GO_TYPE_PLUGIN_LOADER_MODULE);
144 // do not free dirs and plugins_dir, goffice will
145 Inited = true;
146 }
147
GetFirstLoader(std::map<std::string,LoaderStruct>::iterator & it)148 bool Loader::GetFirstLoader (std::map<std::string, LoaderStruct>::iterator &it)
149 {
150 it = loaders.begin ();
151 return it != loaders.end ();
152 }
153
GetNextLoader(std::map<std::string,LoaderStruct>::iterator & it)154 bool Loader::GetNextLoader (std::map<std::string, LoaderStruct>::iterator &it)
155 {
156 it++;
157 return it != loaders.end ();
158 }
159
GetLoader(char const * mime_type)160 Loader *Loader::GetLoader (char const *mime_type)
161 {
162 map<string, LoaderStruct>::iterator it = loaders.find (mime_type);
163 if (it != loaders.end () && (*it).second.read) {
164 if ((*it).second.loader == NULL) {
165 GOErrorInfo *error = NULL;
166 go_plugin_service_load (services[mime_type], &error);
167 if (error) {
168 g_warning ("%s", go_error_info_peek_message (error));
169 g_free (error);
170 }
171 }
172 return (*it).second.loader;
173 } else
174 return NULL;
175 }
176
GetSaver(char const * mime_type)177 Loader *Loader::GetSaver (char const *mime_type)
178 {
179 map<string, LoaderStruct>::iterator it = loaders.find (mime_type);
180 if (it != loaders.end () && (*it).second.write) {
181 if ((*it).second.loader == NULL) {
182 GOErrorInfo *error = NULL;
183 go_plugin_service_load (services[mime_type], &error);
184 if (error) {
185 g_warning ("%s", go_error_info_peek_message (error));
186 g_free (error);
187 }
188 }
189 return (*it).second.loader;
190 } else
191 return NULL;
192 }
193
AddMimeType(const char * mime_type)194 void Loader::AddMimeType (const char *mime_type)
195 {
196 MimeTypes.push_front (mime_type);
197 map<string, LoaderStruct>::iterator it = loaders.find (mime_type);
198 if (it != loaders.end ())
199 (*it).second.loader = this;
200 }
201
RemoveMimeType(const char * mime_type)202 void Loader::RemoveMimeType (const char *mime_type)
203 {
204 MimeTypes.remove (mime_type);
205 map<string, LoaderStruct>::iterator it = loaders.find (mime_type);
206 if (it != loaders.end ())
207 (*it).second.loader = NULL;
208 }
209
Read(G_GNUC_UNUSED Document * doc,G_GNUC_UNUSED GsfInput * in,G_GNUC_UNUSED char const * mime_type,G_GNUC_UNUSED GOIOContext * io)210 ContentType Loader::Read (G_GNUC_UNUSED Document *doc, G_GNUC_UNUSED GsfInput *in, G_GNUC_UNUSED char const *mime_type, G_GNUC_UNUSED GOIOContext *io)
211 {
212 return ContentTypeUnknown;
213 }
214
Write(G_GNUC_UNUSED Object const * obj,G_GNUC_UNUSED GsfOutput * out,G_GNUC_UNUSED char const * mime_type,G_GNUC_UNUSED GOIOContext * io,G_GNUC_UNUSED ContentType type)215 bool Loader::Write (G_GNUC_UNUSED Object const *obj, G_GNUC_UNUSED GsfOutput *out, G_GNUC_UNUSED char const *mime_type, G_GNUC_UNUSED GOIOContext *io, G_GNUC_UNUSED ContentType type)
216 {
217 return false;
218 }
219
220 }
221