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"
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>
43 //Inkscape includes
44 #include "extension/input.h"
45 #include "extension/output.h"
46 #include "extension/db.h"
47 #include "inkscape.h"
48 #include "svg-view-widget.h"
50 //For export dialog
51 #include "ui/widget/scalar-unit.h"
53 namespace Inkscape
54 {
55 namespace UI
56 {
57 namespace Dialog
58 {
60 /*#########################################################################
61 ### Utility
62 #########################################################################*/
63 void
64 fileDialogExtensionToPattern(Glib::ustring &pattern,
65 Glib::ustring &extension);
67 void
68 findEntryWidgets(Gtk::Container *parent,
69 std::vector<Gtk::Entry *> &result);
71 void
72 findExpanderWidgets(Gtk::Container *parent,
73 std::vector<Gtk::Expander *> &result);
75 /*#########################################################################
76 ### SVG Preview Widget
77 #########################################################################*/
79 class FileType
80 {
81 public:
82 FileType() {}
83 ~FileType() {}
84 Glib::ustring name;
85 Glib::ustring pattern;
86 Inkscape::Extension::Extension *extension;
87 };
89 /**
90 * Simple class for displaying an SVG file in the "preview widget."
91 * Currently, this is just a wrapper of the sp_svg_view Gtk widget.
92 * Hopefully we will eventually replace with a pure Gtkmm widget.
93 */
94 class SVGPreview : public Gtk::VBox
95 {
96 public:
98 SVGPreview();
100 ~SVGPreview();
102 bool setDocument(SPDocument *doc);
104 bool setFileName(Glib::ustring &fileName);
106 bool setFromMem(char const *xmlBuffer);
108 bool set(Glib::ustring &fileName, int dialogType);
110 bool setURI(URI &uri);
112 /**
113 * Show image embedded in SVG
114 */
115 void showImage(Glib::ustring &fileName);
117 /**
118 * Show the "No preview" image
119 */
120 void showNoPreview();
122 /**
123 * Show the "Too large" image
124 */
125 void showTooLarge(long fileLength);
127 private:
128 /**
129 * The svg document we are currently showing
130 */
131 SPDocument *document;
133 /**
134 * The sp_svg_view widget
135 */
136 GtkWidget *viewerGtk;
138 /**
139 * are we currently showing the "no preview" image?
140 */
141 bool showingNoPreview;
143 };
145 /*#########################################################################
146 ### F I L E D I A L O G B A S E C L A S S
147 #########################################################################*/
149 /**
150 * This class is the base implementation for the others. This
151 * reduces redundancies and bugs.
152 */
153 class FileDialogBaseGtk : public Gtk::FileChooserDialog
154 {
155 public:
157 /**
158 *
159 */
160 FileDialogBaseGtk(Gtk::Window& parentWindow, const Glib::ustring &title,
161 Gtk::FileChooserAction dialogType, FileDialogType type, gchar const* preferenceBase) :
162 Gtk::FileChooserDialog(parentWindow, title, dialogType),
163 preferenceBase(preferenceBase ? preferenceBase : "unknown"),
164 _dialogType(type)
165 {
166 internalSetup();
167 }
169 /**
170 *
171 */
172 FileDialogBaseGtk(Gtk::Window& parentWindow, const char *title,
173 Gtk::FileChooserAction dialogType, FileDialogType type, gchar const* preferenceBase) :
174 Gtk::FileChooserDialog(parentWindow, title, dialogType),
175 preferenceBase(preferenceBase ? preferenceBase : "unknown"),
176 _dialogType(type)
177 {
178 internalSetup();
179 }
181 /**
182 *
183 */
184 virtual ~FileDialogBaseGtk()
185 {}
187 protected:
188 void cleanup( bool showConfirmed );
190 Glib::ustring const preferenceBase;
191 /**
192 * What type of 'open' are we? (open, import, place, etc)
193 */
194 FileDialogType _dialogType;
196 /**
197 * Our svg preview widget
198 */
199 SVGPreview svgPreview;
201 /**
202 * Child widgets
203 */
204 Gtk::CheckButton previewCheckbox;
206 private:
207 void internalSetup();
209 /**
210 * Callback for user changing preview checkbox
211 */
212 void _previewEnabledCB();
214 /**
215 * Callback for seeing if the preview needs to be drawn
216 */
217 void _updatePreviewCallback();
218 };
223 /*#########################################################################
224 ### F I L E O P E N
225 #########################################################################*/
227 /**
228 * Our implementation class for the FileOpenDialog interface..
229 */
230 class FileOpenDialogImplGtk : public FileOpenDialog, public FileDialogBaseGtk
231 {
232 public:
234 FileOpenDialogImplGtk(Gtk::Window& parentWindow,
235 const Glib::ustring &dir,
236 FileDialogType fileTypes,
237 const Glib::ustring &title);
239 virtual ~FileOpenDialogImplGtk();
241 bool show();
243 Inkscape::Extension::Extension *getSelectionType();
245 Glib::ustring getFilename();
247 std::vector<Glib::ustring> getFilenames();
249 Glib::ustring getCurrentDirectory();
251 private:
253 /**
254 * Create a filter menu for this type of dialog
255 */
256 void createFilterMenu();
258 /**
259 * Filter name->extension lookup
260 */
261 std::map<Glib::ustring, Inkscape::Extension::Extension *> extensionMap;
263 /**
264 * The extension to use to write this file
265 */
266 Inkscape::Extension::Extension *extension;
268 };
272 //########################################################################
273 //# F I L E S A V E
274 //########################################################################
276 /**
277 * Our implementation of the FileSaveDialog interface.
278 */
279 class FileSaveDialogImplGtk : public FileSaveDialog, public FileDialogBaseGtk
280 {
282 public:
283 FileSaveDialogImplGtk(Gtk::Window &parentWindow,
284 const Glib::ustring &dir,
285 FileDialogType fileTypes,
286 const Glib::ustring &title,
287 const Glib::ustring &default_key,
288 const gchar* docTitle);
290 virtual ~FileSaveDialogImplGtk();
292 bool show();
294 Inkscape::Extension::Extension *getSelectionType();
295 virtual void setSelectionType( Inkscape::Extension::Extension * key );
297 Glib::ustring getCurrentDirectory();
299 private:
300 //void change_title(const Glib::ustring& title);
301 void change_path(const Glib::ustring& path);
302 void updateNameAndExtension();
304 /**
305 * Fix to allow the user to type the file name
306 */
307 Gtk::Entry *fileNameEntry;
310 /**
311 * Allow the specification of the output file type
312 */
313 Gtk::ComboBoxText fileTypeComboBox;
316 /**
317 * Data mirror of the combo box
318 */
319 std::vector<FileType> fileTypes;
321 //# Child widgets
322 Gtk::HBox childBox;
323 Gtk::VBox checksBox;
325 Gtk::CheckButton fileTypeCheckbox;
327 /**
328 * Callback for user input into fileNameEntry
329 */
330 void fileTypeChangedCallback();
332 /**
333 * Create a filter menu for this type of dialog
334 */
335 void createFileTypeMenu();
338 /**
339 * The extension to use to write this file
340 */
341 Inkscape::Extension::Extension *extension;
343 /**
344 * Callback for user input into fileNameEntry
345 */
346 void fileNameEntryChangedCallback();
347 };
352 //########################################################################
353 //# F I L E E X P O R T
354 //########################################################################
356 /**
357 * Our implementation of the FileExportDialog interface.
358 */
359 class FileExportDialogImpl : public FileExportDialog, public FileDialogBaseGtk
360 {
362 public:
363 FileExportDialogImpl(Gtk::Window& parentWindow,
364 const Glib::ustring &dir,
365 FileDialogType fileTypes,
366 const Glib::ustring &title,
367 const Glib::ustring &default_key);
369 virtual ~FileExportDialogImpl();
371 bool show();
373 Inkscape::Extension::Extension *getSelectionType();
375 Glib::ustring getFilename();
378 /**
379 * Return the scope of the export. One of the enumerated types
380 * in ScopeType
381 */
382 ScopeType getScope()
383 {
384 if (pageButton.get_active())
385 return SCOPE_PAGE;
386 else if (selectionButton.get_active())
387 return SCOPE_SELECTION;
388 else if (customButton.get_active())
389 return SCOPE_CUSTOM;
390 else
391 return SCOPE_DOCUMENT;
393 }
395 /**
396 * Return left side of the exported region
397 */
398 double getSourceX()
399 { return sourceX0Spinner.getValue(); }
401 /**
402 * Return the top of the exported region
403 */
404 double getSourceY()
405 { return sourceY1Spinner.getValue(); }
407 /**
408 * Return the width of the exported region
409 */
410 double getSourceWidth()
411 { return sourceWidthSpinner.getValue(); }
413 /**
414 * Return the height of the exported region
415 */
416 double getSourceHeight()
417 { return sourceHeightSpinner.getValue(); }
419 /**
420 * Return the units of the coordinates of exported region
421 */
422 Glib::ustring getSourceUnits()
423 { return sourceUnitsSpinner.getUnitAbbr(); }
425 /**
426 * Return the width of the destination document
427 */
428 double getDestinationWidth()
429 { return destWidthSpinner.getValue(); }
431 /**
432 * Return the height of the destination document
433 */
434 double getDestinationHeight()
435 { return destHeightSpinner.getValue(); }
437 /**
438 * Return the height of the exported region
439 */
440 Glib::ustring getDestinationUnits()
441 { return destUnitsSpinner.getUnitAbbr(); }
443 /**
444 * Return the destination DPI image resulution, if bitmap
445 */
446 double getDestinationDPI()
447 { return destDPISpinner.getValue(); }
449 /**
450 * Return whether we should use Cairo for rendering
451 */
452 bool getUseCairo()
453 { return cairoButton.get_active(); }
455 /**
456 * Return whether we should use antialiasing
457 */
458 bool getUseAntialias()
459 { return antiAliasButton.get_active(); }
461 /**
462 * Return the background color for exporting
463 */
464 unsigned long getBackground()
465 { return backgroundButton.get_color().get_pixel(); }
467 private:
469 /**
470 * Fix to allow the user to type the file name
471 */
472 Gtk::Entry *fileNameEntry;
474 //##########################################
475 //# EXTRA WIDGET -- SOURCE SIDE
476 //##########################################
478 Gtk::Frame sourceFrame;
479 Gtk::VBox sourceBox;
481 Gtk::HBox scopeBox;
482 Gtk::RadioButtonGroup scopeGroup;
483 Gtk::RadioButton documentButton;
484 Gtk::RadioButton pageButton;
485 Gtk::RadioButton selectionButton;
486 Gtk::RadioButton customButton;
488 Gtk::Table sourceTable;
489 Inkscape::UI::Widget::Scalar sourceX0Spinner;
490 Inkscape::UI::Widget::Scalar sourceY0Spinner;
491 Inkscape::UI::Widget::Scalar sourceX1Spinner;
492 Inkscape::UI::Widget::Scalar sourceY1Spinner;
493 Inkscape::UI::Widget::Scalar sourceWidthSpinner;
494 Inkscape::UI::Widget::Scalar sourceHeightSpinner;
495 Inkscape::UI::Widget::UnitMenu sourceUnitsSpinner;
498 //##########################################
499 //# EXTRA WIDGET -- DESTINATION SIDE
500 //##########################################
502 Gtk::Frame destFrame;
503 Gtk::VBox destBox;
505 Gtk::Table destTable;
506 Inkscape::UI::Widget::Scalar destWidthSpinner;
507 Inkscape::UI::Widget::Scalar destHeightSpinner;
508 Inkscape::UI::Widget::Scalar destDPISpinner;
509 Inkscape::UI::Widget::UnitMenu destUnitsSpinner;
511 Gtk::HBox otherOptionBox;
512 Gtk::CheckButton cairoButton;
513 Gtk::CheckButton antiAliasButton;
514 Gtk::ColorButton backgroundButton;
517 /**
518 * 'Extra' widget that holds two boxes above
519 */
520 Gtk::HBox exportOptionsBox;
523 //# Child widgets
524 Gtk::CheckButton fileTypeCheckbox;
526 /**
527 * Allow the specification of the output file type
528 */
529 Gtk::ComboBoxText fileTypeComboBox;
532 /**
533 * Data mirror of the combo box
534 */
535 std::vector<FileType> fileTypes;
539 /**
540 * Callback for user input into fileNameEntry
541 */
542 void fileTypeChangedCallback();
544 /**
545 * Create a filter menu for this type of dialog
546 */
547 void createFileTypeMenu();
550 bool append_extension;
552 /**
553 * The extension to use to write this file
554 */
555 Inkscape::Extension::Extension *extension;
557 /**
558 * Callback for user input into fileNameEntry
559 */
560 void fileNameEntryChangedCallback();
562 /**
563 * Filename that was given
564 */
565 Glib::ustring myFilename;
566 };
569 } // namespace Dialog
570 } // namespace UI
571 } // namespace Inkscape
573 #endif /*__FILE_DIALOGIMPL_H__*/
575 /*
576 Local Variables:
577 mode:c++
578 c-file-style:"stroustrup"
579 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
580 indent-tabs-mode:nil
581 fill-column:99
582 End:
583 */
584 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :