summaryrefslogtreecommitdiffstats
path: root/src/document.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/document.cpp')
-rw-r--r--src/document.cpp121
1 files changed, 119 insertions, 2 deletions
diff --git a/src/document.cpp b/src/document.cpp
index 8072ec53d..c7115f906 100644
--- a/src/document.cpp
+++ b/src/document.cpp
@@ -49,6 +49,7 @@
#include "display/drawing.h"
#include "document-private.h"
#include "document-undo.h"
+#include "file.h"
#include "id-clash.h"
#include "inkscape.h"
#include "inkscape-version.h"
@@ -61,6 +62,11 @@
#include "sp-symbol.h"
#include "xml/rebase-hrefs.h"
+#include "libcroco/cr-sel-eng.h"
+#include "libcroco/cr-selector.h"
+#include "libcroco/cr-parser.h"
+#include "src/xml/croco-node-iface.h"
+
using Inkscape::DocumentUndo;
using Inkscape::Util::unit_table;
@@ -71,7 +77,7 @@ using Inkscape::Util::unit_table;
// since we want it to happen when there are no more updates.
#define SP_DOCUMENT_REROUTING_PRIORITY (G_PRIORITY_HIGH_IDLE - 1)
-
+bool sp_no_convert_text_baseline_spacing = false;
static gint sp_document_idle_handler(gpointer data);
static gint sp_document_rerouting_handler(gpointer data);
@@ -452,6 +458,17 @@ SPDocument *SPDocument::createDoc(Inkscape::XML::Document *rdoc,
));
document->oldSignalsConnected = true;
+ /** Fix baseline spacing (pre-92 files) **/
+ if ( (!sp_no_convert_text_baseline_spacing)
+ && sp_version_inside_range( document->root->version.inkscape, 0, 1, 0, 92 ) ) {
+ sp_file_convert_text_baseline_spacing(document);
+ }
+
+ /** Fix font names in legacy documents (pre-92 files) **/
+ if ( sp_version_inside_range( document->root->version.inkscape, 0, 1, 0, 92 ) ) {
+ sp_file_convert_font_name(document);
+ }
+
return document;
}
@@ -1053,6 +1070,104 @@ sigc::connection SPDocument::connectIdChanged(gchar const *id,
return priv->id_changed_signals[g_quark_from_string(id)].connect(slot);
}
+void _getObjectsByClassRecursive(Glib::ustring const &klass, SPObject *parent, std::vector<SPObject *> &objects)
+{
+ if (parent) {
+ Glib::ustring class_attribute;
+ char const *temp = parent->getAttribute("class");
+ if (temp) {
+ class_attribute = temp;
+ }
+
+ if (class_attribute.find( klass ) != std::string::npos) {
+ objects.push_back( parent );
+ }
+
+ // Check children
+ for (auto& child : parent->children) {
+ _getObjectsByClassRecursive( klass, &child, objects );
+ }
+ }
+}
+
+std::vector<SPObject *> SPDocument::getObjectsByClass(Glib::ustring const &klass) const
+{
+ std::vector<SPObject *> objects;
+ g_return_val_if_fail(!klass.empty(), objects);
+
+ _getObjectsByClassRecursive(klass, root, objects);
+ return objects;
+}
+
+void _getObjectsByElementRecursive(Glib::ustring const &element, SPObject *parent,
+ std::vector<SPObject *> &objects)
+{
+ if (parent) {
+ Glib::ustring prefixed = "svg:" + element;
+ if (parent->getRepr()->name() == prefixed) {
+ objects.push_back(parent);
+ }
+
+ // Check children
+ for (auto& child : parent->children) {
+ _getObjectsByElementRecursive(element, &child, objects);
+ }
+ }
+}
+
+std::vector<SPObject *> SPDocument::getObjectsByElement(Glib::ustring const &element) const
+{
+ std::vector<SPObject *> objects;
+ g_return_val_if_fail(!element.empty(), objects);
+
+ _getObjectsByElementRecursive(element, root, objects);
+ return objects;
+}
+
+void _getObjectsBySelectorRecursive(SPObject *parent,
+ CRSelEng *sel_eng, CRSimpleSel *simple_sel,
+ std::vector<SPObject *> &objects)
+{
+ if (parent) {
+ gboolean result = false;
+ cr_sel_eng_matches_node( sel_eng, simple_sel, parent->getRepr(), &result );
+ if (result) {
+ objects.push_back(parent);
+ }
+
+ // Check children
+ for (auto& child : parent->children) {
+ _getObjectsBySelectorRecursive(&child, sel_eng, simple_sel, objects);
+ }
+ }
+}
+
+std::vector<SPObject *> SPDocument::getObjectsBySelector(Glib::ustring const &selector) const
+{
+ // std::cout << "\nSPDocument::getObjectsBySelector: " << selector << std::endl;
+
+ std::vector<SPObject *> objects;
+ g_return_val_if_fail(!selector.empty(), objects);
+
+ static CRSelEng *sel_eng = NULL;
+ if (!sel_eng) {
+ sel_eng = cr_sel_eng_new();
+ cr_sel_eng_set_node_iface(sel_eng, &Inkscape::XML::croco_node_iface);
+ }
+
+ Glib::ustring my_selector = selector + " {"; // Parsing fails sometimes without '{'. Fix me
+ CRSelector *cr_selector = cr_selector_parse_from_buf ((guchar*)my_selector.c_str(), CR_UTF_8);
+ // char * cr_string = (char*)cr_selector_to_string( cr_selector );
+ // std::cout << " selector: |" << (cr_string?cr_string:"Empty") << "|" << std::endl;
+ CRSelector const *cur = NULL;
+ for (cur = cr_selector; cur; cur = cur->next) {
+ if (cur->simple_sel ) {
+ _getObjectsBySelectorRecursive(root, sel_eng, cur->simple_sel, objects);
+ }
+ }
+ return objects;
+}
+
void SPDocument::bindObjectToRepr(Inkscape::XML::Node *repr, SPObject *object)
{
if (object) {
@@ -1408,7 +1523,9 @@ static SPItem *find_group_at_point(unsigned int dkey, SPGroup *group, Geom::Poin
if (SP_IS_GROUP(&o) && SP_GROUP(&o)->effectiveLayerMode(dkey) != SPGroup::LAYER ) {
SPItem *child = SP_ITEM(&o);
Inkscape::DrawingItem *arenaitem = child->get_arenaitem(dkey);
- arenaitem->drawing().update();
+ if (arenaitem) {
+ arenaitem->drawing().update();
+ }
// seen remembers the last (topmost) of groups pickable at this point
if (arenaitem && arenaitem->pick(p, delta, 1) != NULL) {