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
155 {
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
232 {
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
281 {
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 #ifdef NEW_EXPORT_DIALOG
362 //########################################################################
363 //# F I L E E X P O R T
364 //########################################################################
366 /**
367 * Our implementation of the FileExportDialog interface.
368 */
369 class FileExportDialogImpl : public FileExportDialog, public FileDialogBaseGtk
370 {
372 public:
373 FileExportDialogImpl(Gtk::Window& parentWindow,
374 const Glib::ustring &dir,
375 FileDialogType fileTypes,
376 const Glib::ustring &title,
377 const Glib::ustring &default_key);
379 virtual ~FileExportDialogImpl();
381 bool show();
383 Inkscape::Extension::Extension *getSelectionType();
385 Glib::ustring getFilename();
388 /**
389 * Return the scope of the export. One of the enumerated types
390 * in ScopeType
391 */
392 ScopeType getScope()
393 {
394 if (pageButton.get_active())
395 return SCOPE_PAGE;
396 else if (selectionButton.get_active())
397 return SCOPE_SELECTION;
398 else if (customButton.get_active())
399 return SCOPE_CUSTOM;
400 else
401 return SCOPE_DOCUMENT;
403 }
405 /**
406 * Return left side of the exported region
407 */
408 double getSourceX()
409 { return sourceX0Spinner.getValue(); }
411 /**
412 * Return the top of the exported region
413 */
414 double getSourceY()
415 { return sourceY1Spinner.getValue(); }
417 /**
418 * Return the width of the exported region
419 */
420 double getSourceWidth()
421 { return sourceWidthSpinner.getValue(); }
423 /**
424 * Return the height of the exported region
425 */
426 double getSourceHeight()
427 { return sourceHeightSpinner.getValue(); }
429 /**
430 * Return the units of the coordinates of exported region
431 */
432 Glib::ustring getSourceUnits()
433 { return sourceUnitsSpinner.getUnitAbbr(); }
435 /**
436 * Return the width of the destination document
437 */
438 double getDestinationWidth()
439 { return destWidthSpinner.getValue(); }
441 /**
442 * Return the height of the destination document
443 */
444 double getDestinationHeight()
445 { return destHeightSpinner.getValue(); }
447 /**
448 * Return the height of the exported region
449 */
450 Glib::ustring getDestinationUnits()
451 { return destUnitsSpinner.getUnitAbbr(); }
453 /**
454 * Return the destination DPI image resulution, if bitmap
455 */
456 double getDestinationDPI()
457 { return destDPISpinner.getValue(); }
459 /**
460 * Return whether we should use Cairo for rendering
461 */
462 bool getUseCairo()
463 { return cairoButton.get_active(); }
465 /**
466 * Return whether we should use antialiasing
467 */
468 bool getUseAntialias()
469 { return antiAliasButton.get_active(); }
471 /**
472 * Return the background color for exporting
473 */
474 unsigned long getBackground()
475 { return backgroundButton.get_color().get_pixel(); }
477 private:
479 /**
480 * Fix to allow the user to type the file name
481 */
482 Gtk::Entry *fileNameEntry;
484 //##########################################
485 //# EXTRA WIDGET -- SOURCE SIDE
486 //##########################################
488 Gtk::Frame sourceFrame;
489 Gtk::VBox sourceBox;
491 Gtk::HBox scopeBox;
492 Gtk::RadioButtonGroup scopeGroup;
493 Gtk::RadioButton documentButton;
494 Gtk::RadioButton pageButton;
495 Gtk::RadioButton selectionButton;
496 Gtk::RadioButton customButton;
498 Gtk::Table sourceTable;
499 Inkscape::UI::Widget::Scalar sourceX0Spinner;
500 Inkscape::UI::Widget::Scalar sourceY0Spinner;
501 Inkscape::UI::Widget::Scalar sourceX1Spinner;
502 Inkscape::UI::Widget::Scalar sourceY1Spinner;
503 Inkscape::UI::Widget::Scalar sourceWidthSpinner;
504 Inkscape::UI::Widget::Scalar sourceHeightSpinner;
505 Inkscape::UI::Widget::UnitMenu sourceUnitsSpinner;
508 //##########################################
509 //# EXTRA WIDGET -- DESTINATION SIDE
510 //##########################################
512 Gtk::Frame destFrame;
513 Gtk::VBox destBox;
515 Gtk::Table destTable;
516 Inkscape::UI::Widget::Scalar destWidthSpinner;
517 Inkscape::UI::Widget::Scalar destHeightSpinner;
518 Inkscape::UI::Widget::Scalar destDPISpinner;
519 Inkscape::UI::Widget::UnitMenu destUnitsSpinner;
521 Gtk::HBox otherOptionBox;
522 Gtk::CheckButton cairoButton;
523 Gtk::CheckButton antiAliasButton;
524 Gtk::ColorButton backgroundButton;
527 /**
528 * 'Extra' widget that holds two boxes above
529 */
530 Gtk::HBox exportOptionsBox;
533 //# Child widgets
534 Gtk::CheckButton fileTypeCheckbox;
536 /**
537 * Allow the specification of the output file type
538 */
539 Gtk::ComboBoxText fileTypeComboBox;
542 /**
543 * Data mirror of the combo box
544 */
545 std::vector<FileType> fileTypes;
549 /**
550 * Callback for user input into fileNameEntry
551 */
552 void fileTypeChangedCallback();
554 /**
555 * Create a filter menu for this type of dialog
556 */
557 void createFileTypeMenu();
560 bool append_extension;
562 /**
563 * The extension to use to write this file
564 */
565 Inkscape::Extension::Extension *extension;
567 /**
568 * Callback for user input into fileNameEntry
569 */
570 void fileNameEntryChangedCallback();
572 /**
573 * Filename that was given
574 */
575 Glib::ustring myFilename;
576 };
578 #endif // NEW_EXPORT_DIALOG
580 } // namespace Dialog
581 } // namespace UI
582 } // namespace Inkscape
584 #endif /*__FILE_DIALOGIMPL_H__*/
586 /*
587 Local Variables:
588 mode:c++
589 c-file-style:"stroustrup"
590 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
591 indent-tabs-mode:nil
592 fill-column:99
593 End:
594 */
595 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :