Code

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