Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
export-lists.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
2/* Authors:
3 * Anshudhar Kumar Singh <anshudhar2001@gmail.com>
4 *
5 * Copyright (C) 2021 Authors
6 *
7 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
8 */
9
10#include "export-lists.h"
11
12#include <glibmm/i18n.h>
13#include <glibmm/convert.h> // filename_from_utf8
14#include <glibmm/ustring.h>
15#include <gtkmm/builder.h>
16#include <gtkmm/label.h>
17#include <gtkmm/menubutton.h>
18#include <gtkmm/popover.h>
19#include <gtkmm/spinbutton.h>
20#include <gtkmm/viewport.h>
21
22#include "extension/db.h"
23#include "extension/output.h"
24#include "file.h"
25#include "helper/png-write.h"
26#include "io/sys.h"
27#include "preferences.h"
28#include "ui/icon-loader.h"
29#include "ui/builder-utils.h"
30#include "util/units.h"
31
32namespace Inkscape::UI::Dialog {
33
38
39ExtensionList::ExtensionList(BaseObjectType *cobject, const Glib::RefPtr<Gtk::Builder> &refGlade)
40 : Gtk::ComboBoxText{cobject}
41{
42 init();
43}
44
46
48{
49 _builder = create_builder("dialog-export-prefs.glade");
50 _pref_button = &get_widget<Gtk::MenuButton>(_builder, "pref_button");
51 _pref_popover = &get_widget<Gtk::Popover> (_builder, "pref_popover");
52 _pref_holder = &get_widget<Gtk::Viewport> (_builder, "pref_holder");
53
54 _popover_signal = _pref_popover->signal_show().connect([=, this]() {
55 _pref_holder->unset_child();
56 if (auto ext = getExtension()) {
57 if (auto gui = ext->autogui(nullptr, nullptr)) {
58 _pref_holder->set_child(*gui);
59 _pref_popover->grab_focus();
60 }
61 }
62 });
63
65 _watch_pref = prefs->createObserver("/dialogs/export/show_all_extensions", [this]() { setup(); });
66 // limit size of the combobox
67 auto cell_renderer = dynamic_cast<Gtk::CellRendererText*>(get_first_cell());
68 cell_renderer->set_fixed_size(125, -1);
69 cell_renderer->property_wrap_mode().set_value(Pango::WrapMode::WORD);
70 cell_renderer->property_wrap_width().set_value(5);
71}
72
74{
75 bool has_prefs = false;
76 if (auto ext = getExtension()) {
77 has_prefs = (ext->widget_visible_count() > 0);
78 }
79 _pref_button->set_sensitive(has_prefs);
80}
81
83{
84 // See also create_export_filters().
85 this->remove_all();
86
88 bool export_all = prefs->getBool("/dialogs/export/show_all_extensions", false);
89
92 for (auto omod : extensions) {
93 auto oid = Glib::ustring(omod->get_id());
94 // if (!export_all && !omod->is_raster() && !omod->is_exported())
95 // continue;
96 // Comboboxes don't have a disabled row property
97 if (omod->deactivated())
98 continue;
99 this->append(oid, omod->get_filetypename());
100 // Record extensions map for filename-to-combo selections
101 auto ext = omod->get_extension();
102 if (!ext_to_mod[ext]) {
103 // Some extensions have multiple of the same extension (for example PNG)
104 // we're going to pick the first in the found list to back-link to.
105 ext_to_mod[ext] = omod;
106 }
107 }
108 this->set_active_id(SP_MODULE_KEY_RASTER_PNG);
109}
110
115{
116 return dynamic_cast<Inkscape::Extension::Output *>(Inkscape::Extension::db.get(this->get_active_id().c_str()));
117}
118
123{
124 if (auto ext = getExtension()) {
125 return Glib::filename_from_utf8(ext->get_extension());
126 }
127 return "";
128}
129
133void ExtensionList::removeExtension(std::string &filename)
134{
135 auto ext = Inkscape::IO::get_file_extension(filename);
136 if (ext_to_mod[ext]) {
137 filename.erase(filename.size()-ext.size());
138 }
139}
140
141void ExtensionList::setExtensionFromFilename(std::string const &filename)
142{
143 auto ext = Inkscape::IO::get_file_extension(filename);
144 if (ext != getFileExtension()) {
145 if (auto omod = ext_to_mod[ext]) {
146 this->set_active_id(omod->get_id());
147 }
148 }
149}
150
152{
153 if (_initialised) {
154 return;
155 }
156 _initialised = true;
158 default_dpi = prefs->getDouble("/dialogs/export/defaultxdpi/value", DPI_BASE);
159
160 auto const add_button = Gtk::make_managed<Gtk::Button>();
161 Glib::ustring label = _("Add Export");
162 add_button->set_label(label);
163 this->attach(*add_button, 0, 0, 5, 1);
164
165 this->insert_row(0);
166
167 auto const suffix_label = Gtk::make_managed<Gtk::Label>(_("Suffix"));
168 this->attach(*suffix_label, _suffix_col, 0, 1, 1);
169 suffix_label->set_visible(true);
170
171 auto const extension_label = Gtk::make_managed<Gtk::Label>(_("Format"));
172 this->attach(*extension_label, _extension_col, 0, 2, 1);
173 extension_label->set_visible(true);
174
175 auto const dpi_label = Gtk::make_managed<Gtk::Label>(_("DPI"));
176 this->attach(*dpi_label, _dpi_col, 0, 1, 1);
177 dpi_label->set_visible(true);
178
179 append_row();
180
181 add_button->signal_clicked().connect(sigc::mem_fun(*this, &ExportList::append_row));
182 add_button->set_hexpand(true);
183 add_button->set_visible(true);
184
185 this->set_row_spacing(5);
186 this->set_column_spacing(2);
187}
188
189void ExportList::removeExtension(std::string &filename)
190{
191 ExtensionList *extension_cb = dynamic_cast<ExtensionList *>(this->get_child_at(_extension_col, 1));
192 if (extension_cb) {
193 extension_cb->removeExtension(filename);
194 return;
195 }
196}
197
199{
200 int current_row = _num_rows + 1; // because we have label row at top
201 this->insert_row(current_row);
202
203 auto const suffix = Gtk::make_managed<Gtk::Entry>();
204 this->attach(*suffix, _suffix_col, current_row, 1, 1);
205 suffix->set_width_chars(2);
206 suffix->set_hexpand(true);
207 suffix->set_placeholder_text(_("Suffix"));
208 suffix->set_visible(true);
209
210 auto const extension = Gtk::make_managed<ExtensionList>();
211 auto const dpi_sb = Gtk::make_managed<Gtk::SpinButton>();
212
213 extension->setup();
214 extension->set_visible(true);
215 this->attach(*extension, _extension_col, current_row, 1, 1);
216 this->attach(*extension->getPrefButton(), _prefs_col, current_row, 1, 1);
217
218 // Disable DPI when not using a raster image output
219 extension->signal_changed().connect([=]() {
220 if (auto ext = extension->getExtension()) {
221 dpi_sb->set_sensitive(ext->is_raster());
222 }
223 });
224
225 dpi_sb->set_digits(2);
226 dpi_sb->set_increments(0.1, 1.0);
227 dpi_sb->set_range(1.0, 100000.0);
228 dpi_sb->set_value(default_dpi);
229 dpi_sb->set_sensitive(true);
230 dpi_sb->set_width_chars(6);
231 dpi_sb->set_max_width_chars(6);
232 dpi_sb->set_visible(true);
233 this->attach(*dpi_sb, _dpi_col, current_row, 1, 1);
234
235 auto const pIcon = Gtk::manage(sp_get_icon_image("window-close", Gtk::IconSize::NORMAL));
236 auto const delete_btn = Gtk::make_managed<Gtk::Button>();
237 delete_btn->set_has_frame(false);
238 delete_btn->set_child(*pIcon);
239 this->attach(*delete_btn, _delete_col, current_row, 1, 1);
240 delete_btn->signal_clicked().connect(sigc::bind(sigc::mem_fun(*this, &ExportList::delete_row), delete_btn));
241
242 _num_rows++;
243}
244
245void ExportList::delete_row(Gtk::Widget *widget)
246{
247 if (widget == nullptr) {
248 return;
249 }
250 if (_num_rows <= 1) {
251 return;
252 }
253 int row, ignore;
254 query_child(*widget, ignore, row, ignore, ignore);
255 remove_row(row);
256 _num_rows--;
257 if (_num_rows <= 1) {
258 auto const d_button_0 = this->get_child_at(_delete_col, 1);
259 if (d_button_0) {
260 d_button_0->set_visible(false);
261 }
262 }
263}
264
265std::string ExportList::get_suffix(int row)
266{
267 std::string suffix = "";
268 Gtk::Entry *entry = dynamic_cast<Gtk::Entry *>(this->get_child_at(_suffix_col, row + 1));
269 if (entry == nullptr) {
270 return suffix;
271 }
272 suffix = Glib::filename_from_utf8(entry->get_text());
273 return suffix;
274}
276{
277 ExtensionList *extension_cb = dynamic_cast<ExtensionList *>(this->get_child_at(_extension_col, row + 1));
278 return extension_cb->getExtension();
279}
280
281double ExportList::get_dpi(int row)
282{
283 double dpi = default_dpi;
284 auto spin_sb = dynamic_cast<Gtk::SpinButton *>(this->get_child_at(_dpi_col, row + 1));
285 if (spin_sb == nullptr) {
286 return dpi;
287 }
288 dpi = spin_sb->get_value();
289 return dpi;
290}
291
292} // namespace Inkscape::UI::Dialog
293
294/*
295 Local Variables:
296 mode:c++
297 c-file-style:"stroustrup"
298 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
299 indent-tabs-mode:nil
300 fill-column:99
301 End:
302*/
303// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
Gtk builder utilities.
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
Extension * get(const gchar *key) const
This function looks up a Inkscape::Extension::Extension by using its unique id. It then returns a ref...
Definition db.cpp:101
Preference storage class.
Definition preferences.h:61
bool getBool(Glib::ustring const &pref_path, bool def=false)
Retrieve a Boolean value.
double getDouble(Glib::ustring const &pref_path, double def=0.0, Glib::ustring const &unit="")
Retrieve a floating point value.
static Preferences * get()
Access the singleton Preferences object.
std::unique_ptr< PreferencesObserver > createObserver(Glib::ustring path, std::function< void(const Preferences::Entry &new_value)> callback)
Create an observer watching preference 'path' and calling provided function when preference changes.
void removeExtension(std::string &filename)
Inkscape::Preferences * prefs
Inkscape::Extension::Output * getExtension(int row)
void delete_row(Gtk::Widget *widget)
Glib::RefPtr< Gtk::Builder > _builder
Inkscape::Extension::Output * getExtension()
Returns the Output extension currently selected in this dropdown.
sigc::scoped_connection _popover_signal
void removeExtension(std::string &filename)
Removes the file extension, if it's one of the extensions in the list.
std::map< std::string, Inkscape::Extension::Output * > ext_to_mod
std::string getFileExtension()
Returns the file extension (file ending) of the currently selected extension.
void setExtensionFromFilename(std::string const &filename)
Gtk::Image * sp_get_icon_image(Glib::ustring const &icon_name, int size)
Icon Loader.
Glib::ustring label
Definition desktop.h:50
DB db
This is the actual database object.
Definition db.cpp:32
Glib::ustring get_file_extension(Glib::ustring const &path)
Definition sys.cpp:214
Dialog code.
Definition desktop.h:117
Glib::RefPtr< Gtk::Builder > create_builder(const char *filename)
static void append(std::vector< T > &target, std::vector< T > &&source)
Singleton class to access the preferences file in a convenient way.