diff options
| author | Jabier Arraiza Cenoz <jabier.arraiza@marker.es> | 2016-10-04 20:16:52 +0000 |
|---|---|---|
| committer | jabiertxof <info@marker.es> | 2016-10-04 20:16:52 +0000 |
| commit | de6faf491fdc0bfbdd38af7a26089ceb27bc2c06 (patch) | |
| tree | 7f1baa6e45ac1aad0264a38794c0793b573fb91b /src | |
| parent | Fix scaling bug (diff) | |
| parent | xverbs branch merge by dmitry-zhulanov (diff) | |
| download | inkscape-de6faf491fdc0bfbdd38af7a26089ceb27bc2c06.tar.gz inkscape-de6faf491fdc0bfbdd38af7a26089ceb27bc2c06.zip | |
Attemp lock hepers
(bzr r15017.1.38)
Diffstat (limited to 'src')
| -rw-r--r-- | src/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/live_effects/lpe-measure-line.cpp | 77 | ||||
| -rw-r--r-- | src/live_effects/lpe-measure-line.h | 1 | ||||
| -rw-r--r-- | src/main-cmdlineact.cpp | 54 | ||||
| -rw-r--r-- | src/main-cmdlineact.h | 19 | ||||
| -rw-r--r-- | src/main-cmdlinexact.cpp | 576 | ||||
| -rw-r--r-- | src/main-cmdlinexact.h | 54 | ||||
| -rw-r--r-- | src/main.cpp | 31 | ||||
| -rw-r--r-- | src/sp-item.cpp | 2 | ||||
| -rw-r--r-- | src/verbs.cpp | 8 | ||||
| -rw-r--r-- | src/verbs.h | 2 |
11 files changed, 773 insertions, 53 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3c4f28aa8..6a2af6b4b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -221,6 +221,7 @@ set(inkscape_SRC line-geometry.cpp line-snapper.cpp main-cmdlineact.cpp + main-cmdlinexact.cpp media.cpp message-context.cpp message-stack.cpp @@ -337,6 +338,7 @@ set(inkscape_SRC line-snapper.h macros.h main-cmdlineact.h + main-cmdlinexact.h media.h menus-skeleton.h message-context.h diff --git a/src/live_effects/lpe-measure-line.cpp b/src/live_effects/lpe-measure-line.cpp index 57e67ab3a..4780fb817 100644 --- a/src/live_effects/lpe-measure-line.cpp +++ b/src/live_effects/lpe-measure-line.cpp @@ -67,6 +67,7 @@ LPEMeasureLine::LPEMeasureLine(LivePathEffectObject *lpeobject) : line_group_05(_("Line Group 0.5*"), _("Line Group 0.5, from 0.7"), "line_group_05", &wr, this, true), rotate_anotation(_("Rotate Anotation*"), _("Rotate Anotation"), "rotate_anotation", &wr, this, true), hide_back(_("Hide if label over*"), _("Hide DIN line if label over"), "hide_back", &wr, this, true), + lock_measure(_("Lock measure data"), _("Lock measure data to avoid problems on transforms"), "lock_measure", &wr, this, true), dimline_format(_("CSS DIN line*"), _("Override CSS to DIN line, return to save, empty to reset to DIM"), "dimline_format", &wr, this,""), helperlines_format(_("CSS helpers*"), _("Override CSS to helper lines, return to save, empty to reset to DIM"), "helperlines_format", &wr, this,""), anotation_format(_("CSS anotation*"), _("Override CSS to anotation text, return to save, empty to reset to DIM"), "anotation_format", &wr, this,""), @@ -92,6 +93,7 @@ LPEMeasureLine::LPEMeasureLine(LivePathEffectObject *lpeobject) : registerParameter(&line_group_05); registerParameter(&rotate_anotation); registerParameter(&hide_back); + registerParameter(&lock_measure); registerParameter(&dimline_format); registerParameter(&helperlines_format); registerParameter(&anotation_format); @@ -254,6 +256,11 @@ LPEMeasureLine::createArrowMarker(Glib::ustring mode) arrow->setAttribute("refX", "0.0"); arrow->setAttribute("refY", "0.0"); arrow->setAttribute("style", "overflow:visible"); + if (lock_measure) { + arrow->setAttribute("sodipodi:insensitive", "true"); + } else { + arrow->setAttribute("sodipodi:insensitive", NULL); + } /* Create <path> */ Inkscape::XML::Node *arrow_path = xml_doc->createElement("svg:path"); if (mode == (Glib::ustring)"ArrowDIN-start") { @@ -265,6 +272,7 @@ LPEMeasureLine::createArrowMarker(Glib::ustring mode) } else { arrow_path->setAttribute("d", "M 0,0 16,2.11 16,0.5 26,0.5 26,-0.5 16,-0.5 16,-2.11 z"); } + arrow_path->setAttribute("id", (mode + (Glib::ustring)"_path").c_str()); SPCSSAttr *css = sp_repr_css_attr_new(); sp_repr_css_set_property (css, "fill","#000000"); @@ -280,6 +288,11 @@ LPEMeasureLine::createArrowMarker(Glib::ustring mode) } else { Inkscape::XML::Node *arrow= elemref->getRepr(); if (arrow) { + if (lock_measure) { + arrow->setAttribute("sodipodi:insensitive", "true"); + } else { + arrow->setAttribute("sodipodi:insensitive", NULL); + } Inkscape::XML::Node *arrow_data = arrow->firstChild(); if (arrow_data) { SPCSSAttr *css = sp_repr_css_attr_new(); @@ -320,15 +333,23 @@ LPEMeasureLine::createTextLabel(Geom::Point pos, double length, Geom::Coord angl SVGElemRef->attach(SVGElem_uri); SPObject *elemref = NULL; Inkscape::XML::Node *rtspan = NULL; - pos = pos - Point::polar(angle, text_right_left); + if (elemref = SVGElemRef->getObject()) { if (remove) { elemref->deleteObject(); return; } +// Geom::Affine affinetransform = i2anc_affine(SP_OBJECT(elemref)->parent, SP_OBJECT(desktop->doc()->getRoot())); +// pos *= affinetransform; + pos = pos - Point::polar(angle, text_right_left); rtext = elemref->getRepr(); sp_repr_set_svg_double(rtext, "x", pos[Geom::X]); sp_repr_set_svg_double(rtext, "y", pos[Geom::Y]); + if (lock_measure) { + rtext->setAttribute("sodipodi:insensitive", "true"); + } else { + rtext->setAttribute("sodipodi:insensitive", NULL); + } } else { if (remove) { return; @@ -336,6 +357,12 @@ LPEMeasureLine::createTextLabel(Geom::Point pos, double length, Geom::Coord angl rtext = xml_doc->createElement("svg:text"); rtext->setAttribute("xml:space", "preserve"); rtext->setAttribute("id", ( (Glib::ustring)"text-on-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str()); + if (lock_measure) { + rtext->setAttribute("sodipodi:insensitive", "true"); + } else { + rtext->setAttribute("sodipodi:insensitive", NULL); + } + pos = pos - Point::polar(angle, text_right_left); sp_repr_set_svg_double(rtext, "x", pos[Geom::X]); sp_repr_set_svg_double(rtext, "y", pos[Geom::Y]); rtspan = xml_doc->createElement("svg:tspan"); @@ -450,7 +477,11 @@ LPEMeasureLine::createLine(Geom::Point start,Geom::Point end, Glib::ustring id, end = end + Point::polar(angle, helpline_overlap ); } Geom::PathVector line_pathv; - if (main && std::abs(text_top_bottom) < fontsize/1.5 && hide_back && !overflow){ + SPDocument * doc = SP_ACTIVE_DOCUMENT; + Geom::Affine affinetransform = i2anc_affine(SP_OBJECT(sp_lpe_item)->parent, SP_OBJECT(doc->getRoot())); + double parents_scale = (affinetransform.inverse().expansionX() + affinetransform.inverse().expansionY()) / 2.0; + double current_text_top_bottom = text_top_bottom / parents_scale; + if (main && std::abs(current_text_top_bottom) < fontsize/1.5 && hide_back && !overflow){ Geom::Path line_path; double k = 0; if (flip_side) { @@ -476,14 +507,15 @@ LPEMeasureLine::createLine(Geom::Point start,Geom::Point end, Glib::ustring id, line_path.appendNew<Geom::LineSegment>(end); line_pathv.push_back(line_path); } - gchar * line_str = sp_svg_write_path( line_pathv ); - line_pathv.clear(); + if (elemref = SVGElemRef->getObject()) { if (remove) { elemref->deleteObject(); return; } line = elemref->getRepr(); + + gchar * line_str = sp_svg_write_path( line_pathv ); line->setAttribute("d" , line_str); } else { if (remove) { @@ -491,8 +523,16 @@ LPEMeasureLine::createLine(Geom::Point start,Geom::Point end, Glib::ustring id, } line = xml_doc->createElement("svg:path"); line->setAttribute("id", id.c_str()); + gchar * line_str = sp_svg_write_path( line_pathv ); line->setAttribute("d" , line_str); } + if (lock_measure) { + line->setAttribute("sodipodi:insensitive", "true"); + } else { + line->setAttribute("sodipodi:insensitive", NULL); + } + line_pathv.clear(); + Glib::ustring style = (Glib::ustring)"stroke:#000000;fill:none;"; if (overflow && !arrows) { line->setAttribute("inkscape:label", "downline"); @@ -540,9 +580,13 @@ LPEMeasureLine::doBeforeEffect (SPLPEItem const* lpeitem) SPLPEItem * splpeitem = const_cast<SPLPEItem *>(lpeitem); SPPath *sp_path = dynamic_cast<SPPath *>(splpeitem); if (sp_path) { - Geom::PathVector pathvector = sp_path->get_original_curve()->get_pathvector(); SPDocument * doc = SP_ACTIVE_DOCUMENT; - Geom::Affine affinetransform = i2anc_affine(SP_OBJECT(lpeitem), SP_OBJECT(doc->getRoot())); + Geom::Affine affinetransform = i2anc_affine(SP_OBJECT(lpeitem)->parent, SP_OBJECT(doc->getRoot())); + double parents_scale = (affinetransform.inverse().expansionX() + affinetransform.inverse().expansionY()) / 2.0; + double current_text_top_bottom = text_top_bottom / parents_scale; + double current_position = position / parents_scale; + + Geom::PathVector pathvector = sp_path->get_original_curve()->get_pathvector(); pathvector *= affinetransform; if (arrows_outside) { createArrowMarker((Glib::ustring)"ArrowDINout-start"); @@ -617,24 +661,24 @@ LPEMeasureLine::doBeforeEffect (SPLPEItem const* lpeitem) angle = std::fmod(angle, 2*M_PI); if (angle < 0) angle += 2*M_PI; if (angle >= rad_from_deg(90) && angle < rad_from_deg(270)) { - pos = pos - Point::polar(angle_cross, (position - text_top_bottom) + fontsize/2.5); + pos = pos - Point::polar(angle_cross, (current_position - current_text_top_bottom) + fontsize/2.5); } else { - pos = pos - Point::polar(angle_cross, (position + text_top_bottom) - fontsize/2.5); + pos = pos - Point::polar(angle_cross, (current_position + current_text_top_bottom) - fontsize/2.5); } if (scale_insensitive) { - length *= (affinetransform.inverse().expansionX() + affinetransform.inverse().expansionY()) / 2.0; + length *= parents_scale; } createTextLabel(pos, length, angle, remove); bool overflow = false; if ((anotation_width/2) + std::abs(text_right_left) > Geom::distance(start,end)/2.0) { - Geom::Point sstart = end - Point::polar(angle_cross, position); - Geom::Point send = end - Point::polar(angle_cross, position); + Geom::Point sstart = end - Point::polar(angle_cross, current_position); + Geom::Point send = end - Point::polar(angle_cross, current_position); if (text_right_left < 0 && flip_side || text_right_left > 0 && !flip_side) { - sstart = start - Point::polar(angle_cross, position); - send = start - Point::polar(angle_cross, position); + sstart = start - Point::polar(angle_cross, current_position); + send = start - Point::polar(angle_cross, current_position); } Geom::Point prog_end = Geom::Point(); - if (std::abs(text_top_bottom) < fontsize/1.5 && hide_back) { + if (std::abs(current_text_top_bottom) < fontsize/1.5 && hide_back) { if (text_right_left > 0 ) { prog_end = sstart - Point::polar(angle, std::abs(text_right_left) - (anotation_width/1.9) - (Geom::distance(start,end)/2.0)); } else { @@ -669,10 +713,10 @@ LPEMeasureLine::doBeforeEffect (SPLPEItem const* lpeitem) if (flip_side) { arrow_gap *= -1; } - hstart = hstart - Point::polar(angle_cross, position); + hstart = hstart - Point::polar(angle_cross, current_position); Glib::ustring id = (Glib::ustring)"infoline-on-start-" + (Glib::ustring)this->getRepr()->attribute("id"); createLine(start, hstart, id, false, false, remove); - hend = hend - Point::polar(angle_cross, position); + hend = hend - Point::polar(angle_cross, current_position); id = (Glib::ustring)"infoline-on-end-" + (Glib::ustring)this->getRepr()->attribute("id"); createLine(end, hend, id, false, false, remove); if (!arrows_outside) { @@ -688,7 +732,6 @@ LPEMeasureLine::doBeforeEffect (SPLPEItem const* lpeitem) void LPEMeasureLine::doOnRemove (SPLPEItem const* lpeitem) { if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { - SPLPEItem * splpeitem = const_cast<SPLPEItem *>(lpeitem); Inkscape::URI SVGElem_uri(((Glib::ustring)"#" + (Glib::ustring)"text-on-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str()); Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc()); SVGElemRef->attach(SVGElem_uri); diff --git a/src/live_effects/lpe-measure-line.h b/src/live_effects/lpe-measure-line.h index f9c925ef3..83fef26b8 100644 --- a/src/live_effects/lpe-measure-line.h +++ b/src/live_effects/lpe-measure-line.h @@ -67,6 +67,7 @@ private: BoolParam line_group_05; BoolParam rotate_anotation; BoolParam hide_back; + BoolParam lock_measure; TextParam dimline_format; TextParam helperlines_format; TextParam anotation_format; diff --git a/src/main-cmdlineact.cpp b/src/main-cmdlineact.cpp index a23c036a0..03bf4083c 100644 --- a/src/main-cmdlineact.cpp +++ b/src/main-cmdlineact.cpp @@ -14,6 +14,7 @@ #include <verbs.h> #include <inkscape.h> #include <document.h> +#include <file.h> #include <glibmm/i18n.h> @@ -23,8 +24,7 @@ namespace Inkscape { std::list <CmdLineAction *> CmdLineAction::_list; -CmdLineAction::CmdLineAction(bool isVerb, gchar const *arg) : _isVerb(isVerb), _arg(NULL) -{ +CmdLineAction::CmdLineAction (bool isVerb, gchar const * arg) : _isVerb(isVerb), _arg(NULL) { if (arg != NULL) { _arg = g_strdup(arg); } @@ -34,58 +34,68 @@ CmdLineAction::CmdLineAction(bool isVerb, gchar const *arg) : _isVerb(isVerb), _ return; } -CmdLineAction::~CmdLineAction() -{ +CmdLineAction::~CmdLineAction () { if (_arg != NULL) { g_free(_arg); } } +bool +CmdLineAction::isExtended() { + return false; +} + void -CmdLineAction::doIt(ActionContext const &context) +CmdLineAction::doItX (ActionContext const & context) { + (void)context; + printf("CmdLineAction::doItX() %s\n", _arg); +} + +void +CmdLineAction::doIt (ActionContext const & context) { //printf("Doing: %s\n", _arg); if (_isVerb) { - Inkscape::Verb *verb = Inkscape::Verb::getbyid(_arg); + if (isExtended()) { + doItX(context); + return; + } + + Inkscape::Verb * verb = Inkscape::Verb::getbyid(_arg); if (verb == NULL) { printf(_("Unable to find verb ID '%s' specified on the command line.\n"), _arg); return; } - SPAction *action = verb->get_action(context); + SPAction * action = verb->get_action(context); sp_action_perform(action, NULL); } else { - if (context.getDocument() == NULL || context.getSelection() == NULL) { - return; - } + if (context.getDocument() == NULL || context.getSelection() == NULL) { return; } - SPDocument *doc = context.getDocument(); - SPObject *obj = doc->getObjectById(_arg); + SPDocument * doc = context.getDocument(); + SPObject * obj = doc->getObjectById(_arg); if (obj == NULL) { printf(_("Unable to find node ID: '%s'\n"), _arg); return; } - Inkscape::Selection *selection = context.getSelection(); + Inkscape::Selection * selection = context.getSelection(); selection->add(obj); } return; } bool -CmdLineAction::doList(ActionContext const &context) -{ +CmdLineAction::doList (ActionContext const & context) { bool hasActions = !_list.empty(); - for (std::list<CmdLineAction *>::iterator i = _list.begin(); - i != _list.end(); ++i) { - CmdLineAction *entry = *i; + for (std::list<CmdLineAction *>::iterator i = _list.begin(); i != _list.end(); ++i) { + CmdLineAction * entry = *i; entry->doIt(context); } return hasActions; } bool -CmdLineAction::idle(void) -{ +CmdLineAction::idle (void) { std::list<SPDesktop *> desktops; INKSCAPE.get_all_desktops(desktops); @@ -93,8 +103,8 @@ CmdLineAction::idle(void) // should have had time to make more at this point. for (std::list<SPDesktop *>::iterator i = desktops.begin(); i != desktops.end(); ++i) { - SPDesktop *desktop = *i; - //Inkscape::UI::View::View * view = dynamic_cast<Inkscape::UI::View::View *>(desktop); + SPDesktop * desktop = *i; + //Inkscape::UI::View::View * view = dynamic_cast<Inkscape::UI::View::View *>(desktop); doList(ActionContext(desktop)); } return false; diff --git a/src/main-cmdlineact.h b/src/main-cmdlineact.h index 171313401..f50e70e5a 100644 --- a/src/main-cmdlineact.h +++ b/src/main-cmdlineact.h @@ -21,18 +21,23 @@ class ActionContext; class CmdLineAction { bool _isVerb; - char *_arg; - static std::list <CmdLineAction *> _list; + static bool _requestQuit; + +protected: + char * _arg; public: - CmdLineAction(bool isVerb, char const *arg); - virtual ~CmdLineAction(); + CmdLineAction (bool isVerb, char const * arg); + virtual ~CmdLineAction (); + virtual bool isExtended(); + virtual void doItX (ActionContext const & context); + + void doIt (ActionContext const & context); - void doIt(ActionContext const &context); /** Return true if any actions were performed */ - static bool doList(ActionContext const &context); - static bool idle(void); + static bool doList (ActionContext const & context); + static bool idle (void); }; } // Inkscape diff --git a/src/main-cmdlinexact.cpp b/src/main-cmdlinexact.cpp new file mode 100644 index 000000000..99f0c699b --- /dev/null +++ b/src/main-cmdlinexact.cpp @@ -0,0 +1,576 @@ +/* + * Authors: + * Dmitry Zhulanov <dmitry.zhulanov@gmail.com> + * + * Copyright (C) 2016 Authors + * + * Released under GNU GPL v2, read the file 'COPYING' for more information + * + * Format of xverbs.yaml + * using: $ inkscape -B xverbs.yaml + * + * verbose: yes # only "verbose: yes" enable logging + * run: + * # open document to process + * - xverb-id: XFileOpen, gfx_sources/loading_screen/sandclock_atlas.svg + * - xverb-id: XUndoLabel, fresh_document # set label for UndoToLabel xverb works + * # note: if something wrong with undo labels use verb EditUndo instead of XUndoLabel and UndoToLabel at all + * + * # select element to handle + * - xverb-id: XSelectElement, top_sand + * + * # verbs + * - verb-id: EditInvertInAllLayers + * - verb-id: EditDelete + * - verb-id: FitCanvasToDrawing + * + * # save element to separated svg document + * - xverb-id: XFileSaveAs, output/thegame/linux/data/gfx/loading_screen/top_sand.svg + * + * # also save png preview + * - xverb-id: XFileExportPNG, output/thegame/linux/data/gfx_preview/loading_screen/top_sand.png + * + * # return to the fresh_state of document + * - xverb-id: UndoToLabel, fresh_document + * + * # do any other handling + * + * # inkscape have a lot of useful verbs + * - verb-id: FileQuit + */ +#ifdef WITH_YAML +#include <ui/view/view.h> +#include <desktop.h> +#include <helper/action.h> +#include <helper/action-context.h> +#include <selection.h> +#include <verbs.h> +#include <inkscape.h> + +#include <document.h> + +#include <glibmm/i18n.h> + +#include "main-cmdlinexact.h" + +#include "yaml.h" + +#include "extension/system.h" +#include "file.h" +#include <glib.h> +#include "sp-root.h" +#include "document-undo.h" +#include "util/units.h" +#include "sp-namedview.h" +#include "resource-manager.h" +#include "ui/dialog/font-substitution.h" +#include "extension/db.h" +#include "preferences.h" +#include "helper/png-write.h" +#include <document-undo.h> +#include <ui/view/view-widget.h> +#include <ui/interface.h> +#include <verbs.h> + +#define DPI_BASE Inkscape::Util::Quantity::convert(1, "in", "px") + +namespace +{ +bool s_verbose = false; + +bool createDirForFilename( const std::string &filename ) +{ + size_t found = filename.find_last_of("/\\"); + std::string output_directory = filename.substr(0,found); + + if( output_directory == filename ) + return true; + + if (g_mkdir_with_parents(output_directory.c_str(), 0755)) { + printf("Can't create directory %s\n", output_directory.c_str()); + fflush(stdout); + + return false; + } + + return true; +} + +std::vector<std::string> vectorFromString(const std::string &csv) +{ + std::vector<std::string> result; + + std::string delimiters = ","; + + // Skip delimiters at beginning. + std::string::size_type lastPos = csv.find_first_not_of(delimiters, 0); + + // Find first non-delimiter. + std::string::size_type pos = csv.find_first_of(delimiters, lastPos); + + while (std::string::npos != pos || std::string::npos != lastPos) { + // Found a token, add it to the vector. + std::string token = csv.substr(lastPos, pos - lastPos); + token.erase(0, token.find_first_not_of(' ')); //prefixing spaces + token.erase(token.find_last_not_of(' ')+1); //surfixing spaces + result.push_back(token); + + // Skip delimiters. + lastPos = csv.find_first_not_of(delimiters, pos); + + // Find next non-delimiter. + pos = csv.find_first_of(delimiters, lastPos); + } + + return result; +} + +void xFileOpen( const Glib::ustring &uri ) +{ + if (s_verbose) { + printf("open %s\n", uri.c_str()); + fflush(stdout); + } + + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop) { + SPDocument *old_document = desktop->getDocument(); + desktop->setWaitingCursor(); + Inkscape::DocumentUndo::clearRedo(old_document); + } + + SPDocument *doc = NULL; + Inkscape::Extension::Extension *key = NULL; + try { + doc = Inkscape::Extension::open(key, uri.c_str()); + } catch (std::exception &e) { + doc = NULL; + std::string exeption_mgs = e.what(); + printf("Error: open %s:%s\n",uri.c_str(), exeption_mgs.c_str() ); + fflush(stdout); + } + + // Set viewBox if it doesn't exist + if (!doc->getRoot()->viewBox_set + && (doc->getRoot()->width.unit != SVGLength::PERCENT) + && (doc->getRoot()->height.unit != SVGLength::PERCENT)) { + doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDisplayUnit()), doc->getHeight().value(doc->getDisplayUnit()))); + } + + desktop->change_document(doc); + doc->emitResizedSignal(doc->getWidth().value("px"), doc->getHeight().value("px")); + if(desktop) + desktop->clearWaitingCursor(); + + doc->virgin = FALSE; + + // everyone who cares now has a reference, get rid of our`s + doc->doUnref(); + + // resize the window to match the document properties + sp_namedview_window_from_document(desktop); + sp_namedview_update_layers_from_document(desktop); + + if ( INKSCAPE.use_gui() ) { + // Perform a fixup pass for hrefs. + if ( Inkscape::ResourceManager::getManager().fixupBrokenLinks(doc) ) { + Glib::ustring msg = _("Broken links have been changed to point to existing files."); + desktop->showInfoDialog(msg); + } + + // Check for font substitutions + Inkscape::UI::Dialog::FontSubstitution::getInstance().checkFontSubstitutions(doc); + } +} + +void xFileSaveAs( Inkscape::ActionContext const & context, const Glib::ustring &uri ) +{ + SPDocument *doc = context.getDocument(); + if (s_verbose) { + printf("save as %s\n", uri.c_str()); + fflush(stdout); + } + + if( createDirForFilename( uri )) { + Inkscape::Extension::save( + Inkscape::Extension::db.get("org.inkscape.output.svg.inkscape"), + doc, uri.c_str(), false, false, true, Inkscape::Extension::FILE_SAVE_METHOD_SAVE_AS); + if (s_verbose) { + printf("save done: %s\n", uri.c_str() ); + fflush(stdout); + } + } + else { + printf("can't create dirs for filename %s\n", uri.c_str() ); + fflush(stdout); + } +} + +void xFileExportPNG( Inkscape::ActionContext const & context, const Glib::ustring &uri ) +{ + if (s_verbose) { + printf("export png %s\n", uri.c_str()); + fflush(stdout); + } + + SPDocument *doc = context.getDocument(); + + gdouble dpi = 200.0; + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + dpi = prefs->getDouble("/dialogs/export/defaultxdpi/value", DPI_BASE); + + gdouble width = doc->getWidth().value(doc->getDisplayUnit()); + gdouble height = doc->getHeight().value(doc->getDisplayUnit()); + + gdouble bmwidth = (width) * dpi / DPI_BASE; + gdouble bmheight = (height) * dpi / DPI_BASE; + + int png_width = (int)(0.5 + bmwidth); + int png_height = (int)(0.5 + bmheight); + + SPNamedView *nv = desktop->getNamedView(); + + ExportResult status = sp_export_png_file(doc, uri.c_str(), + Geom::Rect(Geom::Point(0,0), Geom::Point(width, height)), png_width, png_height, dpi, dpi, + nv->pagecolor, 0, 0, TRUE); +} + +void xSelectElement( Inkscape::ActionContext const & context, const Glib::ustring &uri ) +{ + if (context.getDocument() == NULL || context.getSelection() == NULL) { + return; + } + + if (s_verbose) { + printf("select element: %s\n", uri.c_str()); + fflush(stdout); + } + + SPDocument * doc = context.getDocument(); + SPObject * obj = doc->getObjectById(uri); + + if (obj == NULL) { + printf(_("Unable to find node ID: '%s'\n"), uri.c_str()); + fflush(stdout); + return; + } + + Inkscape::Selection * selection = context.getSelection(); + selection->add(obj); + + if (s_verbose) { + printf("select done %s\n", uri.c_str()); + fflush(stdout); + } +} + +} // end of unnamed namespace + +namespace Inkscape { + +CmdLineXAction::CmdLineXAction (gchar const * arg, xaction_args_values_map_t &values_map): + CmdLineAction(true, arg), _values_map(values_map) { + this->arg = (char *)arg; + return; +} + +bool +CmdLineXAction::isExtended() { + return true; +} + +void +CmdLineXAction::doItX (ActionContext const & context) { + (void)(context); + + if( arg == "XFileSaveAs") + xFileSaveAs( context, _values_map["filename"] ); + else if (arg == "XFileOpen") + xFileOpen( _values_map["filename"] ); + else if (arg == "XFileExportPNG") + xFileExportPNG( context, _values_map["png_filename"] ); + else if (arg == "XSelectElement") + xSelectElement( context, _values_map["element-id"] ); + else { + printf("unknown xverb: %s", arg.c_str()); + fflush(stdout); + } + + return; +} + +enum parser_state_t { HANDLING_ROOT, + HANDLING_VERBOSE, // options + HANDLING_RUN, HANDLING_RUN_LIST, HANDLING_RUN_LIST_ENTRY + }; // run entries + +struct verb_info_t +{ + bool xverb; + std::vector<std::string> args; +}; + +typedef std::list<verb_info_t> verbs_list_t; + +static verbs_list_t +parseVerbsYAMLFile(gchar const *yaml_filename) +{ + verbs_list_t verbs_list; + + FILE *fh = fopen(yaml_filename, "r"); + if(fh == NULL) { + printf("Failed to open file!\n"); + fflush(stdout); + return verbs_list; + } + + yaml_parser_t parser; + if(!yaml_parser_initialize(&parser)) { + printf("Failed to initialize parser!\n"); + fflush(stdout); + return verbs_list; + } + + /* Set input file */ + yaml_parser_set_input_file(&parser, fh); + + parser_state_t state = HANDLING_ROOT; + + bool handling_key = false; + bool handling_value = false; + + std::string key; + + // parse + yaml_token_t token; + do { + yaml_parser_scan(&parser, &token); + switch(token.type) + { + // avoid "warning: enumeration value", "-Wswitch" + case YAML_NO_TOKEN: + break; + case YAML_STREAM_START_TOKEN: + break; + case YAML_STREAM_END_TOKEN: + break; + case YAML_VERSION_DIRECTIVE_TOKEN: + break; + case YAML_TAG_DIRECTIVE_TOKEN: + break; + case YAML_DOCUMENT_START_TOKEN: + break; + case YAML_DOCUMENT_END_TOKEN: + break; + case YAML_FLOW_SEQUENCE_START_TOKEN: + break; + case YAML_FLOW_SEQUENCE_END_TOKEN: + break; + case YAML_FLOW_MAPPING_START_TOKEN: + break; + case YAML_FLOW_MAPPING_END_TOKEN: + break; + case YAML_FLOW_ENTRY_TOKEN: + break; + case YAML_ALIAS_TOKEN: + break; + case YAML_ANCHOR_TOKEN: + break; + case YAML_TAG_TOKEN: + break; + + /* Token types (read before actual token) */ + case YAML_KEY_TOKEN: + handling_key = true; + handling_value = false; + break; + case YAML_VALUE_TOKEN: + handling_key = false; + handling_value = true; + break; + + /* Block delimeters */ + case YAML_BLOCK_SEQUENCE_START_TOKEN: + if( state == HANDLING_ROOT ) { + if( key == "run" ) + state = HANDLING_RUN; + } + break; + case YAML_BLOCK_ENTRY_TOKEN: + if( state == HANDLING_RUN ) + state = HANDLING_RUN_LIST; + else if( state == HANDLING_RUN_LIST ) + state = HANDLING_RUN_LIST_ENTRY; + else if( state == HANDLING_VERBOSE ) + state = HANDLING_ROOT; + break; + case YAML_BLOCK_END_TOKEN: + if( state == HANDLING_RUN_LIST_ENTRY ) + state = HANDLING_RUN_LIST; + else if( state == HANDLING_RUN_LIST ) + state = HANDLING_RUN; + else if( state == HANDLING_VERBOSE ) + state = HANDLING_ROOT; + else if( state == HANDLING_RUN ) + state = HANDLING_ROOT; + break; + + /* Data */ + case YAML_BLOCK_MAPPING_START_TOKEN: + break; + case YAML_SCALAR_TOKEN: + if( handling_key ) + key = (char *)token.data.scalar.value; + else if ( handling_value ) { + if(state == HANDLING_RUN_LIST) { + if(key == "xverb-id") { + verb_info_t verb; + verb.xverb = true; + verb.args = vectorFromString((char *)token.data.scalar.value); + if ((verb.args.size() > 1) && Verb::getbyid((char *)token.data.scalar.value, false)) + verb.xverb = false; + verbs_list.push_back(verb); + } + else if(key == "verb-id") { + verb_info_t verb; + verb.xverb = false; + verb.args = vectorFromString((char *)token.data.scalar.value); + verbs_list.push_back(verb); + } + else { + printf("unknown verb type [%s]\n", key.c_str()); + fflush(stdout); + } + } + else if(state == HANDLING_ROOT) { + std::string value = (char *)token.data.scalar.value; + if( (key == "verbose") && (value == "yes") ) + s_verbose = true; + } + } + break; + } + } while(token.type != YAML_STREAM_END_TOKEN); + + /* Cleanup */ + yaml_token_delete(&token); + yaml_parser_delete(&parser); + fclose(fh); + + return verbs_list; +} + +void +CmdLineXAction::createActionsFromYAML( gchar const *yaml_filename ) +{ + verbs_list_t verbs_list = parseVerbsYAMLFile(yaml_filename); + + typedef std::map<std::string,int> undo_labels_map_t; + undo_labels_map_t undo_labels_map; + int undo_counter = 0; + + verbs_list_t::iterator iter = verbs_list.begin(); + for (; iter != verbs_list.end(); ++iter) { + verb_info_t &verb = *iter; + std::string &verb_word = verb.args[0]; + if (s_verbose) + printf("handle %s and args count is %d\n", verb_word.c_str(), (int)verb.args.size()); + + if (verb_word == "XFileOpen") { + if( verb.args.size() < 2 ) + { + printf("bad arguments for XFileOpen\n"); + continue; + } + + xaction_args_values_map_t values_map; + values_map["filename"] = verb.args[1]; + new CmdLineXAction(verb_word.c_str(), values_map); + } else if (verb_word == "XFileSaveAs") + { + if (verb.args.size() < 2) { + printf("bad arguments for XFileSaveAs\n"); + continue; + } + + xaction_args_values_map_t values_map; + values_map["filename"] = verb.args[1]; + new CmdLineXAction(verb_word.c_str(), values_map); + } else if (verb_word == "XUndoLabel") { + if (verb.args.size() < 2) { + printf("bad arguments for XUndoLabel\n"); + continue; + } + undo_labels_map[verb.args[1]] = undo_counter; + } else if (verb_word == "UndoToLabel") { + if (verb.args.size() < 2) { + printf("bad arguments for UndoToLabel\n"); + continue; + } + + undo_labels_map_t::iterator iter = undo_labels_map.find(verb.args[1]); + if(iter != undo_labels_map.end()) { + int counter = undo_counter - iter->second; + if( counter > 0 ) { + for(int i = 0; i < counter; ++i) + new CmdLineAction(true, "EditUndo"); + undo_counter -= counter; + } + } + } else if (verb_word == "XSelectElement") { + if (verb.args.size() < 2) { + printf("bad arguments for XSelectElement\n"); + continue; + } + ++undo_counter; + + xaction_args_values_map_t values_map; + values_map["element-id"] = verb.args[1]; + new CmdLineXAction(verb_word.c_str(), values_map); + } else if (verb_word == "XFileExportPNG") { + if (verb.args.size() < 2) { + printf("bad arguments for XFileExportPNG\n"); + continue; + } + + xaction_args_values_map_t values_map; + std::string &png_filename = verb.args[1]; + values_map["png_filename"] = png_filename; + if(createDirForFilename( png_filename )) + new CmdLineXAction(verb_word.c_str(), values_map); + } + else if(!verb.xverb) { + ++undo_counter; + new CmdLineAction(true, verb.args[0].c_str()); + } + else if( Verb::getbyid(verb.args[0].c_str()) != NULL ) + { + ++undo_counter; + new CmdLineAction(true, verb.args[0].c_str()); + } + else { + printf("Unhadled xverb %s\n", verb.args[0].c_str()); + fflush(stdout); + } + } + + fflush(stdout); +} + + +} // Inkscape + +#endif // WITH_YAML + +/* + 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/main-cmdlinexact.h b/src/main-cmdlinexact.h new file mode 100644 index 000000000..8634f3875 --- /dev/null +++ b/src/main-cmdlinexact.h @@ -0,0 +1,54 @@ + +#ifndef __INK_MAIN_CMD_LINE_XACTIONS_H__ +#define __INK_MAIN_CMD_LINE_XACTIONS_H__ + +#ifdef WITH_YAML + +/** \file + * Extended actions that can be queued at the yaml file + */ + +/* + * Authors: + * Dmitry Zhulanov <dmitry.zhulanov@gmail.com> + * + * Copyright (C) 2016 Authors + * + * Released under GNU GPL v2.x, read the file 'COPYING' for more information + */ + +#include "main-cmdlineact.h" +#include <string> + +namespace Inkscape { + +typedef std::map<std::string, std::string > xaction_args_values_map_t; + +class CmdLineXAction : public CmdLineAction { + std::string arg; + xaction_args_values_map_t _values_map; +public: + CmdLineXAction (gchar const * arg, xaction_args_values_map_t &values_map); + + virtual void doItX (ActionContext const & context); + virtual bool isExtended(); + + static void createActionsFromYAML( gchar const *filename ); +}; + +} // Inkscape + + +#endif // WITH_YAML +#endif /* __INK_MAIN_CMD_LINE_XACTIONS_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/main.cpp b/src/main.cpp index 004d96191..0d5f35797 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -112,6 +112,7 @@ #endif #include "main-cmdlineact.h" +#include "main-cmdlinexact.h" #include "widgets/icon.h" #include <errno.h> @@ -127,6 +128,7 @@ enum { SP_ARG_NOGUI, SP_ARG_GUI, SP_ARG_FILE, + SP_ARG_XVERBS, SP_ARG_PRINT, SP_ARG_EXPORT_PNG, SP_ARG_EXPORT_DPI, @@ -227,6 +229,11 @@ static gchar *sp_export_png_utf8 = NULL; static gchar *sp_export_svg_utf8 = NULL; static gchar *sp_global_printer_utf8 = NULL; +#ifdef WITH_YAML +static gchar *sp_xverbs_yaml_utf8 = NULL; +static gchar *sp_xverbs_yaml = NULL; +#endif // WITH_YAML + /** * Reset variables to default values. @@ -300,7 +307,12 @@ struct poptOption options[] = { POPT_ARG_STRING, NULL, SP_ARG_FILE, N_("Open specified document(s) (option string may be excluded)"), N_("FILENAME")}, - +#ifdef WITH_YAML + {"xverbs", 0, + POPT_ARG_STRING, &sp_xverbs_yaml, SP_ARG_XVERBS, + N_("xverbs command"), + N_("XVERBS_FILENAME")}, +#endif // WITH_YAML {"print", 'p', POPT_ARG_STRING, &sp_global_printer, SP_ARG_PRINT, N_("Print document(s) to specified output file (use '| program' for pipe)"), @@ -881,6 +893,9 @@ static int sp_common_main( int argc, char const **argv, GSList **flDest ) fixupSingleFilename( &sp_export_png, &sp_export_png_utf8 ); fixupSingleFilename( &sp_export_svg, &sp_export_svg_utf8 ); fixupSingleFilename( &sp_global_printer, &sp_global_printer_utf8 ); +#ifdef WITH_YAML + fixupSingleFilename( &sp_xverbs_yaml, &sp_xverbs_yaml_utf8 ); +#endif // WITH_YAML } else { @@ -890,6 +905,10 @@ static int sp_common_main( int argc, char const **argv, GSList **flDest ) sp_export_svg_utf8 = g_strdup( sp_export_svg ); if ( sp_global_printer ) sp_global_printer_utf8 = g_strdup( sp_global_printer ); +#ifdef WITH_YAML + if ( sp_xverbs_yaml ) + sp_xverbs_yaml_utf8 = g_strdup( sp_xverbs_yaml ); +#endif // WITH_YAML } #ifdef WITH_DBUS @@ -2131,6 +2150,16 @@ sp_process_args(poptContext ctx) } break; } +#ifdef WITH_YAML + case SP_ARG_XVERBS: { + gchar const *fn = poptGetOptArg(ctx); + if (fn != NULL) { + sp_xverbs_yaml = g_strdup(fn); + Inkscape::CmdLineXAction::createActionsFromYAML((const char *)sp_xverbs_yaml); + } + break; + } +#endif // WITH_YAML case SP_ARG_VERSION: { printf("Inkscape %s (%s)\n", Inkscape::version_string, __DATE__); exit(0); diff --git a/src/sp-item.cpp b/src/sp-item.cpp index d161562fd..f52784489 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -76,7 +76,6 @@ SPItem::SPItem() : SPObject() { transform_center_y = 0; freeze_stroke_width = false; - _is_evaluated = true; _evaluated_status = StatusUnknown; @@ -1409,7 +1408,6 @@ Geom::Affine SPItem::set_transform(Geom::Affine const &transform) { void SPItem::doWriteTransform(Inkscape::XML::Node *repr, Geom::Affine const &transform, Geom::Affine const *adv, bool compensate) { g_return_if_fail(repr != NULL); - // calculate the relative transform, if not given by the adv attribute Geom::Affine advertized_transform; if (adv != NULL) { diff --git a/src/verbs.cpp b/src/verbs.cpp index 5130f1701..72708a7c0 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -817,7 +817,7 @@ Verb *Verb::get_search(unsigned int code) * * @param id Which id to search for. */ -Verb *Verb::getbyid(gchar const *id) +Verb *Verb::getbyid(gchar const *id, bool verbose) { Verb *verb = NULL; VerbIDTable::iterator verb_found = _verb_ids.find(id); @@ -833,8 +833,10 @@ Verb *Verb::getbyid(gchar const *id) && strcmp(id, "SelectionTrace") != 0 && strcmp(id, "PaintBucketPrefs") != 0 #endif - ) - printf("Unable to find: %s\n", id); + ) { + if (verbose) + printf("Unable to find: %s\n", id); + } return verb; } diff --git a/src/verbs.h b/src/verbs.h index 16f88c408..a273fe76e 100644 --- a/src/verbs.h +++ b/src/verbs.h @@ -575,7 +575,7 @@ public: return get_search(code); } } - static Verb * getbyid (gchar const * id); + static Verb * getbyid (gchar const * id, bool verbose = true); /** * Print a message to stderr indicating that this verb needs a GUI to run |
