Commit 408cb49b authored by Tavmjong Bah's avatar Tavmjong Bah Committed by Alex Valavanis

Rewrite of main.cpp using InkscapeApplication (Gtk::Application)

Use Gio::File for accessing files.
Use Gio options to handle command line arguments.
Use Gio::Actions for some command line arguments.
Move file export code to src/io/file-export-cmd.h/.cpp. Make into class.
parent f1b21219
# List of source files containing translatable strings.
# Please keep this file sorted alphabetically.
# Generated by ./generate_POTFILES.sh at Mon Nov 5 10:33:09 CET 2018
# Generated by ./generate_POTFILES.sh at Mon Nov 12 21:20:36 CET 2018
[encoding: UTF-8]
inkscape.appdata.xml.in
inkscape.desktop.in
......@@ -109,6 +109,7 @@ src/gradient-chemistry.cpp
src/gradient-drag.cpp
src/helper/gettext.cpp
src/helper/gettext.h
src/inkscape-application.cpp
src/inkscape.cpp
src/inkview-application.cpp
src/io/resource-manager.cpp
......@@ -178,7 +179,6 @@ src/live_effects/parameter/unit.cpp
src/live_effects/parameter/vector.cpp
src/main-cmdlineact.cpp
src/main-cmdlinexact.cpp
src/main.cpp
src/menus-skeleton.h
src/object/box3d.cpp
src/object/color-profile.cpp
......
......@@ -245,6 +245,7 @@ list(APPEND inkscape_SRC
# All folders for internal inkscape
# these call add_inkscape_source
add_subdirectory(actions)
add_subdirectory(debug)
add_subdirectory(display)
add_subdirectory(extension)
......@@ -278,7 +279,13 @@ set(inkscape_SRC
# -----------------------------------------------------------------------------
# Setup the executable
# -----------------------------------------------------------------------------
set(main_SRC main.cpp)
set(main_SRC
inkscape-main.cpp
inkscape-application.h
inkscape-application.cpp
actions/actions-base.h
actions/actions-base.cpp
)
set(view_SRC
inkview-main.cpp
inkview-application.h
......
# SPDX-License-Identifier: GPL-2.0-or-later
set(actions_SRC
# actions-base.cpp
# HEADERS
# actions-base.h
)
add_inkscape_source("${actions_SRC}")
// 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 "actions-base.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
void
print_inkscape_version()
{
std::cout << "Inkscape " << Inkscape::version_string << std::endl;
}
void
print_extension_directory()
{
std::cout << INKSCAPE_EXTENSIONDIR << 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: returns true if both document and selection found.
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;
}
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;
}
void
select_via_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: did not find object with id: " << id << std::endl;
}
}
}
// 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[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
add_actions_base(InkscapeApplication* 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("extension-directory", sigc::ptr_fun(&print_extension_directory));
app->add_action("verb-list", sigc::ptr_fun(&print_verb_list ));
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( "vacuum-defs", sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&vacuum_defs), app) );
app->add_action_radio_string( "select", sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&select_via_id), app), "null");
app->add_action_radio_string( "verb", sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&verbs), app), "null");
app->add_action_radio_string( "query-id", sigc::bind<InkscapeApplication*>(sigc::ptr_fun(&select_via_id), app), "null"); // For backwards compatibility.
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) );
}
/*
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 :
// 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
class InkscapeApplication;
void add_actions_base(InkscapeApplication* app);
#endif // INK_ACTIONS_BASE_H
This diff is collapsed.
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* The main Inkscape application.
*
* Copyright (C) 2018 Tavmjong Bah
*
* The contents of this file may be used under the GNU General Public License Version 2 or later.
*
*/
#ifndef INKSCAPE_APPLICATION_H
#define INKSCAPE_APPLICATION_H
/*
* The main Inkscape application.
*
* Copyright (C) 2018 Tavmjong Bah
*
* The contents of this file may be used under the GNU General Public License Version 2 or later.
*
*/
#include <gtkmm.h>
#include "document.h"
#include "helper/action.h"
#include "io/file-export-cmd.h" // File export (non-verb)
class InkscapeApplication : public Gtk::Application
{
protected:
InkscapeApplication();
public:
static Glib::RefPtr<InkscapeApplication> create();
SPDocument* get_active_document();
protected:
void on_startup() override;
void on_startup2();
void on_activate() override;
void on_open(const Gio::Application::type_vec_files& files, const Glib::ustring& hint) override;
private:
void create_window(const Glib::RefPtr<Gio::File>& file = Glib::RefPtr<Gio::File>());
private:
// Callbacks
int on_handle_local_options(const Glib::RefPtr<Glib::VariantDict>& options);
// Actions
void on_new();
void on_quit();
void on_about();
Glib::RefPtr<Gtk::Builder> _builder;
bool _with_gui;
InkFileExportCmd _file_export;
// Documents are owned by the application which is responsible for opening/saving/exporting. WIP
std::vector<SPDocument*> _documents;
// Actions from the command line or file.
std::vector<std::pair<std::string, Glib::VariantBase> > _command_line_actions;
};
#endif // INKSCAPE_APPLICATION_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 :
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Inkscape - an ambitious vector drawing program
*
* Authors:
* Tavmjong Bah
*
* (C) 2018 Tavmjong Bah
*
* Released under GNU GPL v2+, read the file 'COPYING' for more information.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "inkscape-application.h"
int main(int argc, char *argv[])
{
auto application = InkscapeApplication::create();
return application->run(argc, argv);
}
/*
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 :
......@@ -67,7 +67,7 @@
Inkscape::Application * Inkscape::Application::_S_inst = nullptr;
bool Inkscape::Application::_crashIsHappening = false;
#define DESKTOP_IS_ACTIVE(d) (!INKSCAPE._desktops->empty() && ((d) == INKSCAPE._desktops->front()))
#define DESKTOP_IS_ACTIVE(d) (INKSCAPE._desktops != nullptr && !INKSCAPE._desktops->empty() && ((d) == INKSCAPE._desktops->front()))
static void (* segv_handler) (int) = SIG_DFL;
static void (* abrt_handler) (int) = SIG_DFL;
......@@ -609,7 +609,7 @@ Application::~Application()
_S_inst = nullptr; // this will probably break things
refCount = 0;
gtk_main_quit ();
// gtk_main_quit ();
}
/** Sets the keyboard modifer to map to Alt.
......@@ -1279,6 +1279,7 @@ Application::action_context_for_document(SPDocument *doc)
// Document is not associated with any desktops - maybe we're in command-line mode
std::map<SPDocument *, AppSelectionModel *>::iterator sel_iter = _selection_models.find(doc);
if (sel_iter == _selection_models.end()) {
std::cout << "Application::action_context_for_document: no selection model" << std::endl;
return Inkscape::ActionContext();
}
return Inkscape::ActionContext(sel_iter->second->getSelection());
......@@ -1309,7 +1310,7 @@ Application::exit ()
signal_shut_down.emit();
Inkscape::Preferences::unload();
gtk_main_quit ();
//gtk_main_quit ();
}
......
......@@ -2,6 +2,8 @@
set(io_SRC
dir-util.cpp
file.cpp
file-export-cmd.cpp
resource.cpp
resource-manager.cpp
stream/bufferstream.cpp
......@@ -16,6 +18,8 @@ set(io_SRC
# -------
# Headers
dir-util.h
file.h
file-export-cmd.h
resource.h
resource-manager.h
stream/bufferstream.h
......
This diff is collapsed.
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* File export from the command line. This code use to be in main.cpp. It should be
* replaced by shared code (Gio::Actions?) for export from the file dialog.
*
* 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_FILE_EXPORT_CMD_H
#define INK_FILE_EXPORT_CMD_H
#include <iostream>
#include <gtkmm.h>
class SPDocument;
class InkFileExportCmd {
public:
InkFileExportCmd();
void do_export(SPDocument* doc, std::string filename_in="");
private:
std::string get_filename_out(std::string filename_in="");
int do_export_svg( SPDocument* doc, std::string filename_out);
int do_export_png( SPDocument* doc, std::string filename_out);
int do_export_ps_pdf(SPDocument* doc, std::string filename_out, std::string mime_type);
int do_export_win_metafile(SPDocument* doc, std::string filename_out, std::string mime_type);
public:
// Should be private, but this is just temporary code (I hope!).
bool over_write;
// One-to-one correspondence with command line options
std::string export_filename; // Only if one file is processed!
Glib::ustring export_type;
bool export_overwrite;
Glib::ustring export_area;
bool export_area_drawing;
bool export_area_page;
int export_margin;
bool export_area_snap;
int export_width;
int export_height;
int export_dpi;
bool export_ignore_filters;
bool export_text_to_path;
int export_ps_level;
Glib::ustring export_pdf_level;
bool export_latex;
Glib::ustring export_id;
bool export_id_only;
bool export_use_hints;
Glib::ustring export_background;
double export_background_opacity;
bool export_plain_svg;
};
#endif // INK_FILE_EXPORT_CMD_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 :
// SPDX-License-Identifier: GPL-2.0-or-later