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) 2004-2007 The Inkscape Organization
15 * Copyright (C) 2007 Joel Holdsworth
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 <set>
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>
43 #ifdef WITH_GNOME_VFS
44 # include <libgnomevfs/gnome-vfs-init.h> // gnome_vfs_initialized
45 #endif
47 //Inkscape includes
48 #include "prefs-utils.h"
49 #include <extension/input.h>
50 #include <extension/output.h>
51 #include <extension/db.h>
52 #include "inkscape.h"
53 #include "svg-view-widget.h"
54 #include "gc-core.h"
56 //For export dialog
57 #include "ui/widget/scalar-unit.h"
59 namespace Inkscape
60 {
61 namespace UI
62 {
63 namespace Dialog
64 {
66 /*#########################################################################
67 ### Utility
68 #########################################################################*/
69 void
70 fileDialogExtensionToPattern(Glib::ustring &pattern,
71 Glib::ustring &extension);
73 void
74 findEntryWidgets(Gtk::Container *parent,
75 std::vector<Gtk::Entry *> &result);
77 void
78 findExpanderWidgets(Gtk::Container *parent,
79 std::vector<Gtk::Expander *> &result);
81 /*#########################################################################
82 ### SVG Preview Widget
83 #########################################################################*/
85 class FileType
86 {
87 public:
88 FileType() {}
89 ~FileType() {}
90 Glib::ustring name;
91 Glib::ustring pattern;
92 Inkscape::Extension::Extension *extension;
93 };
95 /**
96 * Simple class for displaying an SVG file in the "preview widget."
97 * Currently, this is just a wrapper of the sp_svg_view Gtk widget.
98 * Hopefully we will eventually replace with a pure Gtkmm widget.
99 */
100 class SVGPreview : public Gtk::VBox
101 {
102 public:
104 SVGPreview();
106 ~SVGPreview();
108 bool setDocument(SPDocument *doc);
110 bool setFileName(Glib::ustring &fileName);
112 bool setFromMem(char const *xmlBuffer);
114 bool set(Glib::ustring &fileName, int dialogType);
116 bool setURI(URI &uri);
118 /**
119 * Show image embedded in SVG
120 */
121 void showImage(Glib::ustring &fileName);
123 /**
124 * Show the "No preview" image
125 */
126 void showNoPreview();
128 /**
129 * Show the "Too large" image
130 */
131 void showTooLarge(long fileLength);
133 private:
134 /**
135 * The svg document we are currently showing
136 */
137 SPDocument *document;
139 /**
140 * The sp_svg_view widget
141 */
142 GtkWidget *viewerGtk;
144 /**
145 * are we currently showing the "no preview" image?
146 */
147 bool showingNoPreview;
149 };
151 /*#########################################################################
152 ### F I L E D I A L O G B A S E C L A S S
153 #########################################################################*/
155 /**
156 * This class is the base implementation for the others. This
157 * reduces redundancies and bugs.
158 */
159 class FileDialogBaseGtk : public Gtk::FileChooserDialog
160 {
161 public:
163 /**
164 *
165 */
166 FileDialogBaseGtk(Gtk::Window& parentWindow, const Glib::ustring &title,
167 FileDialogType type, gchar const* preferenceBase) :
168 Gtk::FileChooserDialog(parentWindow, title),
169 preferenceBase(preferenceBase ? preferenceBase : "unknown"),
170 dialogType(type)
171 {
172 internalSetup();
173 }
175 /**
176 *
177 */
178 FileDialogBaseGtk(Gtk::Window& parentWindow, const Glib::ustring &title,
179 Gtk::FileChooserAction dialogType, FileDialogType type, gchar const* preferenceBase) :
180 Gtk::FileChooserDialog(parentWindow, title, dialogType),
181 preferenceBase(preferenceBase ? preferenceBase : "unknown"),
182 dialogType(type)
183 {
184 internalSetup();
185 }
187 /**
188 *
189 */
190 virtual ~FileDialogBaseGtk()
191 {}
193 protected:
194 void cleanup( bool showConfirmed );
196 Glib::ustring preferenceBase;
197 /**
198 * What type of 'open' are we? (open, import, place, etc)
199 */
200 FileDialogType dialogType;
202 /**
203 * Our svg preview widget
204 */
205 SVGPreview svgPreview;
207 //# Child widgets
208 Gtk::CheckButton previewCheckbox;
210 private:
211 void internalSetup();
213 /**
214 * Callback for user changing preview checkbox
215 */
216 void _previewEnabledCB();
218 /**
219 * Callback for seeing if the preview needs to be drawn
220 */
221 void _updatePreviewCallback();
222 };
227 /*#########################################################################
228 ### F I L E O P E N
229 #########################################################################*/
231 /**
232 * Our implementation class for the FileOpenDialog interface..
233 */
234 class FileOpenDialogImplGtk : public FileOpenDialog, public FileDialogBaseGtk
235 {
236 public:
238 FileOpenDialogImplGtk(Gtk::Window& parentWindow,
239 const Glib::ustring &dir,
240 FileDialogType fileTypes,
241 const Glib::ustring &title);
243 virtual ~FileOpenDialogImplGtk();
245 bool show();
247 Inkscape::Extension::Extension *getSelectionType();
249 Glib::ustring getFilename();
251 std::vector<Glib::ustring> getFilenames ();
253 private:
255 /**
256 * Create a filter menu for this type of dialog
257 */
258 void createFilterMenu();
260 /**
261 * Filter name->extension lookup
262 */
263 std::map<Glib::ustring, Inkscape::Extension::Extension *> extensionMap;
265 /**
266 * The extension to use to write this file
267 */
268 Inkscape::Extension::Extension *extension;
270 /**
271 * Filename that was given
272 */
273 Glib::ustring myFilename;
275 };
279 //########################################################################
280 //# F I L E S A V E
281 //########################################################################
283 /**
284 * Our implementation of the FileSaveDialog interface.
285 */
286 class FileSaveDialogImplGtk : public FileSaveDialog, public FileDialogBaseGtk
287 {
289 public:
290 FileSaveDialogImplGtk(Gtk::Window &parentWindow,
291 const Glib::ustring &dir,
292 FileDialogType fileTypes,
293 const Glib::ustring &title,
294 const Glib::ustring &default_key);
296 virtual ~FileSaveDialogImplGtk();
298 bool show();
300 Inkscape::Extension::Extension *getSelectionType();
301 virtual void setSelectionType( Inkscape::Extension::Extension * key );
303 Glib::ustring getFilename();
305 void change_title(const Glib::ustring& title);
306 void change_path(const Glib::ustring& path);
307 void updateNameAndExtension();
309 private:
311 /**
312 * Fix to allow the user to type the file name
313 */
314 Gtk::Entry *fileNameEntry;
317 /**
318 * Allow the specification of the output file type
319 */
320 Gtk::ComboBoxText fileTypeComboBox;
323 /**
324 * Data mirror of the combo box
325 */
326 std::vector<FileType> fileTypes;
328 //# Child widgets
329 Gtk::HBox childBox;
330 Gtk::VBox checksBox;
332 Gtk::CheckButton fileTypeCheckbox;
334 /**
335 * Callback for user input into fileNameEntry
336 */
337 void fileTypeChangedCallback();
339 /**
340 * Create a filter menu for this type of dialog
341 */
342 void createFileTypeMenu();
345 /**
346 * The extension to use to write this file
347 */
348 Inkscape::Extension::Extension *extension;
350 /**
351 * Callback for user input into fileNameEntry
352 */
353 void fileNameEntryChangedCallback();
355 /**
356 * Filename that was given
357 */
358 Glib::ustring myFilename;
360 /**
361 * List of known file extensions.
362 */
363 std::set<Glib::ustring> knownExtensions;
364 };
369 //########################################################################
370 //# F I L E E X P O R T
371 //########################################################################
373 /**
374 * Our implementation of the FileExportDialog interface.
375 */
376 class FileExportDialogImpl : public FileExportDialog, public FileDialogBaseGtk
377 {
379 public:
380 FileExportDialogImpl(Gtk::Window& parentWindow,
381 const Glib::ustring &dir,
382 FileDialogType fileTypes,
383 const Glib::ustring &title,
384 const Glib::ustring &default_key);
386 virtual ~FileExportDialogImpl();
388 bool show();
390 Inkscape::Extension::Extension *getSelectionType();
392 Glib::ustring getFilename();
395 /**
396 * Return the scope of the export. One of the enumerated types
397 * in ScopeType
398 */
399 ScopeType getScope()
400 {
401 if (pageButton.get_active())
402 return SCOPE_PAGE;
403 else if (selectionButton.get_active())
404 return SCOPE_SELECTION;
405 else if (customButton.get_active())
406 return SCOPE_CUSTOM;
407 else
408 return SCOPE_DOCUMENT;
410 }
412 /**
413 * Return left side of the exported region
414 */
415 double getSourceX()
416 { return sourceX0Spinner.getValue(); }
418 /**
419 * Return the top of the exported region
420 */
421 double getSourceY()
422 { return sourceY1Spinner.getValue(); }
424 /**
425 * Return the width of the exported region
426 */
427 double getSourceWidth()
428 { return sourceWidthSpinner.getValue(); }
430 /**
431 * Return the height of the exported region
432 */
433 double getSourceHeight()
434 { return sourceHeightSpinner.getValue(); }
436 /**
437 * Return the units of the coordinates of exported region
438 */
439 Glib::ustring getSourceUnits()
440 { return sourceUnitsSpinner.getUnitAbbr(); }
442 /**
443 * Return the width of the destination document
444 */
445 double getDestinationWidth()
446 { return destWidthSpinner.getValue(); }
448 /**
449 * Return the height of the destination document
450 */
451 double getDestinationHeight()
452 { return destHeightSpinner.getValue(); }
454 /**
455 * Return the height of the exported region
456 */
457 Glib::ustring getDestinationUnits()
458 { return destUnitsSpinner.getUnitAbbr(); }
460 /**
461 * Return the destination DPI image resulution, if bitmap
462 */
463 double getDestinationDPI()
464 { return destDPISpinner.getValue(); }
466 /**
467 * Return whether we should use Cairo for rendering
468 */
469 bool getUseCairo()
470 { return cairoButton.get_active(); }
472 /**
473 * Return whether we should use antialiasing
474 */
475 bool getUseAntialias()
476 { return antiAliasButton.get_active(); }
478 /**
479 * Return the background color for exporting
480 */
481 unsigned long getBackground()
482 { return backgroundButton.get_color().get_pixel(); }
484 private:
486 /**
487 * Fix to allow the user to type the file name
488 */
489 Gtk::Entry *fileNameEntry;
491 //##########################################
492 //# EXTRA WIDGET -- SOURCE SIDE
493 //##########################################
495 Gtk::Frame sourceFrame;
496 Gtk::VBox sourceBox;
498 Gtk::HBox scopeBox;
499 Gtk::RadioButtonGroup scopeGroup;
500 Gtk::RadioButton documentButton;
501 Gtk::RadioButton pageButton;
502 Gtk::RadioButton selectionButton;
503 Gtk::RadioButton customButton;
505 Gtk::Table sourceTable;
506 Inkscape::UI::Widget::Scalar sourceX0Spinner;
507 Inkscape::UI::Widget::Scalar sourceY0Spinner;
508 Inkscape::UI::Widget::Scalar sourceX1Spinner;
509 Inkscape::UI::Widget::Scalar sourceY1Spinner;
510 Inkscape::UI::Widget::Scalar sourceWidthSpinner;
511 Inkscape::UI::Widget::Scalar sourceHeightSpinner;
512 Inkscape::UI::Widget::UnitMenu sourceUnitsSpinner;
515 //##########################################
516 //# EXTRA WIDGET -- DESTINATION SIDE
517 //##########################################
519 Gtk::Frame destFrame;
520 Gtk::VBox destBox;
522 Gtk::Table destTable;
523 Inkscape::UI::Widget::Scalar destWidthSpinner;
524 Inkscape::UI::Widget::Scalar destHeightSpinner;
525 Inkscape::UI::Widget::Scalar destDPISpinner;
526 Inkscape::UI::Widget::UnitMenu destUnitsSpinner;
528 Gtk::HBox otherOptionBox;
529 Gtk::CheckButton cairoButton;
530 Gtk::CheckButton antiAliasButton;
531 Gtk::ColorButton backgroundButton;
534 /**
535 * 'Extra' widget that holds two boxes above
536 */
537 Gtk::HBox exportOptionsBox;
540 //# Child widgets
541 Gtk::CheckButton fileTypeCheckbox;
543 /**
544 * Allow the specification of the output file type
545 */
546 Gtk::ComboBoxText fileTypeComboBox;
549 /**
550 * Data mirror of the combo box
551 */
552 std::vector<FileType> fileTypes;
556 /**
557 * Callback for user input into fileNameEntry
558 */
559 void fileTypeChangedCallback();
561 /**
562 * Create a filter menu for this type of dialog
563 */
564 void createFileTypeMenu();
567 bool append_extension;
569 /**
570 * The extension to use to write this file
571 */
572 Inkscape::Extension::Extension *extension;
574 /**
575 * Callback for user input into fileNameEntry
576 */
577 void fileNameEntryChangedCallback();
579 /**
580 * Filename that was given
581 */
582 Glib::ustring myFilename;
583 };
586 }
587 }
588 }
590 #endif /*__FILE_DIALOGIMPL_H__*/
592 /*
593 Local Variables:
594 mode:c++
595 c-file-style:"stroustrup"
596 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
597 indent-tabs-mode:nil
598 fill-column:99
599 End:
600 */
601 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :