Code

Filter effects dialog:
[inkscape.git] / src / ui / dialog / filedialogimpl-gtkmm.h
1 /**\r
2  * Implementation of the file dialog interfaces defined in filedialogimpl.h\r
3  *\r
4  * Authors:\r
5  *   Bob Jamison\r
6  *   Joel Holdsworth\r
7  *   Bruno Dilly\r
8  *   Other dudes from The Inkscape Organization\r
9  *\r
10  * Copyright (C) 2004-2007 Bob Jamison\r
11  * Copyright (C) 2006 Johan Engelen <johan@shouraizou.nl>\r
12  * Copyright (C) 2004-2007 The Inkscape Organization\r
13  * Copyright (C) 2007 Joel Holdsworth\r
14  *\r
15  * Released under GNU GPL, read the file 'COPYING' for more information\r
16  */\r
17  \r
18 #include "filedialog.h"\r
19  \r
20 //General includes\r
21 #include <unistd.h>\r
22 #include <sys/stat.h>\r
23 #include <errno.h>\r
24 #include <set>\r
25 #include <libxml/parser.h>\r
26 #include <libxml/tree.h>\r
27 \r
28 \r
29 //Gtk includes\r
30 #include <glibmm/i18n.h>\r
31 #include <glib/gstdio.h>\r
32 \r
33 //Temporary ugly hack\r
34 //Remove this after the get_filter() calls in\r
35 //show() on both classes are fixed\r
36 #include <gtk/gtkfilechooser.h>\r
37 \r
38 //Another hack\r
39 #include <gtk/gtkentry.h>\r
40 #include <gtk/gtkexpander.h>\r
41 #ifdef WITH_GNOME_VFS\r
42 # include <libgnomevfs/gnome-vfs-init.h>  // gnome_vfs_initialized\r
43 #endif\r
44 \r
45 //Inkscape includes\r
46 #include "prefs-utils.h"\r
47 #include <extension/input.h>\r
48 #include <extension/output.h>\r
49 #include <extension/db.h>\r
50 #include "inkscape.h"\r
51 #include "svg-view-widget.h"\r
52 #include "gc-core.h"\r
53 \r
54 //For export dialog\r
55 #include "ui/widget/scalar-unit.h"\r
56  \r
57 namespace Inkscape\r
58 {\r
59 namespace UI\r
60 {\r
61 namespace Dialog\r
62 {
64 /*#########################################################################\r
65 ### Utility\r
66 #########################################################################*/
67 void\r
68 fileDialogExtensionToPattern(Glib::ustring &pattern,\r
69                       Glib::ustring &extension);
70 \r
71 void\r
72 findEntryWidgets(Gtk::Container *parent,\r
73                  std::vector<Gtk::Entry *> &result);
75 void\r
76 findExpanderWidgets(Gtk::Container *parent,\r
77                     std::vector<Gtk::Expander *> &result);\r
78 \r
79 /*#########################################################################\r
80 ### SVG Preview Widget\r
81 #########################################################################*/
83 class FileType\r
84 {\r
85     public:\r
86     FileType() {}\r
87     ~FileType() {}\r
88     Glib::ustring name;\r
89     Glib::ustring pattern;\r
90     Inkscape::Extension::Extension *extension;\r
91 };\r
92 \r
93 /**\r
94  * Simple class for displaying an SVG file in the "preview widget."\r
95  * Currently, this is just a wrapper of the sp_svg_view Gtk widget.\r
96  * Hopefully we will eventually replace with a pure Gtkmm widget.\r
97  */\r
98 class SVGPreview : public Gtk::VBox\r
99 {\r
100 public:\r
101 \r
102     SVGPreview();\r
103 \r
104     ~SVGPreview();\r
105 \r
106     bool setDocument(SPDocument *doc);\r
107 \r
108     bool setFileName(Glib::ustring &fileName);\r
109 \r
110     bool setFromMem(char const *xmlBuffer);\r
111 \r
112     bool set(Glib::ustring &fileName, int dialogType);\r
113 \r
114     bool setURI(URI &uri);\r
115 \r
116     /**\r
117      * Show image embedded in SVG\r
118      */\r
119     void showImage(Glib::ustring &fileName);\r
120 \r
121     /**\r
122      * Show the "No preview" image\r
123      */\r
124     void showNoPreview();\r
125 \r
126     /**\r
127      * Show the "Too large" image\r
128      */\r
129     void showTooLarge(long fileLength);\r
130 \r
131 private:\r
132     /**\r
133      * The svg document we are currently showing\r
134      */\r
135     SPDocument *document;\r
136 \r
137     /**\r
138      * The sp_svg_view widget\r
139      */\r
140     GtkWidget *viewerGtk;\r
141 \r
142     /**\r
143      * are we currently showing the "no preview" image?\r
144      */\r
145     bool showingNoPreview;\r
146 \r
147 };\r
148 \r
149 /*#########################################################################\r
150 ### F I L E     D I A L O G    B A S E    C L A S S\r
151 #########################################################################*/\r
152 \r
153 /**\r
154  * This class is the base implementation for the others.  This\r
155  * reduces redundancies and bugs.\r
156  */\r
157 class FileDialogBaseGtk : public Gtk::FileChooserDialog\r
158 {\r
159 public:\r
160 \r
161     /**\r
162      *\r
163      */\r
164     FileDialogBaseGtk(Gtk::Window& parentWindow, const Glib::ustring &title,\r
165                 FileDialogType type, gchar const* preferenceBase) :\r
166         Gtk::FileChooserDialog(parentWindow, title),\r
167         preferenceBase(preferenceBase ? preferenceBase : "unknown"),\r
168         dialogType(type)\r
169     {\r
170         internalSetup();\r
171     }\r
172 \r
173     /**\r
174      *\r
175      */\r
176     FileDialogBaseGtk(Gtk::Window& parentWindow, const Glib::ustring &title,\r
177                    Gtk::FileChooserAction dialogType, FileDialogType type, gchar const* preferenceBase) :\r
178         Gtk::FileChooserDialog(parentWindow, title, dialogType),\r
179         preferenceBase(preferenceBase ? preferenceBase : "unknown"),\r
180         dialogType(type)\r
181     {\r
182         internalSetup();\r
183     }\r
184 \r
185     /**\r
186      *\r
187      */\r
188     virtual ~FileDialogBaseGtk()\r
189         {}\r
190 \r
191 protected:\r
192     void cleanup( bool showConfirmed );\r
193 \r
194     Glib::ustring preferenceBase;\r
195     /**\r
196      * What type of 'open' are we? (open, import, place, etc)\r
197      */\r
198     FileDialogType dialogType;\r
199 \r
200     /**\r
201      * Our svg preview widget\r
202      */\r
203     SVGPreview svgPreview;\r
204 \r
205     //# Child widgets\r
206     Gtk::CheckButton previewCheckbox;\r
207 \r
208 private:\r
209     void internalSetup();\r
210 \r
211     /**\r
212      * Callback for user changing preview checkbox\r
213      */\r
214     void _previewEnabledCB();\r
215 \r
216     /**\r
217      * Callback for seeing if the preview needs to be drawn\r
218      */\r
219     void _updatePreviewCallback();\r
220 };\r
221 \r
222 \r
223 \r
224 \r
225 /*#########################################################################\r
226 ### F I L E    O P E N\r
227 #########################################################################*/\r
228 \r
229 /**\r
230  * Our implementation class for the FileOpenDialog interface..\r
231  */\r
232 class FileOpenDialogImplGtk : public FileOpenDialog, public FileDialogBaseGtk\r
233 {\r
234 public:\r
235 \r
236     FileOpenDialogImplGtk(Gtk::Window& parentWindow,\r
237                        const Glib::ustring &dir,\r
238                        FileDialogType fileTypes,\r
239                        const Glib::ustring &title);\r
240 \r
241     virtual ~FileOpenDialogImplGtk();\r
242 \r
243     bool show();\r
244 \r
245     Inkscape::Extension::Extension *getSelectionType();\r
246 \r
247     Glib::ustring getFilename();\r
248 \r
249     std::vector<Glib::ustring> getFilenames ();\r
250 \r
251 private:\r
252 \r
253     /**\r
254      *  Create a filter menu for this type of dialog\r
255      */\r
256     void createFilterMenu();\r
257 \r
258     /**\r
259      * Filter name->extension lookup\r
260      */\r
261     std::map<Glib::ustring, Inkscape::Extension::Extension *> extensionMap;\r
262 \r
263     /**\r
264      * The extension to use to write this file\r
265      */\r
266     Inkscape::Extension::Extension *extension;\r
267 \r
268     /**\r
269      * Filename that was given\r
270      */\r
271     Glib::ustring myFilename;\r
272 \r
273 };\r
274 \r
275 \r
276 \r
277 //########################################################################\r
278 //# F I L E    S A V E\r
279 //########################################################################\r
280 \r
281 /**\r
282  * Our implementation of the FileSaveDialog interface.\r
283  */\r
284 class FileSaveDialogImplGtk : public FileSaveDialog, public FileDialogBaseGtk\r
285 {\r
286 \r
287 public:\r
288     FileSaveDialogImplGtk(Gtk::Window &parentWindow, \r
289                            const Glib::ustring &dir,\r
290                        FileDialogType fileTypes,\r
291                        const Glib::ustring &title,\r
292                        const Glib::ustring &default_key);\r
293 \r
294     virtual ~FileSaveDialogImplGtk();\r
295 \r
296     bool show();\r
297 \r
298     Inkscape::Extension::Extension *getSelectionType();\r
299     virtual void setSelectionType( Inkscape::Extension::Extension * key );\r
300 \r
301     Glib::ustring getFilename();\r
302 \r
303     void change_title(const Glib::ustring& title);\r
304     void change_path(const Glib::ustring& path);\r
305     void updateNameAndExtension();\r
306 \r
307 private:\r
308 \r
309     /**\r
310      * Fix to allow the user to type the file name\r
311      */\r
312     Gtk::Entry *fileNameEntry;\r
313 \r
314 \r
315     /**\r
316      * Allow the specification of the output file type\r
317      */\r
318     Gtk::ComboBoxText fileTypeComboBox;\r
319 \r
320 \r
321     /**\r
322      *  Data mirror of the combo box\r
323      */\r
324     std::vector<FileType> fileTypes;\r
325 \r
326     //# Child widgets\r
327     Gtk::HBox childBox;\r
328     Gtk::VBox checksBox;\r
329 \r
330     Gtk::CheckButton fileTypeCheckbox;\r
331 \r
332     /**\r
333      * Callback for user input into fileNameEntry\r
334      */\r
335     void fileTypeChangedCallback();\r
336 \r
337     /**\r
338      *  Create a filter menu for this type of dialog\r
339      */\r
340     void createFileTypeMenu();\r
341 \r
342 \r
343     /**\r
344      * The extension to use to write this file\r
345      */\r
346     Inkscape::Extension::Extension *extension;\r
347 \r
348     /**\r
349      * Callback for user input into fileNameEntry\r
350      */\r
351     void fileNameEntryChangedCallback();\r
352 \r
353     /**\r
354      * Filename that was given\r
355      */\r
356     Glib::ustring myFilename;\r
357 \r
358     /**\r
359      * List of known file extensions.\r
360      */\r
361     std::set<Glib::ustring> knownExtensions;\r
362 };\r
363 \r
364 \r
365 \r
366 \r
367 //########################################################################\r
368 //# F I L E     E X P O R T\r
369 //########################################################################\r
370 \r
371 /**\r
372  * Our implementation of the FileExportDialog interface.\r
373  */\r
374 class FileExportDialogImpl : public FileExportDialog, public FileDialogBaseGtk\r
375 {\r
376 \r
377 public:\r
378     FileExportDialogImpl(Gtk::Window& parentWindow,\r
379             const Glib::ustring &dir,\r
380             FileDialogType fileTypes,\r
381             const Glib::ustring &title,\r
382             const Glib::ustring &default_key);\r
383 \r
384     virtual ~FileExportDialogImpl();\r
385 \r
386     bool show();\r
387 \r
388     Inkscape::Extension::Extension *getSelectionType();\r
389 \r
390     Glib::ustring getFilename();\r
391 \r
392 \r
393     /**\r
394      * Return the scope of the export.  One of the enumerated types\r
395      * in ScopeType     \r
396      */\r
397     ScopeType getScope()\r
398         { \r
399         if (pageButton.get_active())\r
400             return SCOPE_PAGE;\r
401         else if (selectionButton.get_active())\r
402             return SCOPE_SELECTION;\r
403         else if (customButton.get_active())\r
404             return SCOPE_CUSTOM;\r
405         else\r
406             return SCOPE_DOCUMENT;\r
407 \r
408         }\r
409     \r
410     /**\r
411      * Return left side of the exported region\r
412      */\r
413     double getSourceX()\r
414         { return sourceX0Spinner.getValue(); }\r
415     \r
416     /**\r
417      * Return the top of the exported region\r
418      */\r
419     double getSourceY()\r
420         { return sourceY1Spinner.getValue(); }\r
421     \r
422     /**\r
423      * Return the width of the exported region\r
424      */\r
425     double getSourceWidth()\r
426         { return sourceWidthSpinner.getValue(); }\r
427     \r
428     /**\r
429      * Return the height of the exported region\r
430      */\r
431     double getSourceHeight()\r
432         { return sourceHeightSpinner.getValue(); }\r
433 \r
434     /**\r
435      * Return the units of the coordinates of exported region\r
436      */\r
437     Glib::ustring getSourceUnits()\r
438         { return sourceUnitsSpinner.getUnitAbbr(); }\r
439 \r
440     /**\r
441      * Return the width of the destination document\r
442      */\r
443     double getDestinationWidth()\r
444         { return destWidthSpinner.getValue(); }\r
445 \r
446     /**\r
447      * Return the height of the destination document\r
448      */\r
449     double getDestinationHeight()\r
450         { return destHeightSpinner.getValue(); }\r
451 \r
452     /**\r
453      * Return the height of the exported region\r
454      */\r
455     Glib::ustring getDestinationUnits()\r
456         { return destUnitsSpinner.getUnitAbbr(); }\r
457 \r
458     /**\r
459      * Return the destination DPI image resulution, if bitmap\r
460      */\r
461     double getDestinationDPI()\r
462         { return destDPISpinner.getValue(); }\r
463 \r
464     /**\r
465      * Return whether we should use Cairo for rendering\r
466      */\r
467     bool getUseCairo()\r
468         { return cairoButton.get_active(); }\r
469 \r
470     /**\r
471      * Return whether we should use antialiasing\r
472      */\r
473     bool getUseAntialias()\r
474         { return antiAliasButton.get_active(); }\r
475 \r
476     /**\r
477      * Return the background color for exporting\r
478      */\r
479     unsigned long getBackground()\r
480         { return backgroundButton.get_color().get_pixel(); }\r
481 \r
482 private:\r
483 \r
484     /**\r
485      * Fix to allow the user to type the file name\r
486      */\r
487     Gtk::Entry *fileNameEntry;\r
488 \r
489     //##########################################\r
490     //# EXTRA WIDGET -- SOURCE SIDE\r
491     //##########################################\r
492 \r
493     Gtk::Frame            sourceFrame;\r
494     Gtk::VBox             sourceBox;\r
495 \r
496     Gtk::HBox             scopeBox;\r
497     Gtk::RadioButtonGroup scopeGroup;\r
498     Gtk::RadioButton      documentButton;\r
499     Gtk::RadioButton      pageButton;\r
500     Gtk::RadioButton      selectionButton;\r
501     Gtk::RadioButton      customButton;\r
502 \r
503     Gtk::Table                      sourceTable;\r
504     Inkscape::UI::Widget::Scalar    sourceX0Spinner;\r
505     Inkscape::UI::Widget::Scalar    sourceY0Spinner;\r
506     Inkscape::UI::Widget::Scalar    sourceX1Spinner;\r
507     Inkscape::UI::Widget::Scalar    sourceY1Spinner;\r
508     Inkscape::UI::Widget::Scalar    sourceWidthSpinner;\r
509     Inkscape::UI::Widget::Scalar    sourceHeightSpinner;\r
510     Inkscape::UI::Widget::UnitMenu  sourceUnitsSpinner;\r
511 \r
512 \r
513     //##########################################\r
514     //# EXTRA WIDGET -- DESTINATION SIDE\r
515     //##########################################\r
516 \r
517     Gtk::Frame       destFrame;\r
518     Gtk::VBox        destBox;\r
519 \r
520     Gtk::Table                      destTable;\r
521     Inkscape::UI::Widget::Scalar    destWidthSpinner;\r
522     Inkscape::UI::Widget::Scalar    destHeightSpinner;\r
523     Inkscape::UI::Widget::Scalar    destDPISpinner;\r
524     Inkscape::UI::Widget::UnitMenu  destUnitsSpinner;\r
525 \r
526     Gtk::HBox        otherOptionBox;\r
527     Gtk::CheckButton cairoButton;\r
528     Gtk::CheckButton antiAliasButton;\r
529     Gtk::ColorButton backgroundButton;\r
530 \r
531 \r
532     /**\r
533      * 'Extra' widget that holds two boxes above\r
534      */\r
535     Gtk::HBox exportOptionsBox;\r
536 \r
537 \r
538     //# Child widgets\r
539     Gtk::CheckButton fileTypeCheckbox;\r
540 \r
541     /**\r
542      * Allow the specification of the output file type\r
543      */\r
544     Gtk::ComboBoxText fileTypeComboBox;\r
545 \r
546 \r
547     /**\r
548      *  Data mirror of the combo box\r
549      */\r
550     std::vector<FileType> fileTypes;\r
551 \r
552 \r
553 \r
554     /**\r
555      * Callback for user input into fileNameEntry\r
556      */\r
557     void fileTypeChangedCallback();\r
558 \r
559     /**\r
560      *  Create a filter menu for this type of dialog\r
561      */\r
562     void createFileTypeMenu();\r
563 \r
564 \r
565     bool append_extension;\r
566 \r
567     /**\r
568      * The extension to use to write this file\r
569      */\r
570     Inkscape::Extension::Extension *extension;\r
571 \r
572     /**\r
573      * Callback for user input into fileNameEntry\r
574      */\r
575     void fileNameEntryChangedCallback();\r
576 \r
577     /**\r
578      * Filename that was given\r
579      */\r
580     Glib::ustring myFilename;\r
581 };\r
582 \r
583 \r
584 \r\r
585 }\r
586 }\r
587 }\r
588 \r
589 /*\r
590   Local Variables:\r
591   mode:c++\r
592   c-file-style:"stroustrup"\r
593   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
594   indent-tabs-mode:nil\r
595   fill-column:99\r
596   End:\r
597 */\r
598 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r