summaryrefslogtreecommitdiffstats
path: root/src/actions
diff options
context:
space:
mode:
Diffstat (limited to 'src/actions')
-rw-r--r--src/actions/CMakeLists.txt12
-rw-r--r--src/actions/README26
-rw-r--r--src/actions/actions-base.cpp281
-rw-r--r--src/actions/actions-base.h19
-rw-r--r--src/actions/actions-extra-data.cpp67
-rw-r--r--src/actions/actions-extra-data.h64
-rw-r--r--src/actions/actions-file.cpp142
-rw-r--r--src/actions/actions-file.h31
-rw-r--r--src/actions/actions-helper.cpp48
-rw-r--r--src/actions/actions-helper.h34
-rw-r--r--src/actions/actions-object.cpp159
-rw-r--r--src/actions/actions-object.h30
-rw-r--r--src/actions/actions-output.cpp309
-rw-r--r--src/actions/actions-output.h31
-rw-r--r--src/actions/actions-selection.cpp286
-rw-r--r--src/actions/actions-selection.h30
-rw-r--r--src/actions/actions-transform.cpp132
-rw-r--r--src/actions/actions-transform.h30
-rw-r--r--src/actions/actions-window.cpp96
-rw-r--r--src/actions/actions-window.h31
20 files changed, 1858 insertions, 0 deletions
diff --git a/src/actions/CMakeLists.txt b/src/actions/CMakeLists.txt
new file mode 100644
index 0000000..d5b8339
--- /dev/null
+++ b/src/actions/CMakeLists.txt
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+set(actions_SRC
+ # actions-base.cpp
+ # actions-selection.cpp
+
+ # HEADERS
+ # actions-base.h
+ # actions-selection.h
+ )
+
+add_inkscape_source("${actions_SRC}")
diff --git a/src/actions/README b/src/actions/README
new file mode 100644
index 0000000..b6806d8
--- /dev/null
+++ b/src/actions/README
@@ -0,0 +1,26 @@
+
+This directory contains Gio::Actions.
+
+"A GAction (Gio::Action) is a representation of a single
+user-interesting action in an application."
+(https://wiki.gnome.org/HowDoI/GAction)
+
+In more layman terms, it provides a uniform interface for calling
+functions with an optional single parameter that is not tied to the
+GUI.
+
+Actions provide two operations:
+
+* activation (which results in calling the function),
+* state change (if the action supports a state).
+
+While actions are defined independent of the GUI (unlike GtkAction),
+the can be used by "actionable widgets" (menus, buttons, etc.) by
+simply referring to them by name. They can also be remotely activated
+by D-Bus and GNotifications.
+
+To do:
+
+* Convert 'verbs' to Gio::Actions.
+* Update command line to use actions.
+* Update GUI to use actions.
diff --git a/src/actions/actions-base.cpp b/src/actions/actions-base.cpp
new file mode 100644
index 0000000..4af8113
--- /dev/null
+++ b/src/actions/actions-base.cpp
@@ -0,0 +1,281 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Gio::Actions tied to the application and independent of GUI.
+ *
+ * Copyright (C) 2018 Tavmjong Bah
+ *
+ * The contents of this file may be used under the GNU General Public License Version 2 or later.
+ *
+ */
+
+#include <iostream>
+
+#include <giomm.h> // Not <gtkmm.h>! To eventually allow a headless version!
+#include <glibmm/i18n.h>
+
+#include "actions-base.h"
+#include "actions-helper.h"
+
+#include "inkscape-application.h"
+
+#include "inkscape.h" // Inkscape::Application
+#include "inkscape-version.h" // Inkscape version
+#include "path-prefix.h" // Extension directory
+#include "extension/init.h" // List verbs
+#include "verbs.h" // List verbs
+#include "selection.h" // Selection
+#include "object/sp-root.h" // query_all()
+#include "file.h" // dpi convert method
+#include "io/resource.h"
+
+void
+print_inkscape_version()
+{
+ std::cout << "Inkscape " << Inkscape::version_string << std::endl;
+ std::cerr << " Pango version: " << pango_version_string() << std::endl;
+}
+
+void
+print_system_data_directory()
+{
+ std::cout << INKSCAPE_SYSTEMDIR << std::endl;
+}
+
+void
+print_user_data_directory()
+{
+ std::cout << Inkscape::IO::Resource::profile_path("") << std::endl;
+}
+
+void
+print_verb_list()
+{
+ // This really shouldn't go here, we should init the app.
+ // But, since we're just exiting in this path, there is
+ // no harm, and this is really a better place to put
+ // everything else.
+ Inkscape::Extension::init(); // extension/init.h
+ Inkscape::Verb::list(); // verbs.h
+}
+
+// Helper function for query_x(), query_y(), query_width(), and query_height().
+void
+query_dimension(InkscapeApplication* app, bool extent, Geom::Dim2 const axis)
+{
+ SPDocument* document = nullptr;
+ Inkscape::Selection* selection = nullptr;
+ if (!get_document_and_selection(app, &document, &selection)) {
+ return;
+ }
+
+ if (selection->isEmpty()) {
+ selection->add(document->getRoot());
+ }
+
+ bool first = true;
+ auto items = selection->items();
+ for (auto item : items) {
+ if (!first) {
+ std::cout << ",";
+ }
+ first = false;
+ Geom::OptRect area = item->documentVisualBounds();
+ if (area) {
+ if (extent) {
+ std::cout << area->dimensions()[axis];
+ } else {
+ std::cout << area->min()[axis];
+ }
+ } else {
+ std::cout << "0";
+ }
+ }
+ std::cout << std::endl;
+}
+
+void
+query_x(InkscapeApplication* app)
+{
+ query_dimension(app, false, Geom::X);
+}
+
+void
+query_y(InkscapeApplication* app)
+{
+ query_dimension(app, false, Geom::Y);
+}
+
+void
+query_width(InkscapeApplication* app)
+{
+ query_dimension(app, true, Geom::X);
+}
+
+void
+query_height(InkscapeApplication* app)
+{
+ query_dimension(app, true, Geom::Y);
+}
+
+// Helper for query_all()
+void
+query_all_recurse (SPObject *o)
+{
+ SPItem *item = dynamic_cast<SPItem*>(o);
+ if (item && item->getId()) {
+ Geom::OptRect area = item->documentVisualBounds();
+ if (area) {
+ std::cout << item->getId() << ","
+ << area->min()[Geom::X] << ","
+ << area->min()[Geom::Y] << ","
+ << area->dimensions()[Geom::X] << ","
+ << area->dimensions()[Geom::Y] << std::endl;
+ }
+
+ for (auto& child: o->children) {
+ query_all_recurse (&child);
+ }
+ }
+}
+
+void
+query_all(InkscapeApplication* app)
+{
+ SPDocument* doc = app->get_active_document();
+ if (!doc) {
+ std::cerr << "query_all: no document!" << std::endl;
+ return;
+ }
+
+ SPObject *o = doc->getRoot();
+ if (o) {
+ query_all_recurse(o);
+ }
+}
+
+void
+pdf_page(int page)
+{
+ INKSCAPE.set_pdf_page(page);
+}
+
+void
+convert_dpi_method(Glib::ustring method)
+{
+ if (method == "none") {
+ sp_file_convert_dpi_method_commandline = FILE_DPI_UNCHANGED;
+ } else if (method == "scale-viewbox") {
+ sp_file_convert_dpi_method_commandline = FILE_DPI_VIEWBOX_SCALED;
+ } else if (method == "scale-document") {
+ sp_file_convert_dpi_method_commandline = FILE_DPI_DOCUMENT_SCALED;
+ } else {
+ std::cerr << "dpi_convert_method: invalid option" << std::endl;
+ }
+}
+
+void
+no_convert_baseline()
+{
+ sp_no_convert_text_baseline_spacing = true;
+}
+
+// Temporary: Verbs are to be replaced by Gio::Actions!
+void
+verbs(Glib::ustring verblist, InkscapeApplication* app)
+{
+ auto tokens = Glib::Regex::split_simple("\\s*;\\s*", verblist);
+ for (auto token : tokens) {
+ std::vector<Glib::ustring> parts = Glib::Regex::split_simple("\\s*:\\s*", token); // Second part is always ignored... we could implement it but better to switch to Gio::Actions
+ if (!parts.empty() && !parts[0].empty()) {
+ Inkscape::Verb* verb = Inkscape::Verb::getbyid(parts[0].c_str());
+ if (verb == nullptr) {
+ std::cerr << "verbs_action: Invalid verb: " << parts[0] << std::endl;
+ break;
+ }
+ // Inkscape::ActionContext context = INKSCAPE.action_context_for_document(*document);
+ SPAction* action = verb->get_action(INKSCAPE.active_action_context());
+ sp_action_perform(action, nullptr); // Data is ignored!
+ }
+ }
+}
+
+void
+vacuum_defs(InkscapeApplication* app)
+{
+ SPDocument* document = nullptr;
+ Inkscape::Selection* selection = nullptr;
+ if (!get_document_and_selection(app, &document, &selection)) {
+ return;
+ }
+ document->vacuumDocument();
+}
+
+void
+quit_inkscape(InkscapeApplication* app)
+{
+ app->on_quit();
+}
+
+std::vector<std::vector<Glib::ustring>> raw_data_base =
+{
+ {"inkscape-version", "InkscapeVersion", "Base", N_("Print Inkscape version and exit.") },
+ {"system-data-directory", "InkscapeSystemDir", "Base", N_("Print system data directory and exit.") },
+ {"user-data-directory", "InkscapeUserDir", "Base", N_("Print user data directory and exit.") },
+ {"action-list", "InkscapeActions", "Base", N_("Print a list of actions and exit.") },
+ {"verb-list", "InkscapeVerbs", "Base", N_("Print a list of verbs and exit.") },
+ {"verb", "Verb", "Base", N_("Execute verb(s).") },
+ {"vacuum-defs", "VacuumDefs", "Base", N_("Remove unused definitions (gradients, etc.).") },
+ {"quit-inkscape", "QuitInkscape", "Base", N_("Immediately quit Inkscape.") },
+
+ {"open-page", "ImportPageNumber", "Import", N_("Import page number.") },
+ {"convert-dpi-method", "ImportDPIMethod", "Import", N_("Import DPI convert method.") },
+ {"no-convert-baseline", "ImportBaselineConvert", "Import", N_("Import convert text baselines.") },
+
+ {"query-x", "QueryX", "Query", N_("Query 'x' value(s) of selected objects.") },
+ {"query-y", "QueryY", "Query", N_("Query 'y' value(s) of selected objects.") },
+ {"query-width", "QueryWidth", "Query", N_("Query 'width' value(s) of object(s).") },
+ {"query-height", "QueryHeight", "Query", N_("Query 'height' value(s) of object(s).") },
+ {"query-all", "QueryAll", "Query", N_("Query 'x', 'y', 'width', and 'height'.") }
+};
+
+template<class T>
+void
+add_actions_base(ConcreteInkscapeApplication<T>* app)
+{
+ // Note: "radio" actions are just an easy way to set type without using templating.
+ app->add_action( "inkscape-version", sigc::ptr_fun(&print_inkscape_version) );
+ app->add_action( "system-data-directory", sigc::ptr_fun(&print_system_data_directory) );
+ app->add_action( "user-data-directory", sigc::ptr_fun(&print_user_data_directory) );
+ app->add_action( "action-list", sigc::mem_fun(app, &ConcreteInkscapeApplication<T>::print_action_list) );
+ app->add_action( "verb-list", sigc::ptr_fun(&print_verb_list) );
+ app->add_action_radio_string( "verb", sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&verbs), app), "null");
+ app->add_action( "vacuum-defs", sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&vacuum_defs), app) );
+ app->add_action( "quit-inkscape", sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&quit_inkscape), app) );
+
+ app->add_action_radio_integer( "open-page", sigc::ptr_fun(&pdf_page), 0);
+ app->add_action_radio_string( "convert-dpi-method", sigc::ptr_fun(&convert_dpi_method), "none");
+ app->add_action( "no-convert-baseline", sigc::ptr_fun(&no_convert_baseline) );
+
+
+ app->add_action( "query-x", sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&query_x), app) );
+ app->add_action( "query-y", sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&query_y), app) );
+ app->add_action( "query-width", sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&query_width), app) );
+ app->add_action( "query-height", sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&query_height), app) );
+ app->add_action( "query-all", sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&query_all), app) );
+
+ app->get_action_extra_data().add_data(raw_data_base);
+}
+
+template void add_actions_base(ConcreteInkscapeApplication<Gio::Application>* app);
+template void add_actions_base(ConcreteInkscapeApplication<Gtk::Application>* app);
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/actions/actions-base.h b/src/actions/actions-base.h
new file mode 100644
index 0000000..cf43b8e
--- /dev/null
+++ b/src/actions/actions-base.h
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Gio::Actions tied to the application and without GUI.
+ *
+ * Copyright (C) 2018 Tavmjong Bah
+ *
+ * The contents of this file may be used under the GNU General Public License Version 2 or later.
+ *
+ */
+
+#ifndef INK_ACTIONS_BASE_H
+#define INK_ACTIONS_BASE_H
+
+template<class T> class ConcreteInkscapeApplication;
+
+template<class T>
+void add_actions_base(ConcreteInkscapeApplication<T>* app);
+
+#endif // INK_ACTIONS_BASE_H
diff --git a/src/actions/actions-extra-data.cpp b/src/actions/actions-extra-data.cpp
new file mode 100644
index 0000000..45094d7
--- /dev/null
+++ b/src/actions/actions-extra-data.cpp
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Extra data associated with actions: Label, Section, Tooltip.
+ *
+ * Copyright (C) 2020 Tavmjong Bah
+ *
+ * The contents of this file may be used under the GNU General Public License Version 2 or later.
+ *
+ */
+
+#include "actions-extra-data.h"
+
+#include <iostream>
+
+Glib::ustring
+InkActionExtraData::get_label_for_action(Glib::ustring& action_name)
+{
+ Glib::ustring value;
+ auto search = data.find(action_name);
+ if (search != data.end()) {
+ value = search->second.get_label();
+ }
+ return value;
+}
+
+Glib::ustring
+InkActionExtraData::get_section_for_action(Glib::ustring& action_name) {
+
+ Glib::ustring value;
+ auto search = data.find(action_name);
+ if (search != data.end()) {
+ value = search->second.get_section();
+ }
+ return value;
+}
+
+Glib::ustring
+InkActionExtraData::get_tooltip_for_action(Glib::ustring& action_name) {
+
+ Glib::ustring value;
+ auto search = data.find(action_name);
+ if (search != data.end()) {
+ value = search->second.get_tooltip();
+ }
+ return value;
+}
+
+void
+InkActionExtraData::add_data(std::vector<std::vector<Glib::ustring>> &raw_data)
+{
+ for (auto raw : raw_data) {
+ InkActionExtraDatum datum(raw[1], raw[2], raw[3]);
+ data.emplace(raw[0], datum);
+ }
+}
+
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/actions/actions-extra-data.h b/src/actions/actions-extra-data.h
new file mode 100644
index 0000000..e96234e
--- /dev/null
+++ b/src/actions/actions-extra-data.h
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Extra data associated with actions: Label, Section, Tooltip.
+ *
+ * Copyright (C) 2020 Tavmjong Bah
+ *
+ * The contents of this file may be used under the GNU General Public License Version 2 or later.
+ *
+ */
+
+#ifndef INK_ACTIONS_EXTRA_DATA_H
+#define INK_ACTIONS_EXTRA_DATA_H
+
+#include <map>
+#include <vector>
+
+#include <glibmm/ustring.h>
+
+class InkActionExtraDatum {
+ public:
+ InkActionExtraDatum(Glib::ustring& label, Glib::ustring& section, Glib::ustring& tooltip)
+ : action_label(label)
+ , action_section(section)
+ , action_tooltip(tooltip)
+ {
+ }
+
+ Glib::ustring get_label() { return action_label; }
+ Glib::ustring get_section() { return action_section; }
+ Glib::ustring get_tooltip() { return action_tooltip; }
+
+ private:
+ Glib::ustring action_label;
+ Glib::ustring action_section;
+ Glib::ustring action_tooltip;
+};
+
+class InkActionExtraData {
+
+ public:
+ InkActionExtraData() = default;
+
+ void add_data(std::vector<std::vector<Glib::ustring>> &raw_data);
+
+ Glib::ustring get_label_for_action(Glib::ustring& action_name);
+ Glib::ustring get_section_for_action(Glib::ustring& action_name);
+ Glib::ustring get_tooltip_for_action(Glib::ustring& action_name);
+
+ private:
+ std::map<Glib::ustring, InkActionExtraDatum> data;
+};
+
+#endif // INK_ACTIONS_EXTRA_DATA_H
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/actions/actions-file.cpp b/src/actions/actions-file.cpp
new file mode 100644
index 0000000..0cf05f1
--- /dev/null
+++ b/src/actions/actions-file.cpp
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Gio::Actions for file handling tied to the application and without GUI.
+ *
+ * Copyright (C) 2020 Tavmjong Bah
+ *
+ * The contents of this file may be used under the GNU General Public License Version 2 or later.
+ *
+ */
+
+#include <iostream>
+
+#include <giomm.h> // Not <gtkmm.h>! To eventually allow a headless version!
+#include <glibmm/i18n.h>
+
+#include "actions-file.h"
+#include "actions-helper.h"
+#include "inkscape-application.h"
+
+#include "inkscape.h" // Inkscape::Application
+#include "helper/action-context.h"
+
+// Actions for file handling (should be integrated with file dialog).
+
+void
+file_open(const Glib::VariantBase& value, InkscapeApplication *app)
+{
+ Glib::Variant<Glib::ustring> s = Glib::VariantBase::cast_dynamic<Glib::Variant<Glib::ustring> >(value);
+
+ Glib::RefPtr<Gio::File> file = Gio::File::create_for_path(s.get());
+ if (!file->query_exists()) {
+ std::cerr << "file_open: file '" << s.get() << "' does not exist." << std::endl;
+ return;
+ }
+
+ SPDocument *document = app->document_open(file);
+ INKSCAPE.add_document(document);
+
+ Inkscape::ActionContext context = INKSCAPE.action_context_for_document(document);
+ app->set_active_document(document);
+ app->set_active_selection(context.getSelection());
+ app->set_active_view(context.getView());
+
+ document->ensureUpToDate();
+}
+
+void
+file_new(const Glib::VariantBase& value, InkscapeApplication *app)
+{
+ Glib::Variant<Glib::ustring> s = Glib::VariantBase::cast_dynamic<Glib::Variant<Glib::ustring> >(value);
+
+ SPDocument *document = app->document_new(s.get());
+ INKSCAPE.add_document(document);
+
+ Inkscape::ActionContext context = INKSCAPE.action_context_for_document(document);
+ app->set_active_document(document);
+ app->set_active_selection(context.getSelection());
+ app->set_active_view(context.getView());
+
+ document->ensureUpToDate();
+}
+
+// Need to redo document_revert so that it doesn't depend on windows.
+// void
+// file_revert(InkscapeApplication *app)
+// {
+// app->document_revert(app->get_current_document());
+// }
+
+void
+file_close(InkscapeApplication *app)
+{
+ SPDocument *document = app->get_active_document();
+ app->document_close(document);
+
+ app->set_active_document(nullptr);
+ app->set_active_selection(nullptr);
+ app->set_active_view(nullptr);
+}
+
+// TODO:
+// file_open
+// file_new
+
+// The following might be best tied to the file rather than app.
+// file_revert
+// file_save
+// file_saveas
+// file_saveacopy
+// file_print
+// file_vacuum
+// file_import
+// file_close
+// file_quit ... should just be quit
+// file_template
+
+std::vector<std::vector<Glib::ustring>> raw_data_file =
+{
+ {"file-open", "FileOpen", "File", N_("Open file.") },
+ {"file-new", "FileNew", "File", N_("Open new document using template.") },
+ {"file-close", "FileClose", "File", N_("Close active document.") }
+};
+
+template <class T>
+void
+add_actions_file(ConcreteInkscapeApplication<T>* app)
+{
+ Glib::VariantType Bool( Glib::VARIANT_TYPE_BOOL);
+ Glib::VariantType Int( Glib::VARIANT_TYPE_INT32);
+ Glib::VariantType Double(Glib::VARIANT_TYPE_DOUBLE);
+ Glib::VariantType String(Glib::VARIANT_TYPE_STRING);
+ Glib::VariantType BString(Glib::VARIANT_TYPE_BYTESTRING);
+
+ // Debian 9 has 2.50.0
+#if GLIB_CHECK_VERSION(2, 52, 0)
+
+ app->add_action_with_parameter( "file-open", String, sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&file_open), app));
+ app->add_action_with_parameter( "file-new", String, sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&file_new), app));
+ app->add_action( "file-close", sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&file_close), app));
+#else
+ std::cerr << "add_actions: Some actions require Glibmm 2.52, compiled with: " << glib_major_version << "." << glib_minor_version << std::endl;
+#endif
+
+ app->get_action_extra_data().add_data(raw_data_file);
+}
+
+
+template void add_actions_file(ConcreteInkscapeApplication<Gio::Application>* app);
+template void add_actions_file(ConcreteInkscapeApplication<Gtk::Application>* app);
+
+
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/actions/actions-file.h b/src/actions/actions-file.h
new file mode 100644
index 0000000..b4a0b22
--- /dev/null
+++ b/src/actions/actions-file.h
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Gio::Actions for file handling tied to the application and without GUI.
+ *
+ * Copyright (C) 2020 Tavmjong Bah
+ *
+ * The contents of this file may be used under the GNU General Public License Version 2 or later.
+ *
+ */
+
+#ifndef INK_ACTIONS_FILE_H
+#define INK_ACTIONS_FILE_H
+
+class InkscapeApplication;
+template<class T> class ConcreteInkscapeApplication;
+
+template<class T>
+void add_actions_file(ConcreteInkscapeApplication<T>* app);
+
+#endif // INK_ACTIONS_FILE_H
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/actions/actions-helper.cpp b/src/actions/actions-helper.cpp
new file mode 100644
index 0000000..e72a15d
--- /dev/null
+++ b/src/actions/actions-helper.cpp
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Gio::Actions for selection tied to the application and without GUI.
+ *
+ * Copyright (C) 2018 Tavmjong Bah
+ *
+ * The contents of this file may be used under the GNU General Public License Version 2 or later.
+ *
+ */
+
+#include "actions-helper.h"
+
+#include "inkscape-application.h"
+#include "inkscape.h"
+#include "selection.h"
+
+// Helper function: returns true if both document and selection found. Maybe this should
+// work on current view. Or better, application could return the selection of the current view.
+bool
+get_document_and_selection(InkscapeApplication* app, SPDocument** document, Inkscape::Selection** selection)
+{
+ *document = app->get_active_document();
+ if (!(*document)) {
+ std::cerr << "get_document_and_selection: No document!" << std::endl;
+ return false;
+ }
+
+ // To do: get selection from active view (which could be from desktop or not).
+ Inkscape::ActionContext context = INKSCAPE.action_context_for_document(*document);
+ *selection = context.getSelection();
+ if (!*selection) {
+ std::cerr << "get_document_and_selection: No selection!" << std::endl;
+ return false;
+ }
+
+ return true;
+}
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/actions/actions-helper.h b/src/actions/actions-helper.h
new file mode 100644
index 0000000..da65e10
--- /dev/null
+++ b/src/actions/actions-helper.h
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Gio::Actions for selection tied to the application and without GUI.
+ *
+ * Copyright (C) 2018 Tavmjong Bah
+ *
+ * The contents of this file may be used under the GNU General Public License Version 2 or later.
+ *
+ */
+
+#ifndef INK_ACTIONS_HELPER_H
+#define INK_ACTIONS_HELPER_H
+
+class InkscapeApplication;
+class SPDocument;
+namespace Inkscape {
+ class Selection;
+}
+
+bool get_document_and_selection(InkscapeApplication* app, SPDocument** document, Inkscape::Selection** selection);
+
+
+#endif // INK_ACTIONS_HELPER_H
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/actions/actions-object.cpp b/src/actions/actions-object.cpp
new file mode 100644
index 0000000..d0c6d06
--- /dev/null
+++ b/src/actions/actions-object.cpp
@@ -0,0 +1,159 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Gio::Actions for working with objects without GUI.
+ *
+ * Copyright (C) 2020 Tavmjong Bah
+ *
+ * The contents of this file may be used under the GNU General Public License Version 2 or later.
+ *
+ */
+
+#include <iostream>
+
+#include <giomm.h> // Not <gtkmm.h>! To eventually allow a headless version!
+#include <glibmm/i18n.h>
+
+#include "actions-object.h"
+#include "actions-helper.h"
+#include "document-undo.h"
+#include "inkscape-application.h"
+
+#include "inkscape.h" // Inkscape::Application
+#include "selection.h" // Selection
+
+
+// No sanity checking is done... should probably add.
+void
+object_set_attribute(const Glib::VariantBase& value, InkscapeApplication *app)
+{
+ Glib::Variant<Glib::ustring> s = Glib::VariantBase::cast_dynamic<Glib::Variant<Glib::ustring> >(value);
+
+ std::vector<Glib::ustring> tokens = Glib::Regex::split_simple(",", s.get());
+ if (tokens.size() != 2) {
+ std::cerr << "action:object_set_attribute: requires 'attribute name, attribute value'" << std::endl;
+ return;
+ }
+
+ auto selection = app->get_active_selection();
+ if (selection->isEmpty()) {
+ std::cerr << "action:object_set_attribute: selection empty!" << std::endl;
+ return;
+ }
+
+ // Should this be a selection member function?
+ auto items = selection->items();
+ for (auto i = items.begin(); i != items.end(); ++i) {
+ Inkscape::XML::Node *repr = (*i)->getRepr();
+ repr->setAttribute(tokens[0], tokens[1]);
+ }
+
+ // Needed to update repr (is this the best way?).
+ Inkscape::DocumentUndo::done(app->get_active_document(), 0, "ActionObjectSetAttribute");
+}
+
+
+// No sanity checking is done... should probably add.
+void
+object_set_property(const Glib::VariantBase& value, InkscapeApplication *app)
+{
+ Glib::Variant<Glib::ustring> s = Glib::VariantBase::cast_dynamic<Glib::Variant<Glib::ustring> >(value);
+
+ std::vector<Glib::ustring> tokens = Glib::Regex::split_simple(",", s.get());
+ if (tokens.size() != 2) {
+ std::cerr << "action:object_set_property: requires 'property name, property value'" << std::endl;
+ return;
+ }
+
+ auto selection = app->get_active_selection();
+ if (selection->isEmpty()) {
+ std::cerr << "action:object_set_property: selection empty!" << std::endl;
+ return;
+ }
+
+ // Should this be a selection member function?
+ auto items = selection->items();
+ for (auto i = items.begin(); i != items.end(); ++i) {
+ Inkscape::XML::Node *repr = (*i)->getRepr();
+ SPCSSAttr *css = sp_repr_css_attr(repr, "style");
+ sp_repr_css_set_property(css, tokens[0].c_str(), tokens[1].c_str());
+ sp_repr_css_set(repr, css, "style");
+ sp_repr_css_attr_unref(css);
+ }
+
+ // Needed to update repr (is this the best way?).
+ Inkscape::DocumentUndo::done(app->get_active_document(), 0, "ActionObjectSetProperty");
+}
+
+
+void
+object_unlink_clones(InkscapeApplication *app)
+{
+ auto selection = app->get_active_selection();
+
+ // We should not have to do this!
+ auto document = app->get_active_document();
+ selection->setDocument(document);
+
+ selection->unlink();
+}
+
+
+void
+object_to_path(InkscapeApplication *app)
+{
+ auto selection = app->get_active_selection();
+
+ // We should not have to do this!
+ auto document = app->get_active_document();
+ selection->setDocument(document);
+
+ selection->toCurves();
+}
+
+
+std::vector<std::vector<Glib::ustring>> raw_data_object =
+{
+ {"object-set-attribute", "ObjectSetAttribute", "Object", N_("Set or update an attribute on selected objects. Usage: object-set-attribute:attribute name, attribute value;")},
+ {"object-set-property", "ObjectSetProperty", "Object", N_("Set or update a property on selected objects. Usage: object-set-property:property name, property value;")},
+ {"object-unlink-clones", "ObjectUnlinkClones", "Object", N_("Unlink clones and symbols.") },
+ {"object-to-path", "ObjectToPath", "Object", N_("Convert shapes to paths.") },
+};
+
+template<class T>
+void
+add_actions_object(ConcreteInkscapeApplication<T>* app)
+{
+ Glib::VariantType Bool( Glib::VARIANT_TYPE_BOOL);
+ Glib::VariantType Int( Glib::VARIANT_TYPE_INT32);
+ Glib::VariantType Double(Glib::VARIANT_TYPE_DOUBLE);
+ Glib::VariantType String(Glib::VARIANT_TYPE_STRING);
+
+ // Debian 9 has 2.50.0
+#if GLIB_CHECK_VERSION(2, 52, 0)
+
+ app->add_action_with_parameter( "object-set-attribute", String, sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&object_set_attribute), app));
+ app->add_action_with_parameter( "object-set-property", String, sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&object_set_property), app));
+ app->add_action( "object-unlink-clones", sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&object_unlink_clones), app));
+ app->add_action( "object-to-path", sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&object_to_path), app));
+
+#endif
+
+ app->get_action_extra_data().add_data(raw_data_object);
+}
+
+
+template void add_actions_object(ConcreteInkscapeApplication<Gio::Application>* app);
+template void add_actions_object(ConcreteInkscapeApplication<Gtk::Application>* app);
+
+
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/actions/actions-object.h b/src/actions/actions-object.h
new file mode 100644
index 0000000..dbde543
--- /dev/null
+++ b/src/actions/actions-object.h
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Gio::Actions for working with objects not tied to GUI.
+ *
+ * Copyright (C) 2020 Tavmjong Bah
+ *
+ * The contents of this file may be used under the GNU General Public License Version 2 or later.
+ *
+ */
+
+#ifndef INK_ACTIONS_OBJECT_H
+#define INK_ACTIONS_OBJECT_H
+
+template<class T> class ConcreteInkscapeApplication;
+
+template<class T>
+void add_actions_object(ConcreteInkscapeApplication<T>* app);
+
+#endif // INK_ACTIONS_OBJECT_H
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/actions/actions-output.cpp b/src/actions/actions-output.cpp
new file mode 100644
index 0000000..559bd6b
--- /dev/null
+++ b/src/actions/actions-output.cpp
@@ -0,0 +1,309 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Gio::Actions for output tied to the application and without GUI.
+ *
+ * Copyright (C) 2018 Tavmjong Bah
+ *
+ * The contents of this file may be used under the GNU General Public License Version 2 or later.
+ *
+ */
+
+#include <iostream>
+
+#include <giomm.h> // Not <gtkmm.h>! To eventually allow a headless version!
+#include <glibmm/i18n.h>
+
+#include "actions-output.h"
+#include "actions-helper.h"
+#include "inkscape-application.h"
+
+#include "inkscape.h" // Inkscape::Application
+
+// Actions for command line output (should be integrated with file dialog).
+
+// These actions are currently stateless and result in changes to an instance of the
+// InkFileExportCmd class owned by the application.
+
+void
+export_type(const Glib::VariantBase& value, InkscapeApplication *app)
+{
+ Glib::Variant<Glib::ustring> s = Glib::VariantBase::cast_dynamic<Glib::Variant<Glib::ustring> >(value);
+ app->file_export()->export_type = s.get();
+ // std::cout << "export-type: " << s.get() << std::endl;
+}
+
+void
+export_filename(const Glib::VariantBase& value, InkscapeApplication *app)
+{
+ Glib::Variant<std::string> s = Glib::VariantBase::cast_dynamic<Glib::Variant<std::string> >(value);
+ app->file_export()->export_filename = s.get();
+ // std::cout << "export-filename: " << s.get() << std::endl;
+}
+
+void
+export_overwrite(const Glib::VariantBase& value, InkscapeApplication *app)
+{
+ Glib::Variant<bool> b = Glib::VariantBase::cast_dynamic<Glib::Variant<bool> >(value);
+ app->file_export()->export_overwrite = b.get();
+ // std::cout << "export-overwrite: " << std::boolalpha << b.get() << std::endl;
+}
+
+void
+export_area(const Glib::VariantBase& value, InkscapeApplication *app)
+{
+ Glib::Variant<std::string> s = Glib::VariantBase::cast_dynamic<Glib::Variant<std::string> >(value);
+ app->file_export()->export_area = s.get();
+ // std::cout << "export-area: " << s.get() << std::endl;
+}
+
+void
+export_area_drawing(const Glib::VariantBase& value, InkscapeApplication *app)
+{
+ Glib::Variant<bool> b = Glib::VariantBase::cast_dynamic<Glib::Variant<bool> >(value);
+ app->file_export()->export_area_drawing = b.get();
+ // std::cout << "export-area-drawing: " << std::boolalpha << b.get() << std::endl;
+}
+
+void
+export_area_page(const Glib::VariantBase& value, InkscapeApplication *app)
+{
+ Glib::Variant<bool> b = Glib::VariantBase::cast_dynamic<Glib::Variant<bool> >(value);
+ app->file_export()->export_area_page = b.get();
+ // std::cout << "export-area-page: " << std::boolalpha << b.get() << std::endl;
+}
+
+void
+export_margin(const Glib::VariantBase& value, InkscapeApplication *app)
+{
+ Glib::Variant<int> i = Glib::VariantBase::cast_dynamic<Glib::Variant<int> >(value);
+ app->file_export()->export_margin = i.get();
+ // std::cout << "export-margin: " << i.get() << std::endl;
+}
+
+void
+export_area_snap(const Glib::VariantBase& value, InkscapeApplication *app)
+{
+ Glib::Variant<bool> b = Glib::VariantBase::cast_dynamic<Glib::Variant<bool> >(value);
+ app->file_export()->export_area_snap = b.get();
+ // std::cout << "export-area-snap: " << std::boolalpha << b.get() << std::endl;
+}
+
+void
+export_width(const Glib::VariantBase& value, InkscapeApplication *app)
+{
+ Glib::Variant<int> i = Glib::VariantBase::cast_dynamic<Glib::Variant<int> >(value);
+ app->file_export()->export_width = i.get();
+ // std::cout << "export-width: " << i.get() << std::endl;
+}
+
+void
+export_height(const Glib::VariantBase& value, InkscapeApplication *app)
+{
+ Glib::Variant<int> i = Glib::VariantBase::cast_dynamic<Glib::Variant<int> >(value);
+ app->file_export()->export_height = i.get();
+ // std::cout << "export-height: " << i.get() << std::endl;
+}
+
+void
+export_id(const Glib::VariantBase& value, InkscapeApplication *app)
+{
+ Glib::Variant<std::string> s = Glib::VariantBase::cast_dynamic<Glib::Variant<std::string> >(value);
+ app->file_export()->export_id = s.get();
+ // std::cout << "export-id: " << s.get() << std::endl;
+}
+
+void
+export_id_only(const Glib::VariantBase& value, InkscapeApplication *app)
+{
+ Glib::Variant<bool> b = Glib::VariantBase::cast_dynamic<Glib::Variant<bool> >(value);
+ app->file_export()->export_id_only = b.get();
+ // std::cout << "export-id-only: " << std::boolalpha << b.get() << std::endl;
+}
+
+void
+export_plain_svg(const Glib::VariantBase& value, InkscapeApplication *app)
+{
+ Glib::Variant<bool> b = Glib::VariantBase::cast_dynamic<Glib::Variant<bool> >(value);
+ app->file_export()->export_plain_svg = b.get();
+ // std::cout << "export-plain-svg: " << std::boolalpha << b.get() << std::endl;
+}
+
+void
+export_dpi(const Glib::VariantBase& value, InkscapeApplication *app)
+{
+ Glib::Variant<double> d = Glib::VariantBase::cast_dynamic<Glib::Variant<double> >(value);
+ app->file_export()->export_dpi = d.get();
+ // std::cout << "export-dpi: " << d.get() << std::endl;
+}
+
+void
+export_ignore_filters(const Glib::VariantBase& value, InkscapeApplication *app)
+{
+ Glib::Variant<bool> b = Glib::VariantBase::cast_dynamic<Glib::Variant<bool> >(value);
+ app->file_export()->export_ignore_filters = b.get();
+ // std::cout << "export-ignore-filters: " << std::boolalpha << b.get() << std::endl;
+}
+
+void
+export_text_to_path(const Glib::VariantBase& value, InkscapeApplication *app)
+{
+ Glib::Variant<bool> b = Glib::VariantBase::cast_dynamic<Glib::Variant<bool> >(value);
+ app->file_export()->export_text_to_path = b.get();
+ // std::cout << "export-text-to-path: " << std::boolalpha << b.get() << std::endl;
+}
+
+void
+export_ps_level(const Glib::VariantBase& value, InkscapeApplication *app)
+{
+ Glib::Variant<int> i = Glib::VariantBase::cast_dynamic<Glib::Variant<int> >(value);
+ app->file_export()->export_ps_level = i.get();
+ // std::cout << "export-ps-level: " << i.get() << std::endl;
+}
+
+void
+export_pdf_level(const Glib::VariantBase& value, InkscapeApplication *app)
+{
+ Glib::Variant<Glib::ustring> s = Glib::VariantBase::cast_dynamic<Glib::Variant<Glib::ustring> >(value);
+ app->file_export()->export_pdf_level = s.get();
+ // std::cout << "export-pdf-level" << s.get() << std::endl;
+}
+
+void
+export_latex(const Glib::VariantBase& value, InkscapeApplication *app)
+{
+ Glib::Variant<bool> b = Glib::VariantBase::cast_dynamic<Glib::Variant<bool> >(value);
+ app->file_export()->export_latex = b.get();
+ // std::cout << "export-latex: " << std::boolalpha << b.get() << std::endl;
+}
+
+void
+export_use_hints(const Glib::VariantBase& value, InkscapeApplication *app)
+{
+ Glib::Variant<bool> b = Glib::VariantBase::cast_dynamic<Glib::Variant<bool> >(value);
+ app->file_export()->export_use_hints = b.get();
+ // std::cout << "export-use-hints: " << std::boolalpha << b.get() << std::endl;
+}
+
+void
+export_background(const Glib::VariantBase& value, InkscapeApplication *app)
+{
+ Glib::Variant<std::string> s = Glib::VariantBase::cast_dynamic<Glib::Variant<std::string> >(value);
+ app->file_export()->export_background = s.get();
+ // std::cout << "export-background: " << s.get() << std::endl;
+}
+
+void
+export_background_opacity(const Glib::VariantBase& value, InkscapeApplication *app)
+{
+ Glib::Variant<double> d = Glib::VariantBase::cast_dynamic<Glib::Variant<double> >(value);
+ app->file_export()->export_background_opacity = d.get();
+ // std::cout << d.get() << std::endl;
+}
+
+void
+export_do(InkscapeApplication *app)
+{
+ SPDocument* document = app->get_active_document();
+ std::string filename;
+ if (document->getDocumentURI()) {
+ filename = document->getDocumentURI();
+ }
+ app->file_export()->do_export(document, filename);
+}
+
+std::vector<std::vector<Glib::ustring>> raw_data_output =
+{
+ {"export-type", "ExportType", "Export", N_("Export file type.") },
+ {"export-filename", "ExportFileName", "Export", N_("Export file name.") },
+ {"export-overwrite", "ExportOverWrite", "Export", N_("Export over-write file.") },
+
+ {"export-area", "ExportArea", "Export", N_("Export area.") },
+ {"export-area-drawing", "ExportAreaDrawing", "Export", N_("Export drawing area.") },
+ {"export-area-page", "ExportAreaPage", "Export", N_("Export page area.") },
+ {"export-margin", "ExportMargin", "Export", N_("Export margin.") },
+ {"export-area-snap", "ExportAreaSnap", "Export", N_("Export snap area to integer values.") },
+ {"export-width", "ExportWidth", "Export", N_("Export width.") },
+ {"export-height", "ExportHeight", "Export", N_("Export height.") },
+
+ {"export-id", "ExportID", "Export", N_("Export id(s).") },
+ {"export-id-only", "ExportIDOnly", "Export", N_("Export id(s) only.") },
+
+ {"export-plain-svg", "ExportPlanSVG", "Export", N_("Export as plain SVG.") },
+ {"export-dpi", "ExportDPI", "Export", N_("Export DPI.") },
+ {"export-ignore-filters", "ExportIgnoreFilters", "Export", N_("Export ignore filters.") },
+ {"export-text-to-path", "ExportTextToPath", "Export", N_("Export convert text to paths.") },
+ {"export-ps-level", "ExportPSLevel", "Export", N_("Export PostScript level.") },
+ {"export-pdf-version", "ExportPSVersion", "Export", N_("Export PDF version.") },
+ {"export-latex", "ExportLaTeX", "Export", N_("Export LaTeX.") },
+ {"export-use-hints", "ExportUseHInts", "Export", N_("Export using saved hints.") },
+ {"export-background", "ExportBackground", "Export", N_("Export background color.") },
+ {"export-background-opacity", "ExportBackgroundOpacity", "Export", N_("Export background opacity.") },
+
+ {"export-do", "ExportDo", "Export", N_("Do export.") }
+};
+
+template <class T>
+void
+add_actions_output(ConcreteInkscapeApplication<T>* app)
+{
+ Glib::VariantType Bool( Glib::VARIANT_TYPE_BOOL);
+ Glib::VariantType Int( Glib::VARIANT_TYPE_INT32);
+ Glib::VariantType Double(Glib::VARIANT_TYPE_DOUBLE);
+ Glib::VariantType String(Glib::VARIANT_TYPE_STRING);
+ Glib::VariantType BString(Glib::VARIANT_TYPE_BYTESTRING);
+
+ // Debian 9 has 2.50.0
+#if GLIB_CHECK_VERSION(2, 52, 0)
+
+ // Matches command line options
+ app->add_action_with_parameter( "export-type", String, sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&export_type), app));
+ app->add_action_with_parameter( "export-filename", String, sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&export_filename), app)); // MAY NOT WORK DUE TO std::string
+ app->add_action_with_parameter( "export-overwrite", Bool, sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&export_overwrite), app));
+
+ app->add_action_with_parameter( "export-area", String, sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&export_area), app));
+ app->add_action_with_parameter( "export-area-drawing", Bool, sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&export_area_drawing), app));
+ app->add_action_with_parameter( "export-area-page", Bool, sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&export_area_page), app));
+ app->add_action_with_parameter( "export-margin", Int, sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&export_margin), app));
+ app->add_action_with_parameter( "export-area-snap", Bool, sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&export_area_snap), app));
+ app->add_action_with_parameter( "export-width", Int, sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&export_width), app));
+ app->add_action_with_parameter( "export-height", Int, sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&export_height), app));
+
+ app->add_action_with_parameter( "export-id", String, sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&export_id), app));
+ app->add_action_with_parameter( "export-id-only", Bool, sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&export_id_only), app));
+
+ app->add_action_with_parameter( "export-plain-svg", Bool, sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&export_plain_svg), app));
+ app->add_action_with_parameter( "export-dpi", Double, sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&export_dpi), app));
+ app->add_action_with_parameter( "export-ignore-filters", Bool, sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&export_plain_svg), app));
+ app->add_action_with_parameter( "export-text-to-path", Bool, sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&export_text_to_path), app));
+ app->add_action_with_parameter( "export-ps-level", Int, sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&export_ps_level), app));
+ app->add_action_with_parameter( "export-pdf-version", String, sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&export_pdf_level), app));
+ app->add_action_with_parameter( "export-latex", Bool, sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&export_latex), app));
+ app->add_action_with_parameter( "export-use-hints", Bool, sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&export_use_hints), app));
+ app->add_action_with_parameter( "export-background", String, sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&export_background), app));
+ app->add_action_with_parameter( "export-background-opacity",Double, sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&export_background_opacity), app));
+
+ // Extra
+ app->add_action( "export-do", sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&export_do), app));
+#else
+ std::cerr << "add_actions: Some actions require Glibmm 2.52, compiled with: " << glib_major_version << "." << glib_minor_version << std::endl;
+#endif
+
+ app->get_action_extra_data().add_data(raw_data_output);
+}
+
+
+template void add_actions_output(ConcreteInkscapeApplication<Gio::Application>* app);
+template void add_actions_output(ConcreteInkscapeApplication<Gtk::Application>* app);
+
+
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/actions/actions-output.h b/src/actions/actions-output.h
new file mode 100644
index 0000000..01ea455
--- /dev/null
+++ b/src/actions/actions-output.h
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Gio::Actions for output tied to the application and without GUI.
+ *
+ * Copyright (C) 2018 Tavmjong Bah
+ *
+ * The contents of this file may be used under the GNU General Public License Version 2 or later.
+ *
+ */
+
+#ifndef INK_ACTIONS_OUTPUT_H
+#define INK_ACTIONS_OUTPUT_H
+
+class InkscapeApplication;
+template<class T> class ConcreteInkscapeApplication;
+
+template<class T>
+void add_actions_output(ConcreteInkscapeApplication<T>* app);
+
+#endif // INK_ACTIONS_OUTPUT_H
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/actions/actions-selection.cpp b/src/actions/actions-selection.cpp
new file mode 100644
index 0000000..377ab0c
--- /dev/null
+++ b/src/actions/actions-selection.cpp
@@ -0,0 +1,286 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Gio::Actions for selection tied to the application and without GUI.
+ *
+ * Copyright (C) 2018 Tavmjong Bah
+ *
+ * The contents of this file may be used under the GNU General Public License Version 2 or later.
+ *
+ */
+
+#include <iostream>
+
+#include <giomm.h> // Not <gtkmm.h>! To eventually allow a headless version!
+#include <glibmm/i18n.h>
+
+#include "actions-selection.h"
+#include "actions-helper.h"
+#include "inkscape-application.h"
+
+#include "inkscape.h" // Inkscape::Application
+#include "selection.h" // Selection
+
+#include "object/sp-root.h" // select_all: document->getRoot();
+#include "object/sp-item-group.h" // select_all
+
+void
+select_clear(InkscapeApplication* app)
+{
+ SPDocument* document = nullptr;
+ Inkscape::Selection* selection = nullptr;
+ if (!get_document_and_selection(app, &document, &selection)) {
+ return;
+ }
+ selection->clear();
+}
+
+void
+select_by_id(Glib::ustring ids, InkscapeApplication* app)
+{
+ SPDocument* document = nullptr;
+ Inkscape::Selection* selection = nullptr;
+ if (!get_document_and_selection(app, &document, &selection)) {
+ return;
+ }
+
+ auto tokens = Glib::Regex::split_simple("\\s*,\\s*", ids);
+ for (auto id : tokens) {
+ SPObject* object = document->getObjectById(id);
+ if (object) {
+ selection->add(object);
+ } else {
+ std::cerr << "select_by_id: Did not find object with id: " << id << std::endl;
+ }
+ }
+}
+
+void
+unselect_by_id(Glib::ustring ids, InkscapeApplication* app)
+{
+ SPDocument* document = nullptr;
+ Inkscape::Selection* selection = nullptr;
+ if (!get_document_and_selection(app, &document, &selection)) {
+ return;
+ }
+
+ auto tokens = Glib::Regex::split_simple("\\s*,\\s*", ids);
+ for (auto id : tokens) {
+ SPObject* object = document->getObjectById(id);
+ if (object) {
+ selection->remove(object);
+ } else {
+ std::cerr << "unselect_by_id: Did not find object with id: " << id << std::endl;
+ }
+ }
+}
+
+void
+select_by_class(Glib::ustring klass, InkscapeApplication* app)
+{
+ SPDocument* document = nullptr;
+ Inkscape::Selection* selection = nullptr;
+ if (!get_document_and_selection(app, &document, &selection)) {
+ return;
+ }
+
+ auto objects = document->getObjectsByClass(klass);
+ selection->add(objects.begin(), objects.end());
+}
+
+void
+select_by_element(Glib::ustring element, InkscapeApplication* app)
+{
+ SPDocument* document = nullptr;
+ Inkscape::Selection* selection = nullptr;
+ if (!get_document_and_selection(app, &document, &selection)) {
+ return;
+ }
+ auto objects = document->getObjectsByElement(element);
+ selection->add(objects.begin(), objects.end());
+}
+
+void
+select_by_selector(Glib::ustring selector, InkscapeApplication* app)
+{
+ SPDocument* document = nullptr;
+ Inkscape::Selection* selection = nullptr;
+ if (!get_document_and_selection(app, &document, &selection)) {
+ return;
+ }
+
+ auto objects = document->getObjectsBySelector(selector);
+ selection->add(objects.begin(), objects.end());
+}
+
+
+// Helper
+void
+get_all_items_recursive(std::vector<SPObject *> &objects, SPObject *object, Glib::ustring &condition)
+{
+ for (auto &o : object->childList(false)) {
+ if (dynamic_cast<SPItem *>(o)) {
+ SPGroup *group = dynamic_cast<SPGroup *>(o);
+ if (condition == "layers") {
+ if (group && group->layerMode() == SPGroup::LAYER) {
+ objects.emplace_back(o);
+ continue; // Layers cannot contain layers.
+ }
+ } else if (condition == "no-layers") {
+ if (group && group->layerMode() == SPGroup::LAYER) {
+ // recurse one level
+ } else {
+ objects.emplace_back(o);
+ continue;
+ }
+ } else if (condition == "groups") {
+ if (group) {
+ objects.emplace_back(o);
+ }
+ } else if (condition == "all") {
+ objects.emplace_back(o);
+ } else {
+ // no-groups, default
+ if (!group) {
+ objects.emplace_back(o);
+ continue; // Non-groups cannot contain items.
+ }
+ }
+ get_all_items_recursive(objects, o, condition);
+ }
+ }
+}
+
+
+/*
+ * 'layers': All layers.
+ * 'groups': All groups (including layers).
+ * 'no-layers': All top level objects in all layers (matches GUI "Select All in All Layers").
+ * 'no-groups': All objects other than groups (and layers).
+ * 'all': All objects including groups and their decendents.
+ *
+ * Note: GUI "Select All" requires knowledge of selected layer, which is a desktop property.
+ */
+void
+select_all(Glib::ustring condition, InkscapeApplication* app)
+{
+ if (condition != "" && condition != "layers" && condition != "no-layers" &&
+ condition != "groups" && condition != "no-groups" && condition != "all") {
+ std::cerr << "select_all: allowed options are '', 'all', 'layers', 'no-layers', 'groups', and 'no-groups'" << std::endl;
+ return;
+ }
+
+ SPDocument* document = nullptr;
+ Inkscape::Selection* selection = nullptr;
+ if (!get_document_and_selection(app, &document, &selection)) {
+ return;
+ }
+
+ std::vector<SPObject *> objects;
+ get_all_items_recursive(objects, document->getRoot(), condition);
+
+ selection->setList(objects);
+}
+
+/* See above for conditions. */
+void
+select_invert(Glib::ustring condition, InkscapeApplication* app)
+{
+ if (condition != "" && condition != "layers" && condition != "no-layers" &&
+ condition != "groups" && condition != "no-groups" && condition != "all") {
+ std::cerr << "select_all: allowed options are '', 'all', 'layers', 'no-layers', 'groups', and 'no-groups'" << std::endl;
+ return;
+ }
+
+ SPDocument* document = nullptr;
+ Inkscape::Selection* selection = nullptr;
+ if (!get_document_and_selection(app, &document, &selection)) {
+ return;
+ }
+
+ // Find all objects that match condition.
+ std::vector<SPObject *> objects;
+ get_all_items_recursive(objects, document->getRoot(), condition);
+
+ // Get current selection.
+ std::vector<SPObject *> current(selection->items().begin(), selection->items().end());
+
+ // Remove current selection from object vector (using "erase remove_if idiom").
+ objects.erase(
+ std::remove_if(std::begin(objects), std::end(objects), [&current](const SPObject *x)
+ {
+ return (std::find(current.begin(), current.end(), x) != current.end());
+ }), objects.end());
+
+ // Set selection to object vector.
+ selection->setList(objects);
+}
+
+
+// Debug... print selected items
+void
+select_list(InkscapeApplication* app)
+{
+ SPDocument* document = nullptr;
+ Inkscape::Selection* selection = nullptr;
+ if (!get_document_and_selection(app, &document, &selection)) {
+ return;
+ }
+
+ auto items = selection->items();
+ for (auto i = items.begin(); i != items.end(); ++i) {
+ std::cout << **i << std::endl;
+ }
+}
+
+
+std::vector<std::vector<Glib::ustring>> raw_data_selection =
+{
+ {"select-clear", "SelectClear", "Select", N_("Selection clear") },
+ {"select", "Select", "Select", N_("Select by ID (Deprecated)") },
+ {"unselect", "UnSelect", "Select", N_("Unselect by ID (Deprecated)") },
+ {"select-by-id", "SelectById", "Select", N_("Select by ID") },
+ {"unselect-by-id", "UnselectById", "Select", N_("Unselect by ID") },
+ {"select-by-class", "SelectByClass", "Select", N_("Select by class") },
+ {"select-by-element", "SelectByElement", "Select", N_("Select by SVG element (e.g. 'rect').") },
+ {"select-by-selector", "SelectBySelector", "Select", N_("Select by CSS selector") },
+ {"select-all", "SelectAll", "Select", N_("Select all. Options: 'all' (every object including groups), 'layers', 'no-layers' (top level objects in layers), 'groups' (all groups including layers), 'no-groups' (all objects other than groups and layers, default).")},
+ {"select-invert", "SelectInvert", "Select", N_("Invert selection. Options: 'all', 'layers', 'no-layers', 'groups', 'no-groups' (default).")},
+ {"select-list", "SelectList", "Select", N_("Print a list of objects in current selection.") }
+};
+
+template<class T>
+void
+add_actions_selection(ConcreteInkscapeApplication<T>* app)
+{
+ app->add_action( "select-clear", sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&select_clear), app) );
+ app->add_action_radio_string( "select", sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&select_by_id), app), "null"); // Backwards compatible.
+ app->add_action_radio_string( "unselect", sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&unselect_by_id), app), "null"); // Match select.
+ app->add_action_radio_string( "select-by-id", sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&select_by_id), app), "null");
+ app->add_action_radio_string( "unselect-by-id", sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&unselect_by_id), app), "null");
+ app->add_action_radio_string( "select-by-class", sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&select_by_class), app), "null");
+ app->add_action_radio_string( "select-by-element", sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&select_by_element), app), "null");
+ app->add_action_radio_string( "select-by-selector",sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&select_by_selector), app), "null");
+ app->add_action_radio_string( "select-all", sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&select_all), app), "null");
+ app->add_action_radio_string( "select-invert", sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&select_invert), app), "null");
+ app->add_action( "select-list", sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&select_list), app) );
+
+ app->get_action_extra_data().add_data(raw_data_selection);
+}
+
+template void add_actions_selection(ConcreteInkscapeApplication<Gio::Application>* app);
+template void add_actions_selection(ConcreteInkscapeApplication<Gtk::Application>* app);
+
+
+
+
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/actions/actions-selection.h b/src/actions/actions-selection.h
new file mode 100644
index 0000000..f792a5c
--- /dev/null
+++ b/src/actions/actions-selection.h
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Gio::Actions for selection tied to the application and without GUI.
+ *
+ * Copyright (C) 2018 Tavmjong Bah
+ *
+ * The contents of this file may be used under the GNU General Public License Version 2 or later.
+ *
+ */
+
+#ifndef INK_ACTIONS_SELECTION_H
+#define INK_ACTIONS_SELECTION_H
+
+template<class T> class ConcreteInkscapeApplication;
+
+template<class T>
+void add_actions_selection(ConcreteInkscapeApplication<T>* app);
+
+#endif // INK_ACTIONS_SELECTION_H
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/actions/actions-transform.cpp b/src/actions/actions-transform.cpp
new file mode 100644
index 0000000..a6127da
--- /dev/null
+++ b/src/actions/actions-transform.cpp
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Gio::Actions for selection tied to the application and without GUI.
+ *
+ * Copyright (C) 2018 Tavmjong Bah
+ *
+ * The contents of this file may be used under the GNU General Public License Version 2 or later.
+ *
+ */
+
+#include <iostream>
+
+#include <giomm.h> // Not <gtkmm.h>! To eventually allow a headless version!
+#include <glibmm/i18n.h>
+
+#include "actions-transform.h"
+#include "actions-helper.h"
+#include "document-undo.h"
+#include "inkscape-application.h"
+
+#include "inkscape.h" // Inkscape::Application
+#include "selection.h" // Selection
+
+void
+transform_translate(const Glib::VariantBase& value, InkscapeApplication *app)
+{
+ Glib::Variant<Glib::ustring> s = Glib::VariantBase::cast_dynamic<Glib::Variant<Glib::ustring> >(value);
+
+ std::vector<Glib::ustring> tokens = Glib::Regex::split_simple(",", s.get());
+ if (tokens.size() != 2) {
+ std::cerr << "action:transform_translate: requires two comma separated numbers" << std::endl;
+ return;
+ }
+ double dx = 0;
+ double dy = 0;
+
+ try {
+ dx = std::stod(tokens[0]);
+ dy = std::stod(tokens[1]);
+ } catch (...) {
+ std::cerr << "action:transform-move: invalid arguments" << std::endl;
+ return;
+ }
+
+ auto selection = app->get_active_selection();
+ selection->move(dx, dy);
+
+ // Needed to update repr (is this the best way?).
+ Inkscape::DocumentUndo::done(app->get_active_document(), 0, "ActionTransformTranslate");
+}
+
+void
+transform_rotate(const Glib::VariantBase& value, InkscapeApplication *app)
+{
+
+ Glib::Variant<double> d = Glib::VariantBase::cast_dynamic<Glib::Variant<double> >(value);
+ auto selection = app->get_active_selection();
+
+ selection->rotate(d.get());
+
+ // Needed to update repr (is this the best way?).
+ Inkscape::DocumentUndo::done(app->get_active_document(), 0, "ActionTransformRotate");
+}
+
+void
+transform_scale(const Glib::VariantBase& value, InkscapeApplication *app)
+{
+ Glib::Variant<double> d = Glib::VariantBase::cast_dynamic<Glib::Variant<double> >(value);
+ auto selection = app->get_active_selection();
+ selection->scale(d.get());
+
+ // Needed to update repr (is this the best way?).
+ Inkscape::DocumentUndo::done(app->get_active_document(), 0, "ActionTransformScale");
+}
+
+void
+transform_remove(InkscapeApplication *app)
+{
+ auto selection = app->get_active_selection();
+ selection->removeTransform();
+
+ // Needed to update repr (is this the best way?).
+ Inkscape::DocumentUndo::done(app->get_active_document(), 0, "ActionTransformRemoveTransform");
+}
+
+
+std::vector<std::vector<Glib::ustring>> raw_data_transform =
+{
+ {"transform-translate", "TransformTranslate", "Transform", N_("Translate selected objects (dx,dy).") },
+ {"transform-rotate", "TransformRotate", "Transform", N_("Rotate selected objects by degrees.") },
+ {"transform-scale", "TransformScale", "Transform", N_("Scale selected objects by scale factor.") },
+ {"transform-remove", "TransformRemove", "Transform", N_("Remove any transforms from selected objects.") }
+};
+
+template<class T>
+void
+add_actions_transform(ConcreteInkscapeApplication<T>* app)
+{
+ Glib::VariantType Bool( Glib::VARIANT_TYPE_BOOL);
+ Glib::VariantType Int( Glib::VARIANT_TYPE_INT32);
+ Glib::VariantType Double(Glib::VARIANT_TYPE_DOUBLE);
+ Glib::VariantType String(Glib::VARIANT_TYPE_STRING);
+
+ // Debian 9 has 2.50.0
+#if GLIB_CHECK_VERSION(2, 52, 0)
+
+ app->add_action_with_parameter( "transform-translate", String, sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&transform_translate), app));
+ app->add_action_with_parameter( "transform-rotate", Double, sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&transform_rotate), app));
+ app->add_action_with_parameter( "transform-scale", Double, sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&transform_scale), app));
+ app->add_action( "transform-remove", sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&transform_remove), app));
+
+#endif
+
+ app->get_action_extra_data().add_data(raw_data_transform);
+}
+
+
+template void add_actions_transform(ConcreteInkscapeApplication<Gio::Application>* app);
+template void add_actions_transform(ConcreteInkscapeApplication<Gtk::Application>* app);
+
+
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/actions/actions-transform.h b/src/actions/actions-transform.h
new file mode 100644
index 0000000..03c2afd
--- /dev/null
+++ b/src/actions/actions-transform.h
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Gio::Actions for selection tied to the application and without GUI.
+ *
+ * Copyright (C) 2018 Tavmjong Bah
+ *
+ * The contents of this file may be used under the GNU General Public License Version 2 or later.
+ *
+ */
+
+#ifndef INK_ACTIONS_TRANSFORM_H
+#define INK_ACTIONS_TRANSFORM_H
+
+template<class T> class ConcreteInkscapeApplication;
+
+template<class T>
+void add_actions_transform(ConcreteInkscapeApplication<T>* app);
+
+#endif // INK_ACTIONS_TRANSFORM_H
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/actions/actions-window.cpp b/src/actions/actions-window.cpp
new file mode 100644
index 0000000..abde33b
--- /dev/null
+++ b/src/actions/actions-window.cpp
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Gio::Actions for window handling tied to the application and with GUI.
+ *
+ * Copyright (C) 2020 Tavmjong Bah
+ *
+ * The contents of this file may be used under the GNU General Public License Version 2 or later.
+ *
+ */
+
+#include <iostream>
+
+#include <giomm.h> // Not <gtkmm.h>! To eventually allow a headless version!
+#include <gtkmm.h>
+#include <glibmm/i18n.h>
+
+#include "actions-window.h"
+#include "actions-helper.h"
+#include "inkscape-application.h"
+#include "inkscape-window.h"
+
+#include "inkscape.h" // Inkscape::Application
+#include "helper/action-context.h"
+
+// Actions for window handling (should be integrated with file dialog).
+
+class InkscapeWindow;
+
+// Open a window for current document
+void
+window_open(InkscapeApplication *app)
+{
+ SPDocument *document = app->get_active_document();
+ if (document) {
+ InkscapeWindow* window = app->get_active_window();
+ if (window && window->get_document() && window->get_document()->getVirgin()) {
+ // We have a window with an untouched template document, use this window.
+ app->document_swap (window, document);
+ } else {
+ app->window_open(document);
+ }
+ } else {
+ std::cerr << "window_open(): failed to find document!" << std::endl;
+ }
+}
+
+void
+window_close(InkscapeApplication *app)
+{
+ app->window_close_active();
+}
+
+std::vector<std::vector<Glib::ustring>> raw_data_window =
+{
+ {"window-open", "WindowOpen", "Window", N_("Open a window for the active document. GUI only.") },
+ {"window-close", "WindowClose", "Window", N_("Close the active window.") }
+};
+
+template <class T>
+void
+add_actions_window(ConcreteInkscapeApplication<T>* app)
+{
+ Glib::VariantType Bool( Glib::VARIANT_TYPE_BOOL);
+ Glib::VariantType Int( Glib::VARIANT_TYPE_INT32);
+ Glib::VariantType Double(Glib::VARIANT_TYPE_DOUBLE);
+ Glib::VariantType String(Glib::VARIANT_TYPE_STRING);
+ Glib::VariantType BString(Glib::VARIANT_TYPE_BYTESTRING);
+
+ // Debian 9 has 2.50.0
+#if GLIB_CHECK_VERSION(2, 52, 0)
+
+ app->add_action( "window-open", sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&window_open), app));
+ app->add_action( "window-close", sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&window_close), app));
+#else
+ std::cerr << "add_actions: Some actions require Glibmm 2.52, compiled with: " << glib_major_version << "." << glib_minor_version << std::endl;
+#endif
+
+ app->get_action_extra_data().add_data(raw_data_window);
+}
+
+
+template void add_actions_window(ConcreteInkscapeApplication<Gio::Application>* app);
+template void add_actions_window(ConcreteInkscapeApplication<Gtk::Application>* app);
+
+
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/actions/actions-window.h b/src/actions/actions-window.h
new file mode 100644
index 0000000..a9f7418
--- /dev/null
+++ b/src/actions/actions-window.h
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Gio::Actions for window handling tied to the application and with GUI.
+ *
+ * Copyright (C) 2020 Tavmjong Bah
+ *
+ * The contents of this file may be used under the GNU General Public License Version 2 or later.
+ *
+ */
+
+#ifndef INK_ACTIONS_WINDOW_H
+#define INK_ACTIONS_WINDOW_H
+
+class InkscapeApplication;
+template<class T> class ConcreteInkscapeApplication;
+
+template<class T>
+void add_actions_window(ConcreteInkscapeApplication<T>* app);
+
+#endif // INK_ACTIONS_WINDOW_H
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :