Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
choose-file-utils.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
2
3#include "choose-file-utils.h"
4
5#include <giomm/liststore.h>
6#include <glibmm/i18n.h>
7#include <gtkmm/filefilter.h>
8
9#include "preferences.h"
10
11#include "extension/db.h"
12#include "extension/input.h"
13#include "extension/output.h"
14
15namespace Inkscape::UI::Dialog {
16
17// TODO: Should we always try to use document directory if no path in preferences?
18void get_start_directory(std::string &start_path, Glib::ustring const &prefs_path, bool try_document_dir)
19{
20 // Get the current directory for finding files.
22 std::string attr = prefs->getString(prefs_path); // Glib::ustring -> std::string
23 if (!attr.empty()) {
24 start_path = attr;
25 }
26
27 // Test if the path directory exists.
28 if (!Glib::file_test(start_path, Glib::FileTest::EXISTS)) {
29 std::cerr << "get_start_directory: directory does not exist: " << start_path << std::endl;
30 start_path = "";
31 }
32
33 // If no start path, try document directory.
34 if (start_path.empty() && try_document_dir) {
35 start_path = Glib::get_user_special_dir(Glib::UserDirectory::DOCUMENTS);
36 }
37
38 // If no start path, default to home directory.
39 if (start_path.empty()) {
40 start_path = Glib::get_home_dir();
41 }
42}
43
44Glib::RefPtr<Gio::ListStore<Gtk::FileFilter>>
46
48
49 auto allfiles = Gtk::FileFilter::create();
50 allfiles->set_name(_("All Files"));
51 allfiles->add_pattern("*");
52 filters->append(allfiles);
53
54 auto inkscape = Gtk::FileFilter::create();
55 inkscape->set_name(_("All Inkscape Files"));
56 filters->append(inkscape);
57
58 auto images = Gtk::FileFilter::create();
59 images->set_name(_("Images"));
60 filters->append(images);
61
62 auto bitmaps = Gtk::FileFilter::create();
63 bitmaps->set_name(_("Bitmaps"));
64 filters->append(bitmaps);
65
66 auto vectors = Gtk::FileFilter::create();
67 vectors->set_name(_("Vectors"));
68 filters->append(vectors);
69
70 // Patterns added dynamically below based on which files are supported by input extensions.
73
74 for (auto imod : extension_list) {
75
76 gchar const * extension = imod->get_extension();
77 if (extension[0]) {
78 extension = extension + 1; // extension begins with '.', we need it without!
79 }
80
81 // TODO: Evaluate add_mime_type() instead of add_suffix(). This might allow opening
82 // files with wrong extension.
83
84 // Add filter for this extension.
85 auto filter = Gtk::FileFilter::create();
86 filter->set_name(imod->get_filetypename(true));
87 filter->add_suffix(extension); // Both upper and lower cases.
88 filters->append(filter);
89
90 inkscape->add_suffix(extension);
91
92 if (strncmp("image", imod->get_mimetype(), 5) == 0) {
93 images->add_suffix(extension);
94 }
95
96 // I don't know of any other way to define "bitmap" formats other than by listing them
97 // clang-format off
98 if (strncmp("image/png", imod->get_mimetype(), 9) == 0 ||
99 strncmp("image/jpeg", imod->get_mimetype(), 10) == 0 ||
100 strncmp("image/gif", imod->get_mimetype(), 9) == 0 ||
101 strncmp("image/x-icon", imod->get_mimetype(), 12) == 0 ||
102 strncmp("image/x-navi-animation", imod->get_mimetype(), 22) == 0 ||
103 strncmp("image/x-cmu-raster", imod->get_mimetype(), 18) == 0 ||
104 strncmp("image/x-xpixmap", imod->get_mimetype(), 15) == 0 ||
105 strncmp("image/bmp", imod->get_mimetype(), 9) == 0 ||
106 strncmp("image/vnd.wap.wbmp", imod->get_mimetype(), 18) == 0 ||
107 strncmp("image/tiff", imod->get_mimetype(), 10) == 0 ||
108 strncmp("image/x-xbitmap", imod->get_mimetype(), 15) == 0 ||
109 strncmp("image/x-tga", imod->get_mimetype(), 11) == 0 ||
110 strncmp("image/x-pcx", imod->get_mimetype(), 11) == 0) {
111 bitmaps->add_suffix(extension);
112 } else {
113 vectors->add_suffix(extension);
114 }
115 // clang-format on
116 } // Loop over extension_list
117
118 return filters;
119}
120
121// Return a list of file filters for the Export dialog.
122// Optionally, return a custom list for the Save dialog (hopefully to disappear).
123// With native dialogs, we can only examine the file path on return.
124Glib::RefPtr<Gio::ListStore<Gtk::FileFilter>>
125create_export_filters(bool for_save) {
126
128
129 auto allfiles = Gtk::FileFilter::create();
130 allfiles->set_name(_("All Files"));
131 allfiles->add_pattern("*");
132 filters->append(allfiles);
133
134 // Patterns added dynamically below based on which files are supported by output extensions.
137
138 std::vector<Glib::ustring> file_extensions;
139
140 for (auto omod : extension_list) {
141
142 // std::cout << " " << extension
143 // << " exported: " << std::boolalpha << omod->is_exported()
144 // << " raster: " << std::boolalpha << omod->is_raster()
145 // << " save copy only: " << std::boolalpha << omod->savecopy_only() // Always false!
146 // << " " << omod->get_filetypename()
147 // << std::endl;
148
149 // Save dialogs cannot handle raster images.
150 if (for_save && omod->is_raster()) {
151 continue;
152 }
153
154 gchar const * extension = omod->get_extension();
155 if (extension[0]) {
156 extension = extension + 1; // extension begins with '.', we need it without!
157 }
158 Glib::ustring file_extension(extension);
159
160 // Don't add entry for duplicate filename extensions.
161 if (std::find(file_extensions.begin(), file_extensions.end(), file_extension) != file_extensions.end()) {
162 // std::cout << "Duplicate extension: " << file_extension << std::endl;
163 continue;
164 }
165 file_extensions.emplace_back(extension);
166
167
168 // For duplicate filename extensions, use simplified name.
169 auto name = omod->get_filetypename(true);
170 if (file_extension == "svg") {
171 name = "SVG (.svg)";
172 }
173 else if (file_extension == "svgz") {
174 name = _("Compressed SVG (.svgz)");
175 }
176 else if (file_extension == "dxf") {
177 name = "DXF (.dxf)";
178 }
179 else if (file_extension == "zip") {
180 name = "ZIP (.zip)";
181 }
182 else if (file_extension == "pdf") {
183 name = "PDF (.pdf)";
184 }
185 else if (file_extension == "png") {
186 name = "PNG (.png)";
187 }
188
189 // Add filter for this extension. Also see ExtensionList::setup().
190 auto filter = Gtk::FileFilter::create();
191 filter->set_name(name);
192 filter->add_suffix(extension); // Both upper and lower cases.
193 filters->append(filter);
194 } // Loop over extension_list
195
196 return filters;
197}
198
199} // namespace Inkscape::UI::Dialog
200
201/*
202 Local Variables:
203 mode:c++
204 c-file-style:"stroustrup"
205 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
206 indent-tabs-mode:nil
207 fill-column:99
208 End:
209*/
210// vim:filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99:
std::list< Output * > OutputList
Definition db.h:58
OutputList & get_output_list(OutputList &ou_list)
Creates a list of all the Output extensions.
Definition db.cpp:256
std::list< Input * > InputList
Definition db.h:59
InputList & get_input_list(InputList &ou_list)
Creates a list of all the Input extensions.
Definition db.cpp:242
Preference storage class.
Definition preferences.h:61
Glib::ustring getString(Glib::ustring const &pref_path, Glib::ustring const &def="")
Retrieve an UTF-8 string.
static Preferences * get()
Access the singleton Preferences object.
DB db
This is the actual database object.
Definition db.cpp:32
Dialog code.
Definition desktop.h:117
Glib::RefPtr< Gio::ListStore< Gtk::FileFilter > > create_export_filters(bool for_save)
Create a Gtk::FileFilter for all export file types.
void get_start_directory(std::string &start_path, Glib::ustring const &prefs_path, bool try_document_dir)
Find the start directory for a file dialog.
Glib::RefPtr< Gio::ListStore< Gtk::FileFilter > > create_open_filters()
Create a Gtk::FileFilter for all image file types.
static Glib::ustring const prefs_path
Singleton class to access the preferences file in a convenient way.
Glib::ustring name
Definition toolbars.cpp:55