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,
293 const gchar* docTitle);
295 virtual ~FileSaveDialogImplGtk();
297 bool show();
299 Inkscape::Extension::Extension *getSelectionType();
300 virtual void setSelectionType( Inkscape::Extension::Extension * key );
302 Glib::ustring getCurrentDirectory();
304 private:
305 //void change_title(const Glib::ustring& title);
306 void change_path(const Glib::ustring& path);
307 void updateNameAndExtension();
309 /**
310 * Fix to allow the user to type the file name
311 */
312 Gtk::Entry *fileNameEntry;
315 /**
316 * Allow the specification of the output file type
317 */
318 Gtk::ComboBoxText fileTypeComboBox;
321 /**
322 * Data mirror of the combo box
323 */
324 std::vector<FileType> fileTypes;
326 //# Child widgets
327 Gtk::HBox childBox;
328 Gtk::VBox checksBox;
330 Gtk::CheckButton fileTypeCheckbox;
332 /**
333 * Callback for user input into fileNameEntry
334 */
335 void fileTypeChangedCallback();
337 /**
338 * Create a filter menu for this type of dialog
339 */
340 void createFileTypeMenu();
343 /**
344 * The extension to use to write this file
345 */
346 Inkscape::Extension::Extension *extension;
348 /**
349 * Callback for user input into fileNameEntry
350 */
351 void fileNameEntryChangedCallback();
352 };
357 //########################################################################
358 //# F I L E E X P O R T
359 //########################################################################
361 /**
362 * Our implementation of the FileExportDialog interface.
363 */
364 class FileExportDialogImpl : public FileExportDialog, public FileDialogBaseGtk
365 {
367 public:
368 FileExportDialogImpl(Gtk::Window& parentWindow,
369 const Glib::ustring &dir,
370 FileDialogType fileTypes,
371 const Glib::ustring &title,
372 const Glib::ustring &default_key);
374 virtual ~FileExportDialogImpl();
376 bool show();
378 Inkscape::Extension::Extension *getSelectionType();
380 Glib::ustring getFilename();
383 /**
384 * Return the scope of the export. One of the enumerated types
385 * in ScopeType
386 */
387 ScopeType getScope()
388 {
389 if (pageButton.get_active())
390 return SCOPE_PAGE;
391 else if (selectionButton.get_active())
392 return SCOPE_SELECTION;
393 else if (customButton.get_active())
394 return SCOPE_CUSTOM;
395 else
396 return SCOPE_DOCUMENT;
398 }
400 /**
401 * Return left side of the exported region
402 */
403 double getSourceX()
404 { return sourceX0Spinner.getValue(); }
406 /**
407 * Return the top of the exported region
408 */
409 double getSourceY()
410 { return sourceY1Spinner.getValue(); }
412 /**
413 * Return the width of the exported region
414 */
415 double getSourceWidth()
416 { return sourceWidthSpinner.getValue(); }
418 /**
419 * Return the height of the exported region
420 */
421 double getSourceHeight()
422 { return sourceHeightSpinner.getValue(); }
424 /**
425 * Return the units of the coordinates of exported region
426 */
427 Glib::ustring getSourceUnits()
428 { return sourceUnitsSpinner.getUnitAbbr(); }
430 /**
431 * Return the width of the destination document
432 */
433 double getDestinationWidth()
434 { return destWidthSpinner.getValue(); }
436 /**
437 * Return the height of the destination document
438 */
439 double getDestinationHeight()
440 { return destHeightSpinner.getValue(); }
442 /**
443 * Return the height of the exported region
444 */
445 Glib::ustring getDestinationUnits()
446 { return destUnitsSpinner.getUnitAbbr(); }
448 /**
449 * Return the destination DPI image resulution, if bitmap
450 */
451 double getDestinationDPI()
452 { return destDPISpinner.getValue(); }
454 /**
455 * Return whether we should use Cairo for rendering
456 */
457 bool getUseCairo()
458 { return cairoButton.get_active(); }
460 /**
461 * Return whether we should use antialiasing
462 */
463 bool getUseAntialias()
464 { return antiAliasButton.get_active(); }
466 /**
467 * Return the background color for exporting
468 */
469 unsigned long getBackground()
470 { return backgroundButton.get_color().get_pixel(); }
472 private:
474 /**
475 * Fix to allow the user to type the file name
476 */
477 Gtk::Entry *fileNameEntry;
479 //##########################################
480 //# EXTRA WIDGET -- SOURCE SIDE
481 //##########################################
483 Gtk::Frame sourceFrame;
484 Gtk::VBox sourceBox;
486 Gtk::HBox scopeBox;
487 Gtk::RadioButtonGroup scopeGroup;
488 Gtk::RadioButton documentButton;
489 Gtk::RadioButton pageButton;
490 Gtk::RadioButton selectionButton;
491 Gtk::RadioButton customButton;
493 Gtk::Table sourceTable;
494 Inkscape::UI::Widget::Scalar sourceX0Spinner;
495 Inkscape::UI::Widget::Scalar sourceY0Spinner;
496 Inkscape::UI::Widget::Scalar sourceX1Spinner;
497 Inkscape::UI::Widget::Scalar sourceY1Spinner;
498 Inkscape::UI::Widget::Scalar sourceWidthSpinner;
499 Inkscape::UI::Widget::Scalar sourceHeightSpinner;
500 Inkscape::UI::Widget::UnitMenu sourceUnitsSpinner;
503 //##########################################
504 //# EXTRA WIDGET -- DESTINATION SIDE
505 //##########################################
507 Gtk::Frame destFrame;
508 Gtk::VBox destBox;
510 Gtk::Table destTable;
511 Inkscape::UI::Widget::Scalar destWidthSpinner;
512 Inkscape::UI::Widget::Scalar destHeightSpinner;
513 Inkscape::UI::Widget::Scalar destDPISpinner;
514 Inkscape::UI::Widget::UnitMenu destUnitsSpinner;
516 Gtk::HBox otherOptionBox;
517 Gtk::CheckButton cairoButton;
518 Gtk::CheckButton antiAliasButton;
519 Gtk::ColorButton backgroundButton;
522 /**
523 * 'Extra' widget that holds two boxes above
524 */
525 Gtk::HBox exportOptionsBox;
528 //# Child widgets
529 Gtk::CheckButton fileTypeCheckbox;
531 /**
532 * Allow the specification of the output file type
533 */
534 Gtk::ComboBoxText fileTypeComboBox;
537 /**
538 * Data mirror of the combo box
539 */
540 std::vector<FileType> fileTypes;
544 /**
545 * Callback for user input into fileNameEntry
546 */
547 void fileTypeChangedCallback();
549 /**
550 * Create a filter menu for this type of dialog
551 */
552 void createFileTypeMenu();
555 bool append_extension;
557 /**
558 * The extension to use to write this file
559 */
560 Inkscape::Extension::Extension *extension;
562 /**
563 * Callback for user input into fileNameEntry
564 */
565 void fileNameEntryChangedCallback();
567 /**
568 * Filename that was given
569 */
570 Glib::ustring myFilename;
571 };
574 }
575 }
576 }
578 #endif /*__FILE_DIALOGIMPL_H__*/
580 /*
581 Local Variables:
582 mode:c++
583 c-file-style:"stroustrup"
584 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
585 indent-tabs-mode:nil
586 fill-column:99
587 End:
588 */
589 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :