Code

add import from ocal feature
[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 {\r
63 \r
64 /*#########################################################################\r
65 ### SVG Preview Widget\r
66 #########################################################################*/\r
67 \r
68 /**\r
69  * Simple class for displaying an SVG file in the "preview widget."\r
70  * Currently, this is just a wrapper of the sp_svg_view Gtk widget.\r
71  * Hopefully we will eventually replace with a pure Gtkmm widget.\r
72  */\r
73 class SVGPreview : public Gtk::VBox\r
74 {\r
75 public:\r
76 \r
77     SVGPreview();\r
78 \r
79     ~SVGPreview();\r
80 \r
81     bool setDocument(SPDocument *doc);\r
82 \r
83     bool setFileName(Glib::ustring &fileName);\r
84 \r
85     bool setFromMem(char const *xmlBuffer);\r
86 \r
87     bool set(Glib::ustring &fileName, int dialogType);\r
88 \r
89     bool setURI(URI &uri);\r
90 \r
91     /**\r
92      * Show image embedded in SVG\r
93      */\r
94     void showImage(Glib::ustring &fileName);\r
95 \r
96     /**\r
97      * Show the "No preview" image\r
98      */\r
99     void showNoPreview();\r
100 \r
101     /**\r
102      * Show the "Too large" image\r
103      */\r
104     void showTooLarge(long fileLength);\r
105 \r
106 private:\r
107     /**\r
108      * The svg document we are currently showing\r
109      */\r
110     SPDocument *document;\r
111 \r
112     /**\r
113      * The sp_svg_view widget\r
114      */\r
115     GtkWidget *viewerGtk;\r
116 \r
117     /**\r
118      * are we currently showing the "no preview" image?\r
119      */\r
120     bool showingNoPreview;\r
121 \r
122 };\r
123 \r
124 /*#########################################################################\r
125 ### F I L E     D I A L O G    B A S E    C L A S S\r
126 #########################################################################*/\r
127 \r
128 /**\r
129  * This class is the base implementation for the others.  This\r
130  * reduces redundancies and bugs.\r
131  */\r
132 class FileDialogBaseGtk : public Gtk::FileChooserDialog\r
133 {\r
134 public:\r
135 \r
136     /**\r
137      *\r
138      */\r
139     FileDialogBaseGtk(Gtk::Window& parentWindow, const Glib::ustring &title,\r
140                 FileDialogType type, gchar const* preferenceBase) :\r
141         Gtk::FileChooserDialog(parentWindow, title),\r
142         preferenceBase(preferenceBase ? preferenceBase : "unknown"),\r
143         dialogType(type)\r
144     {\r
145         internalSetup();\r
146     }\r
147 \r
148     /**\r
149      *\r
150      */\r
151     FileDialogBaseGtk(Gtk::Window& parentWindow, const Glib::ustring &title,\r
152                    Gtk::FileChooserAction dialogType, FileDialogType type, gchar const* preferenceBase) :\r
153         Gtk::FileChooserDialog(parentWindow, title, dialogType),\r
154         preferenceBase(preferenceBase ? preferenceBase : "unknown"),\r
155         dialogType(type)\r
156     {\r
157         internalSetup();\r
158     }\r
159 \r
160     /**\r
161      *\r
162      */\r
163     virtual ~FileDialogBaseGtk()\r
164         {}\r
165 \r
166 protected:\r
167     void cleanup( bool showConfirmed );\r
168 \r
169     Glib::ustring preferenceBase;\r
170     /**\r
171      * What type of 'open' are we? (open, import, place, etc)\r
172      */\r
173     FileDialogType dialogType;\r
174 \r
175     /**\r
176      * Our svg preview widget\r
177      */\r
178     SVGPreview svgPreview;\r
179 \r
180     //# Child widgets\r
181     Gtk::CheckButton previewCheckbox;\r
182 \r
183 private:\r
184     void internalSetup();\r
185 \r
186     /**\r
187      * Callback for user changing preview checkbox\r
188      */\r
189     void _previewEnabledCB();\r
190 \r
191     /**\r
192      * Callback for seeing if the preview needs to be drawn\r
193      */\r
194     void _updatePreviewCallback();\r
195 };\r
196 \r
197 \r
198 \r
199 \r
200 /*#########################################################################\r
201 ### F I L E    O P E N\r
202 #########################################################################*/\r
203 \r
204 /**\r
205  * Our implementation class for the FileOpenDialog interface..\r
206  */\r
207 class FileOpenDialogImplGtk : public FileOpenDialog, public FileDialogBaseGtk\r
208 {\r
209 public:\r
210 \r
211     FileOpenDialogImplGtk(Gtk::Window& parentWindow,\r
212                            const Glib::ustring &dir,\r
213                        FileDialogType fileTypes,\r
214                        const Glib::ustring &title);\r
215 \r
216     virtual ~FileOpenDialogImplGtk();\r
217 \r
218     bool show();\r
219 \r
220     Inkscape::Extension::Extension *getSelectionType();\r
221 \r
222     Glib::ustring getFilename();\r
223 \r
224     std::vector<Glib::ustring> getFilenames ();\r
225 \r
226 private:\r
227 \r
228     /**\r
229      *  Create a filter menu for this type of dialog\r
230      */\r
231     void createFilterMenu();\r
232 \r
233     /**\r
234      * Filter name->extension lookup\r
235      */\r
236     std::map<Glib::ustring, Inkscape::Extension::Extension *> extensionMap;\r
237 \r
238     /**\r
239      * The extension to use to write this file\r
240      */\r
241     Inkscape::Extension::Extension *extension;\r
242 \r
243     /**\r
244      * Filename that was given\r
245      */\r
246     Glib::ustring myFilename;\r
247 \r
248 };\r
249 \r
250 \r
251 class FileType\r
252 {\r
253     public:\r
254     FileType() {}\r
255     ~FileType() {}\r
256     Glib::ustring name;\r
257     Glib::ustring pattern;\r
258     Inkscape::Extension::Extension *extension;\r
259 };\r
260 \r
261 \r
262 \r
263 //########################################################################\r
264 //# F I L E    S A V E\r
265 //########################################################################\r
266 \r
267 /**\r
268  * Our implementation of the FileSaveDialog interface.\r
269  */\r
270 class FileSaveDialogImplGtk : public FileSaveDialog, public FileDialogBaseGtk\r
271 {\r
272 \r
273 public:\r
274     FileSaveDialogImplGtk(Gtk::Window &parentWindow, \r
275                            const Glib::ustring &dir,\r
276                        FileDialogType fileTypes,\r
277                        const Glib::ustring &title,\r
278                        const Glib::ustring &default_key);\r
279 \r
280     virtual ~FileSaveDialogImplGtk();\r
281 \r
282     bool show();\r
283 \r
284     Inkscape::Extension::Extension *getSelectionType();\r
285     virtual void setSelectionType( Inkscape::Extension::Extension * key );\r
286 \r
287     Glib::ustring getFilename();\r
288 \r
289     void change_title(const Glib::ustring& title);\r
290     void change_path(const Glib::ustring& path);\r
291     void updateNameAndExtension();\r
292 \r
293 private:\r
294 \r
295     /**\r
296      * Fix to allow the user to type the file name\r
297      */\r
298     Gtk::Entry *fileNameEntry;\r
299 \r
300 \r
301     /**\r
302      * Allow the specification of the output file type\r
303      */\r
304     Gtk::ComboBoxText fileTypeComboBox;\r
305 \r
306 \r
307     /**\r
308      *  Data mirror of the combo box\r
309      */\r
310     std::vector<FileType> fileTypes;\r
311 \r
312     //# Child widgets\r
313     Gtk::HBox childBox;\r
314     Gtk::VBox checksBox;\r
315 \r
316     Gtk::CheckButton fileTypeCheckbox;\r
317 \r
318     /**\r
319      * Callback for user input into fileNameEntry\r
320      */\r
321     void fileTypeChangedCallback();\r
322 \r
323     /**\r
324      *  Create a filter menu for this type of dialog\r
325      */\r
326     void createFileTypeMenu();\r
327 \r
328 \r
329     /**\r
330      * The extension to use to write this file\r
331      */\r
332     Inkscape::Extension::Extension *extension;\r
333 \r
334     /**\r
335      * Callback for user input into fileNameEntry\r
336      */\r
337     void fileNameEntryChangedCallback();\r
338 \r
339     /**\r
340      * Filename that was given\r
341      */\r
342     Glib::ustring myFilename;\r
343 \r
344     /**\r
345      * List of known file extensions.\r
346      */\r
347     std::set<Glib::ustring> knownExtensions;\r
348 };\r
349 \r
350 \r
351 \r
352 \r
353 //########################################################################\r
354 //# F I L E     E X P O R T\r
355 //########################################################################\r
356 \r
357 /**\r
358  * Our implementation of the FileExportDialog interface.\r
359  */\r
360 class FileExportDialogImpl : public FileExportDialog, public FileDialogBaseGtk\r
361 {\r
362 \r
363 public:\r
364     FileExportDialogImpl(Gtk::Window& parentWindow, \r
365                                      const Glib::ustring &dir,\r
366                          FileDialogType fileTypes,\r
367                          const Glib::ustring &title,\r
368                          const Glib::ustring &default_key);\r
369 \r
370     virtual ~FileExportDialogImpl();\r
371 \r
372     bool show();\r
373 \r
374     Inkscape::Extension::Extension *getSelectionType();\r
375 \r
376     Glib::ustring getFilename();\r
377 \r
378 \r
379     /**\r
380      * Return the scope of the export.  One of the enumerated types\r
381      * in ScopeType     \r
382      */\r
383     ScopeType getScope()\r
384         { \r
385         if (pageButton.get_active())\r
386             return SCOPE_PAGE;\r
387         else if (selectionButton.get_active())\r
388             return SCOPE_SELECTION;\r
389         else if (customButton.get_active())\r
390             return SCOPE_CUSTOM;\r
391         else\r
392             return SCOPE_DOCUMENT;\r
393 \r
394         }\r
395     \r
396     /**\r
397      * Return left side of the exported region\r
398      */\r
399     double getSourceX()\r
400         { return sourceX0Spinner.getValue(); }\r
401     \r
402     /**\r
403      * Return the top of the exported region\r
404      */\r
405     double getSourceY()\r
406         { return sourceY1Spinner.getValue(); }\r
407     \r
408     /**\r
409      * Return the width of the exported region\r
410      */\r
411     double getSourceWidth()\r
412         { return sourceWidthSpinner.getValue(); }\r
413     \r
414     /**\r
415      * Return the height of the exported region\r
416      */\r
417     double getSourceHeight()\r
418         { return sourceHeightSpinner.getValue(); }\r
419 \r
420     /**\r
421      * Return the units of the coordinates of exported region\r
422      */\r
423     Glib::ustring getSourceUnits()\r
424         { return sourceUnitsSpinner.getUnitAbbr(); }\r
425 \r
426     /**\r
427      * Return the width of the destination document\r
428      */\r
429     double getDestinationWidth()\r
430         { return destWidthSpinner.getValue(); }\r
431 \r
432     /**\r
433      * Return the height of the destination document\r
434      */\r
435     double getDestinationHeight()\r
436         { return destHeightSpinner.getValue(); }\r
437 \r
438     /**\r
439      * Return the height of the exported region\r
440      */\r
441     Glib::ustring getDestinationUnits()\r
442         { return destUnitsSpinner.getUnitAbbr(); }\r
443 \r
444     /**\r
445      * Return the destination DPI image resulution, if bitmap\r
446      */\r
447     double getDestinationDPI()\r
448         { return destDPISpinner.getValue(); }\r
449 \r
450     /**\r
451      * Return whether we should use Cairo for rendering\r
452      */\r
453     bool getUseCairo()\r
454         { return cairoButton.get_active(); }\r
455 \r
456     /**\r
457      * Return whether we should use antialiasing\r
458      */\r
459     bool getUseAntialias()\r
460         { return antiAliasButton.get_active(); }\r
461 \r
462     /**\r
463      * Return the background color for exporting\r
464      */\r
465     unsigned long getBackground()\r
466         { return backgroundButton.get_color().get_pixel(); }\r
467 \r
468 private:\r
469 \r
470     /**\r
471      * Fix to allow the user to type the file name\r
472      */\r
473     Gtk::Entry *fileNameEntry;\r
474 \r
475     //##########################################\r
476     //# EXTRA WIDGET -- SOURCE SIDE\r
477     //##########################################\r
478 \r
479     Gtk::Frame            sourceFrame;\r
480     Gtk::VBox             sourceBox;\r
481 \r
482     Gtk::HBox             scopeBox;\r
483     Gtk::RadioButtonGroup scopeGroup;\r
484     Gtk::RadioButton      documentButton;\r
485     Gtk::RadioButton      pageButton;\r
486     Gtk::RadioButton      selectionButton;\r
487     Gtk::RadioButton      customButton;\r
488 \r
489     Gtk::Table                      sourceTable;\r
490     Inkscape::UI::Widget::Scalar    sourceX0Spinner;\r
491     Inkscape::UI::Widget::Scalar    sourceY0Spinner;\r
492     Inkscape::UI::Widget::Scalar    sourceX1Spinner;\r
493     Inkscape::UI::Widget::Scalar    sourceY1Spinner;\r
494     Inkscape::UI::Widget::Scalar    sourceWidthSpinner;\r
495     Inkscape::UI::Widget::Scalar    sourceHeightSpinner;\r
496     Inkscape::UI::Widget::UnitMenu  sourceUnitsSpinner;\r
497 \r
498 \r
499     //##########################################\r
500     //# EXTRA WIDGET -- DESTINATION SIDE\r
501     //##########################################\r
502 \r
503     Gtk::Frame       destFrame;\r
504     Gtk::VBox        destBox;\r
505 \r
506     Gtk::Table                      destTable;\r
507     Inkscape::UI::Widget::Scalar    destWidthSpinner;\r
508     Inkscape::UI::Widget::Scalar    destHeightSpinner;\r
509     Inkscape::UI::Widget::Scalar    destDPISpinner;\r
510     Inkscape::UI::Widget::UnitMenu  destUnitsSpinner;\r
511 \r
512     Gtk::HBox        otherOptionBox;\r
513     Gtk::CheckButton cairoButton;\r
514     Gtk::CheckButton antiAliasButton;\r
515     Gtk::ColorButton backgroundButton;\r
516 \r
517 \r
518     /**\r
519      * 'Extra' widget that holds two boxes above\r
520      */\r
521     Gtk::HBox exportOptionsBox;\r
522 \r
523 \r
524     //# Child widgets\r
525     Gtk::CheckButton fileTypeCheckbox;\r
526 \r
527     /**\r
528      * Allow the specification of the output file type\r
529      */\r
530     Gtk::ComboBoxText fileTypeComboBox;\r
531 \r
532 \r
533     /**\r
534      *  Data mirror of the combo box\r
535      */\r
536     std::vector<FileType> fileTypes;\r
537 \r
538 \r
539 \r
540     /**\r
541      * Callback for user input into fileNameEntry\r
542      */\r
543     void fileTypeChangedCallback();\r
544 \r
545     /**\r
546      *  Create a filter menu for this type of dialog\r
547      */\r
548     void createFileTypeMenu();\r
549 \r
550 \r
551     bool append_extension;\r
552 \r
553     /**\r
554      * The extension to use to write this file\r
555      */\r
556     Inkscape::Extension::Extension *extension;\r
557 \r
558     /**\r
559      * Callback for user input into fileNameEntry\r
560      */\r
561     void fileNameEntryChangedCallback();\r
562 \r
563     /**\r
564      * Filename that was given\r
565      */\r
566     Glib::ustring myFilename;\r
567 };\r
568 \r
569 \r
570 \r
571 /*#########################################################################\r
572 ### F I L E     D I A L O G    O C A L    B A S E    C L A S S\r
573 #########################################################################*/\r
574 \r
575 /**\r
576  * This class is the base implementation for export to OCAL.\r
577  */\r
578 class FileDialogOCALBase : public Gtk::Dialog\r
579 {\r
580 public:\r
581 \r
582     /**\r
583      *\r
584      */\r
585     FileDialogOCALBase(const Glib::ustring &title) : Gtk::Dialog(title,true)\r
586     {}\r
587     /*\r
588      *\r
589      */\r
590     virtual ~FileDialogOCALBase()\r
591     {}\r
592 \r
593 protected:\r
594     void cleanup( bool showConfirmed );\r
595 \r
596     //Glib::ustring preferenceBase;\r
597     /**\r
598      * What type of 'open' are we? (open, import, place, etc)\r
599      */\r
600     FileDialogType dialogType;\r
601 };\r
602 \r
603 \r
604 \r
605 \r
606 //########################################################################\r
607 //# F I L E    E X P O R T   T O   O C A L\r
608 //########################################################################\r
609 \r
610 \r
611 \r
612 /**\r
613  * Our implementation of the FileExportToOCALDialog interface.\r
614  */\r
615 class FileExportToOCALDialogImpl : public FileExportToOCALDialog, public FileDialogOCALBase\r
616 {\r
617 \r
618 public:\r
619   FileExportToOCALDialogImpl(Gtk::Window& parentWindow, \r
620                              FileDialogType fileTypes,\r
621                              const Glib::ustring &title,\r
622                              const Glib::ustring &default_key);\r
623     \r
624     virtual ~FileExportToOCALDialogImpl();\r
625 \r
626     bool show();\r
627 \r
628     Inkscape::Extension::Extension *getSelectionType();\r
629     virtual void setSelectionType( Inkscape::Extension::Extension * key );\r
630 \r
631     Glib::ustring getFilename();\r
632 \r
633     Glib::ustring myFilename;\r
634 \r
635     void change_title(const Glib::ustring& title);\r
636     void updateNameAndExtension();\r
637 \r
638 private:\r
639 \r
640     /**\r
641      * Fix to allow the user to type the file name\r
642      */\r
643     Gtk::Entry *fileNameEntry;\r
644     \r
645     \r
646     /**\r
647      * Allow the specification of the output file type\r
648      */\r
649     Gtk::ComboBoxText fileTypeComboBox;\r
650 \r
651 \r
652     /**\r
653      *  Data mirror of the combo box\r
654      */\r
655     std::vector<FileType> fileTypes;\r
656 \r
657     // Child widgets\r
658     Gtk::HBox childBox;\r
659     Gtk::VBox checksBox;\r
660     Gtk::HBox fileBox;\r
661 \r
662     Gtk::CheckButton fileTypeCheckbox;\r
663 \r
664     /**\r
665      * Callback for user input into fileNameEntry\r
666      */\r
667     void fileTypeChangedCallback();\r
668 \r
669     /**\r
670      *  Create a filter menu for this type of dialog\r
671      */\r
672     void createFileTypeMenu();\r
673 \r
674 \r
675     /**\r
676      * The extension to use to write this file\r
677      */\r
678     Inkscape::Extension::Extension *extension;\r
679 \r
680     /**\r
681      * Callback for user input into fileNameEntry\r
682      */\r
683     void fileNameEntryChangedCallback();\r
684 \r
685     /**\r
686      * List of known file extensions.\r
687      */\r
688     std::set<Glib::ustring> knownExtensions;\r
689 };\r
690 \r
691 \r
692 //#########################################################################\r
693 //### F I L E   I M P O R T   F R O M   O C A L\r
694 //#########################################################################\r
695 \r
696 /**\r
697  * Our implementation class for filesListView\r
698  */\r
699 class FileListViewText : public Gtk::ListViewText\r
700 {\r
701 public:\r
702     FileListViewText(guint columns_count, SVGPreview& filesPreview):ListViewText(columns_count)\r
703     {\r
704         myPreview = &filesPreview;\r
705     }\r
706     Glib::ustring getFilename();\r
707 protected:\r
708     void on_row_activated(const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column);\r
709 private:\r
710     Glib::ustring myFilename;\r
711     SVGPreview *myPreview;\r
712 };\r
713 \r
714 /**\r
715  * Our implementation class for the FileImportFromOCALDialog interface..\r
716  */\r
717 class FileImportFromOCALDialogImplGtk : public FileImportFromOCALDialog, public FileDialogOCALBase\r
718 {\r
719 public:\r
720 \r
721     FileImportFromOCALDialogImplGtk(Gtk::Window& parentWindow,\r
722                        const Glib::ustring &dir,\r
723                        FileDialogType fileTypes,\r
724                        const Glib::ustring &title);\r
725 \r
726     virtual ~FileImportFromOCALDialogImplGtk();\r
727 \r
728     bool show();\r
729 \r
730     Inkscape::Extension::Extension *getSelectionType();\r
731 \r
732     Glib::ustring getFilename();\r
733 \r
734 private:\r
735 \r
736     /**\r
737      * Allow the user to type the tag to be searched\r
738      */\r
739     Gtk::Entry *searchTagEntry;\r
740     FileListViewText *filesList;\r
741     SVGPreview *filesPreview;\r
742     Gtk::Label *notFoundLabel;\r
743 \r
744     // Child widgets\r
745     Gtk::HBox tagBox;\r
746     Gtk::HBox filesBox;\r
747     Gtk::HBox messageBox;\r
748     Gtk::ScrolledWindow listScrolledWindow;\r
749     Glib::RefPtr<Gtk::TreeSelection> selection;\r
750 \r
751     /**\r
752      * Callback for user input into searchTagEntry\r
753      */\r
754     void searchTagEntryChangedCallback();\r
755 \r
756 \r
757     /**\r
758      * Prints the names of the all the xml elements \r
759      * that are siblings or children of a given xml node\r
760      */\r
761     void print_xml_element_names(xmlNode * a_node);\r
762 \r
763     /**\r
764      * The extension to use to write this file\r
765      */\r
766     Inkscape::Extension::Extension *extension;\r
767 };\r
768 \r
769 }\r
770 }\r
771 }\r
772 \r
773 /*\r
774   Local Variables:\r
775   mode:c++\r
776   c-file-style:"stroustrup"\r
777   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
778   indent-tabs-mode:nil\r
779   fill-column:99\r
780   End:\r
781 */\r
782 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r