summaryrefslogtreecommitdiffstats
path: root/src/actions/actions-base.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/actions/actions-base.cpp')
-rw-r--r--src/actions/actions-base.cpp281
1 files changed, 281 insertions, 0 deletions
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 :