diff --git a/src/document.cpp b/src/document.cpp
index e537e43de18934769bae79c9b36bba2c08d00e98..d38d5423fde0fee95ba41a4966c36203e6613b5b 100644 (file)
--- a/src/document.cpp
+++ b/src/document.cpp
#include <cstring>
#include "application/application.h"
#include "application/editor.h"
-#include "libnr/nr-matrix-fns.h"
#include "xml/repr.h"
#include "helper/units.h"
#include "inkscape-private.h"
#include "inkscape_version.h"
#include "sp-object-repr.h"
+#include "sp-namedview.h"
+#include "desktop.h"
#include "document-private.h"
#include "dir-util.h"
#include "unit-constants.h"
-#include "prefs-utils.h"
+#include "preferences.h"
#include "libavoid/router.h"
-#include "libnr/nr-rect.h"
#include "sp-item-group.h"
#include "profile-manager.h"
#include "persp3d.h"
#include "transf_mat_3x4.h"
-#define A4_WIDTH_STR "210mm"
-#define A4_HEIGHT_STR "297mm"
-
#define SP_DOCUMENT_UPDATE_PRIORITY (G_PRIORITY_HIGH_IDLE - 1)
static unsigned long next_serial = 0;
-SPDocument::SPDocument() {
- SPDocumentPrivate *p;
-
- keepalive = FALSE;
- virgin = TRUE;
-
- modified_id = 0;
-
- rdoc = NULL;
- rroot = NULL;
- root = NULL;
- style_cascade = cr_cascade_new(NULL, NULL, NULL);
-
- uri = NULL;
- base = NULL;
- name = NULL;
-
- _collection_queue = NULL;
-
- // Initialise instance of connector router.
- router = new Avoid::Router();
+SPDocument::SPDocument() :
+ keepalive(FALSE),
+ virgin(TRUE),
+ modified_since_save(FALSE),
+ rdoc(0),
+ rroot(0),
+ root(0),
+ style_cascade(cr_cascade_new(NULL, NULL, NULL)),
+ uri(0),
+ base(0),
+ name(0),
+ priv(0), // reset in ctor
+ actionkey(0),
+ modified_id(0),
+ profileManager(0), // deferred until after other initialization
+ router(new Avoid::Router()),
+ perspectives(0),
+ current_persp3d(0),
+ _collection_queue(0)
+{
// Don't use the Consolidate moves optimisation.
router->ConsolidateMoves = false;
- perspectives = NULL;
-
- p = new SPDocumentPrivate();
+ SPDocumentPrivate *p = new SPDocumentPrivate();
p->serial = next_serial++;
SPDocument *document;
Inkscape::XML::Node *rroot;
Inkscape::Version sodipodi_version;
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
rroot = rdoc->root();
/* fixme: Again, I moved these here to allow version determining in ::build (Lauris) */
/* Quick hack 2 - get default image size into document */
- if (!rroot->attribute("width")) rroot->setAttribute("width", A4_WIDTH_STR);
- if (!rroot->attribute("height")) rroot->setAttribute("height", A4_HEIGHT_STR);
+ if (!rroot->attribute("width")) rroot->setAttribute("width", "100%");
+ if (!rroot->attribute("height")) rroot->setAttribute("height", "100%");
/* End of quick hack 2 */
/* Quick hack 3 - Set uri attributes */
}
/* End of quick hack 3 */
+ /* Eliminate obsolete sodipodi:docbase, for privacy reasons */
+ rroot->setAttribute("sodipodi:docbase", NULL);
+
+ /* Eliminate any claim to adhere to a profile, as we don't try to */
+ rroot->setAttribute("baseProfile", NULL);
+
// creating namedview
if (!sp_item_group_get_child_by_name((SPGroup *) document->root, NULL, "sodipodi:namedview")) {
// if there's none in the document already,
- Inkscape::XML::Node *r = NULL;
Inkscape::XML::Node *rnew = NULL;
- r = inkscape_get_repr(INKSCAPE, "template.base");
- // see if there's a template with id="base" in the preferences
- if (!r) {
- // if there's none, create an empty element
- rnew = rdoc->createElement("sodipodi:namedview");
- rnew->setAttribute("id", "base");
- } else {
- // otherwise, take from preferences
- rnew = r->duplicate(rroot->document());
+
+ rnew = rdoc->createElement("sodipodi:namedview");
+ //rnew->setAttribute("id", "base");
+
+ // Add namedview data from the preferences
+ // we can't use getAllEntries because this could produce non-SVG doubles
+ Glib::ustring pagecolor = prefs->getString("/template/base/pagecolor");
+ if (!pagecolor.empty()) {
+ rnew->setAttribute("pagecolor", pagecolor.data());
+ }
+ Glib::ustring bordercolor = prefs->getString("/template/base/pagecolor");
+ if (!bordercolor.empty()) {
+ rnew->setAttribute("bordercolor", bordercolor.data());
}
+ sp_repr_set_svg_double(rnew, "borderopacity",
+ prefs->getDouble("/template/base/borderopacity", 1.0));
+ sp_repr_set_svg_double(rnew, "objecttolerance",
+ prefs->getDouble("/template/base/objecttolerance", 10.0));
+ sp_repr_set_svg_double(rnew, "gridtolerance",
+ prefs->getDouble("/template/base/gridtolerance", 10.0));
+ sp_repr_set_svg_double(rnew, "guidetolerance",
+ prefs->getDouble("/template/base/guidetolerance", 10.0));
+ sp_repr_set_svg_double(rnew, "inkscape:pageopacity",
+ prefs->getDouble("/template/base/inkscape:pageopacity", 0.0));
+ sp_repr_set_int(rnew, "inkscape:pageshadow",
+ prefs->getInt("/template/base/inkscape:pageshadow", 2));
+ sp_repr_set_int(rnew, "inkscape:window-width",
+ prefs->getInt("/template/base/inkscape:window-width", 640));
+ sp_repr_set_int(rnew, "inkscape:window-height",
+ prefs->getInt("/template/base/inkscape:window-height", 480));
+
// insert into the document
rroot->addChild(rnew, NULL);
// clean up
g_return_val_if_fail(document->priv != NULL, 0.0);
g_return_val_if_fail(document->root != NULL, 0.0);
- return SP_ROOT(document->root)->width.computed;
+ SPRoot *root = SP_ROOT(document->root);
+
+ if (root->width.unit == SVGLength::PERCENT && root->viewBox_set)
+ return root->viewBox.x1 - root->viewBox.x0;
+ return root->width.computed;
}
void
g_return_val_if_fail(document->priv != NULL, 0.0);
g_return_val_if_fail(document->root != NULL, 0.0);
- return SP_ROOT(document->root)->height.computed;
+ SPRoot *root = SP_ROOT(document->root);
+
+ if (root->height.unit == SVGLength::PERCENT && root->viewBox_set)
+ return root->viewBox.y1 - root->viewBox.y0;
+ return root->height.computed;
+}
+
+Geom::Point sp_document_dimensions(SPDocument *doc)
+{
+ return Geom::Point(sp_document_width(doc), sp_document_height(doc));
}
/**
- * Given an NR::Rect that may, for example, correspond to the bbox of an object,
+ * Given a Geom::Rect that may, for example, correspond to the bbox of an object,
* this function fits the canvas to that rect by resizing the canvas
* and translating the document root into position.
*/
-void SPDocument::fitToRect(NR::Rect const &rect)
+void SPDocument::fitToRect(Geom::Rect const &rect)
{
- g_return_if_fail(!rect.isEmpty());
-
- using NR::X; using NR::Y;
- double const w = rect.extent(X);
- double const h = rect.extent(Y);
+ double const w = rect.width();
+ double const h = rect.height();
double const old_height = sp_document_height(this);
SPUnit const &px(sp_unit_get_by_id(SP_UNIT_PX));
sp_document_set_width(this, w, &px);
sp_document_set_height(this, h, &px);
- NR::translate const tr(NR::Point(0, (old_height - h))
- - rect.min());
+ Geom::Translate const tr(Geom::Point(0, (old_height - h))
+ - to_2geom(rect.min()));
SP_GROUP(root)->translateChildItems(tr);
+ SPNamedView *nv = sp_document_namedview(this, 0);
+ if(nv) {
+ Geom::Translate tr2(-rect.min());
+ nv->translateGuides(tr2);
+
+ // update the viewport so the drawing appears to stay where it was
+ nv->scrollAllDesktops(-tr2[0], tr2[1], false);
+ }
}
void sp_document_set_uri(SPDocument *document, gchar const *uri)
sp_document_setup_viewport (SPDocument *doc, SPItemCtx *ctx)
{
ctx->ctx.flags = 0;
- ctx->i2doc = NR::identity();
+ ctx->i2doc = Geom::identity();
/* Set up viewport in case svg has it defined as percentages */
if (SP_ROOT(doc->root)->viewBox_set) { // if set, take from viewBox
ctx->vp.x0 = SP_ROOT(doc->root)->viewBox.x0;
ctx->vp.x1 = 210 * PX_PER_MM;
ctx->vp.y1 = 297 * PX_PER_MM;
}
- ctx->i2vp = NR::identity();
+ ctx->i2vp = Geom::identity();
}
/**
}
}
-static bool is_within(NR::Rect const &area, NR::Rect const &box)
+static bool is_within(Geom::Rect const &area, Geom::Rect const &box)
{
return area.contains(box);
}
-static bool overlaps(NR::Rect const &area, NR::Rect const &box)
+static bool overlaps(Geom::Rect const &area, Geom::Rect const &box)
{
return area.intersects(box);
}
-static GSList *find_items_in_area(GSList *s, SPGroup *group, unsigned int dkey, NR::Rect const &area,
- bool (*test)(NR::Rect const &, NR::Rect const &), bool take_insensitive = false)
+static GSList *find_items_in_area(GSList *s, SPGroup *group, unsigned int dkey, Geom::Rect const &area,
+ bool (*test)(Geom::Rect const &, Geom::Rect const &), bool take_insensitive = false)
{
g_return_val_if_fail(SP_IS_GROUP(group), s);
s = find_items_in_area(s, SP_GROUP(o), dkey, area, test);
} else {
SPItem *child = SP_ITEM(o);
- NR::Maybe<NR::Rect> box = sp_item_bbox_desktop(child);
+ Geom::OptRect box = sp_item_bbox_desktop(child);
if ( box && test(area, *box) && (take_insensitive || child->isVisibleAndUnlocked(dkey))) {
s = g_slist_append(s, child);
}
@@ -913,11 +952,11 @@ Returns the bottommost item from the list which is at the point, or NULL if none
*/
SPItem*
sp_document_item_from_list_at_point_bottom(unsigned int dkey, SPGroup *group, GSList const *list,
- NR::Point const p, bool take_insensitive)
+ Geom::Point const p, bool take_insensitive)
{
g_return_val_if_fail(group, NULL);
-
- gdouble delta = prefs_get_double_attribute ("options.cursortolerance", "value", 1.0);
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ gdouble delta = prefs->getDouble("/options/cursortolerance/value", 1.0);
for (SPObject *o = sp_object_first_child(SP_OBJECT(group)) ; o != NULL ; o = SP_OBJECT_NEXT(o) ) {
@@ -950,11 +989,11 @@ upwards in z-order and returns what it has found so far (i.e. the found item is
guaranteed to be lower than upto).
*/
SPItem*
-find_item_at_point(unsigned int dkey, SPGroup *group, NR::Point const p, gboolean into_groups, bool take_insensitive = false, SPItem *upto = NULL)
+find_item_at_point(unsigned int dkey, SPGroup *group, Geom::Point const p, gboolean into_groups, bool take_insensitive = false, SPItem *upto = NULL)
{
SPItem *seen = NULL, *newseen = NULL;
-
- gdouble delta = prefs_get_double_attribute ("options.cursortolerance", "value", 1.0);
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ gdouble delta = prefs->getDouble("/options/cursortolerance/value", 1.0);
for (SPObject *o = sp_object_first_child(SP_OBJECT(group)) ; o != NULL ; o = SP_OBJECT_NEXT(o) ) {
if (!SP_IS_ITEM(o)) continue;
@@ -992,11 +1031,11 @@ Returns the topmost non-layer group from the descendants of group which is at po
p, or NULL if none. Recurses into layers but not into groups.
*/
SPItem*
-find_group_at_point(unsigned int dkey, SPGroup *group, NR::Point const p)
+find_group_at_point(unsigned int dkey, SPGroup *group, Geom::Point const p)
{
SPItem *seen = NULL;
-
- gdouble delta = prefs_get_double_attribute ("options.cursortolerance", "value", 1.0);
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ gdouble delta = prefs->getDouble("/options/cursortolerance/value", 1.0);
for (SPObject *o = sp_object_first_child(SP_OBJECT(group)) ; o != NULL ; o = SP_OBJECT_NEXT(o) ) {
if (!SP_IS_ITEM(o)) continue;
*
*/
-GSList *sp_document_items_in_box(SPDocument *document, unsigned int dkey, NR::Rect const &box)
+GSList *sp_document_items_in_box(SPDocument *document, unsigned int dkey, Geom::Rect const &box)
{
g_return_val_if_fail(document != NULL, NULL);
g_return_val_if_fail(document->priv != NULL, NULL);
@@ -1041,7 +1080,7 @@ GSList *sp_document_items_in_box(SPDocument *document, unsigned int dkey, NR::Re
*
*/
-GSList *sp_document_partial_items_in_box(SPDocument *document, unsigned int dkey, NR::Rect const &box)
+GSList *sp_document_partial_items_in_box(SPDocument *document, unsigned int dkey, Geom::Rect const &box)
{
g_return_val_if_fail(document != NULL, NULL);
g_return_val_if_fail(document->priv != NULL, NULL);
@@ -1050,31 +1089,32 @@ GSList *sp_document_partial_items_in_box(SPDocument *document, unsigned int dkey
}
GSList *
-sp_document_items_at_points(SPDocument *document, unsigned const key, std::vector<NR::Point> points)
+sp_document_items_at_points(SPDocument *document, unsigned const key, std::vector<Geom::Point> points)
{
GSList *items = NULL;
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
// When picking along the path, we don't want small objects close together
// (such as hatching strokes) to obscure each other by their deltas,
// so we temporarily set delta to a small value
- gdouble saved_delta = prefs_get_double_attribute ("options.cursortolerance", "value", 1.0);
- prefs_set_double_attribute ("options.cursortolerance", "value", 0.25);
+ gdouble saved_delta = prefs->getDouble("/options/cursortolerance/value", 1.0);
+ prefs->setDouble("/options/cursortolerance/value", 0.25);
for(unsigned int i = 0; i < points.size(); i++) {
SPItem *item = sp_document_item_at_point(document, key, points[i],
- false, NULL);
+ false, NULL);
if (item && !g_slist_find(items, item))
items = g_slist_prepend (items, item);
}
// and now we restore it back
- prefs_set_double_attribute ("options.cursortolerance", "value", saved_delta);
+ prefs->setDouble("/options/cursortolerance/value", saved_delta);
return items;
}
SPItem *
-sp_document_item_at_point(SPDocument *document, unsigned const key, NR::Point const p,
+sp_document_item_at_point(SPDocument *document, unsigned const key, Geom::Point const p,
gboolean const into_groups, SPItem *upto)
{
g_return_val_if_fail(document != NULL, NULL);
@@ -1084,7 +1124,7 @@ sp_document_item_at_point(SPDocument *document, unsigned const key, NR::Point co
}
SPItem*
-sp_document_group_at_point(SPDocument *document, unsigned int key, NR::Point const p)
+sp_document_group_at_point(SPDocument *document, unsigned int key, Geom::Point const p)
{
g_return_val_if_fail(document != NULL, NULL);
g_return_val_if_fail(document->priv != NULL, NULL);