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