1 /*
2 * Authors:
3 * Ted Gould <ted@gould.cx>
4 *
5 * Copyright (C) 2002-2004 Authors
6 *
7 * Released under GNU GPL, read the file 'COPYING' for more information
8 */
10 #include "document.h"
11 #include "implementation/implementation.h"
12 #include "output.h"
14 #include "prefdialog.h"
16 /* Inkscape::Extension::Output */
18 namespace Inkscape {
19 namespace Extension {
21 /**
22 \return None
23 \brief Builds a SPModuleOutput object from a XML description
24 \param module The module to be initialized
25 \param repr The XML description in a Inkscape::XML::Node tree
27 Okay, so you want to build a SPModuleOutput object.
29 This function first takes and does the build of the parent class,
30 which is SPModule. Then, it looks for the <output> section of the
31 XML description. Under there should be several fields which
32 describe the output module to excruciating detail. Those are parsed,
33 copied, and put into the structure that is passed in as module.
34 Overall, there are many levels of indentation, just to handle the
35 levels of indentation in the XML file.
36 */
37 Output::Output (Inkscape::XML::Node * in_repr, Implementation::Implementation * in_imp) : Extension(in_repr, in_imp)
38 {
39 mimetype = NULL;
40 extension = NULL;
41 filetypename = NULL;
42 filetypetooltip = NULL;
43 dataloss = TRUE;
45 if (repr != NULL) {
46 Inkscape::XML::Node * child_repr;
48 child_repr = sp_repr_children(repr);
50 while (child_repr != NULL) {
51 if (!strcmp(child_repr->name(), "output")) {
52 child_repr = sp_repr_children(child_repr);
53 while (child_repr != NULL) {
54 char const * chname = child_repr->name();
55 if (chname[0] == '_') /* Allow _ for translation of tags */
56 chname++;
57 if (!strcmp(chname, "extension")) {
58 g_free (extension);
59 extension = g_strdup(sp_repr_children(child_repr)->content());
60 }
61 if (!strcmp(chname, "mimetype")) {
62 g_free (mimetype);
63 mimetype = g_strdup(sp_repr_children(child_repr)->content());
64 }
65 if (!strcmp(chname, "filetypename")) {
66 g_free (filetypename);
67 filetypename = g_strdup(sp_repr_children(child_repr)->content());
68 }
69 if (!strcmp(chname, "filetypetooltip")) {
70 g_free (filetypetooltip);
71 filetypetooltip = g_strdup(sp_repr_children(child_repr)->content());
72 }
73 if (!strcmp(chname, "dataloss")) {
74 if (!strcmp(sp_repr_children(child_repr)->content(), "FALSE")) {
75 dataloss = FALSE;
76 }
77 }
79 child_repr = sp_repr_next(child_repr);
80 }
82 break;
83 }
85 child_repr = sp_repr_next(child_repr);
86 }
88 }
89 }
91 /**
92 \brief Destroy an output extension
93 */
94 Output::~Output (void)
95 {
96 g_free(mimetype);
97 g_free(extension);
98 g_free(filetypename);
99 g_free(filetypetooltip);
100 return;
101 }
103 /**
104 \return Whether this extension checks out
105 \brief Validate this extension
107 This function checks to make sure that the output extension has
108 a filename extension and a MIME type. Then it calls the parent
109 class' check function which also checks out the implmentation.
110 */
111 bool
112 Output::check (void)
113 {
114 if (extension == NULL)
115 return FALSE;
116 if (mimetype == NULL)
117 return FALSE;
119 return Extension::check();
120 }
122 /**
123 \return IETF mime-type for the extension
124 \brief Get the mime-type that describes this extension
125 */
126 gchar *
127 Output::get_mimetype(void)
128 {
129 return mimetype;
130 }
132 /**
133 \return Filename extension for the extension
134 \brief Get the filename extension for this extension
135 */
136 gchar *
137 Output::get_extension(void)
138 {
139 return extension;
140 }
142 /**
143 \return The name of the filetype supported
144 \brief Get the name of the filetype supported
145 */
146 gchar *
147 Output::get_filetypename(void)
148 {
149 if (filetypename != NULL)
150 return filetypename;
151 else
152 return get_name();
153 }
155 /**
156 \return Tooltip giving more information on the filetype
157 \brief Get the tooltip for more information on the filetype
158 */
159 gchar *
160 Output::get_filetypetooltip(void)
161 {
162 return filetypetooltip;
163 }
165 /**
166 \return A dialog to get settings for this extension
167 \brief Create a dialog for preference for this extension
169 Calls the implementation to get the preferences.
170 */
171 bool
172 Output::prefs (void)
173 {
174 if (!loaded())
175 set_state(Extension::STATE_LOADED);
176 if (!loaded()) return false;
178 Gtk::Widget * controls;
179 controls = imp->prefs_output(this);
180 if (controls == NULL) {
181 // std::cout << "No preferences for Output" << std::endl;
182 return true;
183 }
185 PrefDialog * dialog = new PrefDialog(this->get_name(), controls);
186 int response = dialog->run();
187 dialog->hide();
189 delete dialog;
191 if (response == Gtk::RESPONSE_OK) return true;
192 return false;
193 }
195 /**
196 \return None
197 \brief Save a document as a file
198 \param doc Document to save
199 \param uri File to save the document as
201 This function does a little of the dirty work involved in saving
202 a document so that the implementation only has to worry about geting
203 bits on the disk.
205 The big thing that it does is remove and readd the fields that are
206 only used at runtime and shouldn't be saved. One that may surprise
207 people is the output extension. This is not saved so that the IDs
208 could be changed, and old files will still work properly.
210 After the file is saved by the implmentation the output_extension
211 and dataloss variables are recreated. The output_extension is set
212 to this extension so that future saves use this extension. Dataloss
213 is set so that a warning will occur on closing the document that
214 there may be some dataloss from this extension.
215 */
216 void
217 Output::save (SPDocument * doc, const gchar * uri)
218 {
219 bool modified = false;
220 Inkscape::XML::Node * repr = sp_document_repr_root(doc);
222 gboolean saved = sp_document_get_undo_sensitive(doc);
223 sp_document_set_undo_sensitive (doc, FALSE);
224 repr->setAttribute("inkscape:output_extension", NULL);
225 repr->setAttribute("inkscape:dataloss", NULL);
226 if (repr->attribute("sodipodi:modified") != NULL)
227 modified = true;
228 repr->setAttribute("sodipodi:modified", NULL);
229 sp_document_set_undo_sensitive (doc, saved);
231 try {
232 imp->save(this, doc, uri);
233 }
234 catch (...) {
235 if (modified)
236 repr->setAttribute("sodipodi:modified", "true");
237 throw;
238 }
240 saved = sp_document_get_undo_sensitive(doc);
241 sp_document_set_undo_sensitive (doc, FALSE);
242 repr->setAttribute("inkscape:output_extension", get_id());
243 if (dataloss) {
244 repr->setAttribute("inkscape:dataloss", "true");
245 }
246 sp_document_set_undo_sensitive (doc, saved);
248 return;
249 }
251 } } /* namespace Inkscape, Extension */
253 /*
254 Local Variables:
255 mode:c++
256 c-file-style:"stroustrup"
257 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
258 indent-tabs-mode:nil
259 fill-column:99
260 End:
261 */
262 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :