diff options
| author | Jabier Arraiza Cenoz <jabier.arraiza@marker.es> | 2015-03-18 18:07:14 +0000 |
|---|---|---|
| committer | Jabiertxof <jtx@jtx.marker.es> | 2015-03-18 18:07:14 +0000 |
| commit | e77956b4dbd029c9f6949f81fe083606f995c624 (patch) | |
| tree | 74adda4df8986d65f70efb341c6235277361fd35 /src | |
| parent | updated code to work on 0.92 code (diff) | |
| parent | Latvian translation update (diff) | |
| download | inkscape-e77956b4dbd029c9f6949f81fe083606f995c624.tar.gz inkscape-e77956b4dbd029c9f6949f81fe083606f995c624.zip | |
update to trunk
(bzr r12588.1.39)
Diffstat (limited to 'src')
464 files changed, 7576 insertions, 7069 deletions
diff --git a/src/2geom/sbasis-to-bezier.cpp b/src/2geom/sbasis-to-bezier.cpp index 0525be04b..a2e4253d2 100644 --- a/src/2geom/sbasis-to-bezier.cpp +++ b/src/2geom/sbasis-to-bezier.cpp @@ -37,6 +37,7 @@ #include <2geom/choose.h> #include <2geom/path-sink.h> #include <2geom/exception.h> +#include <2geom/convex-cover.h> #include <iostream> @@ -203,11 +204,8 @@ void sbasis_to_cubic_bezier (std::vector<Point> & bz, D2<SBasis> const& sb) THROW_RANGEERROR("size of sb is too small"); } - bz.resize(4, Point(0,0)); - bz[0][X] = sb[X][0][0]; - bz[0][Y] = sb[Y][0][0]; - bz[3][X] = sb[X][0][1]; - bz[3][Y] = sb[Y][0][1]; + sbasis_to_bezier(bz, sb, 4); // zeroth-order estimate + Geom::ConvexHull bezhull(bz); // calculate first derivatives of x and y wrt t @@ -231,17 +229,23 @@ void sbasis_to_cubic_bezier (std::vector<Point> & bz, D2<SBasis> const& sb) midx += (sb[X][i][0] + sb[X][i][1])/div; div *= 4; } - midx = 8*midx - 4*bz[0][X] - 4*bz[3][X]; div = 2; for (size_t i = 0; i < sb[Y].size(); ++i) { midy += (sb[Y][i][0] + sb[Y][i][1])/div; div *= 4; } - midy = 8*midy - 4*bz[0][Y] - 4*bz[3][Y]; + +// is midpoint in hull: if not, the solution will be ill-conditioned, LP Bug 1428683 + + if (!bezhull.contains_point(Geom::Point(midx, midy))) + return; // calculate Bezier control arms + midx = 8*midx - 4*bz[0][X] - 4*bz[3][X]; // re-define relative to center + midy = 8*midy - 4*bz[0][Y] - 4*bz[3][Y]; + if ((std::abs(xprime[0]) < EPSILON) && (std::abs(yprime[0]) < EPSILON) && ((std::abs(xprime[1]) > EPSILON) || (std::abs(yprime[1]) > EPSILON))) { // degenerate handle at 0 : use distance of closest approach numer = midx*xprime[1] + midy*yprime[1]; @@ -258,7 +262,8 @@ void sbasis_to_cubic_bezier (std::vector<Point> & bz, D2<SBasis> const& sb) dely[0] = yprime[0]*numer/denom; delx[1] = 0; dely[1] = 0; - } else if (std::abs(xprime[1]*yprime[0] - yprime[1]*xprime[0]) > EPSILON) { // general case : fit mid fxn value + } else if (std::abs(xprime[1]*yprime[0] - yprime[1]*xprime[0]) > // general case : fit mid fxn value + 0.002 * std::abs(xprime[1]*xprime[0] + yprime[1]*yprime[0])) { // approx. 0.1 degree of angle denom = xprime[1]*yprime[0] - yprime[1]*xprime[0]; for (int i = 0; i < 2; ++i) { numer = xprime[1 - i]*midy - yprime[1 - i]*midx; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a1f5fc3dd..6659e8c0a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -19,6 +19,7 @@ set(sp_SRC sp-defs.cpp sp-desc.cpp sp-ellipse.cpp + sp-factory.cpp sp-filter-primitive.cpp sp-filter-reference.cpp sp-filter.cpp @@ -46,8 +47,8 @@ set(sp_SRC sp-lpe-item.cpp sp-marker.cpp sp-mask.cpp + sp-mesh.cpp sp-mesh-array.cpp - sp-mesh-gradient.cpp sp-mesh-patch.cpp sp-mesh-row.cpp sp-metadata.cpp @@ -133,8 +134,8 @@ set(sp_SRC sp-marker.h sp-marker-loc.h sp-mask.h + sp-mesh.h sp-mesh-array.h - sp-mesh-gradient.h sp-mesh-patch.h sp-mesh-row.h sp-metadata.h @@ -187,7 +188,6 @@ set(inkscape_SRC console-output-undo-observer.cpp context-fns.cpp desktop-events.cpp - desktop-handles.cpp desktop-style.cpp desktop.cpp device-manager.cpp @@ -195,7 +195,6 @@ set(inkscape_SRC document-subset.cpp document-undo.cpp document.cpp - doxygen-main.cpp ege-color-prof-tracker.cpp event-log.cpp extract-uri.cpp @@ -299,7 +298,6 @@ set(inkscape_SRC context-fns.h decimal-round.h desktop-events.h - desktop-handles.h desktop-style.h desktop.h device-manager.h @@ -336,7 +334,6 @@ set(inkscape_SRC icon-size.h id-clash.h # ige-mac-menu.h - inkscape-private.h inkscape-version.h inkscape.h interface.h @@ -494,6 +491,7 @@ add_subdirectory(2geom) add_subdirectory(libavoid) add_subdirectory(libcola) add_subdirectory(libcroco) +add_subdirectory(inkgc) add_subdirectory(libgdl) add_subdirectory(libuemf) add_subdirectory(libvpsc) @@ -518,10 +516,19 @@ set(inkscape_SRC # make executable for INKSCAPE add_executable(inkscape ${main_SRC} ${inkscape_SRC} ${sp_SRC}) +if(UNIX) +# message after building. +add_custom_command( + TARGET inkscape + POST_BUILD MAIN_DEPENDENCY inkscape + COMMAND ${CMAKE_COMMAND} -E echo 'now run: \"make install\" to copy runtime files & scripts to ${CMAKE_INSTALL_PREFIX}' +) +endif() + add_dependencies(inkscape inkscape_version) target_link_libraries(inkscape - # order from automake + # order from automake #sp_LIB nrtype_LIB diff --git a/src/Makefile.am b/src/Makefile.am index 8fb7e23ef..cfbbd4015 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -23,15 +23,18 @@ endif noinst_LIBRARIES = \ + libinkscape.a \ libcroco/libcroco.a \ libavoid/libavoid.a \ $(internal_GDL) \ libuemf/libuemf.a \ libcola/libcola.a \ + inkgc/libinkgc.a \ libvpsc/libvpsc.a \ livarot/libvarot.a \ 2geom/lib2geom.a \ libdepixelize/libdepixelize.a \ + util/libutil.a \ libinkversion.a all_libs = \ @@ -114,6 +117,7 @@ include filters/Makefile_insert include helper/Makefile_insert include io/Makefile_insert include libcroco/Makefile_insert +include inkgc/Makefile_insert include libgdl/Makefile_insert include libnrtype/Makefile_insert include libavoid/Makefile_insert @@ -194,13 +198,13 @@ DISTCLEANFILES = \ # ################################################ # this should speed up the build -#libinkscape_a_SOURCES = $(ink_common_sources) +libinkscape_a_SOURCES = $(ink_common_sources) -inkscape_SOURCES += main.cpp $(ink_common_sources) $(win32_sources) +inkscape_SOURCES += main.cpp $(win32_sources) inkscape_LDADD = $(all_libs) inkscape_LDFLAGS = $(kdeldflags) $(mwindows) -inkview_SOURCES += inkview.cpp $(ink_common_sources) $(win32_sources) +inkview_SOURCES += inkview.cpp $(win32_sources) inkview_LDADD = $(all_libs) inkview_LDFLAGS = $(mwindows) diff --git a/src/Makefile_insert b/src/Makefile_insert index 107acdf31..800752df4 100644 --- a/src/Makefile_insert +++ b/src/Makefile_insert @@ -29,30 +29,22 @@ ink_common_sources += \ decimal-round.h \ desktop.cpp desktop.h \ desktop-events.cpp desktop-events.h \ - desktop-handles.cpp desktop-handles.h \ desktop-style.cpp desktop-style.h \ device-manager.cpp device-manager.h \ dir-util.cpp dir-util.h \ document.cpp document.h document-private.h \ document-subset.cpp document-subset.h \ document-undo.cpp document-undo.h \ - doxygen-main.cpp \ ege-color-prof-tracker.cpp ege-color-prof-tracker.h \ enums.h \ event-log.cpp event-log.h event.h \ extract-uri.cpp extract-uri.h \ - factory.h \ file.cpp file.h \ fill-or-stroke.h \ filter-chemistry.cpp filter-chemistry.h \ filter-enums.cpp filter-enums.h \ - gc-alloc.h \ - gc-anchored.h gc-anchored.cpp \ - gc-core.h \ - gc.cpp \ - gc-finalized.h gc-finalized.cpp \ - gc-managed.h \ - gc-soft-ptr.h \ + gc-anchored.cpp gc-anchored.h \ + gc-finalized.cpp gc-finalized.h \ gradient-chemistry.cpp gradient-chemistry.h \ gradient-drag.cpp gradient-drag.h \ graphlayout.cpp graphlayout.h \ @@ -63,7 +55,7 @@ ink_common_sources += \ helper/pixbuf-ops.h \ icon-size.h \ id-clash.cpp id-clash.h \ - inkscape.cpp inkscape.h inkscape-private.h \ + inkscape.cpp inkscape.h \ isinf.h \ knot.cpp knot.h \ knot-enums.h \ @@ -125,7 +117,7 @@ ink_common_sources += \ sp-defs.cpp sp-defs.h \ sp-desc.cpp sp-desc.h \ sp-ellipse.cpp sp-ellipse.h \ - sp-factory.h \ + sp-factory.h sp-factory.cpp \ sp-filter.cpp sp-filter.h number-opt-number.h \ sp-filter-primitive.cpp sp-filter-primitive.h \ sp-filter-reference.cpp sp-filter-reference.h \ @@ -162,8 +154,8 @@ ink_common_sources += \ sp-marker-loc.h \ sp-mask.cpp sp-mask.h \ sp-metadata.cpp sp-metadata.h \ + sp-mesh.cpp sp-mesh.h \ sp-mesh-array.cpp sp-mesh-array.h \ - sp-mesh-gradient.cpp sp-mesh-gradient.h \ sp-mesh-patch.cpp sp-mesh-patch.h \ sp-mesh-row.cpp sp-mesh-row.h \ sp-missing-glyph.cpp sp-missing-glyph.h \ diff --git a/src/attributes-test.h b/src/attributes-test.h index ba34717ea..7379e4e85 100644 --- a/src/attributes-test.h +++ b/src/attributes-test.h @@ -38,6 +38,8 @@ public: attindex.html lacks attributeName, begin, additive, font, marker; I've added these manually. + + SVG 2: white-space, shape-inside, shape-outside, shape-padding, shape-margin */ struct {char const *attr; bool supported;} const all_attrs[] = { {"attributeName", true}, @@ -163,7 +165,7 @@ struct {char const *attr; bool supported;} const all_attrs[] = { {"keySplines", true}, {"keyTimes", true}, {"lang", true}, - {"lengthAdjust", false}, + {"lengthAdjust", true}, {"letter-spacing", true}, {"lighting-color", true}, {"limitingConeAngle", true}, @@ -246,6 +248,10 @@ struct {char const *attr; bool supported;} const all_attrs[] = { {"ry", true}, {"scale", true}, {"seed", true}, + {"shape-inside", true}, + {"shape-margin", true}, + {"shape-outside", true}, + {"shape-padding", true}, {"shape-rendering", true}, {"slope", true}, {"spacing", false}, @@ -285,7 +291,7 @@ struct {char const *attr; bool supported;} const all_attrs[] = { {"text-indent", true}, {"text-rendering", true}, {"text-transform", true}, - {"textLength", false}, + {"textLength", true}, {"title", false}, {"to", true}, {"transform", true}, @@ -310,6 +316,7 @@ struct {char const *attr; bool supported;} const all_attrs[] = { {"viewBox", true}, {"viewTarget", false}, {"visibility", true}, + {"white-space", true}, {"width", true}, {"widths", true}, {"word-spacing", true}, diff --git a/src/attributes.cpp b/src/attributes.cpp index 2b04843a7..568f0528a 100644 --- a/src/attributes.cpp +++ b/src/attributes.cpp @@ -195,6 +195,8 @@ static SPStyleProp const props[] = { {SP_ATTR_DX, "dx"}, {SP_ATTR_DY, "dy"}, {SP_ATTR_ROTATE, "rotate"}, + {SP_ATTR_TEXTLENGTH, "textLength"}, + {SP_ATTR_LENGTHADJUST, "lengthAdjust"}, {SP_ATTR_SODIPODI_ROLE, "sodipodi:role"}, /* SPText */ {SP_ATTR_SODIPODI_LINESPACING, "sodipodi:linespacing"}, @@ -289,6 +291,7 @@ static SPStyleProp const props[] = { {SP_ATTR_FY, "fy"}, /* SPMeshPatch */ {SP_ATTR_TENSOR, "tensor"}, + //{SP_ATTR_TYPE, "type"}, /* SPPattern */ {SP_ATTR_PATTERNUNITS, "patternUnits"}, {SP_ATTR_PATTERNCONTENTUNITS, "patternContentUnits"}, @@ -436,6 +439,11 @@ static SPStyleProp const props[] = { {SP_PROP_KERNING, "kerning"}, {SP_PROP_TEXT_ANCHOR, "text-anchor"}, {SP_PROP_WHITE_SPACE, "white-space"}, + /* SVG 2 Text Wrapping */ + {SP_PROP_SHAPE_INSIDE, "shape-inside"}, + {SP_PROP_SHAPE_OUTSIDE, "shape-outside"}, + {SP_PROP_SHAPE_PADDING, "shape-padding"}, + {SP_PROP_SHAPE_MARGIN, "shape-margin"}, /* Text Decoration */ {SP_PROP_TEXT_DECORATION, "text-decoration"}, {SP_PROP_TEXT_DECORATION_LINE, "text-decoration-line"}, diff --git a/src/attributes.h b/src/attributes.h index 8e091df71..91c8868f9 100644 --- a/src/attributes.h +++ b/src/attributes.h @@ -196,6 +196,8 @@ enum SPAttributeEnum { SP_ATTR_DX, SP_ATTR_DY, SP_ATTR_ROTATE, + SP_ATTR_TEXTLENGTH, + SP_ATTR_LENGTHADJUST, SP_ATTR_SODIPODI_ROLE, /* SPText */ SP_ATTR_SODIPODI_LINESPACING, @@ -291,6 +293,7 @@ enum SPAttributeEnum { SP_ATTR_FY, /* SPMeshPatch */ SP_ATTR_TENSOR, + //SP_ATTR_TYPE, /* SPPattern */ SP_ATTR_PATTERNUNITS, SP_ATTR_PATTERNCONTENTUNITS, @@ -443,6 +446,11 @@ enum SPAttributeEnum { SP_PROP_TEXT_ANCHOR, SP_PROP_WHITE_SPACE, + SP_PROP_SHAPE_INSIDE, + SP_PROP_SHAPE_OUTSIDE, + SP_PROP_SHAPE_PADDING, + SP_PROP_SHAPE_MARGIN, + /* Text Decoration */ SP_PROP_TEXT_DECORATION, /* SVG 1 underline etc.( no color or style) OR SVG2 with _LINE, _STYLE, _COLOR values */ SP_PROP_TEXT_DECORATION_LINE, /* SVG 2 underline etc. */ diff --git a/src/box3d-side.cpp b/src/box3d-side.cpp index 3058eab2d..93d55232e 100644 --- a/src/box3d-side.cpp +++ b/src/box3d-side.cpp @@ -28,16 +28,6 @@ static void box3d_side_compute_corner_ids(Box3DSide *side, unsigned int corners[4]); -#include "sp-factory.h" - -namespace { - SPObject* createBox3DSide() { - return new Box3DSide(); - } - - bool box3DSideRegistered = SPFactory::instance().registerObject("inkscape:box3dside", createBox3DSide); -} - Box3DSide::Box3DSide() : SPPolygon() { this->dir1 = Box3D::NONE; this->dir2 = Box3D::NONE; diff --git a/src/box3d.cpp b/src/box3d.cpp index 3c0cbb675..dc04a2eb6 100644 --- a/src/box3d.cpp +++ b/src/box3d.cpp @@ -37,26 +37,16 @@ #include "preferences.h" #include "desktop.h" -#include "desktop-handles.h" + #include "macros.h" static void box3d_ref_changed(SPObject *old_ref, SPObject *ref, SPBox3D *box); static gint counter = 0; -#include "sp-factory.h" - -namespace { - SPObject* createBox3D() { - return new SPBox3D(); - } - - bool box3DRegistered = SPFactory::instance().registerObject("inkscape:box3d", createBox3D); -} - SPBox3D::SPBox3D() : SPGroup() { - this->my_counter = 0; - this->swapped = Box3D::NONE; + this->my_counter = 0; + this->swapped = Box3D::NONE; this->persp_href = NULL; this->persp_ref = new Persp3DReference(this); @@ -87,7 +77,7 @@ void SPBox3D::build(SPDocument *document, Inkscape::XML::Node *repr) { } void SPBox3D::release() { - SPBox3D* object = this; + SPBox3D* object = this; SPBox3D *box = object; if (box->persp_href) { @@ -125,7 +115,7 @@ void SPBox3D::release() { } void SPBox3D::set(unsigned int key, const gchar* value) { - SPBox3D* object = this; + SPBox3D* object = this; SPBox3D *box = object; switch (key) { @@ -210,7 +200,7 @@ void SPBox3D::update(SPCtx *ctx, guint flags) { } Inkscape::XML::Node* SPBox3D::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { - SPBox3D* object = this; + SPBox3D* object = this; SPBox3D *box = object; if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { @@ -401,7 +391,7 @@ box3d_snap (SPBox3D *box, int id, Proj::Pt3 const &pt_proj, Proj::Pt3 const &sta snap_pts[3] = diag2.closest_to (pt); } - gdouble const zoom = inkscape_active_desktop()->current_zoom(); + gdouble const zoom = SP_ACTIVE_DESKTOP->current_zoom(); // determine the distances to all potential snapping points double snap_dists[MAX_POINT_COUNT]; @@ -912,9 +902,11 @@ box3d_swap_sides(int z_orders[6], Box3D::Axis axis) { } } - int tmp = z_orders[pos1]; - z_orders[pos1] = z_orders[pos2]; - z_orders[pos2] = tmp; + if (pos1 != -1){ + int tmp = z_orders[pos1]; + z_orders[pos1] = z_orders[pos2]; + z_orders[pos2] = tmp; + } } diff --git a/src/color-profile.cpp b/src/color-profile.cpp index 28550b75d..85a6fa876 100644 --- a/src/color-profile.cpp +++ b/src/color-profile.cpp @@ -185,17 +185,6 @@ cmsHPROFILE ColorProfileImpl::getNULLProfile() { #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - -#include "sp-factory.h" - -namespace { - SPObject* createColorProfile() { - return new Inkscape::ColorProfile(); - } - - bool rectRegistered = SPFactory::instance().registerObject("svg:color-profile", createColorProfile); -} - ColorProfile::ColorProfile() : SPObject() { this->impl = new ColorProfileImpl(); diff --git a/src/composite-undo-stack-observer.h b/src/composite-undo-stack-observer.h index c93a2338b..33afda48d 100644 --- a/src/composite-undo-stack-observer.h +++ b/src/composite-undo-stack-observer.h @@ -10,7 +10,7 @@ #ifndef SEEN_COMPOSITE_UNDO_COMMIT_OBSERVER_H #define SEEN_COMPOSITE_UNDO_COMMIT_OBSERVER_H -#include "gc-alloc.h" +#include "inkgc/gc-alloc.h" #include "undo-stack-observer.h" #include <list> diff --git a/src/conn-avoid-ref.cpp b/src/conn-avoid-ref.cpp index cb72f65dc..c13b9a5d3 100644 --- a/src/conn-avoid-ref.cpp +++ b/src/conn-avoid-ref.cpp @@ -32,7 +32,7 @@ #include "xml/node.h" #include "document.h" #include "desktop.h" -#include "desktop-handles.h" + #include "document-undo.h" #include "sp-namedview.h" #include "sp-item-group.h" @@ -87,11 +87,11 @@ void SPAvoidRef::setAvoid(char const *value) void SPAvoidRef::handleSettingChange(void) { - SPDesktop *desktop = inkscape_active_desktop(); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (desktop == NULL) { return; } - if (sp_desktop_document(desktop) != item->document) { + if (desktop->getDocument() != item->document) { // We don't want to go any further if the active desktop's document // isn't the same as the document that this item is part of. This // case can happen if a new document is loaded from the file chooser @@ -277,7 +277,7 @@ static std::vector<Geom::Point> approxItemWithPoints(SPItem const *item, const G } static Avoid::Polygon avoid_item_poly(SPItem const *item) { - SPDesktop *desktop = inkscape_active_desktop(); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; g_assert(desktop != NULL); double spacing = desktop->namedview->connector_spacing; @@ -370,7 +370,7 @@ void init_avoided_shape_geometry(SPDesktop *desktop) { // Don't count this as changes to the document, // it is basically just late initialisation. - SPDocument *document = sp_desktop_document(desktop); + SPDocument *document = desktop->getDocument(); bool saved = DocumentUndo::getUndoSensitive(document); DocumentUndo::setUndoSensitive(document, false); diff --git a/src/debug/demangle.cpp b/src/debug/demangle.cpp index 2b00fb8e9..1d94f0eb9 100644 --- a/src/debug/demangle.cpp +++ b/src/debug/demangle.cpp @@ -14,7 +14,7 @@ #include <map> #include "debug/demangle.h" #include "util/format.h" -#include "gc-alloc.h" +#include "inkgc/gc-alloc.h" namespace Inkscape { diff --git a/src/debug/gc-heap.h b/src/debug/gc-heap.h index 957f2067a..d120ddba9 100644 --- a/src/debug/gc-heap.h +++ b/src/debug/gc-heap.h @@ -12,7 +12,7 @@ #ifndef SEEN_INKSCAPE_DEBUG_GC_HEAP_H #define SEEN_INKSCAPE_DEBUG_GC_HEAP_H -#include "gc-core.h" +#include "inkgc/gc-core.h" #include "debug/heap.h" namespace Inkscape { diff --git a/src/debug/heap.cpp b/src/debug/heap.cpp index 8e7a920ba..0135a9ceb 100644 --- a/src/debug/heap.cpp +++ b/src/debug/heap.cpp @@ -13,7 +13,7 @@ # include "config.h" #endif -#include "gc-alloc.h" +#include "inkgc/gc-alloc.h" #include "debug/gc-heap.h" #include "debug/sysv-heap.h" #include <vector> diff --git a/src/debug/logger.cpp b/src/debug/logger.cpp index 485dbc365..2eb81a0ba 100644 --- a/src/debug/logger.cpp +++ b/src/debug/logger.cpp @@ -15,7 +15,7 @@ #include "inkscape-version.h" #include "debug/logger.h" #include "debug/simple-event.h" -#include "gc-alloc.h" +#include "inkgc/gc-alloc.h" namespace Inkscape { diff --git a/src/debug/simple-event.h b/src/debug/simple-event.h index 506ee1b03..03ce5d326 100644 --- a/src/debug/simple-event.h +++ b/src/debug/simple-event.h @@ -16,7 +16,7 @@ #include <vector> #include <glib.h> // g_assert() -#include "gc-alloc.h" +#include "inkgc/gc-alloc.h" #include "debug/event.h" namespace Inkscape { diff --git a/src/desktop-events.cpp b/src/desktop-events.cpp index 5d8ea8b9f..e80e5f6c1 100644 --- a/src/desktop-events.cpp +++ b/src/desktop-events.cpp @@ -17,14 +17,20 @@ #endif #include <map> #include <string> + #include "ui/dialog/guides.h" +#include "desktop-events.h" + +#if WITH_GTKMM_3_0 +# include <gdkmm/devicemanager.h> +#endif + #include <2geom/line.h> #include <2geom/angle.h> #include <glibmm/i18n.h> #include "desktop.h" -#include "desktop-events.h" -#include "desktop-handles.h" + #include "ui/dialog-events.h" #include "display/canvas-axonomgrid.h" #include "display/canvas-grid.h" @@ -40,6 +46,7 @@ #include "display/sp-canvas.h" #include "sp-guide.h" #include "sp-namedview.h" +#include "sp-root.h" #include "ui/tools-switch.h" #include "verbs.h" #include "widgets/desktop-widget.h" @@ -217,11 +224,21 @@ static gint sp_dt_ruler_event(GtkWidget *widget, GdkEvent *event, SPDesktopWidge if ((horiz ? wy : wx) >= 0) { Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); Inkscape::XML::Node *repr = xml_doc->createElement("sodipodi:guide"); + + // If root viewBox set, interpret guides in terms of viewBox (90/96) + double newx = event_dt.x(); + double newy = event_dt.y(); + + SPRoot *root = desktop->doc()->getRoot(); + if( root->viewBox_set ) { + newx = newx * root->viewBox.width() / root->width.computed; + newy = newy * root->viewBox.height() / root->height.computed; + } + sp_repr_set_point(repr, "position", Geom::Point( newx, newy )); sp_repr_set_point(repr, "orientation", normal); - sp_repr_set_point(repr, "position", event_dt); desktop->namedview->appendChild(repr); Inkscape::GC::release(repr); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_NONE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_NONE, _("Create guide")); } desktop->set_coordinate_status(event_dt); @@ -229,7 +246,7 @@ static gint sp_dt_ruler_event(GtkWidget *widget, GdkEvent *event, SPDesktopWidge if (!dragged) { // Ruler click (without drag) toggle the guide visibility on and off Inkscape::XML::Node *repr = desktop->namedview->getRepr(); - sp_namedview_toggle_guides(sp_desktop_document(desktop), repr); + sp_namedview_toggle_guides(desktop->getDocument(), repr); } @@ -477,14 +494,14 @@ gint sp_dt_guide_event(SPCanvasItem *item, GdkEvent *event, gpointer data) assert(false); break; } - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_NONE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_NONE, _("Move guide")); } else { /* Undo movement of any attached shapes. */ guide->moveto(guide->getPoint(), false); guide->set_normal(guide->getNormal(), false); sp_guide_remove(guide); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_NONE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_NONE, _("Delete guide")); } moved = false; @@ -505,7 +522,7 @@ gint sp_dt_guide_event(SPCanvasItem *item, GdkEvent *event, gpointer data) if ((event->crossing.state & GDK_SHIFT_MASK) && (drag_type != SP_DRAG_MOVE_ORIGIN)) { GdkCursor *guide_cursor; guide_cursor = gdk_cursor_new (GDK_EXCHANGE); - gdk_window_set_cursor(gtk_widget_get_window (GTK_WIDGET(sp_desktop_canvas(desktop))), guide_cursor); + gdk_window_set_cursor(gtk_widget_get_window (GTK_WIDGET(desktop->getCanvas())), guide_cursor); #if GTK_CHECK_VERSION(3,0,0) g_object_unref(guide_cursor); #else @@ -514,7 +531,7 @@ gint sp_dt_guide_event(SPCanvasItem *item, GdkEvent *event, gpointer data) } else { GdkCursor *guide_cursor; guide_cursor = gdk_cursor_new (GDK_HAND1); - gdk_window_set_cursor(gtk_widget_get_window (GTK_WIDGET(sp_desktop_canvas(desktop))), guide_cursor); + gdk_window_set_cursor(gtk_widget_get_window (GTK_WIDGET(desktop->getCanvas())), guide_cursor); #if GTK_CHECK_VERSION(3,0,0) g_object_unref(guide_cursor); #else @@ -531,7 +548,7 @@ gint sp_dt_guide_event(SPCanvasItem *item, GdkEvent *event, gpointer data) sp_guideline_set_color(SP_GUIDELINE(item), guide->getColor()); // restore event context's cursor - gdk_window_set_cursor(gtk_widget_get_window (GTK_WIDGET(sp_desktop_canvas(desktop))), desktop->event_context->cursor); + gdk_window_set_cursor(gtk_widget_get_window (GTK_WIDGET(desktop->getCanvas())), desktop->event_context->cursor); desktop->guidesMessageContext()->clear(); break; @@ -553,7 +570,7 @@ gint sp_dt_guide_event(SPCanvasItem *item, GdkEvent *event, gpointer data) if (drag_type != SP_DRAG_MOVE_ORIGIN) { GdkCursor *guide_cursor; guide_cursor = gdk_cursor_new (GDK_EXCHANGE); - gdk_window_set_cursor(gtk_widget_get_window (GTK_WIDGET(sp_desktop_canvas(desktop))), guide_cursor); + gdk_window_set_cursor(gtk_widget_get_window (GTK_WIDGET(desktop->getCanvas())), guide_cursor); #if GTK_CHECK_VERSION(3,0,0) g_object_unref(guide_cursor); #else @@ -574,7 +591,7 @@ gint sp_dt_guide_event(SPCanvasItem *item, GdkEvent *event, gpointer data) case GDK_KEY_Shift_R: GdkCursor *guide_cursor; guide_cursor = gdk_cursor_new (GDK_EXCHANGE); - gdk_window_set_cursor(gtk_widget_get_window (GTK_WIDGET(sp_desktop_canvas(desktop))), guide_cursor); + gdk_window_set_cursor(gtk_widget_get_window (GTK_WIDGET(desktop->getCanvas())), guide_cursor); #if GTK_CHECK_VERSION(3,0,0) g_object_unref(guide_cursor); #else @@ -600,36 +617,35 @@ static GdkInputSource lastType = GDK_SOURCE_MOUSE; static void init_extended() { - std::string avoidName = "pad"; + Glib::ustring avoidName("pad"); + Glib::RefPtr<Gdk::Display> display = Gdk::Display::get_default(); #if GTK_CHECK_VERSION(3,0,0) - GdkDisplay *display = gdk_display_get_default(); - GdkDeviceManager *dm = gdk_display_get_device_manager(display); - GList* devices = gdk_device_manager_list_devices(dm, GDK_DEVICE_TYPE_SLAVE); + Glib::RefPtr<const Gdk::DeviceManager> dm = display->get_device_manager(); + std::vector< Glib::RefPtr<const Gdk::Device> > devices = dm->list_devices(Gdk::DEVICE_TYPE_SLAVE); #else - GList* devices = gdk_devices_list(); + std::vector< Glib::RefPtr<const Gdk::Device> > devices = display->list_devices(); #endif - if ( devices ) { - for ( GList* curr = devices; curr; curr = g_list_next(curr) ) { - GdkDevice* dev = reinterpret_cast<GdkDevice*>(curr->data); - gchar const *devName = gdk_device_get_name(dev); - GdkInputSource devSrc = gdk_device_get_source(dev); + if ( !devices.empty() ) { + for ( std::vector< Glib::RefPtr<const Gdk::Device> >::const_iterator dev = devices.begin(); dev != devices.end(); ++dev ) { + Glib::ustring const devName = (*dev)->get_name(); + Gdk::InputSource devSrc = (*dev)->get_source(); - if ( devName + if ( !devName.empty() && (avoidName != devName) - && (devSrc != GDK_SOURCE_MOUSE) ) { + && (devSrc != Gdk::SOURCE_MOUSE) ) { // g_message("Adding '%s' as [%d]", devName, devSrc); // Set the initial tool for the device switch ( devSrc ) { - case GDK_SOURCE_PEN: + case Gdk::SOURCE_PEN: toolToUse[devName] = TOOLS_CALLIGRAPHIC; break; - case GDK_SOURCE_ERASER: + case Gdk::SOURCE_ERASER: toolToUse[devName] = TOOLS_ERASER; break; - case GDK_SOURCE_CURSOR: + case Gdk::SOURCE_CURSOR: toolToUse[devName] = TOOLS_SELECT; break; default: @@ -640,10 +656,6 @@ static void init_extended() } } } - -#if GTK_CHECK_VERSION(3,0,0) - g_list_free(devices); -#endif } diff --git a/src/desktop-events.h b/src/desktop-events.h index dc85e563b..8dae9b406 100644 --- a/src/desktop-events.h +++ b/src/desktop-events.h @@ -13,6 +13,8 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#include <glib.h> + class SPDesktop; struct SPDesktopWidget; struct SPCanvasItem; diff --git a/src/desktop-handles.cpp b/src/desktop-handles.cpp deleted file mode 100644 index 8fa7ad986..000000000 --- a/src/desktop-handles.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Frontends - * - * Author: - * Lauris Kaplinski <lauris@kaplinski.com> - * - * Copyright (C) 2001-2002 Lauris Kaplinski - * Copyright (C) 2001 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#include "display/sp-canvas.h" -#include "display/sp-canvas-item.h" -#include "desktop.h" -#include "desktop-handles.h" - -Inkscape::Selection * -sp_desktop_selection (SPDesktop const * desktop) -{ - g_assert(desktop != NULL); - - return desktop->selection; -} - -SPDocument * -sp_desktop_document (SPDesktop const * desktop) -{ - g_return_val_if_fail (desktop != NULL, NULL); - - return desktop->doc(); -} - -SPCanvas * -sp_desktop_canvas (SPDesktop const * desktop) -{ - g_return_val_if_fail (desktop != NULL, NULL); - - return (SP_CANVAS_ITEM(desktop->main))->canvas; -} - -SPCanvasItem * -sp_desktop_acetate (SPDesktop const * desktop) -{ - g_return_val_if_fail (desktop != NULL, NULL); - - return desktop->acetate; -} - -SPCanvasGroup * -sp_desktop_main (SPDesktop const * desktop) -{ - g_return_val_if_fail (desktop != NULL, NULL); - - return desktop->main; -} - -SPCanvasGroup * -sp_desktop_gridgroup (SPDesktop const * desktop) -{ - g_return_val_if_fail (desktop != NULL, NULL); - - return desktop->gridgroup; -} - -SPCanvasGroup * -sp_desktop_guides (SPDesktop const * desktop) -{ - g_return_val_if_fail (desktop != NULL, NULL); - - return desktop->guides; -} - -SPCanvasItem * -sp_desktop_drawing (SPDesktop const *desktop) -{ - g_return_val_if_fail (desktop != NULL, NULL); - - return desktop->drawing; -} - -SPCanvasGroup * -sp_desktop_sketch (SPDesktop const * desktop) -{ - g_return_val_if_fail (desktop != NULL, NULL); - - return desktop->sketch; -} - -SPCanvasGroup * -sp_desktop_controls (SPDesktop const * desktop) -{ - g_return_val_if_fail (desktop != NULL, NULL); - - return desktop->controls; -} - -SPCanvasGroup * -sp_desktop_tempgroup (SPDesktop const * desktop) -{ - g_return_val_if_fail (desktop != NULL, NULL); - - return desktop->tempgroup; -} - -Inkscape::MessageStack * -sp_desktop_message_stack (SPDesktop const * desktop) -{ - g_return_val_if_fail (desktop != NULL, NULL); - - return desktop->messageStack(); -} - -SPNamedView * -sp_desktop_namedview (SPDesktop const * desktop) -{ - g_return_val_if_fail (desktop != NULL, NULL); - - return desktop->namedview; -} - - diff --git a/src/desktop-handles.h b/src/desktop-handles.h deleted file mode 100644 index 70a8c8b5f..000000000 --- a/src/desktop-handles.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef SEEN_SP_DESKTOP_HANDLES_H -#define SEEN_SP_DESKTOP_HANDLES_H - -/* - * Frontends - * - * Authors: - * Lauris Kaplinski <lauris@kaplinski.com> - * - * Copyright (C) 1999-2002 Lauris Kaplinski - * Copyright (C) 2000-2001 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - - -class SPDesktop; -class SPDocument; - -namespace Inkscape { -namespace UI { -namespace Tools { - -class ToolBase; - -} -} -} - -class SPNamedView; -struct SPCanvas; -struct SPCanvasGroup; -struct SPCanvasItem; - -namespace Inkscape { - class MessageStack; - class Selection; -} - -#define SP_DESKTOP_ZOOM_MAX 256.0 -#define SP_DESKTOP_ZOOM_MIN 0.01 - -#define SP_COORDINATES_UNDERLINE_NONE (0) -#define SP_COORDINATES_UNDERLINE_X (1 << Geom::X) -#define SP_COORDINATES_UNDERLINE_Y (1 << Geom::Y) - -//ToolBase * sp_desktop_event_context (SPDesktop const * desktop); -Inkscape::Selection * sp_desktop_selection (SPDesktop const * desktop); -SPDocument * sp_desktop_document (SPDesktop const * desktop); -SPCanvas * sp_desktop_canvas (SPDesktop const * desktop); -SPCanvasItem * sp_desktop_acetate (SPDesktop const * desktop); -SPCanvasGroup * sp_desktop_main (SPDesktop const * desktop); -SPCanvasGroup * sp_desktop_gridgroup (SPDesktop const * desktop); -SPCanvasGroup * sp_desktop_guides (SPDesktop const * desktop); -SPCanvasItem *sp_desktop_drawing (SPDesktop const *desktop); -SPCanvasGroup * sp_desktop_sketch (SPDesktop const * desktop); -SPCanvasGroup * sp_desktop_controls (SPDesktop const * desktop); -SPCanvasGroup * sp_desktop_tempgroup (SPDesktop const * desktop); -Inkscape::MessageStack * sp_desktop_message_stack (SPDesktop const * desktop); -SPNamedView * sp_desktop_namedview (SPDesktop const * desktop); - -#endif // SEEN_SP_DESKTOP_HANDLES_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:fileencoding=utf-8:textwidth=99 : diff --git a/src/desktop-style.cpp b/src/desktop-style.cpp index 30869d87d..c713e0d61 100644 --- a/src/desktop-style.cpp +++ b/src/desktop-style.cpp @@ -428,10 +428,9 @@ sp_desktop_get_font_size_tool(SPDesktop *desktop) double ret = 12; if (!style_str.empty()) { - SPStyle *style = sp_style_new(SP_ACTIVE_DOCUMENT); - sp_style_merge_from_style_string(style, style_str.data()); - ret = style->font_size.computed; - sp_style_unref(style); + SPStyle style(SP_ACTIVE_DOCUMENT); + style.mergeString(style_str.data()); + ret = style.font_size.computed; } return ret; } @@ -626,7 +625,7 @@ objects_query_fillstroke (GSList *objects, SPStyle *style_res, bool const isfill paintImpossible = false; paint_res->colorSet = paint->colorSet; - paint_res->currentcolor = paint->currentcolor; + paint_res->paintOrigin = paint->paintOrigin; if (paint_res->set && paint_effectively_set && paint->isPaintserver()) { // copy the server gchar const *string = NULL; // memory leak results if style->get* called inside sp_style_set_to_uri_string. if (isfill) { @@ -1032,7 +1031,7 @@ objects_query_fontnumbers (GSList *objects, SPStyle *style_res) letterspacing_normal = true; } } else { - letterspacing += style->letter_spacing.computed; /// \todo FIXME: we assume non-% units here + letterspacing += style->letter_spacing.computed * Geom::Affine(item->i2dt_affine()).descrim(); /// \todo FIXME: we assume non-% units here letterspacing_normal = false; } @@ -1041,7 +1040,7 @@ objects_query_fontnumbers (GSList *objects, SPStyle *style_res) wordspacing_normal = true; } } else { - wordspacing += style->word_spacing.computed; /// \todo FIXME: we assume non-% units here + wordspacing += style->word_spacing.computed * Geom::Affine(item->i2dt_affine()).descrim(); /// \todo FIXME: we assume non-% units here wordspacing_normal = false; } diff --git a/src/desktop.cpp b/src/desktop.cpp index 74dea3ca1..1152184c9 100644 --- a/src/desktop.cpp +++ b/src/desktop.cpp @@ -37,7 +37,7 @@ #include "color.h" #include "desktop-events.h" #include "desktop.h" -#include "desktop-handles.h" + #include "desktop-style.h" #include "device-manager.h" #include "display/canvas-arena.h" @@ -56,7 +56,6 @@ #include "event-log.h" #include "helper/action-context.h" #include "ui/interface.h" -#include "inkscape-private.h" #include "layer-fns.h" #include "layer-manager.h" #include "layer-model.h" @@ -94,28 +93,28 @@ static void _reconstruction_finish(SPDesktop * desktop); static void _namedview_modified (SPObject *obj, guint flags, SPDesktop *desktop); SPDesktop::SPDesktop() : - _dlg_mgr( 0 ), - namedview( 0 ), - canvas( 0 ), - layers( 0 ), - selection( 0 ), - event_context( 0 ), - layer_manager( 0 ), - event_log( 0 ), - temporary_item_list( 0 ), - snapindicator( 0 ), - acetate( 0 ), - main( 0 ), - gridgroup( 0 ), - guides( 0 ), - drawing( 0 ), - sketch( 0 ), - controls( 0 ), - tempgroup ( 0 ), - table( 0 ), - page( 0 ), - page_border( 0 ), - current( 0 ), + _dlg_mgr( NULL ), + namedview( NULL ), + canvas( NULL ), + layers( NULL ), + selection( NULL ), + event_context( NULL ), + layer_manager( NULL ), + event_log( NULL ), + temporary_item_list( NULL ), + snapindicator( NULL ), + acetate( NULL ), + main( NULL ), + gridgroup( NULL ), + guides( NULL ), + drawing( NULL ), + sketch( NULL ), + controls( NULL ), + tempgroup ( NULL ), + table( NULL ), + page( NULL ), + page_border( NULL ), + current( NULL ), _focusMode(false), dkey( 0 ), number( 0 ), @@ -124,16 +123,15 @@ SPDesktop::SPDesktop() : waiting_cursor( false ), showing_dialogs ( false ), guides_active( false ), - gr_item( 0 ), + gr_item( NULL ), gr_point_type( POINT_LG_BEGIN ), gr_point_i( 0 ), gr_fill_or_stroke( Inkscape::FOR_FILL ), _reconstruction_old_layer_id(), // an id attribute is not allowed to be the empty string _display_mode(Inkscape::RENDERMODE_NORMAL), _display_color_mode(Inkscape::COLORMODE_NORMAL), - _widget( 0 ), - _inkscape( 0 ), - _guides_message_context( 0 ), + _widget( NULL ), + _guides_message_context( NULL ), _active( false ), _w2d(), _d2w(), @@ -299,7 +297,6 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas, Inkscape::UI::View::EditWid // ? // sp_active_desktop_set (desktop); - _inkscape = INKSCAPE; _activate_connection = _activate_signal.connect( sigc::bind( @@ -385,10 +382,6 @@ void SPDesktop::destroy() layer_manager = NULL; } - if (_inkscape) { - _inkscape = NULL; - } - if (drawing) { doc()->getRoot()->invoke_hide(dkey); g_object_unref(drawing); @@ -509,7 +502,7 @@ void SPDesktop::_setDisplayMode(Inkscape::RenderMode mode) { canvas->rendermode = mode; _display_mode = mode; redrawDesktop(); - _widget->setTitle( sp_desktop_document(this)->getName() ); + _widget->setTitle( this->getDocument()->getName() ); } void SPDesktop::_setDisplayColorMode(Inkscape::ColorMode mode) { // reload grayscale matrix from prefs @@ -530,7 +523,7 @@ void SPDesktop::_setDisplayColorMode(Inkscape::ColorMode mode) { canvas->colorrendermode = mode; _display_color_mode = mode; redrawDesktop(); - _widget->setTitle( sp_desktop_document(this)->getName() ); + _widget->setTitle( this->getDocument()->getName() ); } void SPDesktop::displayModeToggle() { @@ -694,7 +687,7 @@ void SPDesktop::set_event_context2(const std::string& toolName) } } - Inkscape::UI::Tools::ToolBase* new_tool = ToolFactory::instance().createObject(toolName); + Inkscape::UI::Tools::ToolBase* new_tool = ToolFactory::createObject(toolName); new_tool->desktop = this; new_tool->message_context = new Inkscape::MessageContext(this->messageStack()); event_context = new_tool; @@ -1431,7 +1424,7 @@ void SPDesktop::emitToolSubselectionChanged(gpointer data) { _tool_subselection_changed.emit(data); - inkscape_subselection_changed (this); + INKSCAPE.subselection_changed (this); } void SPDesktop::updateNow() @@ -1453,7 +1446,7 @@ void SPDesktop::disableInteraction() void SPDesktop::setWaitingCursor() { GdkCursor *waiting = gdk_cursor_new(GDK_WATCH); - gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(sp_desktop_canvas(this))), waiting); + gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(getCanvas())), waiting); #if GTK_CHECK_VERSION(3,0,0) g_object_unref(waiting); #else @@ -1488,7 +1481,7 @@ void SPDesktop::toggleGrids() } } else { //there is no grid present at the moment. add a rectangular grid and make it visible - namedview->writeNewGrid(sp_desktop_document(this), Inkscape::GRID_RECTANGULAR); + namedview->writeNewGrid(this->getDocument(), Inkscape::GRID_RECTANGULAR); showGrids(true); } } diff --git a/src/desktop.h b/src/desktop.h index 509f8a396..a0b9592d0 100644 --- a/src/desktop.h +++ b/src/desktop.h @@ -103,6 +103,9 @@ namespace Inkscape { } } +#define SP_DESKTOP_ZOOM_MAX 256.0 +#define SP_DESKTOP_ZOOM_MIN 0.01 + /** * SPDesktop is a subclass of View, implementing an editable document * canvas. It is extensively used by many UI controls that need certain @@ -424,7 +427,6 @@ public: private: Inkscape::UI::View::EditWidgetInterface *_widget; - InkscapeApplication *_inkscape; Inkscape::MessageContext *_guides_message_context; bool _active; Geom::Affine _w2d; diff --git a/src/device-manager.cpp b/src/device-manager.cpp index 610173d3d..aa3874da8 100644 --- a/src/device-manager.cpp +++ b/src/device-manager.cpp @@ -12,37 +12,48 @@ #include <set> #include "preferences.h" -#include <gtk/gtk.h> +#include <gdkmm/display.h> +#include <gtkmm/accelkey.h> + +#if WITH_GTKMM_3_0 +# include <gdkmm/devicemanager.h> +#endif + #include <glibmm/regex.h> +#include <gtk/gtk.h> + #define noDEBUG_VERBOSE 1 // This is a copy of the private fields of the GdkDevice object, used in order // to create a list of "fake" devices. struct GdkDeviceFake { - gchar *name; - GdkInputSource source; - GdkInputMode mode; - gboolean has_cursor; - gint num_axes; - gint num_keys; + Glib::ustring name; + Gdk::InputSource source; + Gdk::InputMode mode; + bool has_cursor; + int num_axes; + int num_keys; }; static void createFakeList(); -GdkDeviceFake fakeout[5]; -static GList* fakeList = 0; +static std::vector<GdkDeviceFake> fakeList; -static bool isValidDevice(GdkDevice *device) +static bool isValidDevice(Glib::RefPtr<Gdk::Device> device) { bool valid = true; - for (size_t i = 0; (i < G_N_ELEMENTS(fakeout)) && valid; i++) { - gboolean name_matches = (g_strcmp0 (gdk_device_get_name (device), fakeout[i].name) == 0); - gboolean source_matches = (gdk_device_get_source (device) == fakeout[i].source); - gboolean mode_matches = (gdk_device_get_mode (device) == fakeout[i].mode); - gboolean num_axes_matches = (gdk_device_get_n_axes (device) == fakeout[i].num_axes); - gboolean num_keys_matches = (gdk_device_get_n_keys (device) == fakeout[i].num_keys); + for (std::vector<GdkDeviceFake>::iterator it = fakeList.begin(); it != fakeList.end() && valid; ++it) { + const bool name_matches = (device->get_name() == (*it).name); + const bool source_matches = (device->get_source() == (*it).source); + const bool mode_matches = (device->get_mode() == (*it).mode); + const bool num_axes_matches = (device->get_n_axes() == (*it).num_axes); +#if WITH_GTKMM_3_0 + const bool num_keys_matches = (device->get_n_keys() == (*it).num_keys); +#else + const bool num_keys_matches = (gdk_device_get_n_keys(device->gobj()) == (*it).num_keys); +#endif if (name_matches && source_matches && mode_matches && num_axes_matches && num_keys_matches) @@ -157,19 +168,22 @@ InputDevice::~InputDevice() {} class InputDeviceImpl : public InputDevice { public: - InputDeviceImpl(GdkDevice* device, std::set<Glib::ustring> &knownIDs); + InputDeviceImpl(Glib::RefPtr<Gdk::Device> device, std::set<Glib::ustring> &knownIDs); virtual ~InputDeviceImpl() {} virtual Glib::ustring getId() const {return id;} virtual Glib::ustring getName() const {return name;} virtual Gdk::InputSource getSource() const {return source;} - virtual Gdk::InputMode getMode() const {return static_cast<Gdk::InputMode>(gdk_device_get_mode (device));} - virtual gint getNumAxes() const {return gdk_device_get_n_axes (device);} - virtual bool hasCursor() const {return gdk_device_get_has_cursor (device);} + virtual Gdk::InputMode getMode() const {return (device->get_mode());} + virtual gint getNumAxes() const {return device->get_n_axes();} + virtual bool hasCursor() const {return device->get_has_cursor();} + +#if WITH_GTKMM_3_0 + virtual int getNumKeys() const {return device->get_n_keys();} +#else + virtual int getNumKeys() const {return gdk_device_get_n_keys(device->gobj());} +#endif - virtual gint getNumKeys() const { - return gdk_device_get_n_keys (device); - } virtual Glib::ustring getLink() const {return link;} virtual void setLink( Glib::ustring const& link ) {this->link = link;} virtual gint getLiveAxes() const {return liveAxes;} @@ -178,7 +192,7 @@ public: virtual void setLiveButtons(gint buttons) {liveButtons = buttons;} // internal methods not on public superclass: - virtual GdkDevice *getDevice() { return device; } + virtual Glib::RefPtr<Gdk::Device> getDevice() {return device;} private: InputDeviceImpl(InputDeviceImpl const &); // no copy @@ -186,7 +200,7 @@ private: static Glib::ustring createId(Glib::ustring const &id, Gdk::InputSource source, std::set<Glib::ustring> &knownIDs); - GdkDevice* device; + Glib::RefPtr<Gdk::Device> device; Glib::ustring id; Glib::ustring name; Gdk::InputSource source; @@ -213,12 +227,12 @@ private: Glib::ustring const& target; }; -InputDeviceImpl::InputDeviceImpl(GdkDevice* device, std::set<Glib::ustring> &knownIDs) +InputDeviceImpl::InputDeviceImpl(Glib::RefPtr<Gdk::Device> device, std::set<Glib::ustring> &knownIDs) : InputDevice(), device(device), id(), - name(gdk_device_get_name (device) ? gdk_device_get_name (device) : ""), - source(static_cast<Gdk::InputSource>(gdk_device_get_source (device))), + name(!device->get_name().empty() ? device->get_name() : ""), + source(device->get_source()), link(), liveAxes(0), liveButtons(0) @@ -312,28 +326,26 @@ DeviceManagerImpl::DeviceManagerImpl() : DeviceManager(), devices() { -#if GTK_CHECK_VERSION(3,0,0) - GdkDisplay *display = gdk_display_get_default(); - GdkDeviceManager *dm = gdk_display_get_device_manager(display); - GList* devList = gdk_device_manager_list_devices(dm, GDK_DEVICE_TYPE_SLAVE); + Glib::RefPtr<Gdk::Display> display = Gdk::Display::get_default(); + +#if WITH_GTKMM_3_0 + Glib::RefPtr<Gdk::DeviceManager> dm = display->get_device_manager(); + std::vector< Glib::RefPtr<Gdk::Device> > devList = dm->list_devices(Gdk::DEVICE_TYPE_SLAVE); #else - GList* devList = gdk_devices_list(); + std::vector< Glib::RefPtr<Gdk::Device> > devList = display->list_devices(); #endif - if ( !fakeList ) { + if (fakeList.empty()) { createFakeList(); } //devList = fakeList; std::set<Glib::ustring> knownIDs; - for ( GList* curr = devList; curr; curr = g_list_next(curr) ) { - GdkDevice* dev = reinterpret_cast<GdkDevice*>(curr->data); - if (dev) { - -#if GTK_CHECK_VERSION(3,0,0) + for ( std::vector< Glib::RefPtr<Gdk::Device> >::iterator dev = devList.begin(); dev != devList.end(); ++dev ) { +#if WITH_GTKMM_3_0 // GTK+ 3 has added keyboards to the list of supported devices. - if(gdk_device_get_source(dev) != GDK_SOURCE_KEYBOARD) { + if((*dev)->get_source() != Gdk::SOURCE_KEYBOARD) { #endif #if DEBUG_VERBOSE @@ -341,20 +353,14 @@ DeviceManagerImpl::DeviceManagerImpl() : dev->has_cursor?"Yes":"no", dev->num_axes, dev->num_keys); #endif - InputDeviceImpl* device = new InputDeviceImpl(dev, knownIDs); + InputDeviceImpl* device = new InputDeviceImpl(*dev, knownIDs); device->reference(); devices.push_back(Glib::RefPtr<InputDeviceImpl>(device)); -#if GTK_CHECK_VERSION(3,0,0) +#if WITH_GTKMM_3_0 } #endif - - } } - -#if GTK_CHECK_VERSION(3,0,0) - g_list_free(devList); -#endif } void DeviceManagerImpl::loadConfig() @@ -420,8 +426,8 @@ void DeviceManagerImpl::saveConfig() if (i > 0) { tmp += ";"; } - GdkDevice *device = (*it)->getDevice(); - tmp += getAxisToString()[static_cast<Gdk::AxisUse>(gdk_device_get_axis_use (device, i))]; + Glib::RefPtr<Gdk::Device> device = (*it)->getDevice(); + tmp += getAxisToString()[device->get_axis_use(i)]; } prefs->setString( path + "/axes", tmp ); @@ -430,11 +436,12 @@ void DeviceManagerImpl::saveConfig() if (i > 0) { tmp += ";"; } - GdkDevice *device = (*it)->getDevice(); + Glib::RefPtr<Gdk::Device> device = (*it)->getDevice(); guint keyval; - GdkModifierType modifiers; - gdk_device_get_key (device, i, &keyval, &modifiers); - tmp += gtk_accelerator_name(keyval, modifiers); + Gdk::ModifierType modifiers; + device->get_key(i, keyval, modifiers); + Gtk::AccelKey accelkey(keyval, modifiers); + tmp += accelkey.get_abbrev(); } prefs->setString( path + "/keys", tmp ); } @@ -454,8 +461,9 @@ void DeviceManagerImpl::setMode( Glib::ustring const & id, Gdk::InputMode mode ) { std::list<Glib::RefPtr<InputDeviceImpl> >::iterator it = std::find_if(devices.begin(), devices.end(), IdMatcher(id)); if ( it != devices.end() ) { - if (isValidDevice((*it)->getDevice()) && ((*it)->getMode() != mode) ) { - bool success = gdk_device_set_mode((*it)->getDevice(), static_cast<GdkInputMode>(mode)); + Glib::RefPtr<Gdk::Device> device = (*it)->getDevice(); + if (isValidDevice(device) && ((*it)->getMode() != mode) ) { + bool success = device->set_mode(mode); if (success) { signalDeviceChangedPriv.emit(*it); } else { @@ -471,10 +479,10 @@ void DeviceManagerImpl::setAxisUse( Glib::ustring const & id, guint index, Gdk:: if ( it != devices.end() ) { if (isValidDevice((*it)->getDevice())) { if (static_cast<gint>(index) <= (*it)->getNumAxes()) { - GdkDevice *device = (*it)->getDevice(); + Glib::RefPtr<Gdk::Device> device = (*it)->getDevice(); - if (gdk_device_get_axis_use (device, index) != static_cast<GdkAxisUse>(use)) { - gdk_device_set_axis_use(device, index, static_cast<GdkAxisUse>(use)); + if (device->get_axis_use(index) != use) { + device->set_axis_use(index, use); signalDeviceChangedPriv.emit(*it); } } else { @@ -492,7 +500,8 @@ void DeviceManagerImpl::setKey( Glib::ustring const & id, guint index, guint key std::list<Glib::RefPtr<InputDeviceImpl> >::iterator it = std::find_if(devices.begin(), devices.end(), IdMatcher(id)); if ( it != devices.end() ) { if (isValidDevice((*it)->getDevice())) { - gdk_device_set_key((*it)->getDevice(), index, keyval, static_cast<GdkModifierType>(mods)); + Glib::RefPtr<Gdk::Device> device = (*it)->getDevice(); + device->set_key(index, keyval, mods); signalDeviceChangedPriv.emit(*it); } } @@ -628,78 +637,76 @@ DeviceManager& DeviceManager::getManager() { static void createFakeList() { - if ( !fakeList ) { - fakeout[0].name = g_strdup("pad"); - fakeout[0].source = GDK_SOURCE_PEN; - fakeout[0].mode = GDK_MODE_SCREEN; - fakeout[0].has_cursor = TRUE; - fakeout[0].num_axes = 6; - fakeout[0].num_keys = 8; - - fakeout[1].name = g_strdup("eraser"); - fakeout[1].source = GDK_SOURCE_ERASER; - fakeout[1].mode = GDK_MODE_SCREEN; - fakeout[1].has_cursor = TRUE; - fakeout[1].num_axes = 6; - fakeout[1].num_keys = 7; - - fakeout[2].name = g_strdup("cursor"); - fakeout[2].source = GDK_SOURCE_CURSOR; - fakeout[2].mode = GDK_MODE_SCREEN; - fakeout[2].has_cursor = TRUE; - fakeout[2].num_axes = 6; - fakeout[2].num_keys = 7; - - fakeout[3].name = g_strdup("stylus"); - fakeout[3].source = GDK_SOURCE_PEN; - fakeout[3].mode = GDK_MODE_SCREEN; - fakeout[3].has_cursor = TRUE; - fakeout[3].num_axes = 6; - fakeout[3].num_keys = 7; + if (fakeList.empty()) { + fakeList.resize(5); + fakeList[0].name = "pad"; + fakeList[0].source = Gdk::SOURCE_PEN; + fakeList[0].mode = Gdk::MODE_SCREEN; + fakeList[0].has_cursor = true; + fakeList[0].num_axes = 6; + fakeList[0].num_keys = 8; + + fakeList[1].name = "eraser"; + fakeList[1].source = Gdk::SOURCE_ERASER; + fakeList[1].mode = Gdk::MODE_SCREEN; + fakeList[1].has_cursor = true; + fakeList[1].num_axes = 6; + fakeList[1].num_keys = 7; + + fakeList[2].name = "cursor"; + fakeList[2].source = Gdk::SOURCE_CURSOR; + fakeList[2].mode = Gdk::MODE_SCREEN; + fakeList[2].has_cursor = true; + fakeList[2].num_axes = 6; + fakeList[2].num_keys = 7; + + fakeList[3].name = "stylus"; + fakeList[3].source = Gdk::SOURCE_PEN; + fakeList[3].mode = Gdk::MODE_SCREEN; + fakeList[3].has_cursor = true; + fakeList[3].num_axes = 6; + fakeList[3].num_keys = 7; // try to find the first *real* core pointer -#if GTK_CHECK_VERSION(3,0,0) - GdkDisplay *display = gdk_display_get_default(); - GdkDeviceManager *dm = gdk_display_get_device_manager(display); - GList* devList = gdk_device_manager_list_devices(dm, GDK_DEVICE_TYPE_SLAVE); + Glib::RefPtr<Gdk::Display> display = Gdk::Display::get_default(); +#if WITH_GTKMM_3_0 + Glib::RefPtr<Gdk::DeviceManager> dm = display->get_device_manager(); + std::vector< Glib::RefPtr<Gdk::Device> > devList = dm->list_devices(Gdk::DEVICE_TYPE_SLAVE); #else - GList* devList = gdk_devices_list(); + std::vector< Glib::RefPtr<Gdk::Device> > devList = display->list_devices(); #endif + // Set iterator to point at beginning of device list + std::vector< Glib::RefPtr<Gdk::Device> >::iterator dev = devList.begin(); + // Skip past any items in the device list that are not mice - while ( devList && devList->data && (gdk_device_get_source ((GdkDevice*)devList->data) != GDK_SOURCE_MOUSE)) { - devList = g_list_next(devList); + while (dev != devList.end() && (*dev)->get_source() != Gdk::SOURCE_MOUSE) { + ++dev; } - if ( devList && devList->data ) { - GdkDevice *device = (GdkDevice*)devList->data; - fakeout[4].name = g_strdup(gdk_device_get_name (device)); - fakeout[4].source = gdk_device_get_source (device); - fakeout[4].mode = gdk_device_get_mode (device); - fakeout[4].has_cursor = gdk_device_get_has_cursor (device); - fakeout[4].num_axes = gdk_device_get_n_axes (device); - fakeout[4].num_keys = gdk_device_get_n_keys (device); + if (dev != devList.end()) { + Glib::RefPtr<Gdk::Device> device = *dev; + fakeList[4].name = device->get_name(); + fakeList[4].source = device->get_source(); + fakeList[4].mode = device->get_mode(); + fakeList[4].has_cursor = device->get_has_cursor(); + fakeList[4].num_axes = device->get_n_axes(); +#if WITH_GTKMM_3_0 + fakeList[4].num_keys = device->get_n_keys(); +#else + fakeList[4].num_keys = gdk_device_get_n_keys(device->gobj()); +#endif } else { - fakeout[4].name = g_strdup("Core Pointer"); - fakeout[4].source = GDK_SOURCE_MOUSE; - fakeout[4].mode = GDK_MODE_SCREEN; - fakeout[4].has_cursor = TRUE; - fakeout[4].num_axes = 2; - fakeout[4].num_keys = 0; - } - - for ( guint pos = 0; pos < G_N_ELEMENTS(fakeout); pos++) { - fakeList = g_list_append(fakeList, &(fakeout[pos])); + fakeList[4].name = "Core Pointer"; + fakeList[4].source = Gdk::SOURCE_MOUSE; + fakeList[4].mode = Gdk::MODE_SCREEN; + fakeList[4].has_cursor = true; + fakeList[4].num_axes = 2; + fakeList[4].num_keys = 0; } - -#if GTK_CHECK_VERSION(3,0,0) - g_list_free(devList); -#endif } - } - /* Local Variables: mode:c++ diff --git a/src/dir-util-test.h b/src/dir-util-test.h index cc3bc20b8..735f0174e 100644 --- a/src/dir-util-test.h +++ b/src/dir-util-test.h @@ -12,11 +12,19 @@ public: void testBase() { char const* cases[][3] = { +#if defined(WIN32) || defined(__WIN32__) + {"\\foo\\bar", "\\foo", "bar"}, + {"\\foo\\barney", "\\foo\\bar", "\\foo\\barney"}, + {"\\foo\\bar\\baz", "\\foo\\", "bar\\baz"}, + {"\\foo\\bar\\baz", "\\", "foo\\bar\\baz"}, + {"\\foo\\bar\\baz", "\\foo\\qux", "\\foo\\bar\\baz"}, +#else {"/foo/bar", "/foo", "bar"}, {"/foo/barney", "/foo/bar", "/foo/barney"}, {"/foo/bar/baz", "/foo/", "bar/baz"}, {"/foo/bar/baz", "/", "foo/bar/baz"}, {"/foo/bar/baz", "/foo/qux", "/foo/bar/baz"}, +#endif }; for ( size_t i = 0; i < G_N_ELEMENTS(cases); i++ ) diff --git a/src/display/CMakeLists.txt b/src/display/CMakeLists.txt index 800c4d0d4..d4f8c16ff 100644 --- a/src/display/CMakeLists.txt +++ b/src/display/CMakeLists.txt @@ -42,7 +42,6 @@ set(display_SRC nr-filter-tile.cpp nr-filter-turbulence.cpp nr-filter-units.cpp - nr-filter-utils.cpp nr-filter.cpp nr-light.cpp nr-style.cpp diff --git a/src/display/Makefile_insert b/src/display/Makefile_insert index 2355c3653..20e498981 100644 --- a/src/display/Makefile_insert +++ b/src/display/Makefile_insert @@ -90,7 +90,6 @@ ink_common_sources += \ display/nr-filter-types.h \ display/nr-filter-units.cpp \ display/nr-filter-units.h \ - display/nr-filter-utils.cpp \ display/nr-filter-utils.h \ display/nr-light.cpp \ display/nr-light.h \ diff --git a/src/display/canvas-axonomgrid.cpp b/src/display/canvas-axonomgrid.cpp index 592c962a6..a2df86823 100644 --- a/src/display/canvas-axonomgrid.cpp +++ b/src/display/canvas-axonomgrid.cpp @@ -36,7 +36,7 @@ #include "ui/widget/registered-widget.h" #include "desktop.h" -#include "desktop-handles.h" + #include "display/cairo-utils.h" #include "display/canvas-grid.h" #include "display/sp-canvas-util.h" @@ -46,10 +46,11 @@ #include "preferences.h" #include "sp-namedview.h" #include "sp-object.h" +#include "sp-root.h" #include "svg/svg-color.h" #include "2geom/line.h" #include "2geom/angle.h" -#include "util/mathfns.h" +#include "helper/mathfns.h" #include "round.h" #include "util/units.h" @@ -213,22 +214,61 @@ static gboolean sp_nv_read_opacity(gchar const *str, guint32 *color) void CanvasAxonomGrid::readRepr() { + SPRoot *root = doc->getRoot(); + double scale_x = 1.0; + double scale_y = 1.0; + if( root->viewBox_set ) { + scale_x = root->width.computed / root->viewBox.width(); + scale_y = root->height.computed / root->viewBox.height(); + if (Geom::are_near(scale_x / scale_y, 1.0, Geom::EPSILON)) { + // scaling is uniform, try to reduce numerical error + scale_x = (scale_x + scale_y)/2.0; + double scale_none = Inkscape::Util::Quantity::convert(1, doc->getDisplayUnit(), "px"); + if (Geom::are_near(scale_x / scale_none, 1.0, Geom::EPSILON)) + scale_x = scale_none; // objects are same size, reduce numerical error + scale_y = scale_x; + } + } + gchar const *value; + if ( (value = repr->attribute("originx")) ) { + Inkscape::Util::Quantity q = unit_table.parseQuantity(value); - gridunit = q.unit; - origin[Geom::X] = q.value("px"); + + if( q.unit->type == UNIT_TYPE_LINEAR ) { + // Legacy grid not in 'user units' + origin[Geom::X] = q.value("px"); + } else { + // Grid in 'user units' + origin[Geom::X] = q.quantity * scale_x; + } } + if ( (value = repr->attribute("originy")) ) { + Inkscape::Util::Quantity q = unit_table.parseQuantity(value); - gridunit = q.unit; - origin[Geom::Y] = q.value("px"); + + if( q.unit->type == UNIT_TYPE_LINEAR ) { + // Legacy grid not in 'user units' + origin[Geom::Y] = q.value("px"); + } else { + // Grid in 'user units' + origin[Geom::Y] = q.quantity * scale_y; + } } if ( (value = repr->attribute("spacingy")) ) { + Inkscape::Util::Quantity q = unit_table.parseQuantity(value); - gridunit = q.unit; - lengthy = q.value("px"); + + if( q.unit->type == UNIT_TYPE_LINEAR ) { + // Legacy grid not in 'user units' + lengthy = q.value("px"); + } else { + // Grid in 'user units' + lengthy = q.quantity * scale_y; // We do not handle scale_x != scale_y + } if (lengthy < 0.0500) lengthy = 0.0500; } @@ -281,6 +321,10 @@ CanvasAxonomGrid::readRepr() snapper->setSnapVisibleOnly(strcmp(value,"false") != 0 && strcmp(value, "0") != 0); } + if ( (value = repr->attribute("units")) ) { + gridunit = unit_table.getUnit(value); // Display unit identifier in grid menu + } + for (GSList *l = canvasitems; l != NULL; l = l->next) { sp_canvas_item_request_update ( SP_CANVAS_ITEM(l->data) ); } @@ -316,11 +360,14 @@ _wr.setUpdating (true); Inkscape::UI::Widget::RegisteredUnitMenu *_rumg = Gtk::manage( new Inkscape::UI::Widget::RegisteredUnitMenu( _("Grid _units:"), "units", _wr, repr, doc) ); Inkscape::UI::Widget::RegisteredScalarUnit *_rsu_ox = Gtk::manage( new Inkscape::UI::Widget::RegisteredScalarUnit( - _("_Origin X:"), _("X coordinate of grid origin"), "originx", *_rumg, _wr, repr, doc) ); + _("_Origin X:"), _("X coordinate of grid origin"), "originx", + *_rumg, _wr, repr, doc, Inkscape::UI::Widget::RSU_x) ); Inkscape::UI::Widget::RegisteredScalarUnit *_rsu_oy = Gtk::manage( new Inkscape::UI::Widget::RegisteredScalarUnit( - _("O_rigin Y:"), _("Y coordinate of grid origin"), "originy", *_rumg, _wr, repr, doc) ); + _("O_rigin Y:"), _("Y coordinate of grid origin"), "originy", + *_rumg, _wr, repr, doc, Inkscape::UI::Widget::RSU_y) ); Inkscape::UI::Widget::RegisteredScalarUnit *_rsu_sy = Gtk::manage( new Inkscape::UI::Widget::RegisteredScalarUnit( - _("Spacing _Y:"), _("Base length of z-axis"), "spacingy", *_rumg, _wr, repr, doc) ); + _("Spacing _Y:"), _("Base length of z-axis"), "spacingy", + *_rumg, _wr, repr, doc, Inkscape::UI::Widget::RSU_y) ); Inkscape::UI::Widget::RegisteredScalar *_rsu_ax = Gtk::manage( new Inkscape::UI::Widget::RegisteredScalar( _("Angle X:"), _("Angle of x-axis"), "gridanglex", _wr, repr, doc ) ); Inkscape::UI::Widget::RegisteredScalar *_rsu_az = Gtk::manage( new Inkscape::UI::Widget::RegisteredScalar( diff --git a/src/display/canvas-grid.cpp b/src/display/canvas-grid.cpp index 2eeaa7006..9b9f64529 100644 --- a/src/display/canvas-grid.cpp +++ b/src/display/canvas-grid.cpp @@ -35,8 +35,8 @@ #include "ui/widget/registered-widget.h" #include "desktop.h" #include "sp-canvas-util.h" -#include "util/mathfns.h" -#include "desktop-handles.h" +#include "helper/mathfns.h" + #include "display/cairo-utils.h" #include "display/canvas-axonomgrid.h" #include "display/canvas-grid.h" @@ -47,9 +47,10 @@ #include "preferences.h" #include "sp-namedview.h" #include "sp-object.h" +#include "sp-root.h" #include "svg/svg-color.h" #include "svg/stringstream.h" -#include "util/mathfns.h" +#include "helper/mathfns.h" #include "xml/node-event-vector.h" #include "verbs.h" #include "display/sp-canvas.h" @@ -284,12 +285,12 @@ CanvasGrid::createCanvasItem(SPDesktop * desktop) // check if there is already a canvasitem on this desktop linking to this grid for (GSList *l = canvasitems; l != NULL; l = l->next) { - if ( sp_desktop_gridgroup(desktop) == SP_CANVAS_GROUP(SP_CANVAS_ITEM(l->data)->parent) ) { + if ( desktop->getGridGroup() == SP_CANVAS_GROUP(SP_CANVAS_ITEM(l->data)->parent) ) { return NULL; } } - GridCanvasItem * item = INKSCAPE_GRID_CANVASITEM( sp_canvas_item_new(sp_desktop_gridgroup(desktop), INKSCAPE_TYPE_GRID_CANVASITEM, NULL) ); + GridCanvasItem * item = INKSCAPE_GRID_CANVASITEM( sp_canvas_item_new(desktop->getGridGroup(), INKSCAPE_TYPE_GRID_CANVASITEM, NULL) ); item->grid = this; sp_canvas_item_show(SP_CANVAS_ITEM(item)); @@ -367,17 +368,21 @@ bool CanvasGrid::isEnabled() const return snapper->getEnabled(); } +// Used to shift origin when page size changed to fit drawing. void CanvasGrid::setOrigin(Geom::Point const &origin_px) { - Inkscape::SVGOStringStream os_x, os_y; - gdouble val; + SPRoot *root = doc->getRoot(); + double scale_x = 1.0; + double scale_y = 1.0; + if( root->viewBox_set ) { + scale_x = root->viewBox.width() / root->width.computed; + scale_y = root->viewBox.height() / root->height.computed; + } - val = origin_px[Geom::X]; - val = Inkscape::Util::Quantity::convert(val, "px", gridunit); - os_x << val << gridunit->abbr; - val = origin_px[Geom::Y]; - val = Inkscape::Util::Quantity::convert(val, "px", gridunit); - os_y << val << gridunit->abbr; + // Write out in 'user-units' + Inkscape::SVGOStringStream os_x, os_y; + os_x << origin_px[Geom::X] * scale_x; + os_y << origin_px[Geom::Y] * scale_y; repr->setAttribute("originx", os_x.str().c_str()); repr->setAttribute("originy", os_y.str().c_str()); } @@ -504,33 +509,6 @@ static gboolean sp_nv_read_opacity(gchar const *str, guint32 *color) return TRUE; } -/** If the passed scalar is invalid (<=0), then set the widget and the scalar - to use the given old value. - - @param oldVal Old value to use if the new one is invalid. - @param pTarget The scalar to validate. - @param widget Widget associated with the scalar. -*/ -static void validateScalar(double oldVal, - double* pTarget) -{ - // Avoid nullness. - if ( pTarget == NULL ) - return; - - // Invalid new value? - if ( *pTarget <= 0 ) { - // If the old value is somehow invalid as well, then default to 1. - if ( oldVal <= 0 ) - oldVal = 1; - - // Reset the scalar and associated widget to the old value. - *pTarget = oldVal; - } //if - -} //validateScalar - - /** If the passed int is invalid (<=0), then set the widget and the int to use the given old value. @@ -560,34 +538,86 @@ static void validateInt(gint oldVal, void CanvasXYGrid::readRepr() { + SPRoot *root = doc->getRoot(); + double scale_x = 1.0; + double scale_y = 1.0; + if( root->viewBox_set ) { + scale_x = root->width.computed / root->viewBox.width(); + scale_y = root->height.computed / root->viewBox.height(); + if (Geom::are_near(scale_x / scale_y, 1.0, Geom::EPSILON)) { + // scaling is uniform, try to reduce numerical error + scale_x = (scale_x + scale_y)/2.0; + double scale_none = Inkscape::Util::Quantity::convert(1, doc->getDisplayUnit(), "px"); + if (Geom::are_near(scale_x / scale_none, 1.0, Geom::EPSILON)) + scale_x = scale_none; // objects are same size, reduce numerical error + scale_y = scale_x; + } + } + gchar const *value; + if ( (value = repr->attribute("originx")) ) { + Inkscape::Util::Quantity q = unit_table.parseQuantity(value); - gridunit = q.unit; - origin[Geom::X] = q.value("px"); + + if( q.unit->type == UNIT_TYPE_LINEAR ) { + // Legacy grid not in 'user units' + origin[Geom::X] = q.value("px"); + } else { + // Grid in 'user units' + origin[Geom::X] = q.quantity * scale_x; + } } if ( (value = repr->attribute("originy")) ) { + Inkscape::Util::Quantity q = unit_table.parseQuantity(value); - gridunit = q.unit; - origin[Geom::Y] = q.value("px"); + + if( q.unit->type == UNIT_TYPE_LINEAR ) { + // Legacy grid not in 'user units' + origin[Geom::Y] = q.value("px"); + } else { + // Grid in 'user units' + origin[Geom::Y] = q.quantity * scale_y; + } } if ( (value = repr->attribute("spacingx")) ) { - double oldVal = spacing[Geom::X]; + + // Ensure a valid default value + if( spacing[Geom::X] <= 0.0 ) + spacing[Geom::X] = 1.0; + Inkscape::Util::Quantity q = unit_table.parseQuantity(value); - gridunit = q.unit; - spacing[Geom::X] = q.quantity; - validateScalar(oldVal, &spacing[Geom::X]); - spacing[Geom::X] = Inkscape::Util::Quantity::convert(spacing[Geom::X], gridunit, "px"); + // Ensure a valid new value + if( q.quantity > 0 ) { + if( q.unit->type == UNIT_TYPE_LINEAR ) { + // Legacy grid not in 'user units' + spacing[Geom::X] = q.value("px"); + } else { + // Grid in 'user units' + spacing[Geom::X] = q.quantity * scale_x; + } + } } + if ( (value = repr->attribute("spacingy")) ) { - double oldVal = spacing[Geom::Y]; + + // Ensure a valid default value + if( spacing[Geom::Y] <= 0.0 ) + spacing[Geom::Y] = 1.0; + Inkscape::Util::Quantity q = unit_table.parseQuantity(value); - gridunit = q.unit; - spacing[Geom::Y] = q.quantity; - validateScalar(oldVal, &spacing[Geom::Y]); - spacing[Geom::Y] = Inkscape::Util::Quantity::convert(spacing[Geom::Y], gridunit, "px"); + // Ensure a valid new value + if( q.quantity > 0 ) { + if( q.unit->type == UNIT_TYPE_LINEAR ) { + // Legacy grid not in 'user units' + spacing[Geom::Y] = q.value("px"); + } else { + // Grid in 'user units' + spacing[Geom::Y] = q.quantity * scale_y; + } + } } if ( (value = repr->attribute("color")) ) { @@ -629,6 +659,10 @@ CanvasXYGrid::readRepr() snapper->setSnapVisibleOnly(strcmp(value,"false") != 0 && strcmp(value, "0") != 0); } + if ( (value = repr->attribute("units")) ) { + gridunit = unit_table.getUnit(value); // Display unit identifier in grid menu + } + for (GSList *l = canvasitems; l != NULL; l = l->next) { sp_canvas_item_request_update ( SP_CANVAS_ITEM(l->data) ); } @@ -666,13 +700,17 @@ CanvasXYGrid::newSpecificWidget() Inkscape::UI::Widget::RegisteredUnitMenu *_rumg = Gtk::manage( new Inkscape::UI::Widget::RegisteredUnitMenu( _("Grid _units:"), "units", _wr, repr, doc) ); Inkscape::UI::Widget::RegisteredScalarUnit *_rsu_ox = Gtk::manage( new Inkscape::UI::Widget::RegisteredScalarUnit( - _("_Origin X:"), _("X coordinate of grid origin"), "originx", *_rumg, _wr, repr, doc) ); + _("_Origin X:"), _("X coordinate of grid origin"), "originx", + *_rumg, _wr, repr, doc, Inkscape::UI::Widget::RSU_x) ); Inkscape::UI::Widget::RegisteredScalarUnit *_rsu_oy = Gtk::manage( new Inkscape::UI::Widget::RegisteredScalarUnit( - _("O_rigin Y:"), _("Y coordinate of grid origin"), "originy", *_rumg, _wr, repr, doc) ); + _("O_rigin Y:"), _("Y coordinate of grid origin"), "originy", + *_rumg, _wr, repr, doc, Inkscape::UI::Widget::RSU_y) ); Inkscape::UI::Widget::RegisteredScalarUnit *_rsu_sx = Gtk::manage( new Inkscape::UI::Widget::RegisteredScalarUnit( - _("Spacing _X:"), _("Distance between vertical grid lines"), "spacingx", *_rumg, _wr, repr, doc) ); + _("Spacing _X:"), _("Distance between vertical grid lines"), "spacingx", + *_rumg, _wr, repr, doc, Inkscape::UI::Widget::RSU_x) ); Inkscape::UI::Widget::RegisteredScalarUnit *_rsu_sy = Gtk::manage( new Inkscape::UI::Widget::RegisteredScalarUnit( - _("Spacing _Y:"), _("Distance between horizontal grid lines"), "spacingy", *_rumg, _wr, repr, doc) ); + _("Spacing _Y:"), _("Distance between horizontal grid lines"), "spacingy", + *_rumg, _wr, repr, doc, Inkscape::UI::Widget::RSU_y) ); Inkscape::UI::Widget::RegisteredColorPicker *_rcp_gcol = Gtk::manage( new Inkscape::UI::Widget::RegisteredColorPicker( diff --git a/src/display/drawing-group.cpp b/src/display/drawing-group.cpp index bce89d70e..1a9cbfdcc 100644 --- a/src/display/drawing-group.cpp +++ b/src/display/drawing-group.cpp @@ -21,14 +21,11 @@ namespace Inkscape { DrawingGroup::DrawingGroup(Drawing &drawing) : DrawingItem(drawing) - , _style(NULL) , _child_transform(NULL) {} DrawingGroup::~DrawingGroup() { - if (_style) - sp_style_unref(_style); delete _child_transform; // delete NULL; is safe } @@ -42,12 +39,6 @@ DrawingGroup::setPickChildren(bool p) _pick_children = p; } -void -DrawingGroup::setStyle(SPStyle *style) -{ - _setStyleCommon(_style, style); -} - /** * Set additional transform for the group. * This is applied after the normal transform and mainly useful for diff --git a/src/display/drawing-group.h b/src/display/drawing-group.h index ab1f9895d..0c985b43f 100644 --- a/src/display/drawing-group.h +++ b/src/display/drawing-group.h @@ -14,8 +14,6 @@ #include "display/drawing-item.h" -class SPStyle; - namespace Inkscape { class DrawingGroup @@ -28,7 +26,6 @@ public: bool pickChildren() { return _pick_children; } void setPickChildren(bool p); - void setStyle(SPStyle *style); void setChildTransform(Geom::Affine const &new_trans); protected: @@ -40,7 +37,6 @@ protected: virtual DrawingItem *_pickItem(Geom::Point const &p, double delta, unsigned flags); virtual bool _canClip(); - SPStyle *_style; Geom::Affine *_child_transform; }; diff --git a/src/display/drawing-image.cpp b/src/display/drawing-image.cpp index e56f3e58b..8fe337959 100644 --- a/src/display/drawing-image.cpp +++ b/src/display/drawing-image.cpp @@ -24,15 +24,10 @@ namespace Inkscape { DrawingImage::DrawingImage(Drawing &drawing) : DrawingItem(drawing) , _pixbuf(NULL) - , _style(NULL) {} DrawingImage::~DrawingImage() { - if (_style) { - sp_style_unref(_style); - } - // _pixbuf is owned by SPImage - do not delete it } @@ -45,12 +40,6 @@ DrawingImage::setPixbuf(Inkscape::Pixbuf *pb) } void -DrawingImage::setStyle(SPStyle *style) -{ - _setStyleCommon(_style, style); -} - -void DrawingImage::setScale(double sx, double sy) { _scale = Geom::Scale(sx, sy); diff --git a/src/display/drawing-image.h b/src/display/drawing-image.h index 64e4517b0..7511768c9 100644 --- a/src/display/drawing-image.h +++ b/src/display/drawing-image.h @@ -29,7 +29,6 @@ public: ~DrawingImage(); void setPixbuf(Inkscape::Pixbuf *pb); - void setStyle(SPStyle *style); void setScale(double sx, double sy); void setOrigin(Geom::Point const &o); void setClipbox(Geom::Rect const &box); @@ -43,7 +42,6 @@ protected: virtual DrawingItem *_pickItem(Geom::Point const &p, double delta, unsigned flags); Inkscape::Pixbuf *_pixbuf; - SPStyle *_style; // TODO: the following three should probably be merged into a new Geom::Viewbox object Geom::Rect _clipbox; ///< for preserveAspectRatio diff --git a/src/display/drawing-item.cpp b/src/display/drawing-item.cpp index 8ed74b550..89ca66dc4 100644 --- a/src/display/drawing-item.cpp +++ b/src/display/drawing-item.cpp @@ -109,6 +109,8 @@ DrawingItem::DrawingItem(Drawing &drawing) : _drawing(drawing) , _parent(NULL) , _key(0) + , _style(NULL) + , _context_style(NULL) , _opacity(1.0) , _transform(NULL) , _clip(NULL) @@ -188,6 +190,8 @@ DrawingItem::~DrawingItem() delete _clip; delete _mask; delete _filter; + if(_style) + sp_style_unref(_style); } DrawingItem * @@ -351,6 +355,72 @@ DrawingItem::setCached(bool cached, bool persistent) } } +/** + * Process information related to the new style. + * + * Note: _style is not used by DrawingGlyphs which uses its parent style. + */ +void +DrawingItem::setStyle(SPStyle *style, SPStyle *context_style) +{ + // std::cout << "DrawingItem::setStyle: " << name() << " " << style + // << " " << context_style << std::endl; + + if( style != _style ) { + if (style) sp_style_ref(style); + if (_style) sp_style_unref(_style); + _style = style; + } + + if (style && style->filter.set && style->getFilter()) { + if (!_filter) { + int primitives = sp_filter_primitive_count(SP_FILTER(style->getFilter())); + _filter = new Inkscape::Filters::Filter(primitives); + } + sp_filter_build_renderer(SP_FILTER(style->getFilter()), _filter); + } else { + // no filter set for this group + delete _filter; + _filter = NULL; + } + + if (style && style->enable_background.set) { + if (style->enable_background.value == SP_CSS_BACKGROUND_NEW && !_background_new) { + _background_new = true; + _markForUpdate(STATE_BACKGROUND, true); + } else if (style->enable_background.value == SP_CSS_BACKGROUND_ACCUMULATE && _background_new) { + _background_new = false; + _markForUpdate(STATE_BACKGROUND, true); + } + } + + if (context_style != NULL) { + _context_style = context_style; + } else if (_parent != NULL) { + _context_style = _parent->_context_style; + } + + _markForUpdate(STATE_ALL, false); +} + + +/** + * Recursively update children style. + * The purpose of this call is to update fill and stroke for markers that have elements with + * fill/stroke property values of 'context-fill' or 'context-stroke'. Marker styling is not + * updated like other 'clones' as marker instances are not included the SP object tree. + * Note: this is a virtual function. + */ +void +DrawingItem::setChildrenStyle(SPStyle* context_style) +{ + _context_style = context_style; + for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) { + i->setChildrenStyle( context_style ); + } +} + + void DrawingItem::setClip(DrawingItem *item) { @@ -908,6 +978,39 @@ DrawingItem::pick(Geom::Point const &p, double delta, unsigned flags) return NULL; } +// For debugging +Glib::ustring +DrawingItem::name() +{ + SPObject *object = static_cast<SPObject *>(_user_data); + if (object) { + if(object->getId()) + return object->getId(); + else + return "No object id"; + } else { + return "No associated object"; + } +} + +// For debugging: Print drawing tree structure. +void +DrawingItem::recursivePrintTree( unsigned level ) +{ + if (level == 0) { + std::cout << "Display Item Tree" << std::endl; + } + std::cout << "DI: "; + for (unsigned i = 0; i < level; ++i) { + std::cout << " "; + } + std::cout << name() << std::endl; + for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) { + i->recursivePrintTree( level+1 ); + } +} + + /** * Marks the current visual bounding box of the item for redrawing. * This is called whenever the object changes its visible appearance. @@ -998,48 +1101,6 @@ DrawingItem::_markForUpdate(unsigned flags, bool propagate) } /** - * Process information related to the new style. - * - * This function is something of a hack to avoid creating an extra class in the hierarchy - * which would differ from DrawingItem only by having a _style member. - * This is mainly to the benefit of DrawingGlyphs, which use the style of their parent. - * This should probably be refactored some day, possibly by creating the relevant class - * or creating a more complex data model in DrawingText and removing DrawingGlyphs, - * which would cause every item to have a style. - */ -void -DrawingItem::_setStyleCommon(SPStyle *&_style, SPStyle *style) -{ - if (style) sp_style_ref(style); - if (_style) sp_style_unref(_style); - _style = style; - - if (style && style->filter.set && style->getFilter()) { - if (!_filter) { - int primitives = sp_filter_primitive_count(SP_FILTER(style->getFilter())); - _filter = new Inkscape::Filters::Filter(primitives); - } - sp_filter_build_renderer(SP_FILTER(style->getFilter()), _filter); - } else { - // no filter set for this group - delete _filter; - _filter = NULL; - } - - if (style && style->enable_background.set) { - if (style->enable_background.value == SP_CSS_BACKGROUND_NEW && !_background_new) { - _background_new = true; - _markForUpdate(STATE_BACKGROUND, true); - } else if (style->enable_background.value == SP_CSS_BACKGROUND_ACCUMULATE && _background_new) { - _background_new = false; - _markForUpdate(STATE_BACKGROUND, true); - } - } - - _markForUpdate(STATE_ALL, false); -} - -/** * Compute the caching score. * * Higher scores mean the item is more aggresively prioritized for automatic diff --git a/src/display/drawing-item.h b/src/display/drawing-item.h index 9b399e6e3..3c593ceaa 100644 --- a/src/display/drawing-item.h +++ b/src/display/drawing-item.h @@ -20,6 +20,10 @@ #include <exception> #include <list> +namespace Glib { +class ustring; +} + class SPStyle; namespace Inkscape { @@ -108,6 +112,8 @@ public: bool cached() const { return _cached; } void setCached(bool c, bool persistent = false); + virtual void setStyle(SPStyle *style, SPStyle *context_style = NULL); + virtual void setChildrenStyle(SPStyle *context_style); void setOpacity(float opacity); void setAntialiasing(bool a); void setIsolation(unsigned isolation); // CSS Compositing and Blending @@ -131,6 +137,9 @@ public: void clip(DrawingContext &dc, Geom::IntRect const &area); DrawingItem *pick(Geom::Point const &p, double delta, unsigned flags = 0); + virtual Glib::ustring name(); // For debugging + void recursivePrintTree(unsigned level = 0); // For debugging + protected: enum ChildType { CHILD_ORPHAN = 0, // no parent - implies _parent == NULL @@ -149,7 +158,6 @@ protected: void _markForUpdate(unsigned state, bool propagate); void _markForRendering(); void _invalidateFilterBackground(Geom::IntRect const &area); - void _setStyleCommon(SPStyle *&_style, SPStyle *style); double _cacheScore(); Geom::OptIntRect _cacheRect(); virtual unsigned _updateItem(Geom::IntRect const &/*area*/, UpdateContext const &/*ctx*/, @@ -176,6 +184,9 @@ protected: unsigned _key; ///< Some SPItems can have more than one DrawingItem; /// this value is a hack used to distinguish between them + SPStyle *_style; // Not used by DrawingGlyphs + SPStyle *_context_style; // Used for 'context-fill', 'context-stroke' + float _opacity; Geom::Affine *_transform; ///< Incremental transform from parent to this item's coords diff --git a/src/display/drawing-pattern.h b/src/display/drawing-pattern.h index 7483ba067..dc1f93ed1 100644 --- a/src/display/drawing-pattern.h +++ b/src/display/drawing-pattern.h @@ -15,7 +15,6 @@ #include "display/drawing-group.h" typedef struct _cairo_pattern cairo_pattern_t; -class SPStyle; namespace Inkscape { diff --git a/src/display/drawing-shape.cpp b/src/display/drawing-shape.cpp index 66160638f..63efb3c0d 100644 --- a/src/display/drawing-shape.cpp +++ b/src/display/drawing-shape.cpp @@ -34,15 +34,12 @@ namespace Inkscape { DrawingShape::DrawingShape(Drawing &drawing) : DrawingItem(drawing) , _curve(NULL) - , _style(NULL) , _last_pick(NULL) , _repick_after(0) {} DrawingShape::~DrawingShape() { - if (_style) - sp_style_unref(_style); if (_curve) _curve->unref(); } @@ -65,10 +62,17 @@ DrawingShape::setPath(SPCurve *curve) } void -DrawingShape::setStyle(SPStyle *style) +DrawingShape::setStyle(SPStyle *style, SPStyle *context_style) { - _setStyleCommon(_style, style); - _nrstyle.set(style); + DrawingItem::setStyle(style, context_style); // Must be first + _nrstyle.set(_style, _context_style); +} + +void +DrawingShape::setChildrenStyle(SPStyle* context_style) +{ + DrawingItem::setChildrenStyle( context_style ); + _nrstyle.set(_style, _context_style); } unsigned @@ -145,7 +149,6 @@ DrawingShape::_updateItem(Geom::IntRect const &area, UpdateContext const &ctx, u _bbox.unionWith(i->geometricBounds()); } } - return STATE_ALL; } diff --git a/src/display/drawing-shape.h b/src/display/drawing-shape.h index 9d93a642f..1cdbc636e 100644 --- a/src/display/drawing-shape.h +++ b/src/display/drawing-shape.h @@ -28,7 +28,8 @@ public: ~DrawingShape(); void setPath(SPCurve *curve); - void setStyle(SPStyle *style); + virtual void setStyle(SPStyle *style, SPStyle *context_style = NULL); + virtual void setChildrenStyle(SPStyle *context_style); protected: virtual unsigned _updateItem(Geom::IntRect const &area, UpdateContext const &ctx, @@ -45,7 +46,6 @@ protected: DrawingItem *stop_at); SPCurve *_curve; - SPStyle *_style; NRStyle _nrstyle; DrawingItem *_last_pick; diff --git a/src/display/drawing-text.cpp b/src/display/drawing-text.cpp index afe661b2e..e20a7ff2a 100644 --- a/src/display/drawing-text.cpp +++ b/src/display/drawing-text.cpp @@ -55,6 +55,13 @@ DrawingGlyphs::setGlyph(font_instance *font, int glyph, Geom::Affine const &tran _markForUpdate(STATE_ALL, false); } +void +DrawingGlyphs::setStyle(SPStyle * /*style*/, SPStyle * /*context_style*/) +{ + std::cerr << "DrawingGlyphs: Use parent style" << std::endl; +} + + unsigned DrawingGlyphs::_updateItem(Geom::IntRect const &/*area*/, UpdateContext const &ctx, unsigned /*flags*/, unsigned /*reset*/) { DrawingText *ggroup = dynamic_cast<DrawingText *>(_parent); @@ -216,10 +223,17 @@ DrawingText::addComponent(font_instance *font, int glyph, Geom::Affine const &tr } void -DrawingText::setStyle(SPStyle *style) +DrawingText::setStyle(SPStyle *style, SPStyle *context_style) +{ + DrawingGroup::setStyle(style, context_style); // Must be first + _nrstyle.set(_style, _context_style); +} + +void +DrawingText::setChildrenStyle(SPStyle* context_style) { - _nrstyle.set(style); - DrawingGroup::setStyle(style); + DrawingGroup::setChildrenStyle( context_style ); + _nrstyle.set(_style, _context_style); } unsigned diff --git a/src/display/drawing-text.h b/src/display/drawing-text.h index 4453a3db4..3d248df9b 100644 --- a/src/display/drawing-text.h +++ b/src/display/drawing-text.h @@ -28,6 +28,7 @@ public: ~DrawingGlyphs(); void setGlyph(font_instance *font, int glyph, Geom::Affine const &trans); + virtual void setStyle(SPStyle *style, SPStyle *context_style = NULL); // Not to be used protected: unsigned _updateItem(Geom::IntRect const &area, UpdateContext const &ctx, @@ -56,8 +57,8 @@ public: void clear(); bool addComponent(font_instance *font, int glyph, Geom::Affine const &trans, float width, float ascent, float descent, float phase_length); - void setStyle(SPStyle *style); - + virtual void setStyle(SPStyle *style, SPStyle *context_style = NULL); + virtual void setChildrenStyle(SPStyle *context_style); protected: virtual unsigned _updateItem(Geom::IntRect const &area, UpdateContext const &ctx, diff --git a/src/display/drawing.cpp b/src/display/drawing.cpp index 6e728b03d..eadd7e528 100644 --- a/src/display/drawing.cpp +++ b/src/display/drawing.cpp @@ -210,9 +210,9 @@ Drawing::_pickItemsForCaching() } std::set<DrawingItem*> to_cache; - for (i = _candidate_items.begin(); i != _candidate_items.end(); ++i) { - i->item->setCached(true); - to_cache.insert(i->item); + for (CandidateList::iterator j = _candidate_items.begin(); j != i; ++j) { + j->item->setCached(true); + to_cache.insert(j->item); } // Everything which is now in _cached_items but not in to_cache must be uncached // Note that calling setCached on an item modifies _cached_items diff --git a/src/display/nr-filter-primitive.cpp b/src/display/nr-filter-primitive.cpp index b065ac445..c8b569036 100644 --- a/src/display/nr-filter-primitive.cpp +++ b/src/display/nr-filter-primitive.cpp @@ -17,7 +17,7 @@ #include "inkscape.h" #include "desktop.h" -#include "desktop-handles.h" + #include "document.h" #include "sp-root.h" #include "style.h" @@ -171,9 +171,11 @@ Geom::Rect FilterPrimitive::filter_primitive_area(FilterUnits const &units) void FilterPrimitive::setStyle(SPStyle *style) { - if (style) sp_style_ref(style); - if (_style) sp_style_unref(_style); - _style = style; + if( style != _style ) { + if (style) sp_style_ref(style); + if (_style) sp_style_unref(_style); + _style = style; + } } diff --git a/src/display/nr-filter-turbulence.cpp b/src/display/nr-filter-turbulence.cpp index a2a8c5756..19dedb67c 100644 --- a/src/display/nr-filter-turbulence.cpp +++ b/src/display/nr-filter-turbulence.cpp @@ -64,8 +64,10 @@ public: for (i = 0; i < BSize; ++i) { _latticeSelector[i] = i; - _gradient[i][k][0] = static_cast<double>(_random() % (BSize*2) - BSize) / BSize; - _gradient[i][k][1] = static_cast<double>(_random() % (BSize*2) - BSize) / BSize; + do { + _gradient[i][k][0] = static_cast<double>(_random() % (BSize*2) - BSize) / BSize; + _gradient[i][k][1] = static_cast<double>(_random() % (BSize*2) - BSize) / BSize; + } while(_gradient[i][k][0] == 0 && _gradient[i][k][1] == 0); // normalize gradient double s = hypot(_gradient[i][k][0], _gradient[i][k][1]); diff --git a/src/display/nr-filter-utils.cpp b/src/display/nr-filter-utils.cpp deleted file mode 100644 index 1ba341791..000000000 --- a/src/display/nr-filter-utils.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "nr-filter-utils.h" - -namespace Inkscape { -namespace Filters { - -/* Everything moved to .h, because they were short functions that should - * get inlined */ - -} /* namespace Filters */ -} /* namespace Inkscape */ - -/* - 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/display/nr-filter.h b/src/display/nr-filter.h index 9a30efabd..211d8ddd9 100644 --- a/src/display/nr-filter.h +++ b/src/display/nr-filter.h @@ -18,7 +18,7 @@ #include "display/nr-filter-types.h" #include "svg/svg-length.h" #include "sp-filter-units.h" -#include "gc-managed.h" +#include "inkgc/gc-managed.h" namespace Inkscape { class DrawingContext; diff --git a/src/display/nr-style.cpp b/src/display/nr-style.cpp index 96d16bf06..1740785e2 100644 --- a/src/display/nr-style.cpp +++ b/src/display/nr-style.cpp @@ -93,24 +93,47 @@ NRStyle::~NRStyle() text_decoration_stroke.clear(); } -void NRStyle::set(SPStyle *style) +void NRStyle::set(SPStyle *style, SPStyle *context_style) { - if ( style->fill.isPaintserver() ) { + // Handle 'context-fill' and 'context-stroke': Work in progress + const SPIPaint *style_fill = &(style->fill); + if( style_fill->paintOrigin == SP_CSS_PAINT_ORIGIN_CONTEXT_FILL ) { + if( context_style != NULL ) { + style_fill = &(context_style->fill); + } else { + // A marker in the defs section will result in ending up here. + //std::cerr << "NRStyle::set: 'context-fill': 'context_style' is NULL" << std::endl; + } + } else if ( style_fill->paintOrigin == SP_CSS_PAINT_ORIGIN_CONTEXT_STROKE ) { + if( context_style != NULL ) { + style_fill = &(context_style->stroke); + } else { + //std::cerr << "NRStyle::set: 'context-stroke': 'context_style' is NULL" << std::endl; + } + } + + if ( style_fill->isPaintserver() ) { SPPaintServer* server = style->getFillPaintServer(); if ( server && server->isValid() ) { fill.set(server); - } else if ( style->fill.colorSet ) { - fill.set(style->fill.value.color); + } else if ( style_fill->colorSet ) { + fill.set(style_fill->value.color); } else { fill.clear(); } - } else if ( style->fill.isColor() ) { - fill.set(style->fill.value.color); - } else if ( style->fill.isNone() ) { + } else if ( style_fill->isColor() ) { + fill.set(style_fill->value.color); + } else if ( style_fill->isNone() ) { fill.clear(); + } else if ( style_fill->paintOrigin == SP_CSS_PAINT_ORIGIN_CONTEXT_FILL ) { + // A marker in the defs section will result in ending up here. + //std::cerr << "NRStyle::set: fill: context-fill: Double" << std::endl; + } else if ( style_fill->paintOrigin == SP_CSS_PAINT_ORIGIN_CONTEXT_STROKE ) { + //std::cerr << "NRStyle::set: fill: context-stroke: Double" << std::endl; } else { g_assert_not_reached(); } + fill.opacity = SP_SCALE24_TO_FLOAT(style->fill_opacity.value); switch (style->fill_rule.computed) { @@ -124,22 +147,42 @@ void NRStyle::set(SPStyle *style) g_assert_not_reached(); } - if ( style->stroke.isPaintserver() ) { + const SPIPaint *style_stroke = &(style->stroke); + if( style_stroke->paintOrigin == SP_CSS_PAINT_ORIGIN_CONTEXT_FILL ) { + if( context_style != NULL ) { + style_stroke = &(context_style->fill); + } else { + //std::cerr << "NRStyle::set: 'context-fill': 'context_style' is NULL" << std::endl; + } + } else if ( style_stroke->paintOrigin == SP_CSS_PAINT_ORIGIN_CONTEXT_STROKE ) { + if( context_style != NULL ) { + style_stroke = &(context_style->stroke); + } else { + //std::cerr << "NRStyle::set: 'context-stroke': 'context_style' is NULL" << std::endl; + } + } + + if ( style_stroke->isPaintserver() ) { SPPaintServer* server = style->getStrokePaintServer(); if ( server && server->isValid() ) { stroke.set(server); - } else if ( style->stroke.isColor() ) { - stroke.set(style->stroke.colorSet); + } else if ( style_stroke->isColor() ) { + stroke.set(style_stroke->colorSet); } else { stroke.clear(); } - } else if ( style->stroke.isColor() ) { - stroke.set(style->stroke.value.color); - } else if ( style->stroke.isNone() ) { + } else if ( style_stroke->isColor() ) { + stroke.set(style_stroke->value.color); + } else if ( style_stroke->isNone() ) { stroke.clear(); + } else if ( style_stroke->paintOrigin == SP_CSS_PAINT_ORIGIN_CONTEXT_FILL ) { + //std::cerr << "NRStyle::set: stroke: context-fill: Double" << std::endl; + } else if ( style_stroke->paintOrigin == SP_CSS_PAINT_ORIGIN_CONTEXT_STROKE ) { + //std::cerr << "NRStyle::set: stroke: context-stroke: Double" << std::endl; } else { g_assert_not_reached(); } + stroke.opacity = SP_SCALE24_TO_FLOAT(style->stroke_opacity.value); stroke_width = style->stroke_width.computed; switch (style->stroke_linecap.computed) { @@ -266,7 +309,7 @@ void NRStyle::set(SPStyle *style) } else if ( style_td->fill.isNone() ) { text_decoration_fill.clear(); } else { - g_assert_not_reached(); + //g_assert_not_reached(); } if ( style_td->stroke.isPaintserver() ) { @@ -276,7 +319,7 @@ void NRStyle::set(SPStyle *style) } else if ( style_td->stroke.isNone() ) { text_decoration_stroke.clear(); } else { - g_assert_not_reached(); + //g_assert_not_reached(); } } @@ -310,13 +353,16 @@ bool NRStyle::prepareFill(Inkscape::DrawingContext &dc, Geom::OptRect const &pai fill_pattern = pattern->renderPattern(fill.opacity); } else { fill_pattern = fill.server->pattern_new(dc.raw(), paintbox, fill.opacity); - } break; + } + break; case PAINT_COLOR: { SPColor const &c = fill.color; fill_pattern = cairo_pattern_create_rgba( c.v.c[0], c.v.c[1], c.v.c[2], fill.opacity); - } break; - default: break; + } + break; + default: + break; } } if (!fill_pattern) return false; diff --git a/src/display/nr-style.h b/src/display/nr-style.h index f324fdb56..5f78795d3 100644 --- a/src/display/nr-style.h +++ b/src/display/nr-style.h @@ -1,6 +1,7 @@ /** * @file * Style information for rendering. + * Only used by classes DrawingShape and DrawingText *//* * Authors: * Krzysztof Kosiński <tweenk.pl@gmail.com> @@ -28,7 +29,7 @@ struct NRStyle { NRStyle(); ~NRStyle(); - void set(SPStyle *); + void set(SPStyle *style, SPStyle *context_style = NULL); bool prepareFill(Inkscape::DrawingContext &dc, Geom::OptRect const &paintbox, Inkscape::DrawingPattern *pattern); bool prepareStroke(Inkscape::DrawingContext &dc, Geom::OptRect const &paintbox, Inkscape::DrawingPattern *pattern); bool prepareTextDecorationFill(Inkscape::DrawingContext &dc, Geom::OptRect const &paintbox, Inkscape::DrawingPattern *pattern); diff --git a/src/display/snap-indicator.cpp b/src/display/snap-indicator.cpp index 2632d69db..8c0c8163f 100644 --- a/src/display/snap-indicator.cpp +++ b/src/display/snap-indicator.cpp @@ -14,7 +14,7 @@ #include "display/snap-indicator.h" #include "desktop.h" -#include "desktop-handles.h" + #include "display/sodipodi-ctrl.h" #include "display/sodipodi-ctrlrect.h" #include "display/canvas-text.h" @@ -246,7 +246,7 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const &p, bool pre_snap // Display the snap indicator (i.e. the cross) SPCanvasItem * canvasitem = NULL; - canvasitem = sp_canvas_item_new(sp_desktop_tempgroup (_desktop), + canvasitem = sp_canvas_item_new(_desktop->getTempGroup(), SP_TYPE_CTRL, "anchor", SP_ANCHOR_CENTER, "size", 10.0, @@ -256,7 +256,7 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const &p, bool pre_snap "shape", SP_KNOT_SHAPE_CROSS, NULL ); - const int timeout_val = 1200; // TODO add preference for snap indicator timeout? + const int timeout_val = 4000; SP_CTRL(canvasitem)->moveto(p.getPoint()); _snaptarget = _desktop->add_temporary_canvasitem(canvasitem, timeout_val); @@ -280,7 +280,7 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const &p, bool pre_snap tooltip_pos += _desktop->w2d(Geom::Point(0, -2*fontsize)); } - SPCanvasItem *canvas_tooltip = sp_canvastext_new(sp_desktop_tempgroup(_desktop), _desktop, tooltip_pos, tooltip_str); + SPCanvasItem *canvas_tooltip = sp_canvastext_new(_desktop->getTempGroup(), _desktop, tooltip_pos, tooltip_str); sp_canvastext_set_fontsize(SP_CANVASTEXT(canvas_tooltip), fontsize); SP_CANVASTEXT(canvas_tooltip)->rgba = 0xffffffff; SP_CANVASTEXT(canvas_tooltip)->outline = false; @@ -299,7 +299,7 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const &p, bool pre_snap // Display the bounding box, if we snapped to one Geom::OptRect const bbox = p.getTargetBBox(); if (bbox) { - SPCanvasItem* box = sp_canvas_item_new(sp_desktop_tempgroup (_desktop), + SPCanvasItem* box = sp_canvas_item_new(_desktop->getTempGroup(), SP_TYPE_CTRLRECT, NULL); @@ -348,7 +348,7 @@ SnapIndicator::set_new_snapsource(Inkscape::SnapCandidatePoint const &p) bool value = prefs->getBool("/options/snapindicator/value", true); if (value) { - SPCanvasItem * canvasitem = sp_canvas_item_new( sp_desktop_tempgroup (_desktop), + SPCanvasItem * canvasitem = sp_canvas_item_new( _desktop->getTempGroup(), SP_TYPE_CTRL, "anchor", SP_ANCHOR_CENTER, "size", 6.0, @@ -367,7 +367,7 @@ void SnapIndicator::set_new_debugging_point(Geom::Point const &p) { g_assert(_desktop != NULL); - SPCanvasItem * canvasitem = sp_canvas_item_new( sp_desktop_tempgroup (_desktop), + SPCanvasItem * canvasitem = sp_canvas_item_new( _desktop->getTempGroup(), SP_TYPE_CTRL, "anchor", SP_ANCHOR_CENTER, "size", 10.0, diff --git a/src/document-private.h b/src/document-private.h index 8e28b288b..a5033b3c2 100644 --- a/src/document-private.h +++ b/src/document-private.h @@ -75,6 +75,8 @@ struct SPDocumentPrivate { Inkscape::ConsoleOutputUndoObserver console_output_undo_observer; bool seeking; + sigc::connection selChangeConnection; + sigc::connection desktopActivatedConnection; }; #endif // SEEN_SP_DOCUMENT_PRIVATE_H diff --git a/src/document-subset.h b/src/document-subset.h index 298b7872d..2799ff173 100644 --- a/src/document-subset.h +++ b/src/document-subset.h @@ -14,7 +14,7 @@ #include <sigc++/connection.h> #include <sigc++/functors/slot.h> -#include "gc-managed.h" +#include "inkgc/gc-managed.h" #include "gc-anchored.h" class SPObject; diff --git a/src/document-undo.cpp b/src/document-undo.cpp index 15d5d2c70..d4015bafb 100644 --- a/src/document-undo.cpp +++ b/src/document-undo.cpp @@ -99,9 +99,8 @@ void Inkscape::DocumentUndo::done(SPDocument *doc, const unsigned int event_type maybeDone(doc, NULL, event_type, event_description); } -void Inkscape::DocumentUndo::resetKey( InkscapeApplication * /*inkscape*/, SPDesktop * /*desktop*/, GObject *base ) +void Inkscape::DocumentUndo::resetKey( SPDocument *doc ) { - SPDocument *doc = reinterpret_cast<SPDocument *>(base); doc->actionkey.clear(); } @@ -259,7 +258,7 @@ gboolean Inkscape::DocumentUndo::undo(SPDocument *doc) doc->priv->seeking = false; if (ret) - inkscape_external_change(); + INKSCAPE.external_change(); return ret; } @@ -304,7 +303,7 @@ gboolean Inkscape::DocumentUndo::redo(SPDocument *doc) doc->priv->seeking = false; if (ret) - inkscape_external_change(); + INKSCAPE.external_change(); return ret; } diff --git a/src/document-undo.h b/src/document-undo.h index 17b3de252..85b44d562 100644 --- a/src/document-undo.h +++ b/src/document-undo.h @@ -41,7 +41,7 @@ public: static void maybeDone(SPDocument *document, const gchar *keyconst, unsigned int event_type, Glib::ustring const &event_description); - static void resetKey(InkscapeApplication *inkscape, SPDesktop *desktop, GObject *base); + static void resetKey(SPDocument *doc); static void cancel(SPDocument *document); diff --git a/src/document.cpp b/src/document.cpp index 3715d8e6e..62e2f5b46 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -50,7 +50,7 @@ #include "document-private.h" #include "document-undo.h" #include "id-clash.h" -#include "inkscape-private.h" +#include "inkscape.h" #include "inkscape-version.h" #include "libavoid/router.h" #include "persp3d.h" @@ -154,6 +154,14 @@ SPDocument::~SPDocument() { router = NULL; } + if (oldSignalsConnected) { + priv->selChangeConnection.disconnect(); + priv->desktopActivatedConnection.disconnect(); + } else { + _selection_changed_connection.disconnect(); + _desktop_activated_connection.disconnect(); + } + if (priv) { if (priv->partial) { sp_repr_free_log(priv->partial); @@ -208,17 +216,8 @@ SPDocument::~SPDocument() { rerouting_handler_id = 0; } - if (oldSignalsConnected) { - g_signal_handlers_disconnect_by_func(G_OBJECT(INKSCAPE), - reinterpret_cast<gpointer>(DocumentUndo::resetKey), - static_cast<gpointer>(this)); - } else { - _selection_changed_connection.disconnect(); - _desktop_activated_connection.disconnect(); - } - if (keepalive) { - inkscape_unref(); + inkscape_unref(INKSCAPE); keepalive = FALSE; } @@ -369,7 +368,7 @@ SPDocument *SPDocument::createDoc(Inkscape::XML::Document *rdoc, // Create SPRoot element const std::string typeString = NodeTraits::get_type_string(*rroot); - SPObject* rootObj = SPFactory::instance().createObject(typeString); + SPObject* rootObj = SPFactory::createObject(typeString); document->root = dynamic_cast<SPRoot*>(rootObj); if (document->root == 0) { @@ -447,7 +446,7 @@ SPDocument *SPDocument::createDoc(Inkscape::XML::Document *rdoc, rdf_set_defaults( document ); if (keepalive) { - inkscape_ref(); + inkscape_ref(INKSCAPE); } // Check if the document already has a perspective (e.g., when opening an existing @@ -462,10 +461,14 @@ SPDocument *SPDocument::createDoc(Inkscape::XML::Document *rdoc, DocumentUndo::setUndoSensitive(document, true); // reset undo key when selection changes, so that same-key actions on different objects are not coalesced - g_signal_connect(G_OBJECT(INKSCAPE), "change_selection", - G_CALLBACK(DocumentUndo::resetKey), document); - g_signal_connect(G_OBJECT(INKSCAPE), "activate_desktop", - G_CALLBACK(DocumentUndo::resetKey), document); + document->priv->selChangeConnection = INKSCAPE.signal_selection_changed.connect( + sigc::hide(sigc::bind( + sigc::ptr_fun(&DocumentUndo::resetKey), document) + )); + document->priv->desktopActivatedConnection = INKSCAPE.signal_activate_desktop.connect( + sigc::hide(sigc::bind( + sigc::ptr_fun(&DocumentUndo::resetKey), document) + )); document->oldSignalsConnected = true; return document; @@ -593,20 +596,97 @@ SPDocument *SPDocument::doUnref() } /// guaranteed not to return nullptr -Inkscape::Util::Unit const* SPDocument::getDefaultUnit() const +Inkscape::Util::Unit const* SPDocument::getDisplayUnit() const { SPNamedView const* nv = sp_document_namedview(this, NULL); - return nv ? nv->getDefaultUnit() : unit_table.getUnit("pt"); + return nv ? nv->getDisplayUnit() : unit_table.getUnit("px"); } /// guaranteed not to return nullptr // returns 'px' units as default, like legacy Inkscape +// THIS SHOULD NOT BE USED... INSTEAD USE DOCUMENT SCALE Inkscape::Util::Unit const& SPDocument::getSVGUnit() const { SPNamedView const* nv = sp_document_namedview(this, NULL); return nv ? nv->getSVGUnit() : *unit_table.getUnit("px"); } +/// Sets document scale (by changing viewBox) +void SPDocument::setDocumentScale( double scaleX, double scaleY ) { + + root->viewBox = Geom::Rect::from_xywh( + root->viewBox.left(), + root->viewBox.top(), + root->width.computed * scaleX, + root->height.computed * scaleY ); + root->viewBox_set = true; + root->updateRepr(); +} + +/// Sets document scale (by changing viewBox, x and y scaling equal) +void SPDocument::setDocumentScale( double scale ) { + setDocumentScale( scale, scale ); +} + +/// Returns document scale as defined by width/height (in pixels) and viewBox (real world to +/// user-units). +Geom::Scale SPDocument::getDocumentScale() const +{ + Geom::Scale scale; + if( root->viewBox_set ) { + double scale_x = 1.0; + double scale_y = 1.0; + if( root->viewBox.width() > 0.0 ) { + scale_x = root->width.computed / root->viewBox.width(); + } + if( root->viewBox.height() > 0.0 ) { + scale_y = root->height.computed / root->viewBox.height(); + } + scale = Geom::Scale(scale_x, scale_y); + } + // std::cout << "SPDocument::getDocumentScale():\n" << scale << std::endl; + return scale; +} + +// Avoid calling root->updateRepr() twice by combining setting width and height. +// (As done on every delete as clipboard calls this via fitToRect(). Also called in page-sizer.cpp) +void SPDocument::setWidthAndHeight(const Inkscape::Util::Quantity &width, const Inkscape::Util::Quantity &height, bool changeSize) +{ + Inkscape::Util::Unit const *old_width_units = unit_table.getUnit("px"); + if (root->width.unit) + old_width_units = unit_table.getUnit(root->width.unit); + gdouble old_width_converted; // old width converted to new units + if (root->width.unit == SVGLength::PERCENT) + old_width_converted = Inkscape::Util::Quantity::convert(root->width.computed, "px", width.unit); + else + old_width_converted = Inkscape::Util::Quantity::convert(root->width.value, old_width_units, width.unit); + + root->width.computed = width.value("px"); + root->width.value = width.quantity; + root->width.unit = (SVGLength::Unit) width.unit->svgUnit(); + + Inkscape::Util::Unit const *old_height_units = unit_table.getUnit("px"); + if (root->height.unit) + old_height_units = unit_table.getUnit(root->height.unit); + gdouble old_height_converted; // old height converted to new units + if (root->height.unit == SVGLength::PERCENT) + old_height_converted = Inkscape::Util::Quantity::convert(root->height.computed, "px", height.unit); + else + old_height_converted = Inkscape::Util::Quantity::convert(root->height.value, old_height_units, height.unit); + + root->height.computed = height.value("px"); + root->height.value = height.quantity; + root->height.unit = (SVGLength::Unit) height.unit->svgUnit(); + + // viewBox scaled by relative change in page size (maintains document scale). + if (root->viewBox_set && changeSize) { + root->viewBox.setMax(Geom::Point( + root->viewBox.left() + (root->width.value / old_width_converted ) * root->viewBox.width(), + root->viewBox.top() + (root->height.value / old_height_converted) * root->viewBox.height())); + } + root->updateRepr(); +} + Inkscape::Util::Quantity SPDocument::getWidth() const { g_return_val_if_fail(this->priv != NULL, Inkscape::Util::Quantity(0.0, unit_table.getUnit(""))); @@ -624,25 +704,23 @@ Inkscape::Util::Quantity SPDocument::getWidth() const return Inkscape::Util::Quantity(result, unit_table.getUnit(u)); } -void SPDocument::setWidth(const Inkscape::Util::Quantity &width) +void SPDocument::setWidth(const Inkscape::Util::Quantity &width, bool changeSize) { - Inkscape::Util::Unit const *old_units = unit_table.getUnit("px"); + Inkscape::Util::Unit const *old_width_units = unit_table.getUnit("px"); if (root->width.unit) - old_units = unit_table.getUnit(root->width.unit); - gdouble old_converted = Inkscape::Util::Quantity::convert(root->width.value, old_units, width.unit); + old_width_units = unit_table.getUnit(root->width.unit); + gdouble old_width_converted; // old width converted to new units + if (root->width.unit == SVGLength::PERCENT) + old_width_converted = Inkscape::Util::Quantity::convert(root->width.computed, "px", width.unit); + else + old_width_converted = Inkscape::Util::Quantity::convert(root->width.value, old_width_units, width.unit); + root->width.computed = width.value("px"); - /* SVG does not support meters as a unit, so we must translate meters to - * cm when writing */ - if (*width.unit == *unit_table.getUnit("m")) { - root->width.value = width.value("cm"); - root->width.unit = SVGLength::CM; - } else { - root->width.value = width.quantity; - root->width.unit = (SVGLength::Unit) width.unit->svgUnit(); - } + root->width.value = width.quantity; + root->width.unit = (SVGLength::Unit) width.unit->svgUnit(); - if (root->viewBox_set) - root->viewBox.setMax(Geom::Point(root->viewBox.left() + (root->width.value / old_converted) * root->viewBox.width(), root->viewBox.bottom())); + if (root->viewBox_set && changeSize) + root->viewBox.setMax(Geom::Point(root->viewBox.left() + (root->width.value / old_width_converted) * root->viewBox.width(), root->viewBox.bottom())); root->updateRepr(); } @@ -665,25 +743,23 @@ Inkscape::Util::Quantity SPDocument::getHeight() const return Inkscape::Util::Quantity(result, unit_table.getUnit(u)); } -void SPDocument::setHeight(const Inkscape::Util::Quantity &height) +void SPDocument::setHeight(const Inkscape::Util::Quantity &height, bool changeSize) { - Inkscape::Util::Unit const *old_units = unit_table.getUnit("px"); + Inkscape::Util::Unit const *old_height_units = unit_table.getUnit("px"); if (root->height.unit) - old_units = unit_table.getUnit(root->height.unit); - gdouble old_converted = Inkscape::Util::Quantity::convert(root->height.value, old_units, height.unit); + old_height_units = unit_table.getUnit(root->height.unit); + gdouble old_height_converted; // old height converted to new units + if (root->height.unit == SVGLength::PERCENT) + old_height_converted = Inkscape::Util::Quantity::convert(root->height.computed, "px", height.unit); + else + old_height_converted = Inkscape::Util::Quantity::convert(root->height.value, old_height_units, height.unit); + root->height.computed = height.value("px"); - /* SVG does not support meters as a unit, so we must translate meters to - * cm when writing */ - if (*height.unit == *unit_table.getUnit("m")) { - root->height.value = height.value("cm"); - root->height.unit = SVGLength::CM; - } else { - root->height.value = height.quantity; - root->height.unit = (SVGLength::Unit) height.unit->svgUnit(); - } + root->height.value = height.quantity; + root->height.unit = (SVGLength::Unit) height.unit->svgUnit(); - if (root->viewBox_set) - root->viewBox.setMax(Geom::Point(root->viewBox.right(), root->viewBox.top() + (root->height.value / old_converted) * root->viewBox.height())); + if (root->viewBox_set && changeSize) + root->viewBox.setMax(Geom::Point(root->viewBox.right(), root->viewBox.top() + (root->height.value / old_height_converted) * root->viewBox.height())); root->updateRepr(); } @@ -721,7 +797,7 @@ void SPDocument::fitToRect(Geom::Rect const &rect, bool with_margins) double const old_height = getHeight().value("px"); Inkscape::Util::Unit const *nv_units = unit_table.getUnit("px"); - if (root->height.unit) + if (root->height.unit && (root->height.unit != SVGLength::PERCENT)) nv_units = unit_table.getUnit(root->height.unit); SPNamedView *nv = sp_document_namedview(this, NULL); @@ -748,9 +824,10 @@ void SPDocument::fitToRect(Geom::Rect const &rect, bool with_margins) rect.min() - Geom::Point(margin_left, margin_bottom), rect.max() + Geom::Point(margin_right, margin_top)); - - setWidth(Inkscape::Util::Quantity(Inkscape::Util::Quantity::convert(rect_with_margins.width(), "px", nv_units), nv_units)); - setHeight(Inkscape::Util::Quantity(Inkscape::Util::Quantity::convert(rect_with_margins.height(), "px", nv_units), nv_units)); + setWidthAndHeight( + Inkscape::Util::Quantity(Inkscape::Util::Quantity::convert(rect_with_margins.width(), "px", nv_units), nv_units), + Inkscape::Util::Quantity(Inkscape::Util::Quantity::convert(rect_with_margins.height(), "px", nv_units), nv_units) + ); Geom::Translate const tr( Geom::Point(0, old_height - rect_with_margins.height()) diff --git a/src/document.h b/src/document.h index 065c5f323..ed19d123b 100644 --- a/src/document.h +++ b/src/document.h @@ -21,7 +21,7 @@ #include <sigc++/sigc++.h> #include "libcroco/cr-cascade.h" #include <2geom/forward.h> -#include "gc-managed.h" +#include "inkgc/gc-managed.h" #include "gc-finalized.h" #include "gc-anchored.h" #include <glibmm/ustring.h> @@ -38,7 +38,6 @@ class SPGroup; class SPRoot; namespace Inkscape { - struct Application; class Selection; class UndoStackObserver; class EventLog; @@ -241,14 +240,18 @@ public: SPDocument *doRef(); SPDocument *doUnref(); - Inkscape::Util::Unit const* getDefaultUnit() const; + Inkscape::Util::Unit const* getDisplayUnit() const; Inkscape::Util::Unit const& getSVGUnit() const; + void setDocumentScale( const double scaleX, const double scaleY ); + void setDocumentScale( const double scale ); + Geom::Scale getDocumentScale() const; Inkscape::Util::Quantity getWidth() const; Inkscape::Util::Quantity getHeight() const; Geom::Point getDimensions() const; Geom::OptRect preferredBounds() const; - void setWidth(const Inkscape::Util::Quantity &width); - void setHeight(const Inkscape::Util::Quantity &height); + void setWidthAndHeight(const Inkscape::Util::Quantity &width, const Inkscape::Util::Quantity &height, bool changeSize=true); + void setWidth(const Inkscape::Util::Quantity &width, bool changeSize=true); + void setHeight(const Inkscape::Util::Quantity &height, bool changeSize=true); void setViewBox(const Geom::Rect &viewBox); void requestModified(); int ensureUpToDate(); diff --git a/src/doxygen-main.cpp b/src/doxygen-main.dox index 6a5723bfd..6a5723bfd 100644 --- a/src/doxygen-main.cpp +++ b/src/doxygen-main.dox diff --git a/src/extension/dbus/application-interface.cpp b/src/extension/dbus/application-interface.cpp index c0bc19d90..afaf9aedf 100644 --- a/src/extension/dbus/application-interface.cpp +++ b/src/extension/dbus/application-interface.cpp @@ -49,7 +49,7 @@ application_interface_init (ApplicationInterface *app_interface) static bool ensure_desktop_valid(GError **error) { - if (!inkscape_use_gui()) { + if (!INKSCAPE.use_gui()) { g_set_error(error, INKSCAPE_ERROR, INKSCAPE_ERROR_OTHER, "Application interface action requires a GUI"); return false; } @@ -59,7 +59,7 @@ ensure_desktop_valid(GError **error) static bool ensure_desktop_not_present(GError **error) { - if (inkscape_use_gui()) { + if (INKSCAPE.use_gui()) { g_set_error(error, INKSCAPE_ERROR, INKSCAPE_ERROR_OTHER, "Application interface action requires non-GUI (command line) mode"); return false; } @@ -196,7 +196,7 @@ application_interface_document_close_all (ApplicationInterface *app_interface, SPDesktop *desktop = SP_ACTIVE_DESKTOP; g_assert(desktop != NULL); - SPDocument *doc = sp_desktop_document(desktop); + SPDocument *doc = desktop->getDocument(); g_assert(doc != NULL); Inkscape::XML::Node *repr = doc->getReprRoot(); diff --git a/src/extension/dbus/dbus-init.cpp b/src/extension/dbus/dbus-init.cpp index 19b48e10d..43830762c 100644 --- a/src/extension/dbus/dbus-init.cpp +++ b/src/extension/dbus/dbus-init.cpp @@ -153,23 +153,23 @@ gchar * init_document (void) { // This is for command-line use only - g_assert(!inkscape_use_gui()); + g_assert(!INKSCAPE.use_gui()); // Create a blank document and get its selection model etc in an ActionContext SPDocument *doc = SPDocument::createNewDoc(NULL, 1, TRUE); - inkscape_add_document(doc); - return dbus_register_document(inkscape_action_context_for_document(doc)); + INKSCAPE.add_document(doc); + return dbus_register_document(INKSCAPE.action_context_for_document(doc)); } gchar * init_active_document() { - SPDocument *doc = inkscape_active_document(); + SPDocument *doc = INKSCAPE.active_document(); if (!doc) { return NULL; } - return dbus_register_document(inkscape_active_action_context()); + return dbus_register_document(INKSCAPE.active_action_context()); } gchar * diff --git a/src/extension/dbus/document-interface.cpp b/src/extension/dbus/document-interface.cpp index e3452f4ce..4fde6885f 100644 --- a/src/extension/dbus/document-interface.cpp +++ b/src/extension/dbus/document-interface.cpp @@ -21,7 +21,7 @@ #include <string.h> #include <dbus/dbus-glib.h> #include "desktop.h" -#include "desktop-handles.h" //sp_desktop_document() + //sp_desktop_document() #include "desktop-style.h" //sp_desktop_get_style #include "display/canvas-text.h" //text #include "display/sp-canvas.h" //text @@ -156,7 +156,7 @@ get_name_from_object (SPObject * obj) void desktop_ensure_active (SPDesktop* desk) { if (desk != SP_ACTIVE_DESKTOP) - inkscape_activate_desktop (desk); + INKSCAPE.activate_desktop (desk); return; } diff --git a/src/extension/effect.cpp b/src/extension/effect.cpp index 3c8ee5844..e7299ba51 100644 --- a/src/extension/effect.cpp +++ b/src/extension/effect.cpp @@ -9,10 +9,10 @@ */ #include "prefdialog.h" -#include "inkscape-private.h" +#include "inkscape.h" #include "helper/action.h" #include "ui/view/view.h" -#include "desktop-handles.h" + #include "selection.h" #include "sp-namedview.h" #include "desktop.h" @@ -89,11 +89,13 @@ Effect::Effect (Inkscape::XML::Node * in_repr, Implementation::Implementation * } // children of "inkscape-extension" } // if we have an XML file - if (INKSCAPE != NULL && inkscape_use_gui()) { + // \TODO this gets called from the Inkscape::Application constructor, where it initializes the menus. + // But in the constructor, our object isn't quite there yet! + if (Inkscape::Application::exists() && INKSCAPE.use_gui()) { if (_effects_list == NULL) - _effects_list = find_menu(inkscape_get_menus(INKSCAPE), EFFECTS_LIST); + _effects_list = find_menu(INKSCAPE.get_menus(), EFFECTS_LIST); if (_filters_list == NULL) - _filters_list = find_menu(inkscape_get_menus(INKSCAPE), FILTERS_LIST); + _filters_list = find_menu(INKSCAPE.get_menus(), FILTERS_LIST); } if ((_effects_list != NULL || _filters_list != NULL)) { diff --git a/src/extension/error-file.cpp b/src/extension/error-file.cpp index f60af870f..db354c0ce 100644 --- a/src/extension/error-file.cpp +++ b/src/extension/error-file.cpp @@ -48,9 +48,10 @@ ErrorFileNotice::ErrorFileNotice (void) : ) { + // \FIXME change this /* This is some filler text, needs to change before relase */ Glib::ustring dialog_text(_("<span weight=\"bold\" size=\"larger\">One or more extensions failed to load</span>\n\nThe failed extensions have been skipped. Inkscape will continue to run normally but those extensions will be unavailable. For details to troubleshoot this problem, please refer to the error log located at: ")); - gchar * ext_error_file = profile_path(EXTENSION_ERROR_LOG_FILENAME); + gchar * ext_error_file = Inkscape::Application::profile_path(EXTENSION_ERROR_LOG_FILENAME); dialog_text += ext_error_file; g_free(ext_error_file); set_message(dialog_text, true); diff --git a/src/extension/execution-env.cpp b/src/extension/execution-env.cpp index d4b5fd187..13b8d60c4 100644 --- a/src/extension/execution-env.cpp +++ b/src/extension/execution-env.cpp @@ -31,7 +31,7 @@ #include "desktop.h" #include "ui/view/view.h" #include "sp-namedview.h" -#include "desktop-handles.h" + #include "display/sp-canvas.h" #include "util/glib-list-iterators.h" @@ -65,7 +65,7 @@ ExecutionEnv::ExecutionEnv (Effect * effect, Inkscape::UI::View::View * doc, Imp if (desktop != NULL) { Inkscape::Util::GSListConstIterator<SPItem *> selected = - sp_desktop_selection(desktop)->itemList(); + desktop->getSelection()->itemList(); while ( selected != NULL ) { Glib::ustring selected_id; selected_id = (*selected)->getId(); @@ -200,7 +200,7 @@ ExecutionEnv::reselect (void) { if (desktop == NULL) { return; } - Inkscape::Selection * selection = sp_desktop_selection(desktop); + Inkscape::Selection * selection = desktop->getSelection(); for (std::list<Glib::ustring>::iterator i = _selected.begin(); i != _selected.end(); ++i) { SPObject * obj = doc->getObjectById(i->c_str()); diff --git a/src/extension/extension.cpp b/src/extension/extension.cpp index 6a22eb585..3d0f49a20 100644 --- a/src/extension/extension.cpp +++ b/src/extension/extension.cpp @@ -667,7 +667,7 @@ Extension::set_param_color (const gchar * name, guint32 color, SPDocument * doc, void Extension::error_file_open (void) { - gchar * ext_error_file = profile_path(EXTENSION_ERROR_LOG_FILENAME); + gchar * ext_error_file = Inkscape::Application::profile_path(EXTENSION_ERROR_LOG_FILENAME); gchar * filename = g_filename_from_utf8( ext_error_file, -1, NULL, NULL, NULL ); error_file.open(filename); if (!error_file.is_open()) { diff --git a/src/extension/implementation/implementation.cpp b/src/extension/implementation/implementation.cpp index 6f6bddb93..52f63499a 100644 --- a/src/extension/implementation/implementation.cpp +++ b/src/extension/implementation/implementation.cpp @@ -21,7 +21,7 @@ #include "selection.h" #include "desktop.h" -#include "desktop-handles.h" + #include "ui/view/view.h" #include "util/glib-list-iterators.h" @@ -48,8 +48,8 @@ Gtk::Widget *Implementation::prefs_effect(Inkscape::Extension::Effect *module, I SPDocument * current_document = view->doc(); using Inkscape::Util::GSListConstIterator; - GSListConstIterator<SPItem *> selected = - sp_desktop_selection((SPDesktop *)view)->itemList(); + // FIXME very unsafe cast + GSListConstIterator<SPItem *> selected = ((SPDesktop *)view)->getSelection()->itemList(); Inkscape::XML::Node const* first_select = NULL; if (selected != NULL) { const SPItem * item = *selected; diff --git a/src/extension/implementation/script.cpp b/src/extension/implementation/script.cpp index 99c882a01..bbc567f75 100644 --- a/src/extension/implementation/script.cpp +++ b/src/extension/implementation/script.cpp @@ -24,7 +24,7 @@ #include <errno.h> #include <glib/gstdio.h> -#include "desktop-handles.h" + #include "desktop.h" #include "ui/dialog-events.h" #include "extension/effect.h" @@ -690,7 +690,7 @@ void Script::effect(Inkscape::Extension::Effect *module, } Inkscape::Util::GSListConstIterator<SPItem *> selected = - sp_desktop_selection(desktop)->itemList(); //desktop should not be NULL since doc was checked and desktop is a casted pointer + desktop->getSelection()->itemList(); //desktop should not be NULL since doc was checked and desktop is a casted pointer while ( selected != NULL ) { Glib::ustring selected_id; selected_id += "--id="; @@ -1051,7 +1051,7 @@ int Script::execute (const std::list<std::string> &in_command, Glib::ustring stderr_data = fileerr.string(); if (stderr_data.length() != 0 && - inkscape_use_gui() + INKSCAPE.use_gui() ) { checkStderr(stderr_data, Gtk::MESSAGE_INFO, _("Inkscape has received additional data from the script executed. " diff --git a/src/extension/init.cpp b/src/extension/init.cpp index 912d58a13..c16a5a899 100644 --- a/src/extension/init.cpp +++ b/src/extension/init.cpp @@ -243,7 +243,7 @@ init() /* Load search path for extensions */ if (Inkscape::Extension::Extension::search_path.size() == 0) { - Inkscape::Extension::Extension::search_path.push_back(profile_path("extensions")); + Inkscape::Extension::Extension::search_path.push_back(Inkscape::Application::profile_path("extensions")); Inkscape::Extension::Extension::search_path.push_back(g_strdup(INKSCAPE_EXTENSIONDIR)); diff --git a/src/extension/internal/bitmap/imagemagick.cpp b/src/extension/internal/bitmap/imagemagick.cpp index 0d47240d4..76f35415e 100644 --- a/src/extension/internal/bitmap/imagemagick.cpp +++ b/src/extension/internal/bitmap/imagemagick.cpp @@ -25,7 +25,7 @@ #include <glib/gstdio.h> #include "desktop.h" -#include "desktop-handles.h" + #include "selection.h" #include "sp-object.h" #include "util/glib-list-iterators.h" @@ -242,7 +242,9 @@ ImageMagick::prefs_effect(Inkscape::Extension::Effect *module, Inkscape::UI::Vie SPDocument * current_document = view->doc(); using Inkscape::Util::GSListConstIterator; - GSListConstIterator<SPItem *> selected = sp_desktop_selection((SPDesktop *)view)->itemList(); + + // FIXME very unsafe cast + GSListConstIterator<SPItem *> selected = ((SPDesktop *)view)->getSelection()->itemList(); Inkscape::XML::Node * first_select = NULL; if (selected != NULL) { first_select = (*selected)->getRepr(); diff --git a/src/extension/internal/cairo-ps-out.cpp b/src/extension/internal/cairo-ps-out.cpp index d1511ba84..5dc412301 100644 --- a/src/extension/internal/cairo-ps-out.cpp +++ b/src/extension/internal/cairo-ps-out.cpp @@ -146,12 +146,12 @@ CairoPsOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar con bool new_textToPath = FALSE; try { - new_textToPath = mod->get_param_bool("textToPath"); + new_textToPath = (strcmp(mod->get_param_optiongroup("textToPath"), "paths") == 0); } catch(...) {} bool new_textToLaTeX = FALSE; try { - new_textToLaTeX = mod->get_param_bool("textToLaTeX"); + new_textToLaTeX = (strcmp(mod->get_param_optiongroup("textToPath"), "LaTeX") == 0); } catch(...) { g_warning("Parameter <textToLaTeX> might not exist"); @@ -169,14 +169,14 @@ CairoPsOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar con bool new_areaPage = true; try { - new_areaPage = (strcmp(ext->get_param_optiongroup("area"), "page") == 0); + new_areaPage = (strcmp(mod->get_param_optiongroup("area"), "page") == 0); } catch(...) {} bool new_areaDrawing = !new_areaPage; float bleedmargin_px = 0.; try { - bleedmargin_px = ext->get_param_float("bleed"); + bleedmargin_px = mod->get_param_float("bleed"); } catch(...) {} const gchar *new_exportId = NULL; @@ -221,7 +221,7 @@ CairoEpsOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar co Inkscape::Extension::Extension * ext; unsigned int ret; - ext = Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_PS); + ext = Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_EPS); if (ext == NULL) return; @@ -235,12 +235,12 @@ CairoEpsOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar co bool new_textToPath = FALSE; try { - new_textToPath = mod->get_param_bool("textToPath"); + new_textToPath = (strcmp(mod->get_param_optiongroup("textToPath"), "paths") == 0); } catch(...) {} bool new_textToLaTeX = FALSE; try { - new_textToLaTeX = mod->get_param_bool("textToLaTeX"); + new_textToLaTeX = (strcmp(mod->get_param_optiongroup("textToPath"), "LaTeX") == 0); } catch(...) { g_warning("Parameter <textToLaTeX> might not exist"); @@ -258,14 +258,14 @@ CairoEpsOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar co bool new_areaPage = true; try { - new_areaPage = (strcmp(ext->get_param_optiongroup("area"), "page") == 0); + new_areaPage = (strcmp(mod->get_param_optiongroup("area"), "page") == 0); } catch(...) {} bool new_areaDrawing = !new_areaPage; float bleedmargin_px = 0.; try { - bleedmargin_px = ext->get_param_float("bleed"); + bleedmargin_px = mod->get_param_float("bleed"); } catch(...) {} const gchar *new_exportId = NULL; @@ -330,8 +330,11 @@ CairoPsOutput::init (void) "<_item value='PS3'>" N_("PostScript level 3") "</_item>\n" "<_item value='PS2'>" N_("PostScript level 2") "</_item>\n" "</param>\n" - "<param name=\"textToPath\" gui-text=\"" N_("Convert texts to paths") "\" type=\"boolean\">false</param>\n" - "<param name=\"textToLaTeX\" gui-text=\"" N_("PS+LaTeX: Omit text in PS, and create LaTeX file") "\" type=\"boolean\">false</param>\n" + "<param name=\"textToPath\" gui-text=\"" N_("Text output options:") "\" type=\"optiongroup\">\n" + "<option value=\"embed\">" N_("Embed fonts") "</option>\n" + "<option value=\"paths\">" N_("Convert text to paths") "</option>\n" + "<option value=\"LaTeX\">" N_("Omit text in PDF and create LaTeX file") "</option>\n" + "</param>\n" "<param name=\"blurToBitmap\" gui-text=\"" N_("Rasterize filter effects") "\" type=\"boolean\">true</param>\n" "<param name=\"resolution\" gui-text=\"" N_("Resolution for rasterization (dpi):") "\" type=\"int\" min=\"1\" max=\"10000\">96</param>\n" "<param name=\"area\" gui-text=\"" N_("Output page size") "\" type=\"optiongroup\" >\n" @@ -369,8 +372,11 @@ CairoEpsOutput::init (void) "<_item value='PS3'>" N_("PostScript level 3") "</_item>\n" "<_item value='PS2'>" N_("PostScript level 2") "</_item>\n" "</param>\n" - "<param name=\"textToPath\" gui-text=\"" N_("Convert texts to paths") "\" type=\"boolean\">false</param>\n" - "<param name=\"textToLaTeX\" gui-text=\"" N_("EPS+LaTeX: Omit text in EPS, and create LaTeX file") "\" type=\"boolean\">false</param>\n" + "<param name=\"textToPath\" gui-text=\"" N_("Text output options:") "\" type=\"optiongroup\">\n" + "<option value=\"embed\">" N_("Embed fonts") "</option>\n" + "<option value=\"paths\">" N_("Convert text to paths") "</option>\n" + "<option value=\"LaTeX\">" N_("Omit text in PDF and create LaTeX file") "</option>\n" + "</param>\n" "<param name=\"blurToBitmap\" gui-text=\"" N_("Rasterize filter effects") "\" type=\"boolean\">true</param>\n" "<param name=\"resolution\" gui-text=\"" N_("Resolution for rasterization (dpi):") "\" type=\"int\" min=\"1\" max=\"10000\">96</param>\n" "<param name=\"area\" gui-text=\"" N_("Output page size") "\" type=\"optiongroup\" >\n" diff --git a/src/extension/internal/cairo-render-context.cpp b/src/extension/internal/cairo-render-context.cpp index d76c187a2..2d6619e1e 100644 --- a/src/extension/internal/cairo-render-context.cpp +++ b/src/extension/internal/cairo-render-context.cpp @@ -42,6 +42,7 @@ #include "sp-hatch.h" #include "sp-linear-gradient.h" #include "sp-radial-gradient.h" +#include "sp-mesh.h" #include "sp-pattern.h" #include "sp-mask.h" #include "sp-clippath.h" @@ -1259,6 +1260,10 @@ CairoRenderContext::_createPatternForPaintServer(SPPaintServer const *const pain sp_color_get_rgb_floatv(&rg->vector.stops[i].color, rgb); cairo_pattern_add_color_stop_rgba(pattern, rg->vector.stops[i].offset, rgb[0], rgb[1], rgb[2], rg->vector.stops[i].opacity * alpha); } + } else if (SP_IS_MESH (paintserver)) { + SPMesh *mg = SP_MESH(paintserver); + + pattern = mg->pattern_new(_cr, pbox, 1.0); } else if (SP_IS_PATTERN (paintserver)) { pattern = _createPatternPainter(paintserver, pbox); } else if ( dynamic_cast<SPHatch const *>(paintserver) ) { diff --git a/src/extension/internal/cairo-renderer-pdf-out.cpp b/src/extension/internal/cairo-renderer-pdf-out.cpp index 0c4ad4f0a..e5c9406c9 100644 --- a/src/extension/internal/cairo-renderer-pdf-out.cpp +++ b/src/extension/internal/cairo-renderer-pdf-out.cpp @@ -149,7 +149,7 @@ CairoRendererPdfOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, bool new_textToPath = FALSE; try { - new_textToPath = mod->get_param_bool("textToPath"); + new_textToPath = (strcmp(mod->get_param_optiongroup("textToPath"), "paths") == 0); } catch(...) { g_warning("Parameter <textToPath> might not exist"); @@ -157,7 +157,7 @@ CairoRendererPdfOutput::save(Inkscape::Extension::Output *mod, SPDocument *doc, bool new_textToLaTeX = FALSE; try { - new_textToLaTeX = mod->get_param_bool("textToLaTeX"); + new_textToLaTeX = (strcmp(mod->get_param_optiongroup("textToPath"), "LaTeX") == 0); } catch(...) { g_warning("Parameter <textToLaTeX> might not exist"); @@ -247,8 +247,11 @@ CairoRendererPdfOutput::init (void) #endif "<_item value='PDF-1.4'>" N_("PDF 1.4") "</_item>\n" "</param>\n" - "<param name=\"textToPath\" gui-text=\"" N_("Convert texts to paths") "\" type=\"boolean\">false</param>\n" - "<param name=\"textToLaTeX\" gui-text=\"" N_("PDF+LaTeX: Omit text in PDF, and create LaTeX file") "\" type=\"boolean\">false</param>\n" + "<param name=\"textToPath\" gui-text=\"" N_("Text output options:") "\" type=\"optiongroup\">\n" + "<option value=\"embed\">" N_("Embed fonts") "</option>\n" + "<option value=\"paths\">" N_("Convert text to paths") "</option>\n" + "<option value=\"LaTeX\">" N_("Omit text in PDF and create LaTeX file") "</option>\n" + "</param>\n" "<param name=\"blurToBitmap\" gui-text=\"" N_("Rasterize filter effects") "\" type=\"boolean\">true</param>\n" "<param name=\"resolution\" gui-text=\"" N_("Resolution for rasterization (dpi):") "\" type=\"int\" min=\"1\" max=\"10000\">96</param>\n" "<param name=\"area\" gui-text=\"" N_("Output page size:") "\" type=\"optiongroup\" >\n" diff --git a/src/extension/internal/cairo-renderer.cpp b/src/extension/internal/cairo-renderer.cpp index 5a9a28ef9..7fbdc4296 100644 --- a/src/extension/internal/cairo-renderer.cpp +++ b/src/extension/internal/cairo-renderer.cpp @@ -206,7 +206,7 @@ static void sp_shape_render(SPShape *shape, CairoRenderContext *ctx) } else if (marker->orient_mode == MARKER_ORIENT_AUTO_START_REVERSE) { tr = Geom::Rotate::from_degrees( 180.0 ) * sp_shape_marker_get_transform_at_start(pathv.begin()->front()); } else { - tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(pathv.begin()->front().pointAt(0)); + tr = Geom::Rotate::from_degrees(marker->orient.computed) * Geom::Translate(pathv.begin()->front().pointAt(0)); } sp_shape_render_invoke_marker_rendering(marker, tr, style, ctx); } @@ -224,7 +224,7 @@ static void sp_shape_render(SPShape *shape, CairoRenderContext *ctx) if (marker->orient_mode != MARKER_ORIENT_ANGLE) { tr = sp_shape_marker_get_transform_at_start(path_it->front()); } else { - tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(path_it->front().pointAt(0)); + tr = Geom::Rotate::from_degrees(marker->orient.computed) * Geom::Translate(path_it->front().pointAt(0)); } sp_shape_render_invoke_marker_rendering(marker, tr, style, ctx); } @@ -241,7 +241,7 @@ static void sp_shape_render(SPShape *shape, CairoRenderContext *ctx) if (marker->orient_mode != MARKER_ORIENT_ANGLE) { tr = sp_shape_marker_get_transform(*curve_it1, *curve_it2); } else { - tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(curve_it1->pointAt(1)); + tr = Geom::Rotate::from_degrees(marker->orient.computed) * Geom::Translate(curve_it1->pointAt(1)); } sp_shape_render_invoke_marker_rendering(marker, tr, style, ctx); @@ -257,7 +257,7 @@ static void sp_shape_render(SPShape *shape, CairoRenderContext *ctx) if (marker->orient_mode != MARKER_ORIENT_ANGLE) { tr = sp_shape_marker_get_transform_at_end(lastcurve); } else { - tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(lastcurve.pointAt(1)); + tr = Geom::Rotate::from_degrees(marker->orient.computed) * Geom::Translate(lastcurve.pointAt(1)); } sp_shape_render_invoke_marker_rendering(marker, tr, style, ctx); } @@ -281,7 +281,7 @@ static void sp_shape_render(SPShape *shape, CairoRenderContext *ctx) if (marker->orient_mode != MARKER_ORIENT_ANGLE) { tr = sp_shape_marker_get_transform_at_end(lastcurve); } else { - tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(lastcurve.pointAt(1)); + tr = Geom::Rotate::from_degrees(marker->orient.computed) * Geom::Translate(lastcurve.pointAt(1)); } sp_shape_render_invoke_marker_rendering(marker, tr, style, ctx); @@ -517,7 +517,7 @@ static void sp_item_invoke_render(SPItem *item, CairoRenderContext *ctx) SPStyle* style = item->style; if((ctx->getFilterToBitmap() == TRUE) && (style->filter.set != 0)) { - sp_asbitmap_render(item, ctx); + return sp_asbitmap_render(item, ctx); } SPRoot *root = dynamic_cast<SPRoot *>(item); diff --git a/src/extension/internal/cdr-input.cpp b/src/extension/internal/cdr-input.cpp index 3a3e2b58e..f4789a08f 100644 --- a/src/extension/internal/cdr-input.cpp +++ b/src/extension/internal/cdr-input.cpp @@ -263,7 +263,7 @@ SPDocument *CdrInput::open(Inkscape::Extension::Input * /*mod*/, const gchar * u // If only one page is present, import that one without bothering user if (tmpSVGOutput.size() > 1) { CdrImportDialog *dlg = 0; - if (inkscape_use_gui()) { + if (INKSCAPE.use_gui()) { dlg = new CdrImportDialog(tmpSVGOutput); if (!dlg->showDialog()) { delete dlg; @@ -285,7 +285,7 @@ SPDocument *CdrInput::open(Inkscape::Extension::Input * /*mod*/, const gchar * u // Set viewBox if it doesn't exist if (doc && !doc->getRoot()->viewBox_set) { - doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDefaultUnit()), doc->getHeight().value(doc->getDefaultUnit()))); + doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDisplayUnit()), doc->getHeight().value(doc->getDisplayUnit()))); } return doc; } diff --git a/src/extension/internal/emf-inout.cpp b/src/extension/internal/emf-inout.cpp index 4b070cbaa..31e69706f 100644 --- a/src/extension/internal/emf-inout.cpp +++ b/src/extension/internal/emf-inout.cpp @@ -45,8 +45,8 @@ #include "display/drawing-item.h" #include "clear-n_.h" #include "svg/svg.h" -#include "util/units.h" // even though it is included indirectly by wmf-inout.h -#include "inkscape.h" // even though it is included indirectly by wmf-inout.h +#include "util/units.h" // even though it is included indirectly by emf-inout.h +#include "inkscape.h" // even though it is included indirectly by emf-inout.h #include "emf-print.h" #include "emf-inout.h" @@ -188,7 +188,7 @@ double Emf::current_scale(PEMF_CALLBACK_DATA d){ "matrix(a,b,c,d,e,f)" (WITH the double quotes) */ std::string Emf::current_matrix(PEMF_CALLBACK_DATA d, double x, double y, int useoffset){ - std::stringstream cxform; + SVGOStringStream cxform; double scale = current_scale(d); cxform << "\"matrix("; cxform << d->dc[d->level].worldTransform.eM11/scale; cxform << ","; @@ -1058,7 +1058,7 @@ Emf::snap_to_faraway_pair(double *x, double *y) Since exclude clip can go through here, it calls snap_to_faraway_pair for numerical stability. */ std::string Emf::pix_to_xy(PEMF_CALLBACK_DATA d, double x, double y){ - std::stringstream cxform; + SVGOStringStream cxform; double tx = pix_to_x_point(d,x,y); double ty = pix_to_y_point(d,x,y); snap_to_faraway_pair(&tx,&ty); @@ -1515,6 +1515,9 @@ void Emf::common_image_extraction(PEMF_CALLBACK_DATA d, void *pEmr, int dibparams = U_BI_UNKNOWN; // type of image not yet determined tmp_image << "\n\t <image\n"; + if (d->dc[d->level].clip_id){ + tmp_image << "\tclip-path=\"url(#clipEmfPath" << d->dc[d->level].clip_id << ")\"\n"; + } tmp_image << " y=\"" << dy << "\"\n x=\"" << dx <<"\"\n "; MEMPNG mempng; // PNG in memory comes back in this @@ -1727,21 +1730,23 @@ std::cout << "BEFORE DRAW" ) ){ // std::cout << "PATH DRAW at TOP path" << *(d->path) << std::endl; - d->outsvg += " <path "; // this is the ONLY place <path should be used!!! One exception, gradientfill. - if(d->drawtype){ // explicit draw type EMR record - output_style(d, d->drawtype); - } - else if(d->mask & U_DRAW_CLOSED){ // implicit draw type - output_style(d, U_EMR_STROKEANDFILLPATH); - } - else { - output_style(d, U_EMR_STROKEPATH); + if(!(d->path.empty())){ + d->outsvg += " <path "; // this is the ONLY place <path should be used!!! One exception, gradientfill. + if(d->drawtype){ // explicit draw type EMR record + output_style(d, d->drawtype); + } + else if(d->mask & U_DRAW_CLOSED){ // implicit draw type + output_style(d, U_EMR_STROKEANDFILLPATH); + } + else { + output_style(d, U_EMR_STROKEPATH); + } + d->outsvg += "\n\t"; + d->outsvg += "\n\td=\""; // this is the ONLY place d=" should be used!!!! One exception, gradientfill. + d->outsvg += d->path; + d->outsvg += " \" /> \n"; + d->path = ""; } - d->outsvg += "\n\t"; - d->outsvg += "\n\td=\""; // this is the ONLY place d=" should be used!!!! One exception, gradientfill. - d->outsvg += d->path; - d->outsvg += " \" /> \n"; - d->path = ""; // reset the flags d->mask = 0; d->drawtype = 0; @@ -3418,7 +3423,11 @@ std::cout << "BEFORE DRAW" tmp_rectangle << "\n\tz\""; tmp_rectangle << "\n\tstyle=\"stroke:none;fill:url(#"; tmp_rectangle << d->gradients.strings[fill_idx]; - tmp_rectangle << ");\"\n/>\n"; + tmp_rectangle << ");\"\n"; + if (d->dc[d->level].clip_id){ + tmp_rectangle << "\tclip-path=\"url(#clipEmfPath" << d->dc[d->level].clip_id << ")\"\n"; + } + tmp_rectangle << "/>\n"; } d->outsvg += tmp_rectangle.str().c_str(); } @@ -3538,7 +3547,7 @@ Emf::open( Inkscape::Extension::Input * /*mod*/, const gchar *uri ) d.tri = trinfo_release_except_FC(d.tri); - setViewBoxIfMissing(doc); + // in earlier versions no viewbox was generated and a call to setViewBoxIfMissing() was needed here. return doc; } diff --git a/src/extension/internal/emf-print.cpp b/src/extension/internal/emf-print.cpp index f7b6626c4..67a9242bc 100644 --- a/src/extension/internal/emf-print.cpp +++ b/src/extension/internal/emf-print.cpp @@ -251,7 +251,11 @@ unsigned int PrintEmf::begin(Inkscape::Extension::Print *mod, SPDocument *doc) g_error("Fatal programming error in PrintEmf::begin at textcomment_set 1"); } + char *oldlocale = g_strdup(setlocale(LC_NUMERIC, NULL)); + setlocale(LC_NUMERIC, "C"); snprintf(buff, sizeof(buff) - 1, "Drawing=%.1lfx%.1lfpx, %.1lfx%.1lfmm", _width, _height, Inkscape::Util::Quantity::convert(dwInchesX, "in", "mm"), Inkscape::Util::Quantity::convert(dwInchesY, "in", "mm")); + setlocale(LC_NUMERIC, oldlocale); + g_free(oldlocale); rec = textcomment_set(buff); if (!rec || emf_append((PU_ENHMETARECORD)rec, et, U_REC_FREE)) { g_error("Fatal programming error in PrintEmf::begin at textcomment_set 1"); @@ -706,7 +710,7 @@ int PrintEmf::create_pen(SPStyle const *style, const Geom::Affine &transform) n_dash = style->stroke_dasharray.values.size(); dash = new uint32_t[n_dash]; for (i = 0; i < n_dash; i++) { - dash[i] = (uint32_t)(Inkscape::Util::Quantity::convert(1, "mm", "px") * style->stroke_dasharray.values[i]); + dash[i] = style->stroke_dasharray.values[i]; } } } diff --git a/src/extension/internal/filter/color.h b/src/extension/internal/filter/color.h index 19af6e969..c3c26bf8b 100644 --- a/src/extension/internal/filter/color.h +++ b/src/extension/internal/filter/color.h @@ -3,13 +3,14 @@ /* Change the 'COLOR' above to be your file name */ /* - * Copyright (C) 2013 Authors: + * Copyright (C) 2013-2015 Authors: * Ivan Louette (filters) * Nicolas Dufour (UI) <nicoduf@yahoo.fr> * * Color filters * Brilliance * Channel painting + * Color blindness * Color shift * Colorize * Component transfer @@ -231,6 +232,80 @@ ChannelPaint::get_filter_text (Inkscape::Extension::Extension * ext) }; /* Channel Painting filter */ /** + \brief Custom predefined Color Blindness filter. + + Color Blindness filter. + Based on https://openclipart.org/detail/22299/Color%20Blindness%20filters + + Filter's parameters: + * Blindness type (enum, default Achromatomaly) -> colormatrix +*/ +class ColorBlindness : public Inkscape::Extension::Internal::Filter::Filter { +protected: + virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); + +public: + ColorBlindness ( ) : Filter() { }; + virtual ~ColorBlindness ( ) { if (_filter != NULL) g_free((void *)_filter); return; } + + static void init (void) { + Inkscape::Extension::build_from_mem( + "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" + "<name>" N_("Color Blindness") "</name>\n" + "<id>org.inkscape.effect.filter.ColorBlindness</id>\n" + "<param name=\"tab\" type=\"notebook\">\n" + "<page name=\"optionstab\" _gui-text=\"Options\">\n" + "<param name=\"type\" gui-text=\"" N_("Blindness type:") "\" type=\"enum\">\n" + "<_item value=\"0.618 0.32 0.062 0 0 0.163 0.775 0.062 0 0 0.163 0.32 0.516 0 0 0 0 0 1 0 \">" N_("Rod monochromacy (atypical achromatopsia)") "</_item>\n" + "<_item value=\"0.299 0.587 0.114 0 0 0.299 0.587 0.114 0 0 0.299 0.587 0.114 0 0 0 0 0 1 0 \">" N_("Cone monochromacy (typical achromatopsia)") "</_item>\n" + "<_item value=\"0.8 0.2 0 0 0 0.2583 0.74167 0 0 0 0 0.14167 0.85833 0 0 0 0 0 1 0 \">" N_("Geen weak (deuteranomaly)") "</_item>\n" + "<_item value=\"0.625 0.375 0 0 0 0.7 0.3 0 0 0 0 0.3 0.7 0 0 0 0 0 1 0 \">" N_("Green blind (deuteranopia)") "</_item>\n" + "<_item value=\"0.8166 0.1833 0 0 0 0.333 0.666 0 0 0 0 0.125 0.875 0 0 0 0 0 1 0 \">" N_("Red weak (protanomaly)") "</_item>\n" + "<_item value=\"0.566 0.43333 0 0 0 0.55833 0.4416 0 0 0 0 0.24167 0.75833 0 0 0 0 0 1 0 \">" N_("Red blind (protanopia)") "</_item>\n" + "<_item value=\"0.966 0.033 0 0 0 0 0.733 0.266 0 0 0 0.1833 0.816 0 0 0 0 0 1 0 \">" N_("Blue weak (tritanomaly)") "</_item>\n" + "<_item value=\"0.95 0.05 0 0 0 0.2583 0.4333 0.5667 0 0 0 0.475 0.525 0 0 0 0 0 1 0 \">" N_("Blue blind (tritanopia)") "</_item>\n" + "</param>\n" + "</page>\n" + "<page name=\"helptab\" _gui-text=\"Help\">\n" + "<param name=\"help\" xml:space=\"preserve\" type=\"description\">\n" +"Filters based on https://openclipart.org/detail/22299/Color%20Blindness%20filters\n" +"\n" +"These filters don't correctly reflect actual color blindness for two main reasons:\n" +" * Everyone is different, and is not affected exactly the same way.\n" +" * The filters are in the RGB color space, and ignore confusion lines.\n" + "</param>\n" + "</page>\n" + "</param>\n" + "<effect>\n" + "<object-type>all</object-type>\n" + "<effects-menu>\n" + "<submenu name=\"" N_("Filters") "\">\n" + "<submenu name=\"" N_("Color") "\"/>\n" + "</submenu>\n" + "</effects-menu>\n" + "<menu-tip>" N_("Simulate color blindness") "</menu-tip>\n" + "</effect>\n" + "</inkscape-extension>\n", new ColorBlindness()); + }; +}; + +gchar const * +ColorBlindness::get_filter_text (Inkscape::Extension::Extension * ext) +{ + if (_filter != NULL) g_free((void *)_filter); + + std::ostringstream type; + type << ext->get_param_enum("type"); + + _filter = g_strdup_printf( + "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" height=\"1\" width=\"1\" y=\"0\" x=\"0\" inkscape:label=\"Color Blindness\">\n" + "<feColorMatrix values=\"%s\" type=\"matrix\" result=\"colormatrix1\" />\n" + "</filter>\n", type.str().c_str()); + + return _filter; +}; /* Color Blindness filter */ + +/** \brief Custom predefined Color shift filter. Rotate and desaturate hue diff --git a/src/extension/internal/filter/filter-all.cpp b/src/extension/internal/filter/filter-all.cpp index 0273d1669..35504d37f 100644 --- a/src/extension/internal/filter/filter-all.cpp +++ b/src/extension/internal/filter/filter-all.cpp @@ -54,6 +54,7 @@ Filter::filters_all (void ) // Color Brilliance::init(); ChannelPaint::init(); + ColorBlindness::init(); ColorShift::init(); Colorize::init(); ComponentTransfer::init(); diff --git a/src/extension/internal/filter/filter-file.cpp b/src/extension/internal/filter/filter-file.cpp index 48e64f089..b1993057d 100644 --- a/src/extension/internal/filter/filter-file.cpp +++ b/src/extension/internal/filter/filter-file.cpp @@ -29,7 +29,7 @@ namespace Filter { void Filter::filters_all_files(void) { - gchar *filtersProfilePath = profile_path("filters"); + gchar *filtersProfilePath = Inkscape::Application::profile_path("filters"); filters_load_dir(INKSCAPE_FILTERDIR, _("Bundled")); filters_load_dir(filtersProfilePath, _("Personal")); diff --git a/src/extension/internal/gdkpixbuf-input.cpp b/src/extension/internal/gdkpixbuf-input.cpp index 28e44c461..f5fab1fa2 100644 --- a/src/extension/internal/gdkpixbuf-input.cpp +++ b/src/extension/internal/gdkpixbuf-input.cpp @@ -135,8 +135,8 @@ GdkpixbufInput::open(Inkscape::Extension::Input *mod, char const *uri) // Set viewBox if it doesn't exist if (!doc->getRoot()->viewBox_set) { - std::cout << "Viewbox not set, setting" << std::endl; - doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDefaultUnit()), doc->getHeight().value(doc->getDefaultUnit()))); + // std::cerr << "Viewbox not set, setting" << std::endl; + doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDisplayUnit()), doc->getHeight().value(doc->getDisplayUnit()))); } // restore undo, as now this document may be shown to the user if a bitmap was opened diff --git a/src/extension/internal/grid.cpp b/src/extension/internal/grid.cpp index f4e0e5843..270edfe44 100644 --- a/src/extension/internal/grid.cpp +++ b/src/extension/internal/grid.cpp @@ -24,7 +24,7 @@ #include <gtkmm/spinbutton.h> #include "desktop.h" -#include "desktop-handles.h" + #include "document.h" #include "selection.h" #include "sp-object.h" @@ -191,7 +191,9 @@ Grid::prefs_effect(Inkscape::Extension::Effect *module, Inkscape::UI::View::View SPDocument * current_document = view->doc(); using Inkscape::Util::GSListConstIterator; - GSListConstIterator<SPItem *> selected = sp_desktop_selection((SPDesktop *)view)->itemList(); + + // FIXME very unsafe cast + GSListConstIterator<SPItem *> selected = ((SPDesktop *)view)->getSelection()->itemList(); Inkscape::XML::Node * first_select = NULL; if (selected != NULL) { first_select = (*selected)->getRepr(); diff --git a/src/extension/internal/pdfinput/pdf-input.cpp b/src/extension/internal/pdfinput/pdf-input.cpp index c8a7feabf..148d2dcba 100644 --- a/src/extension/internal/pdfinput/pdf-input.cpp +++ b/src/extension/internal/pdfinput/pdf-input.cpp @@ -720,7 +720,7 @@ PdfInput::open(::Inkscape::Extension::Input * /*mod*/, const gchar * uri) { } PdfImportDialog *dlg = NULL; - if (inkscape_use_gui()) { + if (INKSCAPE.use_gui()) { dlg = new PdfImportDialog(pdf_doc, uri); if (!dlg->showDialog()) { _cancelled = true; @@ -883,7 +883,7 @@ PdfInput::open(::Inkscape::Extension::Input * /*mod*/, const gchar * uri) { // Set viewBox if it doesn't exist if (!doc->getRoot()->viewBox_set) { - doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDefaultUnit()), doc->getHeight().value(doc->getDefaultUnit()))); + doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDisplayUnit()), doc->getHeight().value(doc->getDisplayUnit()))); } // Restore undo diff --git a/src/extension/internal/pdfinput/pdf-parser.cpp b/src/extension/internal/pdfinput/pdf-parser.cpp index 0b7dc7905..cc0b38515 100644 --- a/src/extension/internal/pdfinput/pdf-parser.cpp +++ b/src/extension/internal/pdfinput/pdf-parser.cpp @@ -923,7 +923,9 @@ void PdfParser::opSetExtGState(Object args[], int /*numArgs*/) GBool isolated = gFalse; GBool knockout = gFalse; if (!obj4.dictLookup(const_cast<char*>("CS"), &obj5)->isNull()) { -#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) +#if defined(POPPLER_EVEN_NEWER_NEW_COLOR_SPACE_API) + blendingColorSpace = GfxColorSpace::parse(NULL, &obj5, NULL, NULL); +#elif defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) blendingColorSpace = GfxColorSpace::parse(&obj5, NULL, NULL); #elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) blendingColorSpace = GfxColorSpace::parse(&obj5, NULL); @@ -1159,7 +1161,13 @@ void PdfParser::opSetFillColorSpace(Object args[], int /*numArgs*/) res->lookupColorSpace(args[0].getName(), &obj); GfxColorSpace *colorSpace = 0; -#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) +#if defined(POPPLER_EVEN_NEWER_NEW_COLOR_SPACE_API) + if (obj.isNull()) { + colorSpace = GfxColorSpace::parse(NULL, &args[0], NULL, NULL); + } else { + colorSpace = GfxColorSpace::parse(NULL, &obj, NULL, NULL); + } +#elif defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) if (obj.isNull()) { colorSpace = GfxColorSpace::parse(&args[0], NULL, NULL); } else { @@ -1202,7 +1210,13 @@ void PdfParser::opSetStrokeColorSpace(Object args[], int /*numArgs*/) state->setStrokePattern(NULL); res->lookupColorSpace(args[0].getName(), &obj); -#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) +#if defined(POPPLER_EVEN_NEWER_NEW_COLOR_SPACE_API) + if (obj.isNull()) { + colorSpace = GfxColorSpace::parse(NULL, &args[0], NULL, NULL); + } else { + colorSpace = GfxColorSpace::parse(NULL, &obj, NULL, NULL); + } +#elif defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) if (obj.isNull()) { colorSpace = GfxColorSpace::parse(&args[0], NULL, NULL); } else { @@ -2572,24 +2586,12 @@ void PdfParser::opShowSpaceText(Object args[], int /*numArgs*/) } } - - -/* - * The `POPPLER_NEW_GFXFONT' stuff is for the change to GfxFont's getNextChar() call. - * Thanks to tsdgeos for the fix. - * Miklos, does this look ok? - */ - void PdfParser::doShowText(GooString *s) { GfxFont *font; int wMode; double riseX, riseY; CharCode code; -#ifdef POPPLER_NEW_GFXFONT Unicode *u = NULL; -#else - Unicode u[8]; -#endif double x, y, dx, dy, tdx, tdy; double originX, originY, tOriginX, tOriginY; double oldCTM[6], newCTM[6]; @@ -2637,11 +2639,7 @@ void PdfParser::doShowText(GooString *s) { len = s->getLength(); while (len > 0) { n = font->getNextChar(p, len, &code, -#ifdef POPPLER_NEW_GFXFONT &u, &uLen, /* TODO: This looks like a memory leak for u. */ -#else - u, (int)(sizeof(u) / sizeof(Unicode)), &uLen, -#endif &dx, &dy, &originX, &originY); dx = dx * state->getFontSize() + state->getCharSpace(); if (n == 1 && *p == ' ') { @@ -2694,11 +2692,7 @@ void PdfParser::doShowText(GooString *s) { len = s->getLength(); while (len > 0) { n = font->getNextChar(p, len, &code, -#ifdef POPPLER_NEW_GFXFONT &u, &uLen, /* TODO: This looks like a memory leak for u. */ -#else - u, (int)(sizeof(u) / sizeof(Unicode)), &uLen, -#endif &dx, &dy, &originX, &originY); if (wMode) { @@ -2910,7 +2904,9 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg) } } if (!obj1.isNull()) { -#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) +#if defined(POPPLER_EVEN_NEWER_NEW_COLOR_SPACE_API) + colorSpace = GfxColorSpace::parse(NULL, &obj1, NULL, NULL); +#elif defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) colorSpace = GfxColorSpace::parse(&obj1, NULL, NULL); #elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) colorSpace = GfxColorSpace::parse(&obj1, NULL); @@ -3004,7 +3000,9 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg) obj2.free(); } } -#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) +#if defined(POPPLER_EVEN_NEWER_NEW_COLOR_SPACE_API) + GfxColorSpace *maskColorSpace = GfxColorSpace::parse(NULL, &obj1, NULL, NULL); +#elif defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) GfxColorSpace *maskColorSpace = GfxColorSpace::parse(&obj1, NULL, NULL); #elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) GfxColorSpace *maskColorSpace = GfxColorSpace::parse(&obj1, NULL); @@ -3196,7 +3194,9 @@ void PdfParser::doForm(Object *str) { if (obj1.dictLookup(const_cast<char*>("S"), &obj2)->isName(const_cast<char*>("Transparency"))) { transpGroup = gTrue; if (!obj1.dictLookup(const_cast<char*>("CS"), &obj3)->isNull()) { -#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) +#if defined(POPPLER_EVEN_NEWER_NEW_COLOR_SPACE_API) + blendingColorSpace = GfxColorSpace::parse(NULL, &obj3, NULL, NULL); +#elif defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) blendingColorSpace = GfxColorSpace::parse(&obj3, NULL, NULL); #elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) blendingColorSpace = GfxColorSpace::parse(&obj3, NULL); diff --git a/src/extension/internal/pdfinput/svg-builder.cpp b/src/extension/internal/pdfinput/svg-builder.cpp index 7a504add0..a3abb4045 100644 --- a/src/extension/internal/pdfinput/svg-builder.cpp +++ b/src/extension/internal/pdfinput/svg-builder.cpp @@ -91,9 +91,6 @@ SvgBuilder::SvgBuilder(SPDocument *document, gchar *docname, XRef *xref) _preferences = _xml_doc->createElement("svgbuilder:prefs"); _preferences->setAttribute("embedImages", "1"); _preferences->setAttribute("localFonts", "1"); - - _ttm[0] = 1; _ttm[1] = 0; _ttm[2] = 0; _ttm[3] = 1; _ttm[4] = 0; _ttm[5] = 0; - _ttm_is_set = false; } SvgBuilder::SvgBuilder(SvgBuilder *parent, Inkscape::XML::Node *root) { @@ -136,6 +133,9 @@ void SvgBuilder::_init() { initial_state.group_depth = 0; _state_stack.push_back(initial_state); _node_stack.push_back(_container); + + _ttm[0] = 1; _ttm[1] = 0; _ttm[2] = 0; _ttm[3] = 1; _ttm[4] = 0; _ttm[5] = 0; + _ttm_is_set = false; } void SvgBuilder::setDocumentSize(double width, double height) { diff --git a/src/extension/internal/text_reassemble.c b/src/extension/internal/text_reassemble.c index 4dfc49420..d3aafef12 100644 --- a/src/extension/internal/text_reassemble.c +++ b/src/extension/internal/text_reassemble.c @@ -67,11 +67,11 @@ Optional compiler switches for development: File: text_reassemble.c -Version: 0.0.15 -Date: 24-JUL-2014 +Version: 0.0.16 +Date: 25-FEB-2015 Author: David Mathog, Biology Division, Caltech email: mathog@caltech.edu -Copyright: 2014 David Mathog and California Institute of Technology (Caltech) +Copyright: 2015 David Mathog and California Institute of Technology (Caltech) */ #ifdef __cplusplus @@ -80,6 +80,7 @@ extern "C" { #include "text_reassemble.h" #include <libuemf/uemf_utf.h> /* For a couple of text functions. Exact copy from libUEMF. */ +#include <locale.h> #include <float.h> /* Code generated by make_ucd_mn_table.c using: @@ -1936,6 +1937,15 @@ void TR_layout_2_svg(TR_INFO *tri){ double newx,newy,tmpx; uint32_t utmp; + /* copy the current numeric locale, make a copy because setlocale may stomp on + the memory it points to. Then change it because SVG needs decimal points, + not commas, in floats. Restore on exit from this routine. + */ + char *prev_locale = setlocale(LC_NUMERIC,NULL); + char *hold_locale = malloc(sizeof(char) * (strlen(prev_locale) + 1)); + strcpy(hold_locale,prev_locale); + (void) setlocale(LC_NUMERIC,"POSIX"); + /* #define DBG_TR_PARA 0 #define DBG_TR_INPUT 1 @@ -2232,6 +2242,10 @@ void TR_layout_2_svg(TR_INFO *tri){ } /* end of j loop */ TRPRINT(tri,"</tspan></text>\n"); } /* end of i loop */ + + /* restore locale and free memory. */ + (void) setlocale(LC_NUMERIC,hold_locale); + free(hold_locale); } /** diff --git a/src/extension/internal/vsd-input.cpp b/src/extension/internal/vsd-input.cpp index 9f9bf2651..7fd0d363b 100644 --- a/src/extension/internal/vsd-input.cpp +++ b/src/extension/internal/vsd-input.cpp @@ -263,7 +263,7 @@ SPDocument *VsdInput::open(Inkscape::Extension::Input * /*mod*/, const gchar * u // If only one page is present, import that one without bothering user if (tmpSVGOutput.size() > 1) { VsdImportDialog *dlg = 0; - if (inkscape_use_gui()) { + if (INKSCAPE.use_gui()) { dlg = new VsdImportDialog(tmpSVGOutput); if (!dlg->showDialog()) { delete dlg; @@ -285,7 +285,7 @@ SPDocument *VsdInput::open(Inkscape::Extension::Input * /*mod*/, const gchar * u // Set viewBox if it doesn't exist if (!doc->getRoot()->viewBox_set) { - doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDefaultUnit()), doc->getHeight().value(doc->getDefaultUnit()))); + doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDisplayUnit()), doc->getHeight().value(doc->getDisplayUnit()))); } return doc; diff --git a/src/extension/internal/wmf-inout.cpp b/src/extension/internal/wmf-inout.cpp index 72c1c8bd3..503a93418 100644 --- a/src/extension/internal/wmf-inout.cpp +++ b/src/extension/internal/wmf-inout.cpp @@ -176,7 +176,7 @@ double Wmf::current_scale(PWMF_CALLBACK_DATA /*d*/){ /* WMF has no worldTransform, so this always returns an Identity rotation matrix, but the offsets may have values.*/ std::string Wmf::current_matrix(PWMF_CALLBACK_DATA d, double x, double y, int useoffset){ - std::stringstream cxform; + SVGOStringStream cxform; double scale = current_scale(d); cxform << "\"matrix("; cxform << 1.0/scale; cxform << ","; @@ -948,7 +948,7 @@ Wmf::pix_to_abs_size(PWMF_CALLBACK_DATA d, double px) /* returns "x,y" (without the quotes) in inkscape coordinates for a pair of WMF x,y coordinates */ std::string Wmf::pix_to_xy(PWMF_CALLBACK_DATA d, double x, double y){ - std::stringstream cxform; + SVGOStringStream cxform; cxform << pix_to_x_point(d,x,y); cxform << ","; cxform << pix_to_y_point(d,x,y); @@ -1308,6 +1308,9 @@ void Wmf::common_dib_to_image(PWMF_CALLBACK_DATA d, const char *dib, int dibparams = U_BI_UNKNOWN; // type of image not yet determined tmp_image << "\n\t <image\n"; + if (d->dc[d->level].clip_id){ + tmp_image << "\tclip-path=\"url(#clipWmfPath" << d->dc[d->level].clip_id << ")\"\n"; + } tmp_image << " y=\"" << dy << "\"\n x=\"" << dx <<"\"\n "; MEMPNG mempng; // PNG in memory comes back in this @@ -1405,6 +1408,9 @@ void Wmf::common_bm16_to_image(PWMF_CALLBACK_DATA d, U_BITMAP16 Bm16, const char SVGOStringStream tmp_image; tmp_image << "\n\t <image\n"; + if (d->dc[d->level].clip_id){ + tmp_image << "\tclip-path=\"url(#clipWmfPath" << d->dc[d->level].clip_id << ")\"\n"; + } tmp_image << " y=\"" << dy << "\"\n x=\"" << dx <<"\"\n "; MEMPNG mempng; // PNG in memory comes back in this @@ -1752,13 +1758,15 @@ std::cout << "BEFORE DRAW" ) ){ // std::cout << "PATH DRAW at TOP <<+++++++++++++++++++++++++++++++++++++" << std::endl; - d->outsvg += " <path "; // this is the ONLY place <path should be used!!!! - output_style(d); - d->outsvg += "\n\t"; - d->outsvg += "\n\td=\""; // this is the ONLY place d=" should be used!!!! - d->outsvg += d->path; - d->outsvg += " \" /> \n"; - d->path = ""; //reset the path + if(!(d->path.empty())){ + d->outsvg += " <path "; // this is the ONLY place <path should be used!!!! + output_style(d); + d->outsvg += "\n\t"; + d->outsvg += "\n\td=\""; // this is the ONLY place d=" should be used!!!! + d->outsvg += d->path; + d->outsvg += " \" /> \n"; + d->path = ""; //reset the path + } // reset the flags d->mask = 0; d->drawtype = 0; @@ -2600,9 +2608,9 @@ std::cout << "BEFORE DRAW" if(status==-1){ // change of escapement, emit what we have and reset TR_layout_analyze(d->tri); if (d->dc[d->level].clip_id){ - SVGOStringStream tmp_clip; - tmp_clip << "\n<g\n\tclip-path=\"url(#clipWmfPath" << d->dc[d->level].clip_id << ")\"\n>"; - d->outsvg += tmp_clip.str().c_str(); + SVGOStringStream tmp_clip; + tmp_clip << "\n<g\n\tclip-path=\"url(#clipWmfPath" << d->dc[d->level].clip_id << ")\"\n>"; + d->outsvg += tmp_clip.str().c_str(); } TR_layout_2_svg(d->tri); ts << d->tri->out; @@ -2610,7 +2618,7 @@ std::cout << "BEFORE DRAW" d->tri = trinfo_clear(d->tri); (void) trinfo_load_textrec(d->tri, &tsp, tsp.ori,TR_EMFBOT); // ignore return status, it must work if (d->dc[d->level].clip_id){ - d->outsvg += "\n</g>\n"; + d->outsvg += "\n</g>\n"; } } @@ -3113,7 +3121,7 @@ Wmf::open( Inkscape::Extension::Input * /*mod*/, const gchar *uri ) d.tri = trinfo_release_except_FC(d.tri); - setViewBoxIfMissing(doc); + // in earlier versions no viewbox was generated and a call to setViewBoxIfMissing() was needed here. return doc; } diff --git a/src/extension/internal/wmf-print.cpp b/src/extension/internal/wmf-print.cpp index e5ff34009..567f9f366 100644 --- a/src/extension/internal/wmf-print.cpp +++ b/src/extension/internal/wmf-print.cpp @@ -366,11 +366,12 @@ int PrintWmf::create_brush(SPStyle const *style, U_COLORREF *fcolor) if (!fcolor && style) { if (style->fill.isColor()) { fill_mode = DRAW_PAINT; + /* Dead assignment: Value stored to 'opacity' is never read float opacity = SP_SCALE24_TO_FLOAT(style->fill_opacity.value); if (opacity <= 0.0) { opacity = 0.0; // basically the same as no fill } - + */ sp_color_get_rgb_floatv(&style->fill.value.color, rgb); hatchColor = U_RGB(255 * rgb[0], 255 * rgb[1], 255 * rgb[2]); diff --git a/src/extension/internal/wpg-input.cpp b/src/extension/internal/wpg-input.cpp index 12d86a99a..54a14fc72 100644 --- a/src/extension/internal/wpg-input.cpp +++ b/src/extension/internal/wpg-input.cpp @@ -129,7 +129,7 @@ SPDocument *WpgInput::open(Inkscape::Extension::Input * /*mod*/, const gchar * u // Set viewBox if it doesn't exist if (doc && !doc->getRoot()->viewBox_set) { - doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDefaultUnit()), doc->getHeight().value(doc->getDefaultUnit()))); + doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDisplayUnit()), doc->getHeight().value(doc->getDisplayUnit()))); } delete input; diff --git a/src/extension/param/radiobutton.cpp b/src/extension/param/radiobutton.cpp index f9515197c..740acf1d1 100644 --- a/src/extension/param/radiobutton.cpp +++ b/src/extension/param/radiobutton.cpp @@ -249,28 +249,35 @@ void ParamRadioButtonWdg::changed(void) class ComboWdg : public Gtk::ComboBoxText { +private: + ParamRadioButton* _base; + SPDocument* _doc; + Inkscape::XML::Node* _node; + sigc::signal<void> * _changeSignal; + public: - ComboWdg(ParamRadioButton* base, SPDocument * doc, Inkscape::XML::Node * node) : - Gtk::ComboBoxText(), - base(base), - doc(doc), - node(node) + ComboWdg(ParamRadioButton* base, SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal) : + _base(base), + _doc(doc), + _node(node), + _changeSignal(changeSignal) { + this->signal_changed().connect(sigc::mem_fun(this, &ComboWdg::changed)); } virtual ~ComboWdg() {} + void changed (void); +}; -protected: - ParamRadioButton* base; - SPDocument* doc; - Inkscape::XML::Node* node; - - virtual void on_changed() { - if ( base ) { - Glib::ustring value = base->value_from_label(get_active_text()); - base->set(value.c_str(), doc, node); - } +void ComboWdg::changed(void) +{ + if ( _base ) { + Glib::ustring value = _base->value_from_label(get_active_text()); + _base->set(value.c_str(), _doc, _node); } -}; + if (_changeSignal != NULL) { + _changeSignal->emit(); + } +} /** * Returns the value for the options label parameter @@ -317,7 +324,7 @@ Gtk::Widget * ParamRadioButton::get_widget(SPDocument * doc, Inkscape::XML::Node Gtk::ComboBoxText* cbt = 0; bool comboSet = false; if (_mode == MINIMAL) { - cbt = Gtk::manage(new ComboWdg(this, doc, node)); + cbt = Gtk::manage(new ComboWdg(this, doc, node, changeSignal)); cbt->show(); vbox->pack_start(*cbt, false, false); } diff --git a/src/extension/system.cpp b/src/extension/system.cpp index 5225f11ee..6a95717f2 100644 --- a/src/extension/system.cpp +++ b/src/extension/system.cpp @@ -121,7 +121,7 @@ SPDocument *open(Extension *key, gchar const *filename) } if (last_chance_svg) { - if ( inkscape_use_gui() ) { + if ( INKSCAPE.use_gui() ) { sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); } else { g_warning("%s", _("Format autodetect failed. The file is being opened as SVG.")); diff --git a/src/factory.h b/src/factory.h deleted file mode 100644 index c1288b460..000000000 --- a/src/factory.h +++ /dev/null @@ -1,123 +0,0 @@ -/** @file - * Generic Factory - *//* - * Authors: - * Markus Engel - * - * Copyright (C) 2013 Authors - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifndef FACTORY_H_SEEN -#define FACTORY_H_SEEN - -#include <exception> -#include <map> -#include <string> -#include "xml/node.h" - -/** - * A simple singleton implementation. - */ -template <class T> -struct Singleton { - static T &instance() { - static T inst; - return inst; - } -}; - -namespace FactoryExceptions { -class TypeNotRegistered : public std::exception { -public: - TypeNotRegistered(std::string const &type) - : std::exception() - , _type_string(type) { - } - - virtual ~TypeNotRegistered() throw() { - } - - char const *what() const throw() { - return _type_string.c_str(); - } - -private: - std::string const _type_string; -}; -} // namespace FactoryExceptions - -/** - * A Factory for creating objects which can be identified by strings. - */ -template <class BaseObject> -class Factory { -public: - typedef BaseObject *CreateFunction(); - - bool registerObject(std::string const &id, CreateFunction *creator) { - return this->_object_map.insert(std::make_pair(id, creator)).second; - } - - BaseObject *createObject(std::string const &id) const { - typename std::map<std::string const, CreateFunction *>::const_iterator it = this->_object_map.find(id); - - if (it == this->_object_map.end()) { - //throw FactoryExceptions::TypeNotRegistered(id); - if (!(id.empty() // comments, usually - || id == "rdf:RDF" // no SP node yet - || id == "inkscape:clipboard" // SP node not necessary - || id == "inkscape:_templateinfo")) { - g_warning("unknown type: %s", id.c_str()); - } - return NULL; - } - - return it->second(); - } - -private: - std::map<std::string const, CreateFunction *> _object_map; -}; - - -struct NodeTraits { - static std::string get_type_string(Inkscape::XML::Node const &node) { - std::string name; - - switch (node.type()) { - case Inkscape::XML::TEXT_NODE: - name = "string"; - break; - - case Inkscape::XML::ELEMENT_NODE: { - char const *const sptype = node.attribute("sodipodi:type"); - - if (sptype) { - name = sptype; - } else { - name = node.name(); - } - break; - } - default: - name = ""; - break; - } - - return name; - } -}; - -#endif - -/* - 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/file.cpp b/src/file.cpp index 307944001..f9e259fe2 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -32,7 +32,7 @@ #include "ui/dialog/ocaldialogs.h" #include "desktop.h" -#include "desktop-handles.h" + #include "dir-util.h" #include "document-private.h" #include "document-undo.h" @@ -144,7 +144,7 @@ SPDesktop *sp_file_new(const std::string &templ) // Set viewBox if it doesn't exist if (!doc->getRoot()->viewBox_set) { DocumentUndo::setUndoSensitive(doc, false); - doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDefaultUnit()), doc->getHeight().value(doc->getDefaultUnit()))); + doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDisplayUnit()), doc->getHeight().value(doc->getDisplayUnit()))); DocumentUndo::setUndoSensitive(doc, true); } @@ -177,7 +177,7 @@ SPDesktop *sp_file_new(const std::string &templ) Glib::ustring sp_file_default_template_uri() { std::list<gchar *> sources; - sources.push_back( profile_path("templates") ); // first try user's local dir + sources.push_back( Inkscape::Application::profile_path("templates") ); // first try user's local dir sources.push_back( g_strdup(INKSCAPE_TEMPLATESDIR) ); // then the system templates dir std::list<gchar const*> baseNames; gchar const* localized = _("default.svg"); @@ -288,8 +288,14 @@ bool sp_file_open(const Glib::ustring &uri, } if (doc) { + // Set viewBox if it doesn't exist + if (!doc->getRoot()->viewBox_set) { + DocumentUndo::setUndoSensitive(doc, false); + doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDisplayUnit()), doc->getHeight().value(doc->getDisplayUnit()))); + DocumentUndo::setUndoSensitive(doc, true); + } - SPDocument *existing = desktop ? sp_desktop_document(desktop) : NULL; + SPDocument *existing = desktop ? desktop->getDocument() : NULL; if (existing && existing->virgin && replace_empty) { // If the current desktop is empty, open the document there @@ -316,7 +322,7 @@ bool sp_file_open(const Glib::ustring &uri, sp_file_add_recent( doc->getURI() ); } - if ( inkscape_use_gui() ) { + 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."); @@ -348,7 +354,7 @@ void sp_file_revert_dialog() SPDesktop *desktop = SP_ACTIVE_DESKTOP; g_assert(desktop != NULL); - SPDocument *doc = sp_desktop_document(desktop); + SPDocument *doc = desktop->getDocument(); g_assert(doc != NULL); Inkscape::XML::Node *repr = doc->getReprRoot(); @@ -1055,7 +1061,7 @@ void sp_import_document(SPDesktop *desktop, SPDocument *clipdoc, bool in_place) { //TODO: merge with file_import() - SPDocument *target_document = sp_desktop_document(desktop); + SPDocument *target_document = desktop->getDocument(); Inkscape::XML::Node *root = clipdoc->getReprRoot(); Inkscape::XML::Node *target_parent = desktop->currentLayer()->getRepr(); @@ -1086,7 +1092,7 @@ void sp_import_document(SPDesktop *desktop, SPDocument *clipdoc, bool in_place) } // Change the selection to the freshly pasted objects - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); selection->setReprList(pasted_objects); // Apply inverse of parent transform @@ -1221,7 +1227,7 @@ file_import(SPDocument *in_doc, const Glib::ustring &uri, // select and move the imported item if (new_obj && SP_IS_ITEM(new_obj)) { - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); selection->set(SP_ITEM(new_obj)); // preserve parent and viewBox transformations @@ -1232,7 +1238,7 @@ file_import(SPDocument *in_doc, const Glib::ustring &uri, // move to mouse pointer { - sp_desktop_document(desktop)->ensureUpToDate(); + desktop->getDocument()->ensureUpToDate(); Geom::OptRect sel_bbox = selection->visualBounds(); if (sel_bbox) { Geom::Point m( desktop->point() - sel_bbox->midpoint() ); diff --git a/src/filters/blend.cpp b/src/filters/blend.cpp index ca1d5bf96..6e92ef50f 100644 --- a/src/filters/blend.cpp +++ b/src/filters/blend.cpp @@ -13,10 +13,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include <string.h> #include "sp-filter.h" @@ -30,16 +26,6 @@ #include "display/nr-filter-blend.h" #include "display/nr-filter-types.h" -#include "sp-factory.h" - -namespace { - SPObject* createBlend() { - return new SPFeBlend(); - } - - bool blendRegistered = SPFactory::instance().registerObject("svg:feBlend", createBlend); -} - SPFeBlend::SPFeBlend() : SPFilterPrimitive(), blend_mode(Inkscape::Filters::BLEND_NORMAL), in2(Inkscape::Filters::NR_FILTER_SLOT_NOT_SET) diff --git a/src/filters/colormatrix.cpp b/src/filters/colormatrix.cpp index 58f601a65..a7f0296c2 100644 --- a/src/filters/colormatrix.cpp +++ b/src/filters/colormatrix.cpp @@ -14,10 +14,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include <string.h> #include "attributes.h" @@ -29,16 +25,6 @@ #include "display/nr-filter.h" #include "display/nr-filter-colormatrix.h" -#include "sp-factory.h" - -namespace { - SPObject* createColorMatrix() { - return new SPFeColorMatrix(); - } - - bool colorMatrixRegistered = SPFactory::instance().registerObject("svg:feColorMatrix", createColorMatrix); -} - SPFeColorMatrix::SPFeColorMatrix() : SPFilterPrimitive(), type(Inkscape::Filters::COLORMATRIX_MATRIX), value(0) { diff --git a/src/filters/componenttransfer-funcnode.cpp b/src/filters/componenttransfer-funcnode.cpp index d8c5b0d49..76e99a648 100644 --- a/src/filters/componenttransfer-funcnode.cpp +++ b/src/filters/componenttransfer-funcnode.cpp @@ -13,10 +13,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include <glib.h> #include "attributes.h" @@ -31,32 +27,6 @@ #include "macros.h" -#include "sp-factory.h" - -namespace { - SPObject* createFuncR() { - return new SPFeFuncNode(SPFeFuncNode::R); - } - - SPObject* createFuncG() { - return new SPFeFuncNode(SPFeFuncNode::G); - } - - SPObject* createFuncB() { - return new SPFeFuncNode(SPFeFuncNode::B); - } - - SPObject* createFuncA() { - return new SPFeFuncNode(SPFeFuncNode::A); - } - - bool funcRRegistered = SPFactory::instance().registerObject("svg:feFuncR", createFuncR); - bool funcGRegistered = SPFactory::instance().registerObject("svg:feFuncG", createFuncG); - bool funcBRegistered = SPFactory::instance().registerObject("svg:feFuncB", createFuncB); - bool funcARegistered = SPFactory::instance().registerObject("svg:feFuncA", createFuncA); -} - - /* FeFuncNode class */ SPFeFuncNode::SPFeFuncNode(SPFeFuncNode::Channel channel) : SPObject(), type(Inkscape::Filters::COMPONENTTRANSFER_TYPE_IDENTITY), diff --git a/src/filters/componenttransfer.cpp b/src/filters/componenttransfer.cpp index 610b3dd02..3d0264390 100644 --- a/src/filters/componenttransfer.cpp +++ b/src/filters/componenttransfer.cpp @@ -12,10 +12,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include <string.h> #include "document.h" @@ -27,16 +23,6 @@ #include "display/nr-filter.h" #include "display/nr-filter-component-transfer.h" -#include "sp-factory.h" - -namespace { - SPObject* createComponentTransfer() { - return new SPFeComponentTransfer(); - } - - bool componentTransferRegistered = SPFactory::instance().registerObject("svg:feComponentTransfer", createComponentTransfer); -} - SPFeComponentTransfer::SPFeComponentTransfer() : SPFilterPrimitive(), renderer(NULL) { diff --git a/src/filters/composite.cpp b/src/filters/composite.cpp index e600b6d20..3e651a778 100644 --- a/src/filters/composite.cpp +++ b/src/filters/composite.cpp @@ -12,10 +12,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include "attributes.h" #include "svg/svg.h" #include "filters/composite.h" @@ -25,16 +21,6 @@ #include "display/nr-filter-composite.h" #include "sp-filter.h" -#include "sp-factory.h" - -namespace { - SPObject* createComposite() { - return new SPFeComposite(); - } - - bool compositeRegistered = SPFactory::instance().registerObject("svg:feComposite", createComposite); -} - SPFeComposite::SPFeComposite() : SPFilterPrimitive(), composite_operator(COMPOSITE_DEFAULT), k1(0), k2(0), k3(0), k4(0), in2(Inkscape::Filters::NR_FILTER_SLOT_NOT_SET) diff --git a/src/filters/convolvematrix.cpp b/src/filters/convolvematrix.cpp index bd710b116..3a443bebc 100644 --- a/src/filters/convolvematrix.cpp +++ b/src/filters/convolvematrix.cpp @@ -13,10 +13,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include <string.h> #include <math.h> #include <vector> @@ -28,16 +24,6 @@ #include "display/nr-filter.h" #include "display/nr-filter-convolve-matrix.h" -#include "sp-factory.h" - -namespace { - SPObject* createConvolveMatrix() { - return new SPFeConvolveMatrix(); - } - - bool convolveMatrixRegistered = SPFactory::instance().registerObject("svg:feConvolveMatrix", createConvolveMatrix); -} - SPFeConvolveMatrix::SPFeConvolveMatrix() : SPFilterPrimitive() { this->bias = 0; this->divisorIsSet = 0; diff --git a/src/filters/diffuselighting.cpp b/src/filters/diffuselighting.cpp index 09179a69d..120c058d2 100644 --- a/src/filters/diffuselighting.cpp +++ b/src/filters/diffuselighting.cpp @@ -14,10 +14,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include "strneq.h" #include "attributes.h" @@ -36,16 +32,6 @@ /* FeDiffuseLighting base class */ static void sp_feDiffuseLighting_children_modified(SPFeDiffuseLighting *sp_diffuselighting); -#include "sp-factory.h" - -namespace { - SPObject* createDiffuseLighting() { - return new SPFeDiffuseLighting(); - } - - bool diffuseLightingRegistered = SPFactory::instance().registerObject("svg:feDiffuseLighting", createDiffuseLighting); -} - SPFeDiffuseLighting::SPFeDiffuseLighting() : SPFilterPrimitive() { this->surfaceScale = 1; this->diffuseConstant = 1; diff --git a/src/filters/displacementmap.cpp b/src/filters/displacementmap.cpp index 7dedfc031..1dbea67ff 100644 --- a/src/filters/displacementmap.cpp +++ b/src/filters/displacementmap.cpp @@ -12,10 +12,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include "attributes.h" #include "svg/svg.h" #include "filters/displacementmap.h" @@ -25,16 +21,6 @@ #include "display/nr-filter.h" #include "display/nr-filter-displacement-map.h" -#include "sp-factory.h" - -namespace { - SPObject* createDisplacementMap() { - return new SPFeDisplacementMap(); - } - - bool displacementMapRegistered = SPFactory::instance().registerObject("svg:feDisplacementMap", createDisplacementMap); -} - SPFeDisplacementMap::SPFeDisplacementMap() : SPFilterPrimitive() { this->scale=0; this->xChannelSelector = DISPLACEMENTMAP_CHANNEL_ALPHA; diff --git a/src/filters/distantlight.cpp b/src/filters/distantlight.cpp index bd8bd2797..fb7380174 100644 --- a/src/filters/distantlight.cpp +++ b/src/filters/distantlight.cpp @@ -13,10 +13,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include <glib.h> #include "attributes.h" @@ -30,17 +26,6 @@ #include "macros.h" -#include "sp-factory.h" - -namespace { - SPObject* createDistantLight() { - return new SPFeDistantLight(); - } - - bool distantLightRegistered = SPFactory::instance().registerObject("svg:feDistantLight", createDistantLight); -} - - SPFeDistantLight::SPFeDistantLight() : SPObject(), azimuth(0), azimuth_set(FALSE), elevation(0), elevation_set(FALSE) { } diff --git a/src/filters/flood.cpp b/src/filters/flood.cpp index 134492d34..94ca61b98 100644 --- a/src/filters/flood.cpp +++ b/src/filters/flood.cpp @@ -12,10 +12,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include "strneq.h" #include "attributes.h" @@ -27,16 +23,6 @@ #include "display/nr-filter.h" #include "display/nr-filter-flood.h" -#include "sp-factory.h" - -namespace { - SPObject* createFlood() { - return new SPFeFlood(); - } - - bool floodRegistered = SPFactory::instance().registerObject("svg:feFlood", createFlood); -} - SPFeFlood::SPFeFlood() : SPFilterPrimitive() { this->color = 0; diff --git a/src/filters/gaussian-blur.cpp b/src/filters/gaussian-blur.cpp index fc1e65925..43a1f6dfb 100644 --- a/src/filters/gaussian-blur.cpp +++ b/src/filters/gaussian-blur.cpp @@ -27,19 +27,6 @@ #include "display/nr-filter-gaussian.h" #include "display/nr-filter-types.h" -//#define SP_MACROS_SILENT -//#include "macros.h" - -#include "sp-factory.h" - -namespace { - SPObject* createGaussianBlur() { - return new SPGaussianBlur(); - } - - bool gaussianBlurRegistered = SPFactory::instance().registerObject("svg:feGaussianBlur", createGaussianBlur); -} - SPGaussianBlur::SPGaussianBlur() : SPFilterPrimitive() { } diff --git a/src/filters/image.cpp b/src/filters/image.cpp index 116939e0f..62e8b76b9 100644 --- a/src/filters/image.cpp +++ b/src/filters/image.cpp @@ -14,10 +14,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include <sigc++/bind.h> #include "display/nr-filter-image.h" #include "uri.h" @@ -31,16 +27,6 @@ #include "display/nr-filter.h" -#include "sp-factory.h" - -namespace { - SPObject* createImage() { - return new SPFeImage(); - } - - bool imageRegistered = SPFactory::instance().registerObject("svg:feImage", createImage); -} - SPFeImage::SPFeImage() : SPFilterPrimitive() { this->href = NULL; this->from_element = 0; diff --git a/src/filters/merge.cpp b/src/filters/merge.cpp index 882ab36dd..68f671b11 100644 --- a/src/filters/merge.cpp +++ b/src/filters/merge.cpp @@ -11,10 +11,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include "attributes.h" #include "svg/svg.h" #include "xml/repr.h" @@ -24,16 +20,6 @@ #include "display/nr-filter.h" #include "display/nr-filter-merge.h" -#include "sp-factory.h" - -namespace { - SPObject* createMerge() { - return new SPFeMerge(); - } - - bool mergeRegistered = SPFactory::instance().registerObject("svg:feMerge", createMerge); -} - SPFeMerge::SPFeMerge() : SPFilterPrimitive() { } diff --git a/src/filters/mergenode.cpp b/src/filters/mergenode.cpp index ba237c776..691184eb5 100644 --- a/src/filters/mergenode.cpp +++ b/src/filters/mergenode.cpp @@ -13,26 +13,12 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include "attributes.h" #include "xml/repr.h" #include "filters/mergenode.h" #include "filters/merge.h" #include "display/nr-filter-types.h" -#include "sp-factory.h" - -namespace { - SPObject* createMergeNode() { - return new SPFeMergeNode(); - } - - bool mergeNodeRegistered = SPFactory::instance().registerObject("svg:feMergeNode", createMergeNode); -} - SPFeMergeNode::SPFeMergeNode() : SPObject(), input(Inkscape::Filters::NR_FILTER_SLOT_NOT_SET) { } diff --git a/src/filters/morphology.cpp b/src/filters/morphology.cpp index d3611b081..326c9b7a6 100644 --- a/src/filters/morphology.cpp +++ b/src/filters/morphology.cpp @@ -13,10 +13,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include <string.h> #include "attributes.h" @@ -26,16 +22,6 @@ #include "display/nr-filter.h" #include "display/nr-filter-morphology.h" -#include "sp-factory.h" - -namespace { - SPObject* createMorphology() { - return new SPFeMorphology(); - } - - bool morphologyRegistered = SPFactory::instance().registerObject("svg:feMorphology", createMorphology); -} - SPFeMorphology::SPFeMorphology() : SPFilterPrimitive() { this->Operator = Inkscape::Filters::MORPHOLOGY_OPERATOR_ERODE; diff --git a/src/filters/offset.cpp b/src/filters/offset.cpp index 234a1a964..c35649dcc 100644 --- a/src/filters/offset.cpp +++ b/src/filters/offset.cpp @@ -13,10 +13,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include "attributes.h" #include "svg/svg.h" #include "filters/offset.h" @@ -25,16 +21,6 @@ #include "display/nr-filter.h" #include "display/nr-filter-offset.h" -#include "sp-factory.h" - -namespace { - SPObject* createOffset() { - return new SPFeOffset(); - } - - bool offsetRegistered = SPFactory::instance().registerObject("svg:feOffset", createOffset); -} - SPFeOffset::SPFeOffset() : SPFilterPrimitive() { this->dx = 0; this->dy = 0; diff --git a/src/filters/pointlight.cpp b/src/filters/pointlight.cpp index 1c7532b4e..dd3a78f4c 100644 --- a/src/filters/pointlight.cpp +++ b/src/filters/pointlight.cpp @@ -13,10 +13,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include <glib.h> #include "attributes.h" @@ -29,16 +25,6 @@ #define SP_MACROS_SILENT #include "macros.h" -#include "sp-factory.h" - -namespace { - SPObject* createPointLight() { - return new SPFePointLight(); - } - - bool pointLightRegistered = SPFactory::instance().registerObject("svg:fePointLight", createPointLight); -} - SPFePointLight::SPFePointLight() : SPObject(), x(0), x_set(FALSE), y(0), y_set(FALSE), z(0), z_set(FALSE) { } diff --git a/src/filters/specularlighting.cpp b/src/filters/specularlighting.cpp index 6cdd5d9ba..bda1a0f30 100644 --- a/src/filters/specularlighting.cpp +++ b/src/filters/specularlighting.cpp @@ -14,10 +14,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include "strneq.h" #include "attributes.h" @@ -36,16 +32,6 @@ /* FeSpecularLighting base class */ static void sp_feSpecularLighting_children_modified(SPFeSpecularLighting *sp_specularlighting); -#include "sp-factory.h" - -namespace { - SPObject* createSpecularLighting() { - return new SPFeSpecularLighting(); - } - - bool specularLightingRegistered = SPFactory::instance().registerObject("svg:feSpecularLighting", createSpecularLighting); -} - SPFeSpecularLighting::SPFeSpecularLighting() : SPFilterPrimitive() { this->surfaceScale = 1; this->specularConstant = 1; diff --git a/src/filters/spotlight.cpp b/src/filters/spotlight.cpp index c0344067c..2e55d39d0 100644 --- a/src/filters/spotlight.cpp +++ b/src/filters/spotlight.cpp @@ -13,10 +13,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include <glib.h> #include "attributes.h" @@ -29,16 +25,6 @@ #define SP_MACROS_SILENT #include "macros.h" -#include "sp-factory.h" - -namespace { - SPObject* createSpotLight() { - return new SPFeSpotLight(); - } - - bool spotLightRegistered = SPFactory::instance().registerObject("svg:feSpotLight", createSpotLight); -} - SPFeSpotLight::SPFeSpotLight() : SPObject(), x(0), x_set(FALSE), y(0), y_set(FALSE), z(0), z_set(FALSE), pointsAtX(0), pointsAtX_set(FALSE), pointsAtY(0), pointsAtY_set(FALSE), pointsAtZ(0), pointsAtZ_set(FALSE), diff --git a/src/filters/tile.cpp b/src/filters/tile.cpp index 19e96f47d..623f3ab37 100644 --- a/src/filters/tile.cpp +++ b/src/filters/tile.cpp @@ -11,10 +11,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include "attributes.h" #include "svg/svg.h" #include "filters/tile.h" @@ -22,16 +18,6 @@ #include "display/nr-filter.h" #include "display/nr-filter-tile.h" -#include "sp-factory.h" - -namespace { - SPObject* createTile() { - return new SPFeTile(); - } - - bool tileRegistered = SPFactory::instance().registerObject("svg:feTile", createTile); -} - SPFeTile::SPFeTile() : SPFilterPrimitive() { } diff --git a/src/filters/turbulence.cpp b/src/filters/turbulence.cpp index d33667a8c..7541175ed 100644 --- a/src/filters/turbulence.cpp +++ b/src/filters/turbulence.cpp @@ -14,10 +14,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include "attributes.h" #include "svg/svg.h" #include "turbulence.h" @@ -28,16 +24,6 @@ #include "display/nr-filter.h" #include "display/nr-filter-turbulence.h" -#include "sp-factory.h" - -namespace { - SPObject* createTurbulence() { - return new SPFeTurbulence(); - } - - bool turbulenceRegistered = SPFactory::instance().registerObject("svg:feTurbulence", createTurbulence); -} - SPFeTurbulence::SPFeTurbulence() : SPFilterPrimitive() { this->stitchTiles = 0; this->seed = 0; diff --git a/src/gc-allocator.h b/src/gc-allocator.h deleted file mode 100644 index e69de29bb..000000000 --- a/src/gc-allocator.h +++ /dev/null diff --git a/src/gc-anchored.h b/src/gc-anchored.h index 99b78c784..33305df5c 100644 --- a/src/gc-anchored.h +++ b/src/gc-anchored.h @@ -9,7 +9,7 @@ #ifndef SEEN_INKSCAPE_GC_ANCHORED_H #define SEEN_INKSCAPE_GC_ANCHORED_H -#include "gc-managed.h" +#include "inkgc/gc-managed.h" namespace Inkscape { diff --git a/src/gc-finalized.h b/src/gc-finalized.h index 814a2af18..d39338643 100644 --- a/src/gc-finalized.h +++ b/src/gc-finalized.h @@ -18,7 +18,7 @@ #include <new> #include <cstddef> -#include "gc-core.h" +#include "inkgc/gc-core.h" namespace Inkscape { diff --git a/src/gradient-chemistry.cpp b/src/gradient-chemistry.cpp index 27f4d7a98..aecf1aa35 100644 --- a/src/gradient-chemistry.cpp +++ b/src/gradient-chemistry.cpp @@ -31,7 +31,7 @@ #include "document-undo.h" #include "desktop.h" #include "desktop-style.h" -#include "desktop-handles.h" + #include "ui/tools/tool-base.h" #include "selection.h" #include "verbs.h" @@ -41,7 +41,7 @@ #include "sp-gradient-vector.h" #include "sp-linear-gradient.h" #include "sp-radial-gradient.h" -#include "sp-mesh-gradient.h" +#include "sp-mesh.h" #include "sp-stop.h" #include "gradient-drag.h" #include "gradient-chemistry.h" @@ -151,7 +151,7 @@ static SPGradient *sp_gradient_get_private_normalized(SPDocument *document, SPGr repr = xml_doc->createElement("svg:radialGradient"); } else { // Rows/patches added in sp_gradient_reset_to_userspace for new meshes. - repr = xml_doc->createElement("svg:meshGradient"); + repr = xml_doc->createElement("svg:mesh"); } // privates are garbage-collectable @@ -413,7 +413,7 @@ SPGradient *sp_gradient_reset_to_userspace(SPGradient *gr, SPItem *item) // IN SPMeshNodeArray::create() //sp_repr_set_svg_double(repr, "x", bbox->min()[Geom::X]); //sp_repr_set_svg_double(repr, "y", bbox->min()[Geom::Y]); - SPMeshGradient* mg = SP_MESHGRADIENT( gr ); + SPMesh* mg = SP_MESH( gr ); mg->array.create( mg, item, bbox ); } @@ -758,10 +758,10 @@ guint32 sp_item_gradient_stop_query_style(SPItem *item, GrPointType point_type, break; } return 0; - } else if (SP_IS_MESHGRADIENT(gradient)) { + } else if (SP_IS_MESH(gradient)) { // Mesh gradient - SPMeshGradient *mg = SP_MESHGRADIENT(gradient); + SPMesh *mg = SP_MESH(gradient); switch (point_type) { case POINT_MG_CORNER: { @@ -859,7 +859,7 @@ void sp_item_gradient_stop_set_style(SPItem *item, GrPointType point_type, guint } else { // Mesh gradient - SPMeshGradient *mg = SP_MESHGRADIENT(gradient); + SPMesh *mg = SP_MESH(gradient); bool changed = false; switch (point_type) { @@ -868,9 +868,8 @@ void sp_item_gradient_stop_set_style(SPItem *item, GrPointType point_type, guint gchar const* color_str = sp_repr_css_property( stop, "stop-color", NULL ); if( color_str ) { SPColor color( 0 ); - SPStyle* style = sp_style_new(0); SPIPaint paint; - paint.read( color_str, *style ); + paint.read( color_str ); if( paint.isColor() ) { color = paint.value.color; } @@ -1210,8 +1209,8 @@ void sp_item_gradient_set_coords(SPItem *item, GrPointType point_type, guint poi gradient->requestModified(SP_OBJECT_MODIFIED_FLAG); } } - } else if (SP_IS_MESHGRADIENT(gradient)) { - SPMeshGradient *mg = SP_MESHGRADIENT(gradient); + } else if (SP_IS_MESH(gradient)) { + SPMesh *mg = SP_MESH(gradient); //Geom::Affine new_transform; //bool transform_set = false; @@ -1241,7 +1240,7 @@ void sp_item_gradient_set_coords(SPItem *item, GrPointType point_type, guint poi } if( write_repr ) { //std::cout << "Write mesh repr" << std::endl; - sp_meshgradient_repr_write( mg ); + sp_mesh_repr_write( mg ); } } @@ -1347,8 +1346,8 @@ Geom::Point getGradientCoords(SPItem *item, GrPointType point_type, guint point_ g_warning( "Bad radial gradient handle type" ); break; } - } else if (SP_IS_MESHGRADIENT(gradient)) { - SPMeshGradient *mg = SP_MESHGRADIENT(gradient); + } else if (SP_IS_MESH(gradient)) { + SPMesh *mg = SP_MESH(gradient); switch (point_type) { case POINT_MG_CORNER: @@ -1569,20 +1568,20 @@ SPGradient *sp_gradient_vector_for_object( SPDocument *const doc, SPDesktop *con void sp_gradient_invert_selected_gradients(SPDesktop *desktop, Inkscape::PaintTarget fill_or_stroke) { - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); for (GSList const* i = selection->itemList(); i != NULL; i = i->next) { sp_item_gradient_invert_vector_color(SP_ITEM(i->data), fill_or_stroke); } // we did an undoable action - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_GRADIENT, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_GRADIENT, _("Invert gradient colors")); } void sp_gradient_reverse_selected_gradients(SPDesktop *desktop) { - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); Inkscape::UI::Tools::ToolBase *ev = desktop->getEventContext(); if (!ev) { @@ -1602,7 +1601,7 @@ void sp_gradient_reverse_selected_gradients(SPDesktop *desktop) } // we did an undoable action - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_GRADIENT, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_GRADIENT, _("Reverse gradient")); } diff --git a/src/gradient-drag.cpp b/src/gradient-drag.cpp index d945231fc..cb2bd737f 100644 --- a/src/gradient-drag.cpp +++ b/src/gradient-drag.cpp @@ -22,11 +22,11 @@ #include <cstring> #include <string> -#include "desktop-handles.h" + #include "selection.h" #include "desktop.h" #include "desktop-style.h" -#include "desktop-handles.h" + #include "document.h" #include "document-undo.h" #include "display/sp-ctrlline.h" @@ -43,7 +43,7 @@ #include "knot.h" #include "sp-linear-gradient.h" #include "sp-radial-gradient.h" -#include "sp-mesh-gradient.h" +#include "sp-mesh.h" #include "sp-mesh-row.h" #include "sp-mesh-patch.h" #include "gradient-chemistry.h" @@ -414,7 +414,7 @@ SPStop *GrDrag::addStopNearPoint(SPItem *item, Geom::Point mouse_p, double toler //r1_knot = false; } } - } else if (SP_IS_MESHGRADIENT(gradient)) { + } else if (SP_IS_MESH(gradient)) { // add_stop_near_point() // Find out which curve pointer is over and use that curve to determine @@ -422,7 +422,7 @@ SPStop *GrDrag::addStopNearPoint(SPItem *item, Geom::Point mouse_p, double toler // This is silly as we already should know which line we are over... // but that information is not saved (sp_gradient_context_is_over_line). - SPMeshGradient *mg = SP_MESHGRADIENT(gradient); + SPMesh *mg = SP_MESH(gradient); Geom::Affine transform = Geom::Affine(mg->gradientTransform)*(Geom::Affine)item->i2dt_affine(); guint rows = mg->array.patch_rows(); @@ -550,7 +550,7 @@ SPStop *GrDrag::addStopNearPoint(SPItem *item, Geom::Point mouse_p, double toler } else { - SPMeshGradient *mg = SP_MESHGRADIENT(gradient); + SPMesh *mg = SP_MESH(gradient); if( divide_row > -1 ) { mg->array.split_row( divide_row, divide_coord ); @@ -559,11 +559,11 @@ SPStop *GrDrag::addStopNearPoint(SPItem *item, Geom::Point mouse_p, double toler } // Update repr - sp_meshgradient_repr_write( mg ); + sp_mesh_repr_write( mg ); mg->array.built = false; mg->ensureArray(); // How do we do this? - DocumentUndo::done(sp_desktop_document (desktop), SP_VERB_CONTEXT_MESH, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MESH, _("Added patch row or column")); } // Mesh @@ -631,7 +631,7 @@ GrDrag::GrDrag(SPDesktop *desktop) : vert_levels(), draggers(0), lines(0), - selection(sp_desktop_selection(desktop)), + selection(desktop->getSelection()), sel_changed_connection(), sel_modified_connection(), style_set_connection(), @@ -796,7 +796,7 @@ static void gr_knot_moved_handler(SPKnot *knot, Geom::Point const &ppointer, gui d_new->updateKnotShape (); d_new->updateTip (); d_new->updateDependencies(true); - DocumentUndo::done(sp_desktop_document (d_new->parent->desktop), SP_VERB_CONTEXT_GRADIENT, _("Merge gradient handles")); + DocumentUndo::done(d_new->parent->desktop->getDocument(), SP_VERB_CONTEXT_GRADIENT, _("Merge gradient handles")); return; } } @@ -1102,8 +1102,7 @@ static void gr_knot_ungrabbed_handler(SPKnot *knot, unsigned int state, gpointer dragger->updateDependencies(true); // we did an undoable action - DocumentUndo::done(sp_desktop_document (dragger->parent->desktop), SP_VERB_CONTEXT_GRADIENT, - _("Move gradient handle")); + DocumentUndo::done(dragger->parent->desktop->getDocument(), SP_VERB_CONTEXT_GRADIENT, _("Move gradient handle")); } /** @@ -1350,7 +1349,7 @@ GrDragger::updateHandles ( Geom::Point pc_old, MeshNodeOperation op ) // Must be a mesh gradient SPGradient *gradient = getGradient(draggable->item, draggable->fill_or_stroke); - if ( !SP_IS_MESHGRADIENT( gradient ) ) continue; + if ( !SP_IS_MESH( gradient ) ) continue; selected_corners[ gradient ].push_back( draggable->point_i ); } @@ -1375,8 +1374,8 @@ GrDragger::updateHandles ( Geom::Point pc_old, MeshNodeOperation op ) // Must be a mesh gradient SPGradient *gradient = getGradient(item, fill_or_stroke); - if ( !SP_IS_MESHGRADIENT( gradient ) ) continue; - SPMeshGradient *mg = SP_MESHGRADIENT( gradient ); + if ( !SP_IS_MESH( gradient ) ) continue; + SPMesh *mg = SP_MESH( gradient ); // pc_old is the old corner position in desktop coordinates, we need it in gradient coordinate. gradient = sp_gradient_convert_to_userspace (gradient, item, (fill_or_stroke == Inkscape::FOR_FILL) ? "fill" : "stroke"); @@ -1869,7 +1868,7 @@ void GrDrag::setDeselected(GrDragger *dragger) void GrDrag::addLine(SPItem *item, Geom::Point p1, Geom::Point p2, Inkscape::PaintTarget fill_or_stroke) { CtrlLineType type = (fill_or_stroke == Inkscape::FOR_FILL) ? CTLINE_PRIMARY : CTLINE_SECONDARY; - SPCtrlLine *line = ControlManager::getManager().createControlLine(sp_desktop_controls(this->desktop), p1, p2, type); + SPCtrlLine *line = ControlManager::getManager().createControlLine(this->desktop->getControls(), p1, p2, type); sp_canvas_item_move_to_z(line, 0); line->item = item; @@ -1885,7 +1884,7 @@ void GrDrag::addLine(SPItem *item, Geom::Point p1, Geom::Point p2, Inkscape::Pai void GrDrag::addCurve(SPItem *item, Geom::Point p0, Geom::Point p1, Geom::Point p2, Geom::Point p3, Inkscape::PaintTarget fill_or_stroke) { CtrlLineType type = (fill_or_stroke == Inkscape::FOR_FILL) ? CTLINE_PRIMARY : CTLINE_SECONDARY; - SPCtrlCurve *line = ControlManager::getManager().createControlCurve(sp_desktop_controls(this->desktop), p0, p1, p2, p3, type); + SPCtrlCurve *line = ControlManager::getManager().createControlCurve(this->desktop->getControls(), p0, p1, p2, p3, type); sp_canvas_item_move_to_z(line, 0); line->item = item; @@ -1959,7 +1958,7 @@ void GrDrag::addDraggersLinear(SPLinearGradient *lg, SPItem *item, Inkscape::Pai /** *Add draggers for the mesh gradient mg on item */ -void GrDrag::addDraggersMesh(SPMeshGradient *mg, SPItem *item, Inkscape::PaintTarget fill_or_stroke) +void GrDrag::addDraggersMesh(SPMesh *mg, SPItem *item, Inkscape::PaintTarget fill_or_stroke) { std::vector< std::vector< SPMeshNode* > > nodes = mg->array.nodes; @@ -1978,7 +1977,7 @@ void GrDrag::addDraggersMesh(SPMeshGradient *mg, SPItem *item, Inkscape::PaintTa // Make sure we have at least one patch defined. if( mg->array.patch_rows() == 0 || mg->array.patch_columns() == 0 ) { - std::cout << "Empty Mesh Gradient, No Draggers to Add" << std::endl; + std::cout << "Empty Mesh, No Draggers to Add" << std::endl; return; } @@ -2033,7 +2032,7 @@ void GrDrag::addDraggersMesh(SPMeshGradient *mg, SPItem *item, Inkscape::PaintTa } default: - std::cout << "Bad Mesh Gradient draggable type" << std::endl; + std::cout << "Bad Mesh draggable type" << std::endl; break; } } @@ -2098,8 +2097,8 @@ void GrDrag::updateDraggers() addDraggersLinear( SP_LINEARGRADIENT(server), item, Inkscape::FOR_FILL ); } else if ( SP_IS_RADIALGRADIENT(server) ) { addDraggersRadial( SP_RADIALGRADIENT(server), item, Inkscape::FOR_FILL ); - } else if ( SP_IS_MESHGRADIENT(server) ) { - addDraggersMesh( SP_MESHGRADIENT(server), item, Inkscape::FOR_FILL ); + } else if ( SP_IS_MESH(server) ) { + addDraggersMesh( SP_MESH(server), item, Inkscape::FOR_FILL ); } } } @@ -2114,8 +2113,8 @@ void GrDrag::updateDraggers() addDraggersLinear( SP_LINEARGRADIENT(server), item, Inkscape::FOR_STROKE ); } else if ( SP_IS_RADIALGRADIENT(server) ) { addDraggersRadial( SP_RADIALGRADIENT(server), item, Inkscape::FOR_STROKE ); - } else if ( SP_IS_MESHGRADIENT(server) ) { - addDraggersMesh( SP_MESHGRADIENT(server), item, Inkscape::FOR_STROKE ); + } else if ( SP_IS_MESH(server) ) { + addDraggersMesh( SP_MESH(server), item, Inkscape::FOR_STROKE ); } } } @@ -2170,9 +2169,9 @@ void GrDrag::updateLines() Geom::Point center = getGradientCoords(item, POINT_RG_CENTER, 0, Inkscape::FOR_FILL); addLine(item, center, getGradientCoords(item, POINT_RG_R1, 0, Inkscape::FOR_FILL), Inkscape::FOR_FILL); addLine(item, center, getGradientCoords(item, POINT_RG_R2, 0, Inkscape::FOR_FILL), Inkscape::FOR_FILL); - } else if ( SP_IS_MESHGRADIENT(server) ) { + } else if ( SP_IS_MESH(server) ) { - SPMeshGradient *mg = SP_MESHGRADIENT(server); + SPMesh *mg = SP_MESH(server); guint rows = mg->array.patch_rows(); guint columns = mg->array.patch_columns(); @@ -2232,10 +2231,10 @@ void GrDrag::updateLines() Geom::Point center = getGradientCoords(item, POINT_RG_CENTER, 0, Inkscape::FOR_STROKE); addLine(item, center, getGradientCoords(item, POINT_RG_R1, 0, Inkscape::FOR_STROKE), Inkscape::FOR_STROKE); addLine(item, center, getGradientCoords(item, POINT_RG_R2, 0, Inkscape::FOR_STROKE), Inkscape::FOR_STROKE); - } else if ( SP_IS_MESHGRADIENT(server) ) { + } else if ( SP_IS_MESH(server) ) { // MESH FIXME: TURN ROUTINE INTO FUNCTION AND CALL FOR BOTH FILL AND STROKE. - SPMeshGradient *mg = SP_MESHGRADIENT(server); + SPMesh *mg = SP_MESH(server); guint rows = mg->array.patch_rows(); guint columns = mg->array.patch_columns(); @@ -2375,7 +2374,7 @@ void GrDrag::selected_move(double x, double y, bool write_repr, bool scale_radia if (write_repr && did) { // we did an undoable action - DocumentUndo::maybeDone(sp_desktop_document (desktop), "grmoveh", SP_VERB_CONTEXT_GRADIENT, + DocumentUndo::maybeDone(desktop->getDocument(), "grmoveh", SP_VERB_CONTEXT_GRADIENT, _("Move gradient handle(s)")); return; } @@ -2411,7 +2410,7 @@ void GrDrag::selected_move(double x, double y, bool write_repr, bool scale_radia if (write_repr && did) { // we did an undoable action - DocumentUndo::maybeDone(sp_desktop_document (desktop), "grmovem", SP_VERB_CONTEXT_GRADIENT, + DocumentUndo::maybeDone(desktop->getDocument(), "grmovem", SP_VERB_CONTEXT_GRADIENT, _("Move gradient mid stop(s)")); } } diff --git a/src/gradient-drag.h b/src/gradient-drag.h index 964ea8093..da264b4bb 100644 --- a/src/gradient-drag.h +++ b/src/gradient-drag.h @@ -33,7 +33,7 @@ class SPKnot; class SPDesktop; class SPCSSAttr; class SPLinearGradient; -class SPMeshGradient; +class SPMesh; class SPItem; class SPObject; class SPRadialGradient; @@ -206,7 +206,7 @@ private: void addDraggersRadial(SPRadialGradient *rg, SPItem *item, Inkscape::PaintTarget fill_or_stroke); void addDraggersLinear(SPLinearGradient *lg, SPItem *item, Inkscape::PaintTarget fill_or_stroke); - void addDraggersMesh( SPMeshGradient *mg, SPItem *item, Inkscape::PaintTarget fill_or_stroke); + void addDraggersMesh( SPMesh *mg, SPItem *item, Inkscape::PaintTarget fill_or_stroke); bool styleSet( const SPCSSAttr *css ); diff --git a/src/graphlayout.cpp b/src/graphlayout.cpp index 18159cb41..e5d61ab64 100644 --- a/src/graphlayout.cpp +++ b/src/graphlayout.cpp @@ -117,7 +117,7 @@ void graphlayout(GSList const *const items) { // add the connector spacing to the size of node bounding boxes // so that connectors can always be routed between shapes - SPDesktop* desktop = inkscape_active_desktop(); + SPDesktop* desktop = SP_ACTIVE_DESKTOP; double spacing = 0; if(desktop) spacing = desktop->namedview->connector_spacing+0.1; diff --git a/src/helper/CMakeLists.txt b/src/helper/CMakeLists.txt index b0e473ddd..74ce2c85d 100644 --- a/src/helper/CMakeLists.txt +++ b/src/helper/CMakeLists.txt @@ -32,6 +32,7 @@ set(helper_SRC geom-nodetype.h geom.h gnome-utils.h + mathfns.h pixbuf-ops.h png-write.h stock-items.h diff --git a/src/helper/Makefile_insert b/src/helper/Makefile_insert index 4c6437f13..5cb4cea8d 100644 --- a/src/helper/Makefile_insert +++ b/src/helper/Makefile_insert @@ -14,6 +14,7 @@ ink_common_sources += \ helper/geom-nodetype.h \ helper/gnome-utils.cpp \ helper/gnome-utils.h \ + helper/mathfns.h \ helper/png-write.cpp \ helper/png-write.h \ helper/sp-marshal.cpp \ diff --git a/src/helper/geom.cpp b/src/helper/geom.cpp index 6eba6e949..91689375f 100644 --- a/src/helper/geom.cpp +++ b/src/helper/geom.cpp @@ -556,6 +556,55 @@ pathv_to_linear( Geom::PathVector const &pathv, double /*maxdisp*/) return output; } +/* + * Converts all segments in all paths to Geom Cubic bezier. + * This is used in lattice2 LPE, maybe is better move the function to the effect + * But maybe could be usable by others, so i put here. + * The straight curve part is needed as it for the effect to work apropiately + */ +Geom::PathVector +pathv_to_cubicbezier( Geom::PathVector const &pathv) +{ + Geom::PathVector output; + double cubicGap = 0.01; + for (Geom::PathVector::const_iterator pit = pathv.begin(); pit != pathv.end(); ++pit) { + output.push_back( Geom::Path() ); + output.back().start( pit->initialPoint() ); + output.back().close( pit->closed() ); + bool end_open = false; + if (pit->closed()) { + const Geom::Curve &closingline = pit->back_closed(); + if (!are_near(closingline.initialPoint(), closingline.finalPoint())) { + end_open = true; + } + } + Geom::Path pitCubic = (Geom::Path)(*pit); + if(end_open && pit->closed()){ + pitCubic.close(false); + pitCubic.appendNew<Geom::LineSegment>( pitCubic.initialPoint() ); + pitCubic.close(true); + } + for (Geom::Path::const_iterator cit = pitCubic.begin(); cit != pitCubic.end_open(); ++cit) { + if (is_straight_curve(*cit)) { + Geom::CubicBezier b(cit->initialPoint(), cit->pointAt(0.3334) + Geom::Point(cubicGap,cubicGap), cit->finalPoint(), cit->finalPoint()); + output.back().append(b); + } else { + Geom::BezierCurve const *curve = dynamic_cast<Geom::BezierCurve const *>(&*cit); + if (curve && curve->order() == 3) { + Geom::CubicBezier b((*curve)[0], (*curve)[1], (*curve)[2], (*curve)[3]); + output.back().append(b); + } else { + // convert all other curve types to cubicbeziers + Geom::Path cubicbezier_path = Geom::cubicbezierpath_from_sbasis(cit->toSBasis(), 0.1); + output.back().append(cubicbezier_path); + } + } + } + } + + return output; +} + // The next routine is modified from curv4_div::recursive_bezier from file agg_curves.cpp //---------------------------------------------------------------------------- // Anti-Grain Geometry (AGG) - Version 2.5 diff --git a/src/helper/geom.h b/src/helper/geom.h index caff95733..3232d9fd5 100644 --- a/src/helper/geom.h +++ b/src/helper/geom.h @@ -27,6 +27,7 @@ void pathv_matrix_point_bbox_wind_distance ( Geom::PathVector const & pathv, Geo Geom::PathVector pathv_to_linear_and_cubic_beziers( Geom::PathVector const &pathv ); Geom::PathVector pathv_to_linear( Geom::PathVector const &pathv, double maxdisp ); +Geom::PathVector pathv_to_cubicbezier( Geom::PathVector const &pathv); void recursive_bezier4(const double x1, const double y1, const double x2, const double y2, const double x3, const double y3, const double x4, const double y4, std::vector<Geom::Point> &pointlist, diff --git a/src/util/mathfns.h b/src/helper/mathfns.h index 830e159da..8fb88dc26 100644 --- a/src/util/mathfns.h +++ b/src/helper/mathfns.h @@ -1,5 +1,5 @@ /* - * Inkscape::Util::... some mathmatical functions + * ... some mathmatical functions * * Authors: * Johan Engelen <goejendaagh@zonnet.nl> @@ -65,7 +65,6 @@ inline double round_to_upper_multiple_plus(double x, double const c1, double con return ceil((x - c0) / c1) * c1 + c0; } - } } diff --git a/src/helper/stock-items.cpp b/src/helper/stock-items.cpp index 582dcd2a8..5a56b89ff 100644 --- a/src/helper/stock-items.cpp +++ b/src/helper/stock-items.cpp @@ -29,7 +29,7 @@ #include "document-private.h" #include "sp-pattern.h" #include "sp-marker.h" -#include "desktop-handles.h" +#include "desktop.h" #include "inkscape.h" #include "io/sys.h" @@ -195,8 +195,8 @@ SPObject *get_stock_item(gchar const *urn, gboolean stock) gchar * base = g_strndup(e, a); - SPDesktop *desktop = inkscape_active_desktop(); - SPDocument *doc = sp_desktop_document(desktop); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + SPDocument *doc = desktop->getDocument(); SPDefs *defs = doc->getDefs(); if (!defs) { g_free(base); @@ -265,8 +265,8 @@ SPObject *get_stock_item(gchar const *urn, gboolean stock) else { - SPDesktop *desktop = inkscape_active_desktop(); - SPDocument *doc = sp_desktop_document(desktop); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + SPDocument *doc = desktop->getDocument(); SPObject *object = doc->getObjectById(urn); return object; diff --git a/src/inkgc/CMakeLists.txt b/src/inkgc/CMakeLists.txt new file mode 100644 index 000000000..22dd464e1 --- /dev/null +++ b/src/inkgc/CMakeLists.txt @@ -0,0 +1,15 @@ + +set(libgc_SRC + gc.cpp + + # ------- + # Headers + gc-alloc.h + gc-anchored.h + gc-core.h + gc-managed.h + gc-soft-ptr.h +) + +add_inkscape_lib(gc_LIB "${libgc_SRC}") +# add_inkscape_source("${libgc_SRC}") diff --git a/src/inkgc/Makefile_insert b/src/inkgc/Makefile_insert new file mode 100644 index 000000000..58aa39bb9 --- /dev/null +++ b/src/inkgc/Makefile_insert @@ -0,0 +1,13 @@ +## Makefile.am fragment sourced by src/Makefile.am. + +inkgc/all: inkgc/libinkgc.a + +inkgc/clean: + rm -f inkgc/libinkgc.a $(inkgc_libinkgc_a_OBJECTS) + +inkgc_libinkgc_a_SOURCES = \ + inkgc/gc.cpp \ + inkgc/gc-alloc.h \ + inkgc/gc-core.h \ + inkgc/gc-managed.h \ + inkgc/gc-soft-ptr.h diff --git a/src/gc-alloc.h b/src/inkgc/gc-alloc.h index ba672ae2c..917ee972d 100644 --- a/src/gc-alloc.h +++ b/src/inkgc/gc-alloc.h @@ -17,7 +17,7 @@ #include <limits> #include <cstddef> -#include "gc-core.h" +#include "inkgc/gc-core.h" namespace Inkscape { diff --git a/src/gc-core.h b/src/inkgc/gc-core.h index d9d0bf4ff..d9d0bf4ff 100644 --- a/src/gc-core.h +++ b/src/inkgc/gc-core.h diff --git a/src/gc-managed.h b/src/inkgc/gc-managed.h index 74d224c9b..f435d7802 100644 --- a/src/gc-managed.h +++ b/src/inkgc/gc-managed.h @@ -14,7 +14,7 @@ #ifndef SEEN_INKSCAPE_GC_MANAGED_H #define SEEN_INKSCAPE_GC_MANAGED_H -#include "gc-core.h" +#include "inkgc/gc-core.h" namespace Inkscape { diff --git a/src/gc-soft-ptr.h b/src/inkgc/gc-soft-ptr.h index 9e7304939..45a3ddcf7 100644 --- a/src/gc-soft-ptr.h +++ b/src/inkgc/gc-soft-ptr.h @@ -13,7 +13,7 @@ #ifndef SEEN_INKSCAPE_GC_SOFT_PTR_H #define SEEN_INKSCAPE_GC_SOFT_PTR_H -#include "gc-core.h" +#include "inkgc/gc-core.h" namespace Inkscape { diff --git a/src/gc.cpp b/src/inkgc/gc.cpp index 280a8b1dc..90c02d9c8 100644 --- a/src/gc.cpp +++ b/src/inkgc/gc.cpp @@ -9,7 +9,7 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include "gc-core.h" +#include "inkgc/gc-core.h" #include <stdexcept> #include <cstring> #include <string> diff --git a/src/inkscape-private.h b/src/inkscape-private.h deleted file mode 100644 index d28ed223e..000000000 --- a/src/inkscape-private.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef SEEN_INKSCAPE_PRIVATE_H -#define SEEN_INKSCAPE_PRIVATE_H - -/* - * Some forward declarations - * - * Authors: - * Lauris Kaplinski <lauris@kaplinski.com> - * - * Copyright (C) 1999-2002 Lauris Kaplinski - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ -#include <glib-object.h> - -#define SP_TYPE_INKSCAPE (inkscape_get_type ()) -#define SP_INKSCAPE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_INKSCAPE, Inkscape)) -#define SP_INKSCAPE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_INKSCAPE, InkscapeClass)) -#define SP_IS_INKSCAPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_INKSCAPE)) -#define SP_IS_INKSCAPE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_INKSCAPE)) - -#include "inkscape.h" - -struct SPColor; -namespace Inkscape { class Selection; } - -GType inkscape_get_type (void); - -void inkscape_ref (void); -void inkscape_unref (void); - -guint inkscape_mapalt(); -void inkscape_mapalt(guint); - -guint inkscape_trackalt(); -void inkscape_trackalt(guint); - -/* - * These are meant solely for desktop, document etc. implementations - */ - -void inkscape_selection_modified (Inkscape::Selection *selection, guint flags); -void inkscape_selection_changed (Inkscape::Selection * selection); -void inkscape_selection_set (Inkscape::Selection * selection); -void inkscape_eventcontext_set (Inkscape::UI::Tools::ToolBase * eventcontext); -void inkscape_add_desktop (SPDesktop * desktop); -void inkscape_remove_desktop (SPDesktop * desktop); -void inkscape_activate_desktop (SPDesktop * desktop); -void inkscape_reactivate_desktop (SPDesktop * desktop); - -void inkscape_set_color (SPColor *color, float opacity); - -#endif // SEEN_INKSCAPE_PRIVATE_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:fileencoding=utf-8:textwidth=99 : diff --git a/src/inkscape.cpp b/src/inkscape.cpp index 36a802e5f..6a0e0f35a 100644 --- a/src/inkscape.cpp +++ b/src/inkscape.cpp @@ -1,13 +1,15 @@ /** * @file - * Legacy interface to main application. + * Interface to main application. */ /* Authors: * Lauris Kaplinski <lauris@kaplinski.com> * bulia byak <buliabyak@users.sf.net> + * Liam P. White <inkscapebrony@gmail.com> * - * Copyright (C) 1999-2005 authors - * g++ port Copyright (C) 2003 Nathan Hurst + * Copyright (C) 1999-2014 authors + * c++ port Copyright (C) 2003 Nathan Hurst + * c++ification Copyright (C) 2014 Liam P. White * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -50,240 +52,174 @@ #include <gtk/gtk.h> #include <signal.h> #include <string> + #include "desktop.h" -#include "desktop-handles.h" + #include "device-manager.h" #include "document.h" -#include "ui/tools/tool-base.h" #include "extension/db.h" #include "extension/init.h" #include "extension/output.h" #include "extension/system.h" -#include "inkscape-private.h" +#include "helper/action-context.h" +#include "helper/sp-marshal.h" +#include "inkscape.h" #include "io/sys.h" #include "layer-model.h" #include "message-stack.h" #include "preferences.h" #include "resource-manager.h" #include "selection.h" +#include "ui/tools/tool-base.h" #include "ui/dialog/debug.h" #include "xml/repr.h" -#include "helper/action-context.h" -#include "helper/sp-marshal.h" - -static InkscapeApplication *inkscape = NULL; /* Backbones of configuration xml data */ #include "menus-skeleton.h" -enum { - MODIFY_SELECTION, // global: one of selections modified - CHANGE_SELECTION, // global: one of selections changed - CHANGE_SUBSELECTION, // global: one of subselections (text selection, gradient handle, etc) changed - SET_SELECTION, // global: one of selections set - SET_EVENTCONTEXT, // tool switched - ACTIVATE_DESKTOP, // some desktop got focus - DEACTIVATE_DESKTOP, // some desktop lost focus - SHUTDOWN_SIGNAL, // inkscape is quitting - DIALOGS_HIDE, // user pressed F12 - DIALOGS_UNHIDE, // user pressed F12 - EXTERNAL_CHANGE, // a document was changed by some external means (undo or XML editor); this - // may not be reflected by a selection change and thus needs a separate signal - LAST_SIGNAL -}; +// Inkscape::Application static members +Inkscape::Application * Inkscape::Application::_S_inst = NULL; +bool Inkscape::Application::_crashIsHappening = false; -#define DESKTOP_IS_ACTIVE(d) (inkscape->desktops && ((d) == inkscape->desktops->data)) +#define DESKTOP_IS_ACTIVE(d) (!INKSCAPE._desktops->empty() && ((d) == INKSCAPE._desktops->front())) +static void (* segv_handler) (int) = SIG_DFL; +static void (* abrt_handler) (int) = SIG_DFL; +static void (* fpe_handler) (int) = SIG_DFL; +static void (* ill_handler) (int) = SIG_DFL; +#ifndef WIN32 +static void (* bus_handler) (int) = SIG_DFL; +#endif -/*################################ -# FORWARD DECLARATIONS -################################*/ +#define INKSCAPE_PROFILE_DIR "inkscape" +#define INKSCAPE_PROFILE_DIR_047DEV "Inkscape" +#define INKSCAPE_LEGACY_PROFILE_DIR ".inkscape" +#define MENUS_FILE "menus.xml" -static void inkscape_dispose (GObject *object); +#define SP_INDENT 8 -static void inkscape_activate_desktop_private (InkscapeApplication *inkscape, SPDesktop *desktop); -static void inkscape_deactivate_desktop_private (InkscapeApplication *inkscape, SPDesktop *desktop); +#ifdef WIN32 +typedef int uid_t; +#define getuid() 0 +#endif + +/** C++ification TODO list + * - _S_inst should NOT need to be assigned inside the constructor, but if it isn't the Filters+Extensions menus break. + * - Application::_deskops has to be a pointer because of a signal bug somewhere else. Basically, it will attempt to access a deleted object in sp_ui_close_all(), + * but if it's a pointer we can stop and return NULL in Application::active_desktop() + * - These functions are calling Application::create for no good reason I can determine: + * + * Inkscape::UI::Dialog::SVGPreview::SVGPreview() + * src/ui/dialog/filedialogimpl-gtkmm.cpp:542:9 + * void Inkscape::UI::Widget::ImageIcon::init() + * src/ui/widget/imageicon.cpp:93:9 + */ -class AppSelectionModel { - Inkscape::LayerModel _layer_model; - Inkscape::Selection *_selection; +class InkErrorHandler : public Inkscape::ErrorReporter { public: - AppSelectionModel(SPDocument *doc) { - _layer_model.setDocument(doc); - // TODO: is this really how we should manage the lifetime of the selection? - // I just copied this from the initialization of the Selection in SPDesktop. - // When and how is it actually released? - _selection = Inkscape::GC::release(new Inkscape::Selection(&_layer_model, NULL)); + InkErrorHandler(bool useGui) : Inkscape::ErrorReporter(), + _useGui(useGui) + {} + virtual ~InkErrorHandler() {} + + virtual void handleError( Glib::ustring const& primary, Glib::ustring const& secondary ) const + { + if (_useGui) { + Gtk::MessageDialog err(primary, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK, true); + err.set_secondary_text(secondary); + err.run(); + } else { + g_message("%s", primary.data()); + g_message("%s", secondary.data()); + } } - Inkscape::Selection *getSelection() const { return _selection; } +private: + bool _useGui; }; -struct InkscapeApplication { - GObject object; - Inkscape::XML::Document *menus; - std::map<SPDocument *, int> document_set; - std::map<SPDocument *, AppSelectionModel *> selection_models; - GSList *desktops; - gchar *argv0; - gboolean dialogs_toggle; - gboolean use_gui; // may want to consider a virtual function - // for overriding things like the warning dlg's - guint mapalt; - guint trackalt; -}; +void inkscape_ref(Inkscape::Application & in) +{ + in.refCount++; +} -struct InkscapeApplicationClass { - GObjectClass object_class; - - /* Signals */ - void (* change_selection) (InkscapeApplication * inkscape, Inkscape::Selection * selection); - void (* change_subselection) (InkscapeApplication * inkscape, SPDesktop *desktop); - void (* modify_selection) (InkscapeApplication * inkscape, Inkscape::Selection * selection, guint flags); - void (* set_selection) (InkscapeApplication * inkscape, Inkscape::Selection * selection); - void (* set_eventcontext) (InkscapeApplication * inkscape, Inkscape::UI::Tools::ToolBase * eventcontext); - void (* activate_desktop) (InkscapeApplication * inkscape, SPDesktop * desktop); - void (* deactivate_desktop) (InkscapeApplication * inkscape, SPDesktop * desktop); - void (* destroy_document) (InkscapeApplication *inkscape, SPDocument *doc); - void (* color_set) (InkscapeApplication *inkscape, SPColor *color, double opacity); - void (* shut_down) (InkscapeApplication *inkscape); - void (* dialogs_hide) (InkscapeApplication *inkscape); - void (* dialogs_unhide) (InkscapeApplication *inkscape); - void (* external_change) (InkscapeApplication *inkscape); -}; +void inkscape_unref(Inkscape::Application & in) +{ + in.refCount--; + + if (&in == Inkscape::Application::_S_inst) { + if (in.refCount <= 0) { + delete Inkscape::Application::_S_inst; + } + } else { + g_error("Attempt to unref an Application (=%p) not the current instance (=%p) (maybe it's already been destroyed?)", + &in, Inkscape::Application::_S_inst); + } +} -static guint inkscape_signals[LAST_SIGNAL] = {0}; +// Callback passed to g_timeout_add_seconds() +// gets the current instance and calls autosave() +int inkscape_autosave(gpointer) { + g_assert(Inkscape::Application::exists()); + return INKSCAPE.autosave(); +} -static void (* segv_handler) (int) = SIG_DFL; -static void (* abrt_handler) (int) = SIG_DFL; -static void (* fpe_handler) (int) = SIG_DFL; -static void (* ill_handler) (int) = SIG_DFL; -#ifndef WIN32 -static void (* bus_handler) (int) = SIG_DFL; -#endif +namespace Inkscape { -#define INKSCAPE_PROFILE_DIR "inkscape" -#define INKSCAPE_PROFILE_DIR_047DEV "Inkscape" -#define INKSCAPE_LEGACY_PROFILE_DIR ".inkscape" -#define MENUS_FILE "menus.xml" +/** + * Defined only for debugging purposes. If we are certain the bugs are gone we can remove this + * and the references in inkscape_ref and inkscape_unref. + */ +Application* +Application::operator &() const +{ + return const_cast<Application*>(this); +} +/** + * Creates a new Inkscape::Application global object. + */ +void +Application::create(const char *argv0, bool use_gui) +{ + if (!Application::exists()) { + new Application(argv0, use_gui); + } else { + g_assert_not_reached(); + } +} -G_DEFINE_TYPE(InkscapeApplication, inkscape, G_TYPE_OBJECT); /** - * Initializes the inkscape class, registering all of its signal handlers - * and virtual functions + * Checks whether the current Inkscape::Application global object exists. */ -static void -inkscape_class_init (InkscapeApplicationClass * klass) +bool +Application::exists() { - GObjectClass * object_class = G_OBJECT_CLASS(klass); - - inkscape_signals[MODIFY_SELECTION] = g_signal_new ("modify_selection", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (InkscapeApplicationClass, modify_selection), - NULL, NULL, - sp_marshal_VOID__POINTER_UINT, - G_TYPE_NONE, 2, - G_TYPE_POINTER, G_TYPE_UINT); - inkscape_signals[CHANGE_SELECTION] = g_signal_new ("change_selection", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (InkscapeApplicationClass, change_selection), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - inkscape_signals[CHANGE_SUBSELECTION] = g_signal_new ("change_subselection", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (InkscapeApplicationClass, change_subselection), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - inkscape_signals[SET_SELECTION] = g_signal_new ("set_selection", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (InkscapeApplicationClass, set_selection), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - inkscape_signals[SET_EVENTCONTEXT] = g_signal_new ("set_eventcontext", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (InkscapeApplicationClass, set_eventcontext), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - inkscape_signals[ACTIVATE_DESKTOP] = g_signal_new ("activate_desktop", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (InkscapeApplicationClass, activate_desktop), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - inkscape_signals[DEACTIVATE_DESKTOP] = g_signal_new ("deactivate_desktop", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (InkscapeApplicationClass, deactivate_desktop), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - inkscape_signals[SHUTDOWN_SIGNAL] = g_signal_new ("shut_down", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (InkscapeApplicationClass, shut_down), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - inkscape_signals[DIALOGS_HIDE] = g_signal_new ("dialogs_hide", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (InkscapeApplicationClass, dialogs_hide), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - inkscape_signals[DIALOGS_UNHIDE] = g_signal_new ("dialogs_unhide", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (InkscapeApplicationClass, dialogs_unhide), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - inkscape_signals[EXTERNAL_CHANGE] = g_signal_new ("external_change", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (InkscapeApplicationClass, external_change), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - object_class->dispose = inkscape_dispose; - - klass->activate_desktop = inkscape_activate_desktop_private; - klass->deactivate_desktop = inkscape_deactivate_desktop_private; + return Application::_S_inst != NULL; } -#ifdef WIN32 -typedef int uid_t; -#define getuid() 0 -#endif +/** + * Returns the current Inkscape::Application global object. + * \pre Application::_S_inst != NULL + */ +Application& +Application::instance() +{ + if (!exists()) { + g_error("Inkscape::Application does not yet exist."); + } + return *Application::_S_inst; +} /** * static gint inkscape_autosave(gpointer); * - * Callback passed to g_timeout_add_seconds() * Responsible for autosaving all open documents */ -static gint inkscape_autosave(gpointer) +int Application::autosave() { - if (inkscape->document_set.empty()) { // nothing to autosave + if (_document_set.empty()) { // nothing to autosave return TRUE; } Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -302,7 +238,7 @@ static gint inkscape_autosave(gpointer) } GDir *autosave_dir_ptr = g_dir_open(autosave_dir.c_str(), 0, NULL); - if( !autosave_dir_ptr ){ + if (!autosave_dir_ptr) { // Try to create the autosave directory if it doesn't exist if (g_mkdir(autosave_dir.c_str(), 0755)) { // the creation failed @@ -333,8 +269,8 @@ static gint inkscape_autosave(gpointer) gint docnum = 0; SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Autosaving documents...")); - for (std::map<SPDocument*,int>::iterator iter = inkscape->document_set.begin(); - iter != inkscape->document_set.end(); + for (std::map<SPDocument*,int>::iterator iter = _document_set.begin(); + iter != _document_set.end(); ++iter) { SPDocument *doc = iter->first; @@ -342,7 +278,6 @@ static gint inkscape_autosave(gpointer) ++docnum; Inkscape::XML::Node *repr = doc->getReprRoot(); - // g_debug("Document %d: \"%s\" %s", docnum, doc ? doc->getName() : "(null)", doc ? (doc->isModifiedSinceSave() ? "(dirty)" : "(clean)") : "(null)"); if (doc->isModifiedSinceSave()) { gchar *oldest_autosave = 0; @@ -373,8 +308,6 @@ static gint inkscape_autosave(gpointer) } } - // g_debug("%d previous autosaves exists. Max = %d", count, autosave_max); - // Have we reached the limit for number of autosaves? if ( count >= autosave_max ){ // Remove the oldest file @@ -396,8 +329,6 @@ static gint inkscape_autosave(gpointer) g_free(baseName); baseName = 0; - // g_debug("Filename: %s", full_path); - // Try to save the file FILE *file = Inkscape::IO::fopen_utf8name(full_path, "w"); gchar *errortext = 0; @@ -435,7 +366,7 @@ static gint inkscape_autosave(gpointer) return TRUE; } -void inkscape_autosave_init() +void Application::autosave_init() { static guint32 autosave_timeout_id = 0; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -446,139 +377,149 @@ void inkscape_autosave_init() autosave_timeout_id = 0; } - // g_debug("options.autosave.enable = %d", prefs->getBool("/options/autosave/enable", true)); // Is autosave enabled? if (!prefs->getBool("/options/autosave/enable", true)){ autosave_timeout_id = 0; } else { // Turn on autosave guint32 timeout = prefs->getInt("/options/autosave/interval", 10) * 60; - // g_debug("options.autosave.interval = %d", prefs->getInt("/options/autosave/interval", 10)); autosave_timeout_id = g_timeout_add_seconds(timeout, inkscape_autosave, NULL); } } - -static void -inkscape_init (InkscapeApplication * object) +void Application::argv0(char const* argv) { - if (!inkscape) { - inkscape = (InkscapeApplication *) object; - } else { - g_assert_not_reached (); - } - - new (&inkscape->document_set) std::map<SPDocument *, int>(); - new (&inkscape->selection_models) std::map<SPDocument *, AppSelectionModel *>(); - - inkscape->menus = NULL; - inkscape->desktops = NULL; - inkscape->dialogs_toggle = TRUE; - inkscape->mapalt = GDK_MOD1_MASK; - inkscape->trackalt = FALSE; + _argv0 = g_strdup(argv); } -static void -inkscape_dispose (GObject *object) +/* \brief Constructor for the application. + * Creates a new Inkscape::Application. + * + * \pre Application::_S_inst == NULL + */ + +Application::Application(const char* argv, bool use_gui) : + _menus(NULL), + _desktops(NULL), + refCount(1), + _dialogs_toggle(TRUE), + _mapalt(GDK_MOD1_MASK), + _trackalt(FALSE), + _use_gui(use_gui) { - InkscapeApplication *inkscape = (InkscapeApplication *) object; + /* fixme: load application defaults */ - g_assert (!inkscape->desktops); + segv_handler = signal (SIGSEGV, Application::crash_handler); + abrt_handler = signal (SIGABRT, Application::crash_handler); + fpe_handler = signal (SIGFPE, Application::crash_handler); + ill_handler = signal (SIGILL, Application::crash_handler); +#ifndef WIN32 + bus_handler = signal (SIGBUS, Application::crash_handler); +#endif - Inkscape::Preferences::unload(); + _argv0 = g_strdup(argv); - if (inkscape->menus) { - /* fixme: This is not the best place */ - Inkscape::GC::release(inkscape->menus); - inkscape->menus = NULL; - } + // \TODO: this belongs to Application::init but if it isn't here + // then the Filters and Extensions menus don't work. + _S_inst = this; - inkscape->selection_models.~map(); - inkscape->document_set.~map(); + /* Load the preferences and menus */ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + InkErrorHandler* handler = new InkErrorHandler(use_gui); + prefs->setErrorHandler(handler); + { + Glib::ustring msg; + Glib::ustring secondary; + if (prefs->getLastError( msg, secondary )) { + handler->handleError(msg, secondary); + } + } - G_OBJECT_CLASS (inkscape_parent_class)->dispose (object); + if (use_gui) { + load_menus(); + Inkscape::DeviceManager::getManager().loadConfig(); + } + Inkscape::ResourceManager::getManager(); - gtk_main_quit (); -} + /* set language for user interface according setting in preferences */ + Glib::ustring ui_language = prefs->getString("/ui/language"); + if(!ui_language.empty()) + { + setenv("LANGUAGE", ui_language, 1); + } + /* DebugDialog redirection. On Linux, default to OFF, on Win32, default to ON. + * Use only if use_gui is enabled + */ +#ifdef WIN32 +#define DEFAULT_LOG_REDIRECT true +#else +#define DEFAULT_LOG_REDIRECT false +#endif -void -inkscape_ref (void) -{ - if (inkscape) - g_object_ref (G_OBJECT (inkscape)); -} + if (use_gui == TRUE && prefs->getBool("/dialogs/debug/redirect", DEFAULT_LOG_REDIRECT)) + { + Inkscape::UI::Dialog::DebugDialog::getInstance()->captureLogMessages(); + } + /* Check for global remapping of Alt key */ + if (use_gui) + { + mapalt(guint(prefs->getInt("/options/mapalt/value", 0))); + trackalt(guint(prefs->getInt("/options/trackalt/value", 0))); + } -void -inkscape_unref (void) -{ - if (inkscape) - g_object_unref (G_OBJECT (inkscape)); -} + /* Initialize the extensions */ + Inkscape::Extension::init(); -/* returns the mask of the keyboard modifier to map to Alt, zero if no mapping */ -/* Needs to be a guint because gdktypes.h does not define a 'no-modifier' value */ -guint -inkscape_mapalt() { - return inkscape->mapalt; + autosave_init(); } -/* Sets the keyboard modifer to map to Alt. Zero switches off mapping, as does '1', which is the default */ -void inkscape_mapalt(guint maskvalue) +Application::~Application() { - if(maskvalue<2 || maskvalue> 5 ){ /* MOD5 is the highest defined in gdktypes.h */ - inkscape->mapalt=0; - }else{ - inkscape->mapalt=(GDK_MOD1_MASK << (maskvalue-1)); + if (_desktops) { + g_error("FATAL: desktops still in list on application destruction!"); } -} -guint -inkscape_trackalt() { - return inkscape->trackalt; -} - -void inkscape_trackalt(guint trackvalue) -{ - inkscape->trackalt = trackvalue; -} + Inkscape::Preferences::unload(); + if (_menus) { + Inkscape::GC::release(_menus); + _menus = NULL; + } -static void -inkscape_activate_desktop_private (InkscapeApplication */*inkscape*/, SPDesktop *desktop) -{ - desktop->set_active (true); -} + if (_argv0) { + g_free(_argv0); + _argv0 = NULL; + } + _S_inst = NULL; // this will probably break things -static void -inkscape_deactivate_desktop_private (InkscapeApplication */*inkscape*/, SPDesktop *desktop) -{ - desktop->set_active (false); + refCount = 0; + gtk_main_quit (); } - -/* fixme: This is EVIL, and belongs to main after all */ - -#define SP_INDENT 8 - - -static bool crashIsHappening = false; - -bool inkscapeIsCrashing() +/** Sets the keyboard modifer to map to Alt. + * + * Zero switches off mapping, as does '1', which is the default. + */ +void Application::mapalt(guint maskvalue) { - return crashIsHappening; + if ( maskvalue < 2 || maskvalue > 5 ) { // MOD5 is the highest defined in gdktypes.h + _mapalt = 0; + } else { + _mapalt = (GDK_MOD1_MASK << (maskvalue-1)); + } } -static void -inkscape_crash_handler (int /*signum*/) +void +Application::crash_handler (int /*signum*/) { using Inkscape::Debug::SimpleEvent; using Inkscape::Debug::EventTracker; using Inkscape::Debug::Logger; - static gint recursion = FALSE; + static bool recursion = false; /* * reset all signal handlers: any further crashes should just be allowed @@ -596,9 +537,9 @@ inkscape_crash_handler (int /*signum*/) if (recursion) { abort (); } - recursion = TRUE; + recursion = true; - crashIsHappening = true; + _crashIsHappening = true; EventTracker<SimpleEvent<Inkscape::Debug::Event::CORE> > tracker("crash"); tracker.set<SimpleEvent<> >("emergency-save"); @@ -612,11 +553,11 @@ inkscape_crash_handler (int /*signum*/) gint count = 0; gchar *curdir = g_get_current_dir(); // This one needs to be freed explicitly - gchar *inkscapedir = g_path_get_dirname(INKSCAPE->argv0); // Needs to be freed + gchar *inkscapedir = g_path_get_dirname(INKSCAPE._argv0); // Needs to be freed GSList *savednames = NULL; GSList *failednames = NULL; - for (std::map<SPDocument*,int>::iterator iter = inkscape->document_set.begin(); - iter != inkscape->document_set.end(); + for (std::map<SPDocument*,int>::iterator iter = INKSCAPE._document_set.begin(), e = INKSCAPE._document_set.end(); + iter != e; ++iter) { SPDocument *doc = iter->first; Inkscape::XML::Node *repr; @@ -757,7 +698,7 @@ inkscape_crash_handler (int /*signum*/) } *(b + pos) = '\0'; - if ( inkscape_get_instance() && inkscape_use_gui() ) { + if ( exists() && instance().use_gui() ) { GtkWidget *msgbox = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", b); gtk_dialog_run (GTK_DIALOG (msgbox)); gtk_widget_destroy (msgbox); @@ -774,132 +715,19 @@ inkscape_crash_handler (int /*signum*/) /* on exit, allow restored signal handler to take over and crash us */ } - -class InkErrorHandler : public Inkscape::ErrorReporter { -public: - InkErrorHandler(bool useGui) : Inkscape::ErrorReporter(), - _useGui(useGui) - {} - virtual ~InkErrorHandler() {} - - virtual void handleError( Glib::ustring const& primary, Glib::ustring const& secondary ) const - { - if (_useGui) { - Gtk::MessageDialog err(primary, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK, true); - err.set_secondary_text(secondary); - err.run(); - } else { - g_message("%s", primary.data()); - g_message("%s", secondary.data()); - } - } - -private: - bool _useGui; -}; - -void -inkscape_application_init (const gchar *argv0, gboolean use_gui) -{ - inkscape = (InkscapeApplication *)g_object_new (SP_TYPE_INKSCAPE, NULL); - /* fixme: load application defaults */ - - segv_handler = signal (SIGSEGV, inkscape_crash_handler); - abrt_handler = signal (SIGABRT, inkscape_crash_handler); - fpe_handler = signal (SIGFPE, inkscape_crash_handler); - ill_handler = signal (SIGILL, inkscape_crash_handler); -#ifndef WIN32 - bus_handler = signal (SIGBUS, inkscape_crash_handler); -#endif - - inkscape->use_gui = use_gui; - inkscape->argv0 = g_strdup(argv0); - - /* Load the preferences and menus */ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - InkErrorHandler* handler = new InkErrorHandler(use_gui); - prefs->setErrorHandler(handler); - { - Glib::ustring msg; - Glib::ustring secondary; - if (prefs->getLastError( msg, secondary )) { - handler->handleError(msg, secondary); - } - } - - if (use_gui) { - inkscape_load_menus(inkscape); - Inkscape::DeviceManager::getManager().loadConfig(); - } - Inkscape::ResourceManager::getManager(); - - /* set language for user interface according setting in preferences */ - Glib::ustring ui_language = prefs->getString("/ui/language"); - if(!ui_language.empty()) - { - setenv("LANGUAGE", ui_language, 1); - } - - /* DebugDialog redirection. On Linux, default to OFF, on Win32, default to ON. - * Use only if use_gui is enabled - */ -#ifdef WIN32 -#define DEFAULT_LOG_REDIRECT true -#else -#define DEFAULT_LOG_REDIRECT false -#endif - - if (use_gui == TRUE && prefs->getBool("/dialogs/debug/redirect", DEFAULT_LOG_REDIRECT)) - { - Inkscape::UI::Dialog::DebugDialog::getInstance()->captureLogMessages(); - } - - /* Check for global remapping of Alt key */ - if (use_gui) - { - inkscape_mapalt(guint(prefs->getInt("/options/mapalt/value", 0))); - inkscape_trackalt(guint(prefs->getInt("/options/trackalt/value", 0))); - } - - /* Initialize the extensions */ - Inkscape::Extension::init(); - - inkscape_autosave_init(); - - return; -} - -/** - * Returns the current InkscapeApplication global object - */ -InkscapeApplication * -inkscape_get_instance() -{ - return inkscape; -} - -gboolean inkscape_use_gui() -{ - return inkscape_get_instance()->use_gui; -} - /** * Menus management * */ -bool inkscape_load_menus( InkscapeApplication * inkscape ) +bool Application::load_menus() { gchar *fn = profile_path(MENUS_FILE); gchar *menus_xml = 0; gsize len = 0; - if ( inkscape != inkscape_get_instance() ) { - g_warning("BAD BAD BAD THINGS"); - } - if ( g_file_get_contents(fn, &menus_xml, &len, NULL) ) { // load the menus_xml file - inkscape->menus = sp_repr_read_mem(menus_xml, len, NULL); + _menus = sp_repr_read_mem(menus_xml, len, NULL); g_free(menus_xml); menus_xml = 0; @@ -907,146 +735,157 @@ bool inkscape_load_menus( InkscapeApplication * inkscape ) g_free(fn); fn = 0; - if ( !inkscape->menus ) { - inkscape->menus = sp_repr_read_mem(menus_skeleton, MENUS_SKELETON_SIZE, NULL); + if ( !_menus ) { + _menus = sp_repr_read_mem(menus_skeleton, MENUS_SKELETON_SIZE, NULL); } - return (inkscape->menus != NULL); + return (_menus != 0); } void -inkscape_selection_modified (Inkscape::Selection *selection, guint flags) +Application::selection_modified (Inkscape::Selection *selection, guint flags) { g_return_if_fail (selection != NULL); if (DESKTOP_IS_ACTIVE (selection->desktop())) { - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[MODIFY_SELECTION], 0, selection, flags); + signal_selection_modified.emit(selection, flags); } } void -inkscape_selection_changed (Inkscape::Selection * selection) +Application::selection_changed (Inkscape::Selection * selection) { g_return_if_fail (selection != NULL); - + if (DESKTOP_IS_ACTIVE (selection->desktop())) { - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[CHANGE_SELECTION], 0, selection); + signal_selection_changed.emit(selection); } } void -inkscape_subselection_changed (SPDesktop *desktop) +Application::subselection_changed (SPDesktop *desktop) { g_return_if_fail (desktop != NULL); if (DESKTOP_IS_ACTIVE (desktop)) { - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[CHANGE_SUBSELECTION], 0, desktop); + signal_subselection_changed.emit(desktop); } } void -inkscape_selection_set (Inkscape::Selection * selection) +Application::selection_set (Inkscape::Selection * selection) { g_return_if_fail (selection != NULL); if (DESKTOP_IS_ACTIVE (selection->desktop())) { - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_SELECTION], 0, selection); - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[CHANGE_SELECTION], 0, selection); + signal_selection_set.emit(selection); + signal_selection_changed.emit(selection); } } void -inkscape_eventcontext_set (Inkscape::UI::Tools::ToolBase * eventcontext) +Application::eventcontext_set (Inkscape::UI::Tools::ToolBase * eventcontext) { g_return_if_fail (eventcontext != NULL); g_return_if_fail (SP_IS_EVENT_CONTEXT (eventcontext)); if (DESKTOP_IS_ACTIVE (eventcontext->desktop)) { - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_EVENTCONTEXT], 0, eventcontext); + signal_eventcontext_set.emit(eventcontext); } } void -inkscape_add_desktop (SPDesktop * desktop) +Application::add_desktop (SPDesktop * desktop) { g_return_if_fail (desktop != NULL); - g_return_if_fail (inkscape != NULL); + if (_desktops == NULL) { + _desktops = new std::vector<SPDesktop*>; + } - g_assert (!g_slist_find (inkscape->desktops, desktop)); + if (std::find(_desktops->begin(), _desktops->end(), desktop) != _desktops->end()) { + g_error("Attempted to add desktop already in list."); + } - inkscape->desktops = g_slist_prepend (inkscape->desktops, desktop); + _desktops->insert(_desktops->begin(), desktop); - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[ACTIVATE_DESKTOP], 0, desktop); - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_EVENTCONTEXT], 0, desktop->getEventContext()); - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_SELECTION], 0, sp_desktop_selection (desktop)); - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[CHANGE_SELECTION], 0, sp_desktop_selection (desktop)); + signal_activate_desktop.emit(desktop); + signal_eventcontext_set.emit(desktop->getEventContext()); + signal_selection_set.emit(desktop->getSelection()); + signal_selection_changed.emit(desktop->getSelection()); } void -inkscape_remove_desktop (SPDesktop * desktop) +Application::remove_desktop (SPDesktop * desktop) { g_return_if_fail (desktop != NULL); - g_return_if_fail (inkscape != NULL); - g_assert (g_slist_find (inkscape->desktops, desktop)); + if (std::find (_desktops->begin(), _desktops->end(), desktop) == _desktops->end() ) { + g_error("Attempted to remove desktop not in list."); + } if (DESKTOP_IS_ACTIVE (desktop)) { - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[DEACTIVATE_DESKTOP], 0, desktop); - if (inkscape->desktops->next != NULL) { - SPDesktop * new_desktop = static_cast<SPDesktop *>(inkscape->desktops->next->data); - inkscape->desktops = g_slist_remove (inkscape->desktops, new_desktop); - inkscape->desktops = g_slist_prepend (inkscape->desktops, new_desktop); - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[ACTIVATE_DESKTOP], 0, new_desktop); - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_EVENTCONTEXT], 0, new_desktop->getEventContext()); - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_SELECTION], 0, sp_desktop_selection (new_desktop)); - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[CHANGE_SELECTION], 0, sp_desktop_selection (new_desktop)); + signal_deactivate_desktop.emit(desktop); + if (_desktops->size() > 1) { + SPDesktop * new_desktop = *(++_desktops->begin()); + _desktops->erase(std::find(_desktops->begin(), _desktops->end(), new_desktop)); + _desktops->insert(_desktops->begin(), new_desktop); + + signal_activate_desktop.emit(new_desktop); + signal_eventcontext_set.emit(new_desktop->getEventContext()); + signal_selection_set.emit(new_desktop->getSelection()); + signal_selection_changed.emit(new_desktop->getSelection()); } else { - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_EVENTCONTEXT], 0, NULL); - if (sp_desktop_selection(desktop)) - sp_desktop_selection(desktop)->clear(); + signal_eventcontext_set.emit(NULL); + if (desktop->getSelection()) + desktop->getSelection()->clear(); } } - inkscape->desktops = g_slist_remove (inkscape->desktops, desktop); + _desktops->erase(std::find(_desktops->begin(), _desktops->end(), desktop)); // if this was the last desktop, shut down the program - if (inkscape->desktops == NULL) { - inkscape_exit (inkscape); + if (_desktops->empty()) { + this->exit(); + delete _desktops; + _desktops = NULL; } } void -inkscape_activate_desktop (SPDesktop * desktop) +Application::activate_desktop (SPDesktop * desktop) { g_return_if_fail (desktop != NULL); - g_return_if_fail (inkscape != NULL); if (DESKTOP_IS_ACTIVE (desktop)) { return; } - g_assert (g_slist_find (inkscape->desktops, desktop)); + std::vector<SPDesktop*>::iterator i; + + if ((i = std::find (_desktops->begin(), _desktops->end(), desktop)) == _desktops->end()) { + g_error("Tried to activate desktop not added to list."); + } - SPDesktop *current = static_cast<SPDesktop *>(inkscape->desktops->data); + SPDesktop *current = _desktops->front(); - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[DEACTIVATE_DESKTOP], 0, current); + signal_deactivate_desktop.emit(current); - inkscape->desktops = g_slist_remove (inkscape->desktops, desktop); - inkscape->desktops = g_slist_prepend (inkscape->desktops, desktop); + _desktops->erase (i); + _desktops->insert (_desktops->begin(), desktop); - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[ACTIVATE_DESKTOP], 0, desktop); - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_EVENTCONTEXT], 0, desktop->getEventContext()); - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_SELECTION], 0, sp_desktop_selection (desktop)); - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[CHANGE_SELECTION], 0, sp_desktop_selection (desktop)); + signal_activate_desktop.emit(desktop); + signal_eventcontext_set.emit(desktop->getEventContext()); + signal_selection_set(desktop->getSelection()); + signal_selection_changed(desktop->getSelection()); } @@ -1054,65 +893,62 @@ inkscape_activate_desktop (SPDesktop * desktop) * Resends ACTIVATE_DESKTOP for current desktop; needed when a new desktop has got its window that dialogs will transientize to */ void -inkscape_reactivate_desktop (SPDesktop * desktop) +Application::reactivate_desktop (SPDesktop * desktop) { g_return_if_fail (desktop != NULL); - g_return_if_fail (inkscape != NULL); - if (DESKTOP_IS_ACTIVE (desktop)) - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[ACTIVATE_DESKTOP], 0, desktop); + if (DESKTOP_IS_ACTIVE (desktop)) { + signal_activate_desktop.emit(desktop); + } } SPDesktop * -inkscape_find_desktop_by_dkey (unsigned int dkey) +Application::find_desktop_by_dkey (unsigned int dkey) { - for (GSList *r = inkscape->desktops; r; r = r->next) { - if ((static_cast<SPDesktop *>(r->data))->dkey == dkey){ - return (static_cast<SPDesktop *>(r->data)); + for (std::vector<SPDesktop*>::iterator r = _desktops->begin(), e = _desktops->end(); r != e; ++r) { + if ((*r)->dkey == dkey){ + return *r; } } return NULL; } - - -static unsigned int -inkscape_maximum_dkey() +unsigned int +Application::maximum_dkey() { unsigned int dkey = 0; - for (GSList *r = inkscape->desktops; r; r = r->next) { - if ((static_cast<SPDesktop *>(r->data))->dkey > dkey){ - dkey = (static_cast<SPDesktop *>(r->data))->dkey; + for (std::vector<SPDesktop*>::iterator r = _desktops->begin(), e = _desktops->end(); r != e; ++r) { + if ((*r)->dkey > dkey){ + dkey = (*r)->dkey; } } - return dkey; } -static SPDesktop * -inkscape_next_desktop () +SPDesktop * +Application::next_desktop () { SPDesktop *d = NULL; - unsigned int dkey_current = (static_cast<SPDesktop *>(inkscape->desktops->data))->dkey; + unsigned int dkey_current = (_desktops->front())->dkey; - if (dkey_current < inkscape_maximum_dkey()) { + if (dkey_current < maximum_dkey()) { // find next existing - for (unsigned int i = dkey_current + 1; i <= inkscape_maximum_dkey(); i++) { - d = inkscape_find_desktop_by_dkey (i); + for (unsigned int i = dkey_current + 1; i <= maximum_dkey(); ++i) { + d = find_desktop_by_dkey (i); if (d) { break; } } } else { // find first existing - for (unsigned int i = 0; i <= inkscape_maximum_dkey(); i++) { - d = inkscape_find_desktop_by_dkey (i); + for (unsigned int i = 0; i <= maximum_dkey(); ++i) { + d = find_desktop_by_dkey (i); if (d) { break; } @@ -1120,22 +956,21 @@ inkscape_next_desktop () } g_assert (d); - return d; } -static SPDesktop * -inkscape_prev_desktop () +SPDesktop * +Application::prev_desktop () { SPDesktop *d = NULL; - unsigned int dkey_current = (static_cast<SPDesktop *>(inkscape->desktops->data))->dkey; + unsigned int dkey_current = (_desktops->front())->dkey; if (dkey_current > 0) { // find prev existing - for (signed int i = dkey_current - 1; i >= 0; i--) { - d = inkscape_find_desktop_by_dkey (i); + for (signed int i = dkey_current - 1; i >= 0; --i) { + d = find_desktop_by_dkey (i); if (d) { break; } @@ -1143,81 +978,74 @@ inkscape_prev_desktop () } if (!d) { // find last existing - d = inkscape_find_desktop_by_dkey (inkscape_maximum_dkey()); + d = find_desktop_by_dkey (maximum_dkey()); } g_assert (d); - return d; } void -inkscape_switch_desktops_next () +Application::switch_desktops_next () { - inkscape_next_desktop()->presentWindow(); + next_desktop()->presentWindow(); } - - void -inkscape_switch_desktops_prev () +Application::switch_desktops_prev() { - inkscape_prev_desktop()->presentWindow(); + prev_desktop()->presentWindow(); } - - void -inkscape_dialogs_hide () +Application::dialogs_hide() { - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[DIALOGS_HIDE], 0); - inkscape->dialogs_toggle = FALSE; + signal_dialogs_hide.emit(); + _dialogs_toggle = false; } void -inkscape_dialogs_unhide () +Application::dialogs_unhide() { - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[DIALOGS_UNHIDE], 0); - inkscape->dialogs_toggle = TRUE; + signal_dialogs_unhide.emit(); + _dialogs_toggle = true; } void -inkscape_dialogs_toggle () +Application::dialogs_toggle() { - if (inkscape->dialogs_toggle) { - inkscape_dialogs_hide (); + if (_dialogs_toggle) { + dialogs_hide(); } else { - inkscape_dialogs_unhide (); + dialogs_unhide(); } } void -inkscape_external_change () +Application::external_change() { - g_return_if_fail (inkscape != NULL); - - g_signal_emit (G_OBJECT (inkscape), inkscape_signals[EXTERNAL_CHANGE], 0); + signal_external_change.emit(); } /** * fixme: These need probably signals too */ void -inkscape_add_document (SPDocument *document) +Application::add_document (SPDocument *document) { g_return_if_fail (document != NULL); // try to insert the pair into the list - if (!(inkscape->document_set.insert(std::make_pair(document, 1)).second)) { + if (!(_document_set.insert(std::make_pair(document, 1)).second)) { //insert failed, this key (document) is already in the list - for (std::map<SPDocument*,int>::iterator iter = inkscape->document_set.begin(); - iter != inkscape->document_set.end(); + for (std::map<SPDocument*,int>::iterator iter = _document_set.begin(); + iter != _document_set.end(); ++iter) { if (iter->first == document) { // found this document in list, increase its count @@ -1227,10 +1055,10 @@ inkscape_add_document (SPDocument *document) } else { // insert succeeded, this document is new. Do we need to create a // selection model for it, i.e. are we running without a desktop? - if (!inkscape->use_gui) { + if (!_use_gui) { // Create layer model and selection model so we can run some verbs without a GUI - g_assert(inkscape->selection_models.find(document) == inkscape->selection_models.end()); - inkscape->selection_models[document] = new AppSelectionModel(document); + g_assert(_selection_models.find(document) == _selection_models.end()); + _selection_models[document] = new AppSelectionModel(document); } } } @@ -1238,24 +1066,24 @@ inkscape_add_document (SPDocument *document) // returns true if this was last reference to this document, so you can delete it bool -inkscape_remove_document (SPDocument *document) +Application::remove_document (SPDocument *document) { g_return_val_if_fail (document != NULL, false); - for (std::map<SPDocument*,int>::iterator iter = inkscape->document_set.begin(); - iter != inkscape->document_set.end(); + for (std::map<SPDocument *,int>::iterator iter = _document_set.begin(); + iter != _document_set.end(); ++iter) { if (iter->first == document) { // found this document in list, decrease its count iter->second --; if (iter->second < 1) { // this was the last one, remove the pair from list - inkscape->document_set.erase (iter); + _document_set.erase (iter); // also remove the selection model - std::map<SPDocument *, AppSelectionModel *>::iterator sel_iter = inkscape->selection_models.find(document); - if (sel_iter != inkscape->selection_models.end()) { - inkscape->selection_models.erase(sel_iter); + std::map<SPDocument *, AppSelectionModel *>::iterator sel_iter = _selection_models.find(document); + if (sel_iter != _selection_models.end()) { + _selection_models.erase(sel_iter); } return true; @@ -1269,37 +1097,38 @@ inkscape_remove_document (SPDocument *document) } SPDesktop * -inkscape_active_desktop (void) +Application::active_desktop() { - if (inkscape->desktops == NULL) { + if (!_desktops || _desktops->empty()) { return NULL; } - return static_cast<SPDesktop *>(inkscape->desktops->data); + return _desktops->front(); } SPDocument * -inkscape_active_document (void) +Application::active_document() { if (SP_ACTIVE_DESKTOP) { - return sp_desktop_document (SP_ACTIVE_DESKTOP); - } else if (!inkscape->document_set.empty()) { + return SP_ACTIVE_DESKTOP->getDocument(); + } else if (!_document_set.empty()) { // If called from the command line there will be no desktop // So 'fall back' to take the first listed document in the Inkscape instance - return inkscape->document_set.begin()->first; + return _document_set.begin()->first; } return NULL; } -bool inkscape_is_sole_desktop_for_document(SPDesktop const &desktop) { +bool +Application::sole_desktop_for_document(SPDesktop const &desktop) { SPDocument const* document = desktop.doc(); if (!document) { return false; } - for ( GSList *iter = inkscape->desktops ; iter ; iter = iter->next ) { - SPDesktop *other_desktop=static_cast<SPDesktop *>(iter->data); - SPDocument *other_document=other_desktop->doc(); + for ( std::vector<SPDesktop*>::iterator iter = _desktops->begin(), e = _desktops->end() ; iter != e; ++iter ) { + SPDesktop *other_desktop = *iter; + SPDocument *other_document = other_desktop->doc(); if ( other_document == document && other_desktop != &desktop ) { return false; } @@ -1308,7 +1137,7 @@ bool inkscape_is_sole_desktop_for_document(SPDesktop const &desktop) { } Inkscape::UI::Tools::ToolBase * -inkscape_active_event_context (void) +Application::active_event_context (void) { if (SP_ACTIVE_DESKTOP) { return SP_ACTIVE_DESKTOP->getEventContext(); @@ -1318,34 +1147,36 @@ inkscape_active_event_context (void) } Inkscape::ActionContext -inkscape_active_action_context() +Application::active_action_context() { if (SP_ACTIVE_DESKTOP) { return Inkscape::ActionContext(SP_ACTIVE_DESKTOP); } - SPDocument *doc = inkscape_active_document(); + SPDocument *doc = active_document(); if (!doc) { return Inkscape::ActionContext(); } - return inkscape_action_context_for_document(doc); + return action_context_for_document(doc); } Inkscape::ActionContext -inkscape_action_context_for_document(SPDocument *doc) +Application::action_context_for_document(SPDocument *doc) { // If there are desktops, check them first to see if the document is bound to one of them - for (GSList *iter = inkscape->desktops ; iter ; iter = iter->next) { - SPDesktop *desktop=static_cast<SPDesktop *>(iter->data); - if (desktop->doc() == doc) { - return Inkscape::ActionContext(desktop); + if (_desktops != NULL) { + for (std::vector<SPDesktop*>::iterator iter = _desktops->begin(), e = _desktops->end() ; iter != e ; ++iter) { + SPDesktop *desktop = *iter; + if (desktop->doc() == doc) { + return Inkscape::ActionContext(desktop); + } } } // Document is not associated with any desktops - maybe we're in command-line mode - std::map<SPDocument *, AppSelectionModel *>::iterator sel_iter = inkscape->selection_models.find(doc); - if (sel_iter == inkscape->selection_models.end()) { + std::map<SPDocument *, AppSelectionModel *>::iterator sel_iter = _selection_models.find(doc); + if (sel_iter == _selection_models.end()) { return Inkscape::ActionContext(); } return Inkscape::ActionContext(sel_iter->second->getSelection()); @@ -1357,10 +1188,10 @@ inkscape_action_context_for_document(SPDocument *doc) #####################*/ void -inkscape_refresh_display (InkscapeApplication *inkscape) +Application::refresh_display () { - for (GSList *l = inkscape->desktops; l != NULL; l = l->next) { - (static_cast<Inkscape::UI::View::View*>(l->data))->requestRedraw(); + for (std::vector<SPDesktop*>::iterator l = _desktops->begin(), e = _desktops->end(); l != e; ++l) { + (*l)->requestRedraw(); } } @@ -1370,26 +1201,26 @@ inkscape_refresh_display (InkscapeApplication *inkscape) * saves the preferences if appropriate, and quits. */ void -inkscape_exit (InkscapeApplication */*inkscape*/) +Application::exit () { - g_assert (INKSCAPE); - //emit shutdown signal so that dialogs could remember layout - g_signal_emit (G_OBJECT (INKSCAPE), inkscape_signals[SHUTDOWN_SIGNAL], 0); + signal_shut_down.emit(); Inkscape::Preferences::unload(); gtk_main_quit (); } char * -homedir_path(const char *filename) +Application::homedir_path(const char *filename) { static const gchar *homedir = NULL; if (!homedir) { homedir = g_get_home_dir(); } if (!homedir) { - homedir = g_path_get_dirname(INKSCAPE->argv0); + if (Application::exists()) { + homedir = g_path_get_dirname(Application::instance()._argv0); + } } return g_build_filename(homedir, filename, NULL); } @@ -1400,7 +1231,7 @@ homedir_path(const char *filename) * file should be located. */ gchar * -profile_path(const char *filename) +Application::profile_path(const char *filename) { static const gchar *prefdir = NULL; @@ -1512,21 +1343,21 @@ profile_path(const char *filename) } Inkscape::XML::Node * -inkscape_get_menus (InkscapeApplication * inkscape) +Application::get_menus() { - Inkscape::XML::Node *repr = inkscape->menus->root(); + Inkscape::XML::Node *repr = _menus->root(); g_assert (!(strcmp (repr->name(), "inkscape"))); return repr->firstChild(); } void -inkscape_get_all_desktops(std::list< SPDesktop* >& listbuf) +Application::get_all_desktops(std::list< SPDesktop* >& listbuf) { - for(GSList* l = inkscape->desktops; l != NULL; l = l->next) { - listbuf.push_back(static_cast< SPDesktop* >(l->data)); - } + listbuf.insert(listbuf.end(), _desktops->begin(), _desktops->end()); } +} // namespace Inkscape + /* Local Variables: mode:c++ diff --git a/src/inkscape.h b/src/inkscape.h index 3a9b85fc9..fe424377c 100644 --- a/src/inkscape.h +++ b/src/inkscape.h @@ -6,116 +6,220 @@ * * Authors: * Lauris Kaplinski <lauris@kaplinski.com> + * Liam P. White <inkscapebrony@gmail.com> * - * Copyright (C) 1999-2003 Authors + * Copyright (C) 1999-2014 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ -#include <list> +#include <map> +#include <vector> #include <glib.h> +#include <glib-object.h> +#include <sigc++/signal.h> +#include "layer-model.h" +#include "selection.h" class SPDesktop; class SPDocument; +struct SPColor; namespace Inkscape { + +class Application; namespace UI { namespace Tools { class ToolBase; -} -} -} - -struct InkscapeApplication; - -namespace Inkscape { - class ActionContext; - namespace XML { - class Node; - struct Document; - } -} - -#define INKSCAPE inkscape_get_instance() - -void inkscape_autosave_init(); - -void inkscape_application_init (const gchar *argv0, gboolean use_gui); - -bool inkscape_load_config (const gchar *filename, Inkscape::XML::Document *config, const gchar *skeleton, unsigned int skel_size, const gchar *e_notreg, const gchar *e_notxml, const gchar *e_notsp, const gchar *warn); - -/* Menus */ -bool inkscape_load_menus (InkscapeApplication * inkscape); -bool inkscape_save_menus (InkscapeApplication * inkscape); -Inkscape::XML::Node *inkscape_get_menus (InkscapeApplication * inkscape); - -InkscapeApplication *inkscape_get_instance(); -gboolean inkscape_use_gui(); - -bool inkscapeIsCrashing(); +} // namespace Tools +} // namespace UI -SPDesktop * inkscape_find_desktop_by_dkey (unsigned int dkey); +class ActionContext; -#define SP_ACTIVE_EVENTCONTEXT inkscape_active_event_context () -Inkscape::UI::Tools::ToolBase * inkscape_active_event_context (void); +namespace XML { +class Node; +struct Document; +} // namespace XML -#define SP_ACTIVE_DOCUMENT inkscape_active_document () -SPDocument * inkscape_active_document (void); +} // namespace Inkscape -#define SP_ACTIVE_DESKTOP inkscape_active_desktop () -SPDesktop * inkscape_active_desktop (void); +void inkscape_ref (Inkscape::Application & in); +void inkscape_unref(Inkscape::Application & in); -// Use this function to get selection model etc for a document, if possible! -// The "active" alternative below has all the horrible static cling of a singleton. -Inkscape::ActionContext -inkscape_action_context_for_document(SPDocument *doc); +#define INKSCAPE (Inkscape::Application::instance()) +#define SP_ACTIVE_EVENTCONTEXT (INKSCAPE.active_event_context()) +#define SP_ACTIVE_DOCUMENT (INKSCAPE.active_document()) +#define SP_ACTIVE_DESKTOP (INKSCAPE.active_desktop()) -// More horrible static cling... sorry about this. Should really replace all of -// the static stuff with a single instance of some kind of engine class holding -// all the document / non-GUI stuff, and an optional GUI class that behaves a -// bit like SPDesktop does currently. Then it will be easier to write good code -// that doesn't just expect a GUI all the time (like lots of the app currently -// does). -// Also, while the "active" document / desktop concepts are convenient, they -// appear to have been abused somewhat, further increasing static cling. -Inkscape::ActionContext inkscape_active_action_context(); +class AppSelectionModel { + Inkscape::LayerModel _layer_model; + Inkscape::Selection *_selection; -bool inkscape_is_sole_desktop_for_document(SPDesktop const &desktop); +public: + AppSelectionModel(SPDocument *doc) { + _layer_model.setDocument(doc); + // TODO: is this really how we should manage the lifetime of the selection? + // I just copied this from the initialization of the Selection in SPDesktop. + // When and how is it actually released? + _selection = Inkscape::GC::release(new Inkscape::Selection(&_layer_model, NULL)); + } -gchar *homedir_path(const char *filename); -gchar *profile_path(const char *filename); + Inkscape::Selection *getSelection() const { return _selection; } +}; -/* Inkscape desktop stuff */ -void inkscape_activate_desktop (SPDesktop * desktop); -void inkscape_switch_desktops_next (); -void inkscape_switch_desktops_prev (); -void inkscape_get_all_desktops (std::list< SPDesktop* >& listbuf); - -void inkscape_dialogs_hide (); -void inkscape_dialogs_unhide (); -void inkscape_dialogs_toggle (); - -void inkscape_external_change (); -void inkscape_subselection_changed (SPDesktop *desktop); - -/* Moved document add/remove functions into public inkscape.h as they are used - (rightly or wrongly) by console-mode functions */ -void inkscape_add_document (SPDocument *document); -bool inkscape_remove_document (SPDocument *document); - -/* - * fixme: This has to be rethought - */ - -void inkscape_refresh_display (InkscapeApplication *inkscape); - -/* - * fixme: This also - */ +namespace Inkscape { -void inkscape_exit (InkscapeApplication *inkscape); +class Application { +public: + static Application& instance(); + static bool exists(); + static void create(const char* argv0, bool use_gui); + + // returns the mask of the keyboard modifier to map to Alt, zero if no mapping + // Needs to be a guint because gdktypes.h does not define a 'no-modifier' value + guint mapalt() const { return _mapalt; } + + // Sets the keyboard modifer to map to Alt. Zero switches off mapping, as does '1', which is the default + void mapalt(guint maskvalue); + + guint trackalt() const { return _trackalt; } + void trackalt(guint trackvalue) { _trackalt = trackvalue; } + + bool use_gui() const { return _use_gui; } + void use_gui(gboolean guival) { _use_gui = guival; } + + char const* argv0() const { return _argv0; } + void argv0(char const *); + + // no setter for this -- only we can control this variable + static bool isCrashing() { return _crashIsHappening; } + + // useful functions + void autosave_init(); + void application_init (const gchar *argv0, gboolean use_gui); + void load_config (const gchar *filename, Inkscape::XML::Document *config, const gchar *skeleton, + unsigned int skel_size, const gchar *e_notreg, const gchar *e_notxml, + const gchar *e_notsp, const gchar *warn); + + bool load_menus(); + bool save_menus(); + Inkscape::XML::Node * get_menus(); + + Inkscape::UI::Tools::ToolBase * active_event_context(); + SPDocument * active_document(); + SPDesktop * active_desktop(); + + // Use this function to get selection model etc for a document + Inkscape::ActionContext action_context_for_document(SPDocument *doc); + Inkscape::ActionContext active_action_context(); + + bool sole_desktop_for_document(SPDesktop const &desktop); + + // Inkscape desktop stuff + void add_desktop(SPDesktop * desktop); + void remove_desktop(SPDesktop* desktop); + void activate_desktop (SPDesktop * desktop); + void switch_desktops_next (); + void switch_desktops_prev (); + void get_all_desktops (std::list< SPDesktop* >& listbuf); + void reactivate_desktop (SPDesktop * desktop); + SPDesktop * find_desktop_by_dkey (unsigned int dkey); + unsigned int maximum_dkey(); + SPDesktop * next_desktop (); + SPDesktop * prev_desktop (); + + void dialogs_hide (); + void dialogs_unhide (); + void dialogs_toggle (); + + void external_change (); + void selection_modified (Inkscape::Selection *selection, guint flags); + void selection_changed (Inkscape::Selection * selection); + void subselection_changed (SPDesktop *desktop); + void selection_set (Inkscape::Selection * selection); + + void eventcontext_set (Inkscape::UI::Tools::ToolBase * eventcontext); + + // Moved document add/remove functions into public inkscape.h as they are used + // (rightly or wrongly) by console-mode functions + void add_document (SPDocument *document); + bool remove_document (SPDocument *document); + + static char *homedir_path(const char *filename); + static char *profile_path(const char *filename); + + // fixme: This has to be rethought + void refresh_display (); + + // fixme: This also + void exit (); + + static void crash_handler(int signum); + + int autosave(); + + // nobody should be accessing our reference count, so it's made private. + friend void ::inkscape_ref (Application & in); + friend void ::inkscape_unref(Application & in); + + // signals + + // one of selections changed + sigc::signal<void, Inkscape::Selection *> signal_selection_changed; + // one of subselections (text selection, gradient handle, etc) changed + sigc::signal<void, SPDesktop *> signal_subselection_changed; + // one of selections modified + sigc::signal<void, Inkscape::Selection *, guint /*flags*/> signal_selection_modified; + // one of selections set + sigc::signal<void, Inkscape::Selection *> signal_selection_set; + // tool switched + sigc::signal<void, Inkscape::UI::Tools::ToolBase * /*eventcontext*/> signal_eventcontext_set; + // some desktop got focus + sigc::signal<void, SPDesktop *> signal_activate_desktop; + // some desktop lost focus + sigc::signal<void, SPDesktop *> signal_deactivate_desktop; + + // these are orphaned signals (nothing emits them and nothing connects to them) + sigc::signal<void, SPDocument *> signal_destroy_document; + sigc::signal<void, SPColor *, double /*opacity*/> signal_color_set; + + // inkscape is quitting + sigc::signal<void> signal_shut_down; + // user pressed F12 + sigc::signal<void> signal_dialogs_hide; + // user pressed F12 + sigc::signal<void> signal_dialogs_unhide; + // a document was changed by some external means (undo or XML editor); this + // may not be reflected by a selection change and thus needs a separate signal + sigc::signal<void> signal_external_change; + +private: + static Inkscape::Application * _S_inst; + + Application(const char* argv0, bool use_gui); + ~Application(); + + Application(Application const&); // no copy + Application& operator=(Application const&); // no assign + Application* operator&() const; // no pointer access + + Inkscape::XML::Document * _menus; + std::map<SPDocument *, int> _document_set; + std::map<SPDocument *, AppSelectionModel *> _selection_models; + std::vector<SPDesktop *> * _desktops; + + unsigned refCount; + bool _dialogs_toggle; + guint _mapalt; + guint _trackalt; + char * _argv0; + static bool _crashIsHappening; + bool _use_gui; +}; + +} // namespace Inkscape #endif diff --git a/src/inkview.cpp b/src/inkview.cpp index 2969bb140..2c667237e 100644 --- a/src/inkview.cpp +++ b/src/inkview.cpp @@ -47,7 +47,7 @@ #include <gdk/gdkkeysyms.h> #include <gtk/gtk.h> -#include "gc-core.h" +#include "inkgc/gc-core.h" #include "preferences.h" #include <glibmm/i18n.h> @@ -60,9 +60,7 @@ #include "io/inkjar.h" #endif -#include "inkscape-private.h" - -InkscapeApplication *inkscape; +#include "inkscape.h" #include <iostream> @@ -232,7 +230,8 @@ main (int argc, const char **argv) ss.view = NULL; ss.fullscreen = false; - inkscape = (InkscapeApplication *)g_object_new (SP_TYPE_INKSCAPE, NULL); + Inkscape::Application::create(argv[0], true); + //Inkscape::Application &inkscape = Inkscape::Application::instance(); // starting at where the commandline options stopped parsing because // we want all the files to be in the list diff --git a/src/io/resource.cpp b/src/io/resource.cpp index ac1c5f06b..501eab03b 100644 --- a/src/io/resource.cpp +++ b/src/io/resource.cpp @@ -73,7 +73,7 @@ Util::ptr_shared<char> get_path(Domain domain, Type type, char const *filename) case TEMPLATES: name = "templates"; break; default: return get_path(SYSTEM, type, filename); } - path = profile_path(name); + path = Inkscape::Application::profile_path(name); } break; } diff --git a/src/knot.cpp b/src/knot.cpp index 4118873c1..b3813ab53 100644 --- a/src/knot.cpp +++ b/src/knot.cpp @@ -19,7 +19,7 @@ #include <glibmm/i18n.h> #include "display/sodipodi-ctrl.h" #include "desktop.h" -#include "desktop-handles.h" + #include "knot.h" #include "knot-ptr.h" #include "document.h" @@ -109,7 +109,7 @@ SPKnot::SPKnot(SPDesktop *desktop, gchar const *tip) this->tip = g_strdup (tip); } - this->item = sp_canvas_item_new(sp_desktop_controls (desktop), + this->item = sp_canvas_item_new(desktop->getControls(), SP_TYPE_CTRL, "anchor", SP_ANCHOR_CENTER, "size", 8.0, @@ -342,7 +342,7 @@ static int sp_knot_handler(SPCanvasItem */*item*/, GdkEvent *event, SPKnot *knot knot->ungrabbed_signal.emit(knot, event->button.state); - DocumentUndo::undo(sp_desktop_document(knot->desktop)); + DocumentUndo::undo(knot->desktop->getDocument()); knot->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Node or handle drag canceled.")); transform_escaped = true; consumed = TRUE; diff --git a/src/knotholder.cpp b/src/knotholder.cpp index f46daa09e..a2d1cf017 100644 --- a/src/knotholder.cpp +++ b/src/knotholder.cpp @@ -165,7 +165,8 @@ KnotHolder::knot_clicked_handler(SPKnot *knot, guint state) if (saved_item) { //increasingly aggressive sanity checks if (saved_item->document) { - if (object_verb <= SP_VERB_LAST && object_verb >= SP_VERB_INVALID) { + // enum is unsigned so can't be less than SP_VERB_INVALID + if (object_verb <= SP_VERB_LAST) { DocumentUndo::done(saved_item->document, object_verb, _("Change handle")); } diff --git a/src/layer-manager.cpp b/src/layer-manager.cpp index c02d75d16..3bbc831d5 100644 --- a/src/layer-manager.cpp +++ b/src/layer-manager.cpp @@ -11,11 +11,11 @@ #include <set> #include <sigc++/functors/mem_fun.h> #include <sigc++/adaptors/hide.h> -#include "gc-managed.h" +#include "inkgc/gc-managed.h" #include "gc-finalized.h" #include "document.h" #include "desktop.h" -#include "desktop-handles.h" + #include "layer-manager.h" #include "preferences.h" #include "ui/view/view.h" @@ -154,7 +154,7 @@ void LayerManager::setCurrentLayer( SPObject* obj ) Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if (prefs->getBool("/options/selection/layerdeselect", true)) { - sp_desktop_selection( _desktop )->clear(); + _desktop->getSelection()->clear(); } } } diff --git a/src/layer-manager.h b/src/layer-manager.h index 9eea68004..a304929c6 100644 --- a/src/layer-manager.h +++ b/src/layer-manager.h @@ -15,7 +15,7 @@ #include "document-subset.h" #include "gc-finalized.h" -#include "gc-soft-ptr.h" +#include "inkgc/gc-soft-ptr.h" class SPDesktop; class SPDocument; diff --git a/src/libcroco/cr-statement.c b/src/libcroco/cr-statement.c index fb8df867f..4666f26ec 100644 --- a/src/libcroco/cr-statement.c +++ b/src/libcroco/cr-statement.c @@ -2011,7 +2011,7 @@ cr_statement_ruleset_set_sel_list (CRStatement * a_this, * cr_statement_ruleset_get_declarations: * *@a_this: the current instance of #CRStatement. - *@a_decl_list: out parameter. A pointer to the the returned + *@a_decl_list: out parameter. A pointer to the returned *list of declaration. Must not be NULL. * *Gets a pointer to the list of declaration contained diff --git a/src/libnrtype/Layout-TNG-Compute.cpp b/src/libnrtype/Layout-TNG-Compute.cpp index bd1acbe46..beff3734b 100644 --- a/src/libnrtype/Layout-TNG-Compute.cpp +++ b/src/libnrtype/Layout-TNG-Compute.cpp @@ -344,7 +344,7 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ if (char_attributes.is_mandatory_break && span->end != span->start) { *last_emergency_break_span = *last_break_span = *span; - TRACE(("span %d end of para; width = %f chars = %d\n", span->start.iter_span - para.unbroken_spans.begin(), span->width, char_count)); + TRACE(("span %ld end of para; width = %f chars = %d\n", span->start.iter_span - para.unbroken_spans.begin(), span->width, char_count)); return false; } @@ -362,7 +362,7 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ } // todo: break between chars if necessary (ie no word breaks present) when doing rectangular flowing - // sum the glyph widths, letter spacing and word spacing to get the character width + // sum the glyph widths, letter spacing, word spacing, and textLength adjustment to get the character width double char_width = 0.0; while (span->end_glyph_index < (unsigned)span->end.iter_span->glyph_string->num_glyphs && span->end.iter_span->glyph_string->log_clusters[span->end_glyph_index] <= (int)span->end.char_byte) { @@ -373,9 +373,10 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ span->end_glyph_index++; } if (char_attributes.is_cursor_position) - char_width += text_source->style->letter_spacing.computed; + char_width += text_source->style->letter_spacing.computed * _flow.getTextLengthMultiplierDue(); if (char_attributes.is_white) - char_width += text_source->style->word_spacing.computed; + char_width += text_source->style->word_spacing.computed * _flow.getTextLengthMultiplierDue(); + char_width += _flow.getTextLengthIncrementDue(); span->width += char_width; IFTRACE(char_count++); @@ -400,13 +401,13 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ span->word_spacing = text_source->style->word_spacing.computed; if (test_width > maximum_width && !char_attributes.is_white) { // whitespaces don't matter, we can put as many as we want at eol - TRACE(("span %d exceeded scanrun; width = %f chars = %d\n", span->start.iter_span - para.unbroken_spans.begin(), span->width, char_count)); + TRACE(("span %ld exceeded scanrun; width = %f chars = %d\n", span->start.iter_span - para.unbroken_spans.begin(), span->width, char_count)); return false; } } while (span->end.char_byte != 0); // while we haven't wrapped to the next span - TRACE(("fitted span %d width = %f chars = %d\n", span->start.iter_span - para.unbroken_spans.begin(), span->width, char_count)); + TRACE(("fitted span %ld width = %f chars = %d\n", span->start.iter_span - para.unbroken_spans.begin(), span->width, char_count)); return true; } @@ -661,6 +662,14 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ new_glyph.in_character = _flow._characters.size(); new_glyph.rotation = glyph_rotate; + // We may have scaled font size to fit textLength; now, if + // @lengthAdjust=spacingAndGlyphs, this scaling must be only horizontal, + // not vertical, so we unscale it back vertically during output + if (_flow.lengthAdjust == Inkscape::Text::Layout::LENGTHADJUST_SPACINGANDGLYPHS) + new_glyph.vertical_scale = 1.0 / _flow.getTextLengthMultiplierDue(); + else + new_glyph.vertical_scale = 1.0; + /* put something like this back in when we do glyph-rotation-horizontal/vertical if (new_span.block_progression == LEFT_TO_RIGHT || new_span.block_progression == RIGHT_TO_LEFT) { new_glyph.x += new_span.line_height.ascent; @@ -743,9 +752,10 @@ static void dumpUnbrokenSpans(ParagraphInfo *para){ new_character.in_glyph = _flow._glyphs.size() - 1; _flow._characters.push_back(new_character); if (new_character.char_attributes.is_white) - advance_width += text_source->style->word_spacing.computed + add_to_each_whitespace; // justification + advance_width += text_source->style->word_spacing.computed * _flow.getTextLengthMultiplierDue() + add_to_each_whitespace; // justification if (new_character.char_attributes.is_cursor_position) - advance_width += text_source->style->letter_spacing.computed; + advance_width += text_source->style->letter_spacing.computed * _flow.getTextLengthMultiplierDue(); + advance_width += _flow.getTextLengthIncrementDue(); iter_source_text++; char_index_in_unbroken_span++; char_byte = iter_source_text.base() - unbroken_span.input_stream_first_character.base(); @@ -1111,13 +1121,13 @@ unsigned Layout::Calculator::_buildSpansForPara(ParagraphInfo *para) const UnbrokenSpan new_span; new_span.pango_item_index = -1; new_span.input_index = input_index; - new_span.line_height.ascent = control_code->ascent; - new_span.line_height.descent = control_code->descent; + new_span.line_height.ascent = control_code->ascent * _flow.getTextLengthMultiplierDue(); + new_span.line_height.descent = control_code->descent * _flow.getTextLengthMultiplierDue(); new_span.line_height.leading = 0.0; new_span.text_bytes = 0; new_span.char_index_in_para = char_index_in_para; para->unbroken_spans.push_back(new_span); - TRACE(("add gap span %d\n", para->unbroken_spans.size() - 1)); + TRACE(("add gap span %lu\n", para->unbroken_spans.size() - 1)); } } else if (_flow._input_stream[input_index]->Type() == TEXT_SOURCE && pango_item_index < para->pango_items.size()) { Layout::InputStreamTextSource const *text_source = static_cast<Layout::InputStreamTextSource const *>(_flow._input_stream[input_index]); @@ -1154,13 +1164,13 @@ unsigned Layout::Calculator::_buildSpansForPara(ParagraphInfo *para) const if (_block_progression == TOP_TO_BOTTOM || _block_progression == BOTTOM_TO_TOP) { if (text_source->x.size() > char_index_in_source) new_span.x = text_source->x[char_index_in_source]; if (text_source->y.size() > char_index_in_source) new_span.y = text_source->y[char_index_in_source]; - if (text_source->dx.size() > char_index_in_source) new_span.dx = text_source->dx[char_index_in_source]; - if (text_source->dy.size() > char_index_in_source) new_span.dy = text_source->dy[char_index_in_source]; + if (text_source->dx.size() > char_index_in_source) new_span.dx = text_source->dx[char_index_in_source].computed * _flow.getTextLengthMultiplierDue(); + if (text_source->dy.size() > char_index_in_source) new_span.dy = text_source->dy[char_index_in_source].computed * _flow.getTextLengthMultiplierDue(); } else { if (text_source->x.size() > char_index_in_source) new_span.y = text_source->x[char_index_in_source]; if (text_source->y.size() > char_index_in_source) new_span.x = text_source->y[char_index_in_source]; - if (text_source->dx.size() > char_index_in_source) new_span.dy = text_source->dx[char_index_in_source]; - if (text_source->dy.size() > char_index_in_source) new_span.dx = text_source->dy[char_index_in_source]; + if (text_source->dx.size() > char_index_in_source) new_span.dy = text_source->dx[char_index_in_source].computed * _flow.getTextLengthMultiplierDue(); + if (text_source->dy.size() > char_index_in_source) new_span.dx = text_source->dy[char_index_in_source].computed * _flow.getTextLengthMultiplierDue(); } if (text_source->rotate.size() > char_index_in_source) new_span.rotate = text_source->rotate[char_index_in_source]; else if (char_index_in_source == 0) new_span.rotate = 0.f; @@ -1189,7 +1199,7 @@ unsigned Layout::Calculator::_buildSpansForPara(ParagraphInfo *para) const } // now we know the length, do some final calculations and add the UnbrokenSpan to the list - new_span.font_size = text_source->styleComputeFontSize(); + new_span.font_size = text_source->styleComputeFontSize() * _flow.getTextLengthMultiplierDue(); if (new_span.text_bytes) { new_span.glyph_string = pango_glyph_string_new(); /* Some assertions intended to help diagnose bug #1277746. */ @@ -1289,7 +1299,7 @@ unsigned Layout::Calculator::_buildSpansForPara(ParagraphInfo *para) const new_span.baseline_shift = text_source->style->baseline_shift.computed; // TODO: metrics for vertical text - TRACE(("add text span %d \"%s\"\n", para->unbroken_spans.size(), text_source->text->raw().substr(span_start_byte_in_source, new_span.text_bytes).c_str())); + TRACE(("add text span %lu \"%s\"\n", para->unbroken_spans.size(), text_source->text->raw().substr(span_start_byte_in_source, new_span.text_bytes).c_str())); TRACE((" %d glyphs\n", new_span.glyph_string->num_glyphs)); } else { // if there's no text we still need to initialise the styles @@ -1302,7 +1312,7 @@ unsigned Layout::Calculator::_buildSpansForPara(ParagraphInfo *para) const new_span.line_height.setZero(); new_span.line_height_multiplier = 1.0; } - TRACE(("add style init span %d\n", para->unbroken_spans.size())); + TRACE(("add style init span %lu\n", para->unbroken_spans.size())); } para->unbroken_spans.push_back(new_span); @@ -1338,7 +1348,7 @@ bool Layout::Calculator::_goToNextWrapShape() _current_shape_index++; if (_current_shape_index == _flow._input_wrap_shapes.size()) return false; _scanline_maker = new ShapeScanlineMaker(_flow._input_wrap_shapes[_current_shape_index].shape, _block_progression); - TRACE(("begin wrap shape %d\n", _current_shape_index)); + TRACE(("begin wrap shape %u\n", _current_shape_index)); return true; } @@ -1396,7 +1406,7 @@ bool Layout::Calculator::_findChunksForLine(ParagraphInfo const ¶, scan_runs = _scanline_maker->makeScanline(*line_height); } - TRACE(("finding line fit y=%f, %d scan runs\n", scan_runs.front().y, scan_runs.size())); + TRACE(("finding line fit y=%f, %lu scan runs\n", scan_runs.front().y, scan_runs.size())); chunk_info->clear(); chunk_info->reserve(scan_runs.size()); if (para.direction == RIGHT_TO_LEFT) std::reverse(scan_runs.begin(), scan_runs.end()); @@ -1495,7 +1505,7 @@ bool Layout::Calculator::_buildChunksInScanRun(ParagraphInfo const ¶, } } - TRACE(("chunk complete, used %f width (%d whitespaces, %d brokenspans)\n", new_chunk.text_width, new_chunk.whitespace_count, new_chunk.broken_spans.size())); + TRACE(("chunk complete, used %f width (%d whitespaces, %lu brokenspans)\n", new_chunk.text_width, new_chunk.whitespace_count, new_chunk.broken_spans.size())); chunk_info->push_back(new_chunk); if (scan_run.width() >= 4.0 * line_height->total() && last_span_at_break.end == start_span_pos) { @@ -1533,7 +1543,7 @@ bool Layout::Calculator::_buildChunksInScanRun(ParagraphInfo const ¶, chunk_info->back().text_width += last_span_at_break.width; chunk_info->back().whitespace_count += last_span_at_break.whitespace_count; } - TRACE(("correction: fitted span %d width = %f\n", last_span_at_break.start.iter_span - para.unbroken_spans.begin(), last_span_at_break.width)); + TRACE(("correction: fitted span %lu width = %f\n", last_span_at_break.start.iter_span - para.unbroken_spans.begin(), last_span_at_break.width)); } } @@ -1556,6 +1566,7 @@ bool Layout::Calculator::_buildChunksInScanRun(ParagraphInfo const ¶, return true; } + /** The management function to start the whole thing off. */ bool Layout::Calculator::calculate() { @@ -1605,7 +1616,7 @@ bool Layout::Calculator::calculate() else para.alignment = para.direction == LEFT_TO_RIGHT ? LEFT : RIGHT; - TRACE(("para prepared, adding as #%d\n", _flow._paragraphs.size())); + TRACE(("para prepared, adding as #%lu\n", _flow._paragraphs.size())); Layout::Paragraph new_paragraph; new_paragraph.base_direction = para.direction; new_paragraph.alignment = para.alignment; @@ -1627,7 +1638,7 @@ bool Layout::Calculator::calculate() _scanline_maker->completeLine(); // Increments y by line height } while (span_pos.iter_span != para.unbroken_spans.end()); - TRACE(("para %d end\n\n", _flow._paragraphs.size() - 1)); + TRACE(("para %lu end\n\n", _flow._paragraphs.size() - 1)); if (_scanline_maker != NULL) { bool is_empty_para = _flow._characters.empty() || _flow._characters.back().line(&_flow).in_paragraph != _flow._paragraphs.size() - 1; if ((is_empty_para && para_end_input_index + 1 >= _flow._input_stream.size()) @@ -1690,6 +1701,14 @@ bool Layout::Calculator::calculate() _flow._input_truncated = true; } + if (_flow.textLength._set) { + // Calculate the adjustment needed to meet the textLength + double actual_length = _flow.getActualLength(); + double difference = _flow.textLength.computed - actual_length; + _flow.textLengthMultiplier = (actual_length + difference) / actual_length; + _flow.textLengthIncrement = difference / (_flow._characters.size() == 1? 1 : _flow._characters.size() - 1); + } + return true; } @@ -1739,7 +1758,12 @@ void Layout::_calculateCursorShapeForEmpty() bool Layout::calculateFlow() { - bool result = Calculator(this).calculate(); + Layout::Calculator calc = Calculator(this); + bool result = calc.calculate(); + if (textLengthIncrement != 0) { + TRACE(("Recalculating layout the second time to fit textLength!\n")); + result = calc.calculate(); + } if (_characters.empty()) _calculateCursorShapeForEmpty(); return result; diff --git a/src/libnrtype/Layout-TNG-Input.cpp b/src/libnrtype/Layout-TNG-Input.cpp index fa1e8c11b..84f3f260e 100644 --- a/src/libnrtype/Layout-TNG-Input.cpp +++ b/src/libnrtype/Layout-TNG-Input.cpp @@ -72,6 +72,11 @@ void Layout::appendText(Glib::ustring const &text, SPStyle *style, void *source_ last_rotate = *it; new_source->rotate.resize(1, last_rotate); } + new_source->textLength._set = optional_attributes->textLength._set; + new_source->textLength.value = optional_attributes->textLength.value; + new_source->textLength.computed = optional_attributes->textLength.computed; + new_source->textLength.unit = optional_attributes->textLength.unit; + new_source->lengthAdjust = optional_attributes->lengthAdjust; } _input_stream.push_back(new_source); @@ -325,7 +330,7 @@ PangoFontDescription *Layout::InputStreamTextSource::styleGetFontDescription() c Layout::InputStreamTextSource::~InputStreamTextSource() { - sp_style_unref(style); + sp_style_unref(style); } }//namespace Text diff --git a/src/libnrtype/Layout-TNG-OutIter.cpp b/src/libnrtype/Layout-TNG-OutIter.cpp index 6dc42d998..c9c318960 100644 --- a/src/libnrtype/Layout-TNG-OutIter.cpp +++ b/src/libnrtype/Layout-TNG-OutIter.cpp @@ -401,15 +401,17 @@ std::vector<Geom::Point> Layout::createSelectionShape(iterator const &it_start, bottom_right[Geom::X] = span_x + _characters[char_index].x; double baseline_y = _spans[span_index].line(this).baseline_y + _spans[span_index].baseline_shift; + double vertical_scale = _glyphs.back().vertical_scale; + if (_directions_are_orthogonal(_blockProgression(), TOP_TO_BOTTOM)) { - double span_height = _spans[span_index].line_height.ascent + _spans[span_index].line_height.descent; + double span_height = vertical_scale * (_spans[span_index].line_height.ascent + _spans[span_index].line_height.descent); top_left[Geom::Y] = top_left[Geom::X]; top_left[Geom::X] = baseline_y - span_height * 0.5; bottom_right[Geom::Y] = bottom_right[Geom::X]; bottom_right[Geom::X] = baseline_y + span_height * 0.5; } else { - top_left[Geom::Y] = baseline_y - _spans[span_index].line_height.ascent; - bottom_right[Geom::Y] = baseline_y + _spans[span_index].line_height.descent; + top_left[Geom::Y] = baseline_y - vertical_scale * _spans[span_index].line_height.ascent; + bottom_right[Geom::Y] = baseline_y + vertical_scale * _spans[span_index].line_height.descent; } } @@ -505,21 +507,23 @@ void Layout::queryCursorShape(iterator const &it, Geom::Point &position, double position[Geom::Y] = span->line(this).baseline_y + span->baseline_shift; } // up to now *position is the baseline point, not the final point which will be the bottom of the descent + double vertical_scale = _glyphs.back().vertical_scale; + if (_directions_are_orthogonal(_blockProgression(), TOP_TO_BOTTOM)) { - height = span->line_height.ascent + span->line_height.descent; + height = vertical_scale * span->line_height.ascent + span->line_height.descent; rotation += M_PI / 2; std::swap(position[Geom::X], position[Geom::Y]); - position[Geom::X] -= sin(rotation) * height * 0.5; - position[Geom::Y] += cos(rotation) * height * 0.5; + position[Geom::X] -= vertical_scale * sin(rotation) * height * 0.5; + position[Geom::Y] += vertical_scale * cos(rotation) * height * 0.5; } else { double caret_slope_run = 0.0, caret_slope_rise = 1.0; if (span->font) const_cast<font_instance*>(span->font)->FontSlope(caret_slope_run, caret_slope_rise); double caret_slope = atan2(caret_slope_run, caret_slope_rise); - height = (span->line_height.ascent + span->line_height.descent) / cos(caret_slope); + height = vertical_scale * (span->line_height.ascent + span->line_height.descent) / cos(caret_slope); rotation += caret_slope; - position[Geom::X] -= sin(rotation) * span->line_height.descent; - position[Geom::Y] += cos(rotation) * span->line_height.descent; + position[Geom::X] -= sin(rotation) * vertical_scale * span->line_height.descent; + position[Geom::Y] += cos(rotation) * vertical_scale * span->line_height.descent; } } } @@ -601,9 +605,10 @@ void Layout::simulateLayoutUsingKerning(iterator const &from, iterator const &to if (input_item->Type() == TEXT_SOURCE) { SPStyle const *style = static_cast<InputStreamTextSource*>(input_item)->style; if (_characters[char_index].char_attributes.is_white) - dx -= style->word_spacing.computed; + dx -= style->word_spacing.computed * getTextLengthMultiplierDue(); if (_characters[char_index].char_attributes.is_cursor_position) - dx -= style->letter_spacing.computed; + dx -= style->letter_spacing.computed * getTextLengthMultiplierDue(); + dx -= getTextLengthIncrementDue(); } if (fabs(dx) > 0.0001) { diff --git a/src/libnrtype/Layout-TNG-Output.cpp b/src/libnrtype/Layout-TNG-Output.cpp index 61a141cc3..6e3faf33b 100644 --- a/src/libnrtype/Layout-TNG-Output.cpp +++ b/src/libnrtype/Layout-TNG-Output.cpp @@ -108,7 +108,7 @@ void Layout::_getGlyphTransformMatrix(int glyph_index, Geom::Affine *matrix) con (*matrix)[0] = span.font_size * cos_rotation; (*matrix)[1] = span.font_size * sin_rotation; (*matrix)[2] = span.font_size * sin_rotation; - (*matrix)[3] = -span.font_size * cos_rotation; + (*matrix)[3] = -span.font_size * cos_rotation * (_glyphs[glyph_index].vertical_scale); // unscale vertically so the specified text height is preserved if lengthAdjust=spacingAndGlyphs if (span.block_progression == LEFT_TO_RIGHT || span.block_progression == RIGHT_TO_LEFT) { (*matrix)[4] = _lines[_chunks[span.in_chunk].in_line].baseline_y + _glyphs[glyph_index].y; (*matrix)[5] = _chunks[span.in_chunk].left_x + _glyphs[glyph_index].x; @@ -804,6 +804,36 @@ void Layout::transform(Geom::Affine const &transform) } } +double Layout::getTextLengthIncrementDue() const +{ + if (textLength._set && textLengthIncrement != 0 && lengthAdjust == Inkscape::Text::Layout::LENGTHADJUST_SPACING) { + return textLengthIncrement; + } + return 0; +} + + +double Layout::getTextLengthMultiplierDue() const +{ + if (textLength._set && textLengthMultiplier != 1 && (lengthAdjust == Inkscape::Text::Layout::LENGTHADJUST_SPACINGANDGLYPHS)) { + return textLengthMultiplier; + } + return 1; +} + +double Layout::getActualLength() const +{ + double length = 0; + for (std::vector<Span>::const_iterator it_span = _spans.begin() ; it_span != _spans.end() ; it_span++) { + // take x_end of the last span of each chunk + if (it_span == _spans.end() - 1 || (it_span + 1)->in_chunk != it_span->in_chunk) + length += it_span->x_end; + } + return length; + + +} + }//namespace Text }//namespace Inkscape diff --git a/src/libnrtype/Layout-TNG.cpp b/src/libnrtype/Layout-TNG.cpp index dd9c90949..8b0889188 100644 --- a/src/libnrtype/Layout-TNG.cpp +++ b/src/libnrtype/Layout-TNG.cpp @@ -20,6 +20,10 @@ Layout::Layout() : _input_truncated(0), _path_fitted(NULL) { + textLength._set = false; + textLengthMultiplier = 1; + textLengthIncrement = 0; + lengthAdjust = LENGTHADJUST_SPACING; } Layout::~Layout() @@ -31,6 +35,11 @@ void Layout::clear() { _clearInputObjects(); _clearOutputObjects(); + + textLength._set = false; + textLengthMultiplier = 1; + textLengthIncrement = 0; + lengthAdjust = LENGTHADJUST_SPACING; } bool Layout::_directions_are_orthogonal(Direction d1, Direction d2) diff --git a/src/libnrtype/Layout-TNG.h b/src/libnrtype/Layout-TNG.h index fd5bbfaef..e91c32ebe 100644 --- a/src/libnrtype/Layout-TNG.h +++ b/src/libnrtype/Layout-TNG.h @@ -21,6 +21,7 @@ #include <algorithm> #include <vector> #include <boost/optional.hpp> +#include <svg/svg-length.h> #ifdef HAVE_CAIRO_PDF namespace Inkscape { @@ -37,7 +38,6 @@ using Inkscape::Extension::Internal::CairoRenderContext; class SPStyle; class Shape; struct SPPrintContext; -class SVGLength; class Path; class SPCurve; class font_instance; @@ -160,6 +160,9 @@ public: /** Display alignment for shapes. See appendWrapShape(). */ enum DisplayAlign {DISPLAY_ALIGN_BEFORE, DISPLAY_ALIGN_CENTER, DISPLAY_ALIGN_AFTER}; + /** lengthAdjust values */ + enum LengthAdjust {LENGTHADJUST_SPACING, LENGTHADJUST_SPACINGANDGLYPHS}; + /** The optional attributes which can be applied to a SVG text or related tag. See appendText(). See SVG1.1 section 10.4 for the definitions of all these members. See sp_svg_length_list_read() for @@ -172,6 +175,8 @@ public: std::vector<SVGLength> dx; std::vector<SVGLength> dy; std::vector<SVGLength> rotate; + SVGLength textLength; + LengthAdjust lengthAdjust; }; /** Control codes which can be embedded in the text to be flowed. See @@ -290,6 +295,43 @@ public: //@} + // ************************** textLength and friends ************************* + + /** Gives the length target of this layout, as given by textLength attribute. + + FIXME: by putting it here we only support @textLength on text and flowRoot, not on any + spans inside. For spans, we will need to add markers of start and end of a textLength span + into the _input_stream. These spans can nest (SVG 1.1, section 10.5). After a first layout + calculation, we would go through the input stream and, for each end of a textLength span, + go through its items, choose those where it wasn't yet set by a nested span, calculate + their number of characters, divide the length deficit by it, and set set the + textLengthMultiplier for those characters only. For now we do this for the entire layout, + without dealing with spans. + */ + SVGLength textLength; + + /** How do we meet textLength if specified: by letterspacing or by scaling horizontally */ + LengthAdjust lengthAdjust; + + /** By how much each character needs to be wider or narrower, using the specified lengthAdjust + strategy, for the layout to meet its textLength target. Is set to non-zero after the layout + is calculated for the first time, then it is recalculated with each glyph getting its adjustment. */ + /** This one is used by scaling strategies: each glyph width is multiplied by this */ + double textLengthMultiplier; + /** This one is used by letterspacing strategy: to each glyph width, this is added */ + double textLengthIncrement; + + /** Get the actual spacing increment if it's due with the current values of above stuff, otherwise 0 */ + double getTextLengthIncrementDue() const; + /** Get the actual scale multiplier if it's due with the current values of above stuff, otherwise 1 */ + double getTextLengthMultiplierDue() const; + + /** Get actual length of layout, by summing span lengths. For one-line non-flowed text, just + the width; for multiline non-flowed, sum of lengths of all lines; for flowed text, sum of + scanline widths for all non-last lines plus text width of last line. */ + double getActualLength() const; + + // ************************** doing the actual flowing ************************* /** \name Processing @@ -618,6 +660,8 @@ private: std::vector<SVGLength> dx; std::vector<SVGLength> dy; std::vector<SVGLength> rotate; + SVGLength textLength; + LengthAdjust lengthAdjust; // a few functions for some of the more complicated style accesses float styleComputeFontSize() const; @@ -701,6 +745,7 @@ private: float y; /// relative to the current line's baseline float rotation; /// absolute, modulo any object transforms, which we don't know about float width; + float vertical_scale; /// to implement lengthAdjust="spacingAndGlyphs" that must scale glyphs only horizontally; instead we change font size and then undo that change vertically only inline Span const & span(Layout const *l) const {return l->_spans[l->_characters[in_character].in_span];} inline Chunk const & chunk(Layout const *l) const {return l->_chunks[l->_spans[l->_characters[in_character].in_span].in_chunk];} inline Line const & line(Layout const *l) const {return l->_lines[l->_chunks[l->_spans[l->_characters[in_character].in_span].in_chunk].in_line];} diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index fad06cd00..a6ab3b239 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -385,27 +385,27 @@ std::pair<Glib::ustring, Glib::ustring> FontLister::selection_update() #endif // Get fontspec from a selection, preferences, or thin air. Glib::ustring fontspec; - SPStyle *query = sp_style_new(SP_ACTIVE_DOCUMENT); + SPStyle query(SP_ACTIVE_DOCUMENT); // Directly from stored font specification. int result = - sp_desktop_query_style(SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION); + sp_desktop_query_style(SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION); //std::cout << " Attempting selected style" << std::endl; - if (result != QUERY_STYLE_NOTHING && query->font_specification.set) { - fontspec = query->font_specification.value; + if (result != QUERY_STYLE_NOTHING && query.font_specification.set) { + fontspec = query.font_specification.value; //std::cout << " fontspec from query :" << fontspec << ":" << std::endl; } // From style if (fontspec.empty()) { //std::cout << " Attempting desktop style" << std::endl; - int rfamily = sp_desktop_query_style(SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY); - int rstyle = sp_desktop_query_style(SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTSTYLE); + int rfamily = sp_desktop_query_style(SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTFAMILY); + int rstyle = sp_desktop_query_style(SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTSTYLE); // Must have text in selection if (rfamily != QUERY_STYLE_NOTHING && rstyle != QUERY_STYLE_NOTHING) { - fontspec = fontspec_from_style(query); + fontspec = fontspec_from_style(&query); } //std::cout << " fontspec from style :" << fontspec << ":" << std::endl; } @@ -413,11 +413,10 @@ std::pair<Glib::ustring, Glib::ustring> FontLister::selection_update() // From preferences if (fontspec.empty()) { //std::cout << " Attempting preferences" << std::endl; - sp_style_read_from_prefs(query, "/tools/text"); - fontspec = fontspec_from_style(query); + query.readFromPrefs("/tools/text"); + fontspec = fontspec_from_style(&query); //std::cout << " fontspec from prefs :" << fontspec << ":" << std::endl; } - sp_style_unref(query); // From thin air if (fontspec.empty()) { diff --git a/src/line-geometry.cpp b/src/line-geometry.cpp index 566af8840..c5357e213 100644 --- a/src/line-geometry.cpp +++ b/src/line-geometry.cpp @@ -13,7 +13,7 @@ #include "inkscape.h" #include "desktop.h" #include "desktop-style.h" -#include "desktop-handles.h" + #include "display/sp-canvas.h" #include "display/sp-ctrlline.h" #include "display/sodipodi-ctrl.h" @@ -201,8 +201,8 @@ boost::optional<Geom::Point> Line::intersection_with_viewbox (SPDesktop *desktop void create_canvas_point(Geom::Point const &pos, double size, guint32 rgba) { - SPDesktop *desktop = inkscape_active_desktop(); - SPCanvasItem * canvas_pt = sp_canvas_item_new(sp_desktop_controls(desktop), SP_TYPE_CTRL, + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + SPCanvasItem * canvas_pt = sp_canvas_item_new(desktop->getControls(), SP_TYPE_CTRL, "size", size, "filled", 1, "fill_color", rgba, @@ -214,8 +214,8 @@ void create_canvas_point(Geom::Point const &pos, double size, guint32 rgba) void create_canvas_line(Geom::Point const &p1, Geom::Point const &p2, guint32 rgba) { - SPDesktop *desktop = inkscape_active_desktop(); - SPCtrlLine *line = ControlManager::getManager().createControlLine(sp_desktop_controls(desktop), p1, p2); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + SPCtrlLine *line = ControlManager::getManager().createControlLine(desktop->getControls(), p1, p2); line->setRgba32(rgba); sp_canvas_item_show(line); } diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index e49a15dd0..1da364580 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -363,6 +363,10 @@ Effect::Effect(LivePathEffectObject *lpeobject) show_orig_path(false), lpeobj(lpeobject), concatenate_before_pwd2(false), + sp_lpe_item(NULL), + defaultUnit("px"), + current_zoom(1), + sp_curve(NULL), provides_own_flash_paths(true), // is automatically set to false if providesOwnFlashPaths() is not overridden is_ready(false) // is automatically set to false if providesOwnFlashPaths() is not overridden { @@ -450,7 +454,7 @@ void Effect::doOnRemove (SPLPEItem const* /*lpeitem*/) void Effect::doOnApply_impl(SPLPEItem const* lpeitem) { sp_lpe_item = const_cast<SPLPEItem *>(lpeitem); - defaultUnit = &sp_lpe_item->document->getDefaultUnit()->abbr; + defaultUnit = sp_lpe_item->document->getDisplayUnit()->abbr; /*sp_curve = SP_SHAPE(sp_lpe_item)->getCurve(); pathvector_before_effect = sp_curve->get_pathvector();*/ doOnApply(lpeitem); @@ -459,11 +463,13 @@ void Effect::doOnApply_impl(SPLPEItem const* lpeitem) void Effect::doBeforeEffect_impl(SPLPEItem const* lpeitem) { sp_lpe_item = const_cast<SPLPEItem *>(lpeitem); - defaultUnit = &sp_lpe_item->document->getDefaultUnit()->abbr; + defaultUnit = sp_lpe_item->document->getDisplayUnit()->abbr; //printf("(SPLPEITEM*) %p\n", sp_lpe_item); - sp_curve = SP_SHAPE(sp_lpe_item)->getCurve(); - pathvector_before_effect = sp_curve->get_pathvector(); - + SPShape * shape = dynamic_cast<SPShape *>(sp_lpe_item); + if(shape){ + sp_curve = shape->getCurve(); + pathvector_before_effect = sp_curve->get_pathvector(); + } doBeforeEffect(lpeitem); } @@ -476,7 +482,7 @@ void Effect::doAcceptPathPreparations(SPLPEItem *lpeitem) { // switch to pen context - SPDesktop *desktop = inkscape_active_desktop(); // TODO: Is there a better method to find the item's desktop? + SPDesktop *desktop = SP_ACTIVE_DESKTOP; // TODO: Is there a better method to find the item's desktop? if (!tools_isactive(desktop, TOOLS_FREEHAND_PEN)) { tools_switch(desktop, TOOLS_FREEHAND_PEN); } diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index 7da76b267..ac1f0b8dc 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -159,7 +159,7 @@ protected: bool concatenate_before_pwd2; SPLPEItem * sp_lpe_item; // these get stored in doBeforeEffect_impl, and derived classes may do as they please with them. - Glib::ustring const * defaultUnit; // these get stored in doBeforeEffect_impl, and derived classes may do as they please with them. + Glib::ustring defaultUnit; // these get stored in doBeforeEffect_impl, and derived classes may do as they please with them. double current_zoom; std::vector<Geom::Point> selectedNodesPoints; SPCurve * sp_curve; diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index c5390a0c9..b924d8a23 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -54,20 +54,17 @@ const double defaultEndPower = 0.6667; LPEBSpline::LPEBSpline(LivePathEffectObject *lpeobject) : Effect(lpeobject), - // initialise your parameters here: - //testpointA(_("Test Point A"), _("Test A"), "ptA", &wr, this, - //Geom::Point(100,100)), steps(_("Steps with CTRL:"), _("Change number of steps with CTRL pressed"), "steps", &wr, this, 2), + helper_size(_("Helper size:"), _("Helper size"), "helper_size", &wr, this, 0), ignoreCusp(_("Ignore cusp nodes"), _("Change ignoring cusp nodes"), "ignoreCusp", &wr, this, true), onlySelected(_("Change only selected nodes"), _("Change only selected nodes"), "onlySelected", &wr, this, false), - showHelper(_("Show helper paths"), _("Show helper paths"), "showHelper", &wr, this, false), weight(_("Change weight:"), _("Change weight of the effect"), "weight", &wr, this, defaultStartPower) { - registerParameter(dynamic_cast<Parameter *>(&weight)); - registerParameter(dynamic_cast<Parameter *>(&steps)); - registerParameter(dynamic_cast<Parameter *>(&ignoreCusp)); - registerParameter(dynamic_cast<Parameter *>(&onlySelected)); - registerParameter(dynamic_cast<Parameter *>(&showHelper)); + registerParameter(&weight); + registerParameter(&steps); + registerParameter(&helper_size); + registerParameter(&ignoreCusp); + registerParameter(&onlySelected); weight.param_set_range(noPower, 1); weight.param_set_increments(0.1, 0.1); @@ -76,6 +73,10 @@ LPEBSpline::LPEBSpline(LivePathEffectObject *lpeobject) steps.param_set_range(1, 10); steps.param_set_increments(1, 1); steps.param_set_digits(0); + + helper_size.param_set_range(0.0, 999.0); + helper_size.param_set_increments(5, 5); + helper_size.param_set_digits(2); } LPEBSpline::~LPEBSpline() {} @@ -106,9 +107,7 @@ void LPEBSpline::doEffect(SPCurve *curve) // Make copy of old path as it is changed during processing Geom::PathVector const original_pathv = curve->get_pathvector(); curve->reset(); - double radiusHelperNodes = 6.0; - radiusHelperNodes /= current_zoom; - radiusHelperNodes = Inkscape::Util::Quantity::convert(radiusHelperNodes, "px", *defaultUnit); + for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { if (path_it->empty()) @@ -236,8 +235,8 @@ void LPEBSpline::doEffect(SPCurve *curve) } nCurve->curveto(pointAt1, pointAt2, node); } - if(!are_near(node,curve_it1->finalPoint()) && showHelper){ - drawHandle(node, radiusHelperNodes); + if(!are_near(node,curve_it1->finalPoint()) && helper_size > 0.0){ + drawHandle(node, helper_size); } ++curve_it1; ++curve_it2; @@ -250,21 +249,21 @@ void LPEBSpline::doEffect(SPCurve *curve) nCurve->reset(); delete nCurve; } - if(showHelper){ + if(helper_size > 0.0){ Geom::PathVector const pathv = curve->get_pathvector(); hp.push_back(pathv[0]); } } void -LPEBSpline::drawHandle(Geom::Point p, double radiusHelperNodes) +LPEBSpline::drawHandle(Geom::Point p, double helper_size) { char const * svgd = "M 1,0.5 A 0.5,0.5 0 0 1 0.5,1 0.5,0.5 0 0 1 0,0.5 0.5,0.5 0 0 1 0.5,0 0.5,0.5 0 0 1 1,0.5 Z"; Geom::PathVector pathv = sp_svg_read_pathv(svgd); Geom::Affine aff = Geom::Affine(); - aff *= Geom::Scale(radiusHelperNodes); + aff *= Geom::Scale(helper_size); pathv *= aff; - pathv += p - Geom::Point(0.5*radiusHelperNodes, 0.5*radiusHelperNodes); + pathv += p - Geom::Point(0.5*helper_size, 0.5*helper_size); hp.push_back(pathv[0]); } @@ -356,17 +355,20 @@ void LPEBSpline::toWeight() void LPEBSpline::changeWeight(double weightValue) { - SPPath *path = SP_PATH(sp_lpe_item); - SPCurve *curve = path->get_curve_for_edit(); - LPEBSpline::doBSplineFromWidget(curve, weightValue); - gchar *str = sp_svg_write_path(curve->get_pathvector()); - path->getRepr()->setAttribute("inkscape:original-d", str); + SPPath *path = dynamic_cast<SPPath *>(sp_lpe_item); + if(path){ + SPCurve *curve = path->get_curve_for_edit(); + LPEBSpline::doBSplineFromWidget(curve, weightValue); + gchar *str = sp_svg_write_path(curve->get_pathvector()); + path->getRepr()->setAttribute("inkscape:original-d", str); + } } void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weightValue) { using Geom::X; using Geom::Y; + if (curve->get_segment_count() < 1) return; // Make copy of old path as it is changed during processing diff --git a/src/live_effects/lpe-bspline.h b/src/live_effects/lpe-bspline.h index a17c0c4ac..642562b24 100644 --- a/src/live_effects/lpe-bspline.h +++ b/src/live_effects/lpe-bspline.h @@ -38,9 +38,9 @@ public: ScalarParam steps; private: + ScalarParam helper_size; BoolParam ignoreCusp; BoolParam onlySelected; - BoolParam showHelper; ScalarParam weight; Geom::PathVector hp; diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 51787e292..fd9b853d5 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -15,9 +15,6 @@ #include <gdk/gdk.h> #include "live_effects/lpe-copy_rotate.h" -#include "sp-shape.h" -#include "display/curve.h" - #include <2geom/path.h> #include <2geom/transforms.h> #include <2geom/d2-sbasis.h> @@ -38,28 +35,41 @@ public: virtual Geom::Point knot_get() const; }; +class KnotHolderEntityRotationAngle : public LPEKnotHolderEntity { +public: + KnotHolderEntityRotationAngle(LPECopyRotate *effect) : LPEKnotHolderEntity(effect) {}; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual Geom::Point knot_get() const; +}; + +class KnotHolderEntityOrigin : public LPEKnotHolderEntity { +public: + KnotHolderEntityOrigin(LPECopyRotate *effect) : LPEKnotHolderEntity(effect) {}; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual Geom::Point knot_get() const; +}; } // namespace CR LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : Effect(lpeobject), + origin(_("Origin"), _("Origin of the rotation"), "origin", &wr, this, "Adjust the origin of the rotation"), starting_angle(_("Starting:"), _("Angle of the first copy"), "starting_angle", &wr, this, 0.0), rotation_angle(_("Rotation angle:"), _("Angle between two successive copies"), "rotation_angle", &wr, this, 30.0), num_copies(_("Number of copies:"), _("Number of copies of the original path"), "num_copies", &wr, this, 5), copiesTo360(_("360º Copies"), _("No rotation angle, fixed to 360º"), "copiesTo360", &wr, this, true), - origin(_("Origin"), _("Origin of the rotation"), "origin", &wr, this, "Adjust the origin of the rotation"), - dist_angle_handle(100) + dist_angle_handle(100.0) { show_orig_path = true; _provides_knotholder_entities = true; // register all your parameters here, so Inkscape knows which parameters this effect has: - registerParameter( dynamic_cast<Parameter *>(&copiesTo360) ); - registerParameter( dynamic_cast<Parameter *>(&starting_angle) ); - registerParameter( dynamic_cast<Parameter *>(&rotation_angle) ); - registerParameter( dynamic_cast<Parameter *>(&num_copies) ); - registerParameter( dynamic_cast<Parameter *>(&origin) ); - + registerParameter(&copiesTo360); + registerParameter(&starting_angle); + registerParameter(&rotation_angle); + registerParameter(&num_copies); + registerParameter(&origin); + num_copies.param_make_integer(true); num_copies.param_set_range(0, 1000); } @@ -73,47 +83,58 @@ void LPECopyRotate::doOnApply(SPLPEItem const* lpeitem) { using namespace Geom; - original_bbox(lpeitem); - Point A(boundingbox_X.min(), boundingbox_Y.middle()); - Point B(boundingbox_X.max(), boundingbox_Y.middle()); - Point C(boundingbox_X.middle(), boundingbox_Y.middle()); + A = Point(boundingbox_X.min(), boundingbox_Y.middle()); + B = Point(boundingbox_X.middle(), boundingbox_Y.middle()); origin.param_setValue(A); - - dir = unit_vector(B - A); + origin.param_update_default(A); dist_angle_handle = L2(B - A); + dir = unit_vector(B - A); } -Geom::Piecewise<Geom::D2<Geom::SBasis> > -LPECopyRotate::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in) + +void +LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) { using namespace Geom; - + original_bbox(lpeitem); + if(copiesTo360 ){ + rotation_angle.param_set_value(360.0/(double)num_copies); + } + A = Point(boundingbox_X.min(), boundingbox_Y.middle()); + B = Point(boundingbox_X.middle(), boundingbox_Y.middle()); + dir = unit_vector(B - A); // I first suspected the minus sign to be a bug in 2geom but it is // likely due to SVG's choice of coordinate system orientation (max) start_pos = origin + dir * Rotate(-deg_to_rad(starting_angle)) * dist_angle_handle; - double rotation_angle_end = rotation_angle; - if(copiesTo360){ - rotation_angle_end = 360.0/(double)num_copies; + rot_pos = origin + dir * Rotate(-deg_to_rad(rotation_angle+starting_angle)) * dist_angle_handle; + if(copiesTo360 ){ + rot_pos = origin; } - rot_pos = origin + dir * Rotate(-deg_to_rad(starting_angle + rotation_angle_end)) * dist_angle_handle; + SPLPEItem * item = const_cast<SPLPEItem*>(lpeitem); + item->apply_to_clippath(item); + item->apply_to_mask(item); - A = pwd2_in.firstValue(); - B = pwd2_in.lastValue(); - dir = unit_vector(B - A); +} - Piecewise<D2<SBasis> > output; +Geom::Piecewise<Geom::D2<Geom::SBasis> > +LPECopyRotate::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in) +{ + using namespace Geom; + + if(num_copies == 1){ + return pwd2_in; + } + + Piecewise<D2<SBasis> > output; Affine pre = Translate(-origin) * Rotate(-deg_to_rad(starting_angle)); for (int i = 0; i < num_copies; ++i) { - // I first suspected the minus sign to be a bug in 2geom but it is - // likely due to SVG's choice of coordinate system orientation (max) - Rotate rot(-deg_to_rad(rotation_angle_end * i)); + Rotate rot(-deg_to_rad(rotation_angle * i)); Affine t = pre * rot * Translate(origin); output.concat(pwd2_in * t); } - return output; } @@ -121,12 +142,13 @@ void LPECopyRotate::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector<Geom::PathVector> &hp_vec) { using namespace Geom; - - Path path(start_pos); - path.appendNew<LineSegment>((Geom::Point) origin); - path.appendNew<LineSegment>(rot_pos); - PathVector pathv; - pathv.push_back(path); + hp_vec.clear(); + Geom::Path hp; + hp.start(start_pos); + hp.appendNew<Geom::LineSegment>((Geom::Point)origin); + hp.appendNew<Geom::LineSegment>(origin + dir * Rotate(-deg_to_rad(rotation_angle+starting_angle)) * dist_angle_handle); + Geom::PathVector pathv; + pathv.push_back(hp); hp_vec.push_back(pathv); } @@ -135,9 +157,22 @@ void LPECopyRotate::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *des { KnotHolderEntity *e = new CR::KnotHolderEntityStartingAngle(this); e->create( desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, - _("Adjust the starting angle") ); + _("Adjust the starting angle")); knotholder->add(e); } + { + KnotHolderEntity *e = new CR::KnotHolderEntityRotationAngle(this); + e->create( desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, + _("Adjust the rotation angle")); + knotholder->add(e); + } +} + +void +LPECopyRotate::resetDefaults(SPItem const* item) +{ + Effect::resetDefaults(item); + original_bbox(SP_LPE_ITEM(item)); }; namespace CR { @@ -164,6 +199,26 @@ KnotHolderEntityStartingAngle::knot_set(Geom::Point const &p, Geom::Point const sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true); } +void +KnotHolderEntityRotationAngle::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state) +{ + LPECopyRotate* lpe = dynamic_cast<LPECopyRotate *>(_effect); + + Geom::Point const s = snap_knot_position(p, state); + + // I first suspected the minus sign to be a bug in 2geom but it is + // likely due to SVG's choice of coordinate system orientation (max) + lpe->rotation_angle.param_set_value(rad_to_deg(-angle_between(lpe->dir, s - lpe->origin)) - lpe->starting_angle); + if (state & GDK_SHIFT_MASK) { + lpe->dist_angle_handle = L2(lpe->B - lpe->A); + } else { + lpe->dist_angle_handle = L2(p - lpe->origin); + } + + // FIXME: this should not directly ask for updating the item. It should write to SVG, which triggers updating. + sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true); +} + Geom::Point KnotHolderEntityStartingAngle::knot_get() const { @@ -171,9 +226,14 @@ KnotHolderEntityStartingAngle::knot_get() const return lpe->start_pos; } -} // namespace CR - +Geom::Point +KnotHolderEntityRotationAngle::knot_get() const +{ + LPECopyRotate const *lpe = dynamic_cast<LPECopyRotate const*>(_effect); + return lpe->rot_pos; +} +} // namespace CR /* ######################## */ diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index 123c92cdd..9392026a7 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -36,21 +36,25 @@ public: virtual Geom::Piecewise<Geom::D2<Geom::SBasis> > doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in); + virtual void doBeforeEffect (SPLPEItem const* lpeitem); + + virtual void resetDefaults(SPItem const* item); + /* the knotholder entity classes must be declared friends */ friend class CR::KnotHolderEntityStartingAngle; + friend class CR::KnotHolderEntityRotationAngle; void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item); protected: virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector<Geom::PathVector> &hp_vec); private: + PointParam origin; ScalarParam starting_angle; ScalarParam rotation_angle; ScalarParam num_copies; BoolParam copiesTo360; - PointParam origin; - Geom::Point A; Geom::Point B; Geom::Point dir; diff --git a/src/live_effects/lpe-fillet-chamfer.cpp b/src/live_effects/lpe-fillet-chamfer.cpp index 119759b87..c8458b8cb 100644 --- a/src/live_effects/lpe-fillet-chamfer.cpp +++ b/src/live_effects/lpe-fillet-chamfer.cpp @@ -57,12 +57,12 @@ LPEFilletChamfer::LPEFilletChamfer(LivePathEffectObject *lpeobject) : only_selected(_("Change only selected nodes"), _("Change only selected nodes"), "only_selected", &wr, this, false), flexible(_("Flexible radius size (%)"), _("Flexible radius size (%)"), "flexible", &wr, this, false), use_knot_distance(_("Use knots distance instead radius"), _("Use knots distance instead radius"), "use_knot_distance", &wr, this, false), - unit(_("Unit"), _("Unit"), "unit", &wr, this), - method(_("Method"), _("Fillets methods"), "method", FMConverter, &wr, this, FM_AUTO), - radius(_("Radius (unit or %)"), _("Radius, in unit or %"), "radius", &wr, this, 0.), - chamfer_steps(_("Chamfer steps"), _("Chamfer steps"), "chamfer_steps", &wr, this, 0), + unit(_("Unit:"), _("Unit"), "unit", &wr, this), + method(_("Method:"), _("Fillets methods"), "method", FMConverter, &wr, this, FM_AUTO), + radius(_("Radius (unit or %):"), _("Radius, in unit or %"), "radius", &wr, this, 0.), + chamfer_steps(_("Chamfer steps:"), _("Chamfer steps"), "chamfer_steps", &wr, this, 0), - helper_size(_("Helper size with direction"), _("Helper size with direction"), "helper_size", &wr, this, 0) + helper_size(_("Helper size with direction:"), _("Helper size with direction"), "helper_size", &wr, this, 0) { registerParameter(&fillet_chamfer_values); registerParameter(&unit); @@ -223,7 +223,7 @@ void LPEFilletChamfer::updateFillet() { double power = 0; if (!flexible) { - power = Inkscape::Util::Quantity::convert(radius, unit.get_abbreviation(), *defaultUnit) * -1; + power = Inkscape::Util::Quantity::convert(radius, unit.get_abbreviation(), defaultUnit) * -1; } else { power = radius; } diff --git a/src/live_effects/lpe-knot.cpp b/src/live_effects/lpe-knot.cpp index 3876aa24b..820221abf 100644 --- a/src/live_effects/lpe-knot.cpp +++ b/src/live_effects/lpe-knot.cpp @@ -404,7 +404,7 @@ LPEKnot::doEffect_path (std::vector<Geom::Path> const &path_in) for (unsigned comp=0; comp<path_in.size(); comp++){ //find the relevant path component in gpaths (required to allow groups!) - //Q: do we always recieve the group members in the same order? can we rest on that? + //Q: do we always receive the group members in the same order? can we rest on that? unsigned i0 = 0; for (i0=0; i0<gpaths.size(); i0++){ if (path_in[comp]==gpaths[i0]) break; diff --git a/src/live_effects/lpe-lattice.cpp b/src/live_effects/lpe-lattice.cpp index a241a8a2e..c05bae7e1 100644 --- a/src/live_effects/lpe-lattice.cpp +++ b/src/live_effects/lpe-lattice.cpp @@ -236,6 +236,21 @@ LPELattice::resetDefaults(SPItem const* item) grid_point15[Geom::X] = 2.0/3*boundingbox_X.max()+1.0/3*boundingbox_X.min(); grid_point15[Geom::Y] = 2.0/3*boundingbox_Y.max()+1.0/3*boundingbox_Y.min(); + grid_point1.param_update_default(grid_point1); + grid_point2.param_update_default(grid_point2); + grid_point3.param_update_default(grid_point3); + grid_point4.param_update_default(grid_point4); + grid_point5.param_update_default(grid_point5); + grid_point6.param_update_default(grid_point6); + grid_point7.param_update_default(grid_point7); + grid_point8.param_update_default(grid_point8); + grid_point9.param_update_default(grid_point9); + grid_point10.param_update_default(grid_point10); + grid_point11.param_update_default(grid_point11); + grid_point12.param_update_default(grid_point12); + grid_point13.param_update_default(grid_point13); + grid_point14.param_update_default(grid_point14); + grid_point15.param_update_default(grid_point15); } /** diff --git a/src/live_effects/lpe-lattice2.cpp b/src/live_effects/lpe-lattice2.cpp index e1cd91340..08bbbd504 100644 --- a/src/live_effects/lpe-lattice2.cpp +++ b/src/live_effects/lpe-lattice2.cpp @@ -23,18 +23,17 @@ #include "sp-path.h" #include "display/curve.h" #include "svg/svg.h" - +#include "helper/geom.h" +#include <2geom/path.h> #include <2geom/sbasis.h> #include <2geom/sbasis-2d.h> +#include "helper/geom-curves.h" #include <2geom/sbasis-geometric.h> #include <2geom/bezier-to-sbasis.h> #include <2geom/sbasis-to-bezier.h> #include <2geom/d2.h> #include <2geom/piecewise.h> #include <2geom/transforms.h> -#include "ui/tools-switch.h" - -#include "desktop.h" // TODO: should be factored out (see below) using namespace Geom; @@ -43,61 +42,63 @@ namespace LivePathEffect { LPELattice2::LPELattice2(LivePathEffectObject *lpeobject) : Effect(lpeobject), - // initialise your parameters here: - grid_point0(_("Control handle 0:"), _("Control handle 0 - Ctrl+Alt+Click to reset"), "gridpoint0", &wr, this), - grid_point1(_("Control handle 1:"), _("Control handle 1 - Ctrl+Alt+Click to reset"), "gridpoint1", &wr, this), - grid_point2(_("Control handle 2:"), _("Control handle 2 - Ctrl+Alt+Click to reset"), "gridpoint2", &wr, this), - grid_point3(_("Control handle 3:"), _("Control handle 3 - Ctrl+Alt+Click to reset"), "gridpoint3", &wr, this), - grid_point4(_("Control handle 4:"), _("Control handle 4 - Ctrl+Alt+Click to reset"), "gridpoint4", &wr, this), - grid_point5(_("Control handle 5:"), _("Control handle 5 - Ctrl+Alt+Click to reset"), "gridpoint5", &wr, this), - grid_point6(_("Control handle 6:"), _("Control handle 6 - Ctrl+Alt+Click to reset"), "gridpoint6", &wr, this), - grid_point7(_("Control handle 7:"), _("Control handle 7 - Ctrl+Alt+Click to reset"), "gridpoint7", &wr, this), - grid_point8x9(_("Control handle 8x9:"), _("Control handle 8x9 - Ctrl+Alt+Click to reset"), "gridpoint8x9", &wr, this), - grid_point10x11(_("Control handle 10x11:"), _("Control handle 10x11 - Ctrl+Alt+Click to reset"), "gridpoint10x11", &wr, this), - grid_point12(_("Control handle 12:"), _("Control handle 12 - Ctrl+Alt+Click to reset"), "gridpoint12", &wr, this), - grid_point13(_("Control handle 13:"), _("Control handle 13 - Ctrl+Alt+Click to reset"), "gridpoint13", &wr, this), - grid_point14(_("Control handle 14:"), _("Control handle 14 - Ctrl+Alt+Click to reset"), "gridpoint14", &wr, this), - grid_point15(_("Control handle 15:"), _("Control handle 15 - Ctrl+Alt+Click to reset"), "gridpoint15", &wr, this), - grid_point16(_("Control handle 16:"), _("Control handle 16 - Ctrl+Alt+Click to reset"), "gridpoint16", &wr, this), - grid_point17(_("Control handle 17:"), _("Control handle 17 - Ctrl+Alt+Click to reset"), "gridpoint17", &wr, this), - grid_point18(_("Control handle 18:"), _("Control handle 18 - Ctrl+Alt+Click to reset"), "gridpoint18", &wr, this), - grid_point19(_("Control handle 19:"), _("Control handle 19 - Ctrl+Alt+Click to reset"), "gridpoint19", &wr, this), - grid_point20x21(_("Control handle 20x21:"), _("Control handle 20x21 - Ctrl+Alt+Click to reset"), "gridpoint20x21", &wr, this), - grid_point22x23(_("Control handle 22x23:"), _("Control handle 22x23 - Ctrl+Alt+Click to reset"), "gridpoint22x23", &wr, this), - grid_point24x26(_("Control handle 24x26:"), _("Control handle 24x26 - Ctrl+Alt+Click to reset"), "gridpoint24x26", &wr, this), - grid_point25x27(_("Control handle 25x27:"), _("Control handle 25x27 - Ctrl+Alt+Click to reset"), "gridpoint25x27", &wr, this), - grid_point28x30(_("Control handle 28x30:"), _("Control handle 28x30 - Ctrl+Alt+Click to reset"), "gridpoint28x30", &wr, this), - grid_point29x31(_("Control handle 29x31:"), _("Control handle 29x31 - Ctrl+Alt+Click to reset"), "gridpoint29x31", &wr, this), - grid_point32x33x34x35(_("Control handle 32x33x34x35:"), _("Control handle 32x33x34x35 - Ctrl+Alt+Click to reset"), "gridpoint32x33x34x35", &wr, this) - - + horizontalMirror(_("Mirror movements in horizontal"), _("Mirror movements in horizontal"), "horizontalMirror", &wr, this, false), + verticalMirror(_("Mirror movements in vertical"), _("Mirror movements in vertical"), "verticalMirror", &wr, this, false), + grid_point0(_("Control 0:"), _("Control 0 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"), "gridpoint0", &wr, this), + grid_point1(_("Control 1:"), _("Control 1 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"), "gridpoint1", &wr, this), + grid_point2(_("Control 2:"), _("Control 2 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"), "gridpoint2", &wr, this), + grid_point3(_("Control 3:"), _("Control 3 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"), "gridpoint3", &wr, this), + grid_point4(_("Control 4:"), _("Control 4 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"), "gridpoint4", &wr, this), + grid_point5(_("Control 5:"), _("Control 5 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"), "gridpoint5", &wr, this), + grid_point6(_("Control 6:"), _("Control 6 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"), "gridpoint6", &wr, this), + grid_point7(_("Control 7:"), _("Control 7 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"), "gridpoint7", &wr, this), + grid_point8x9(_("Control 8x9:"), _("Control 8x9 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"), "gridpoint8x9", &wr, this), + grid_point10x11(_("Control 10x11:"), _("Control 10x11 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"), "gridpoint10x11", &wr, this), + grid_point12(_("Control 12:"), _("Control 12 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"), "gridpoint12", &wr, this), + grid_point13(_("Control 13:"), _("Control 13 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"), "gridpoint13", &wr, this), + grid_point14(_("Control 14:"), _("Control 14 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"), "gridpoint14", &wr, this), + grid_point15(_("Control 15:"), _("Control 15 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"), "gridpoint15", &wr, this), + grid_point16(_("Control 16:"), _("Control 16 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"), "gridpoint16", &wr, this), + grid_point17(_("Control 17:"), _("Control 17 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"), "gridpoint17", &wr, this), + grid_point18(_("Control 18:"), _("Control 18 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"), "gridpoint18", &wr, this), + grid_point19(_("Control 19:"), _("Control 19 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"), "gridpoint19", &wr, this), + grid_point20x21(_("Control 20x21:"), _("Control 20x21 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"), "gridpoint20x21", &wr, this), + grid_point22x23(_("Control 22x23:"), _("Control 22x23 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"), "gridpoint22x23", &wr, this), + grid_point24x26(_("Control 24x26:"), _("Control 24x26 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"), "gridpoint24x26", &wr, this), + grid_point25x27(_("Control 25x27:"), _("Control 25x27 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"), "gridpoint25x27", &wr, this), + grid_point28x30(_("Control 28x30:"), _("Control 28x30 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"), "gridpoint28x30", &wr, this), + grid_point29x31(_("Control 29x31:"), _("Control 29x31 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"), "gridpoint29x31", &wr, this), + grid_point32x33x34x35(_("Control 32x33x34x35:"), _("Control 32x33x34x35 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"), "gridpoint32x33x34x35", &wr, this), + expanded(false) { // register all your parameters here, so Inkscape knows which parameters this effect has: - registerParameter( dynamic_cast<Parameter *>(&grid_point0) ); - registerParameter( dynamic_cast<Parameter *>(&grid_point1) ); - registerParameter( dynamic_cast<Parameter *>(&grid_point2) ); - registerParameter( dynamic_cast<Parameter *>(&grid_point3) ); - registerParameter( dynamic_cast<Parameter *>(&grid_point4) ); - registerParameter( dynamic_cast<Parameter *>(&grid_point5) ); - registerParameter( dynamic_cast<Parameter *>(&grid_point6) ); - registerParameter( dynamic_cast<Parameter *>(&grid_point7) ); - registerParameter( dynamic_cast<Parameter *>(&grid_point8x9) ); - registerParameter( dynamic_cast<Parameter *>(&grid_point10x11) ); - registerParameter( dynamic_cast<Parameter *>(&grid_point12) ); - registerParameter( dynamic_cast<Parameter *>(&grid_point13) ); - registerParameter( dynamic_cast<Parameter *>(&grid_point14) ); - registerParameter( dynamic_cast<Parameter *>(&grid_point15) ); - registerParameter( dynamic_cast<Parameter *>(&grid_point16) ); - registerParameter( dynamic_cast<Parameter *>(&grid_point17) ); - registerParameter( dynamic_cast<Parameter *>(&grid_point18) ); - registerParameter( dynamic_cast<Parameter *>(&grid_point19) ); - registerParameter( dynamic_cast<Parameter *>(&grid_point20x21) ); - registerParameter( dynamic_cast<Parameter *>(&grid_point22x23) ); - registerParameter( dynamic_cast<Parameter *>(&grid_point24x26) ); - registerParameter( dynamic_cast<Parameter *>(&grid_point25x27) ); - registerParameter( dynamic_cast<Parameter *>(&grid_point28x30) ); - registerParameter( dynamic_cast<Parameter *>(&grid_point29x31) ); - registerParameter( dynamic_cast<Parameter *>(&grid_point32x33x34x35) ); + registerParameter(&horizontalMirror); + registerParameter(&verticalMirror); + registerParameter(&grid_point0); + registerParameter(&grid_point1); + registerParameter(&grid_point2); + registerParameter(&grid_point3); + registerParameter(&grid_point4); + registerParameter(&grid_point5); + registerParameter(&grid_point6); + registerParameter(&grid_point7); + registerParameter(&grid_point8x9); + registerParameter(&grid_point10x11); + registerParameter(&grid_point12); + registerParameter(&grid_point13); + registerParameter(&grid_point14); + registerParameter(&grid_point15); + registerParameter(&grid_point16); + registerParameter(&grid_point17); + registerParameter(&grid_point18); + registerParameter(&grid_point19); + registerParameter(&grid_point20x21); + registerParameter(&grid_point22x23); + registerParameter(&grid_point24x26); + registerParameter(&grid_point25x27); + registerParameter(&grid_point28x30); + registerParameter(&grid_point29x31); + registerParameter(&grid_point32x33x34x35); } LPELattice2::~LPELattice2() @@ -107,6 +108,10 @@ LPELattice2::~LPELattice2() Geom::Piecewise<Geom::D2<Geom::SBasis> > LPELattice2::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in) { + PathVector pathv = path_from_piecewise(pwd2_in,0.001); + //this is because strange problems whith sb2 and LineSegment + PathVector cubic = pathv_to_cubicbezier(pathv); + Geom::Piecewise<Geom::D2<Geom::SBasis> > const &pwd2_in_linear_and_cubic = paths_to_pw(cubic); D2<SBasis2d> sb2; //Initialisation of the sb2 @@ -118,44 +123,45 @@ LPELattice2::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd } //Grouping the point params in a convenient vector - std::vector<Geom::Point *> handles(36); + + std::vector<Geom::Point > handles(36); - handles[0] = &grid_point0; - handles[1] = &grid_point1; - handles[2] = &grid_point2; - handles[3] = &grid_point3; - handles[4] = &grid_point4; - handles[5] = &grid_point5; - handles[6] = &grid_point6; - handles[7] = &grid_point7; - handles[8] = &grid_point8x9; - handles[9] = &grid_point8x9; - handles[10] = &grid_point10x11; - handles[11] = &grid_point10x11; - handles[12] = &grid_point12; - handles[13] = &grid_point13; - handles[14] = &grid_point14; - handles[15] = &grid_point15; - handles[16] = &grid_point16; - handles[17] = &grid_point17; - handles[18] = &grid_point18; - handles[19] = &grid_point19; - handles[20] = &grid_point20x21; - handles[21] = &grid_point20x21; - handles[22] = &grid_point22x23; - handles[23] = &grid_point22x23; - handles[24] = &grid_point24x26; - handles[25] = &grid_point25x27; - handles[26] = &grid_point24x26; - handles[27] = &grid_point25x27; - handles[28] = &grid_point28x30; - handles[29] = &grid_point29x31; - handles[30] = &grid_point28x30; - handles[31] = &grid_point29x31; - handles[32] = &grid_point32x33x34x35; - handles[33] = &grid_point32x33x34x35; - handles[34] = &grid_point32x33x34x35; - handles[35] = &grid_point32x33x34x35; + handles[0] = grid_point0; + handles[1] = grid_point1; + handles[2] = grid_point2; + handles[3] = grid_point3; + handles[4] = grid_point4; + handles[5] = grid_point5; + handles[6] = grid_point6; + handles[7] = grid_point7; + handles[8] = grid_point8x9; + handles[9] = grid_point8x9; + handles[10] = grid_point10x11; + handles[11] = grid_point10x11; + handles[12] = grid_point12; + handles[13] = grid_point13; + handles[14] = grid_point14; + handles[15] = grid_point15; + handles[16] = grid_point16; + handles[17] = grid_point17; + handles[18] = grid_point18; + handles[19] = grid_point19; + handles[20] = grid_point20x21; + handles[21] = grid_point20x21; + handles[22] = grid_point22x23; + handles[23] = grid_point22x23; + handles[24] = grid_point24x26; + handles[25] = grid_point25x27; + handles[26] = grid_point24x26; + handles[27] = grid_point25x27; + handles[28] = grid_point28x30; + handles[29] = grid_point29x31; + handles[30] = grid_point28x30; + handles[31] = grid_point29x31; + handles[32] = grid_point32x33x34x35; + handles[33] = grid_point32x33x34x35; + handles[34] = grid_point32x33x34x35; + handles[35] = grid_point32x33x34x35; Geom::Point origin = Geom::Point(boundingbox_X.min(),boundingbox_Y.min()); @@ -185,7 +191,7 @@ LPELattice2::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd // i = Upperleft corner of the considerated rectangle // corner = actual corner of the rectangle // origin = Upperleft point - double dl = dot((*handles[corner+4*i] - (base + origin)), dir)/dot(dir,dir); + double dl = dot((handles[corner+4*i] - (base + origin)), dir)/dot(dir,dir); sb2[dim][i][corner] = dl/( dim ? height : width )*pow(4.0,ui+vi); } } @@ -195,8 +201,8 @@ LPELattice2::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd Piecewise<D2<SBasis> > output; output.push_cut(0.); - for(unsigned i = 0; i < pwd2_in.size(); i++) { - D2<SBasis> B = pwd2_in[i]; + for(unsigned i = 0; i < pwd2_in_linear_and_cubic.size(); i++) { + D2<SBasis> B = pwd2_in_linear_and_cubic[i]; B[Geom::X] -= origin[Geom::X]; B[Geom::X]*= 1/width; B[Geom::Y] -= origin[Geom::Y]; @@ -211,6 +217,7 @@ LPELattice2::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd return output; } + Gtk::Widget * LPELattice2::newWidget() { @@ -218,12 +225,17 @@ LPELattice2::newWidget() Gtk::VBox * vbox = Gtk::manage( new Gtk::VBox(Effect::newWidget()) ); vbox->set_border_width(5); - Gtk::Button* resetButton = Gtk::manage(new Gtk::Button(Glib::ustring(_("Reset grid")))); - resetButton->set_alignment(0.0, 0.5); + vbox->set_homogeneous(false); + vbox->set_spacing(6); + Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false,0)); + Gtk::VBox * vboxExpander = Gtk::manage( new Gtk::VBox(Effect::newWidget()) ); + vboxExpander->set_border_width(0); + vboxExpander->set_spacing(2); + Gtk::Button * resetButton = Gtk::manage(new Gtk::Button(Glib::ustring(_("Reset grid")))); resetButton->signal_clicked().connect(sigc::mem_fun (*this,&LPELattice2::resetGrid)); - Gtk::Widget* resetButtonWidget = dynamic_cast<Gtk::Widget *>(resetButton); - resetButtonWidget->set_tooltip_text("Reset grid"); - vbox->pack_start(*resetButtonWidget, true, true,2); + resetButton->set_size_request(140,30); + vbox->pack_start(*hbox, true,true,2); + hbox->pack_start(*resetButton, false, false,2); std::vector<Parameter *>::iterator it = param_vector.begin(); while (it != param_vector.end()) { if ((*it)->widget_is_visible) { @@ -234,7 +246,11 @@ LPELattice2::newWidget() } Glib::ustring * tip = param->param_getTooltip(); if (widg) { - vbox->pack_start(*widg, true, true, 2); + if (param->param_key == "horizontalMirror" || param->param_key == "verticalMirror") { + vbox->pack_start(*widg, true, true, 2); + } else { + vboxExpander->pack_start(*widg, true, true, 2); + } if (tip) { widg->set_tooltip_text(*tip); } else { @@ -246,14 +262,96 @@ LPELattice2::newWidget() ++it; } + + expander = Gtk::manage(new Gtk::Expander(Glib::ustring(_("Show Points")))); + expander->add(*vboxExpander); + expander->set_expanded(expanded); + vbox->pack_start(*expander, true, true, 2); + expander->property_expanded().signal_changed().connect(sigc::mem_fun(*this, &LPELattice2::on_expander_changed) ); return dynamic_cast<Gtk::Widget *>(vbox); } void +LPELattice2::on_expander_changed() +{ + expanded = expander->get_expanded(); + if(expander->get_expanded()){ + expander->set_label (Glib::ustring(_("Hide Points"))); + } else { + expander->set_label (Glib::ustring(_("Show Points"))); + } +} +void +LPELattice2::vertical(PointParam ¶mA, PointParam ¶mB, Geom::Line vert){ + Geom::Point A = paramA; + Geom::Point B = paramB; + double Y = (A[Geom::Y] + B[Geom::Y])/2; + A[Geom::Y] = Y; + B[Geom::Y] = Y; + Geom::Point nearest = vert.pointAt(vert.nearestPoint(A)); + double distA = Geom::distance(A,nearest); + double distB = Geom::distance(B,nearest); + double distanceMed = (distA + distB)/2; + if(A[Geom::X] > B[Geom::X]){ + distanceMed *= -1; + } + A[Geom::X] = nearest[Geom::X] - distanceMed; + B[Geom::X] = nearest[Geom::X] + distanceMed; + paramA.param_setValue(A, true); + paramB.param_setValue(B, true); +} + +void +LPELattice2::horizontal(PointParam ¶mA, PointParam ¶mB, Geom::Line horiz){ + Geom::Point A = paramA; + Geom::Point B = paramB; + double X = (A[Geom::X] + B[Geom::X])/2; + A[Geom::X] = X; + B[Geom::X] = X; + Geom::Point nearest = horiz.pointAt(horiz.nearestPoint(A)); + double distA = Geom::distance(A,nearest); + double distB = Geom::distance(B,nearest); + double distanceMed = (distA + distB)/2; + if(A[Geom::Y] > B[Geom::Y]){ + distanceMed *= -1; + } + A[Geom::Y] = nearest[Geom::Y] - distanceMed; + B[Geom::Y] = nearest[Geom::Y] + distanceMed; + paramA.param_setValue(A, true); + paramB.param_setValue(B, true); +} + +void LPELattice2::doBeforeEffect (SPLPEItem const* lpeitem) { original_bbox(lpeitem); setDefaults(); + Geom::Line vert(grid_point8x9.param_get_default(),grid_point10x11.param_get_default()); + Geom::Line horiz(grid_point24x26.param_get_default(),grid_point25x27.param_get_default()); + if(verticalMirror){ + vertical(grid_point0, grid_point1,vert); + vertical(grid_point2, grid_point3,vert); + vertical(grid_point4, grid_point5,vert); + vertical(grid_point6, grid_point7,vert); + vertical(grid_point12, grid_point13,vert); + vertical(grid_point14, grid_point15,vert); + vertical(grid_point16, grid_point17,vert); + vertical(grid_point18, grid_point19,vert); + vertical(grid_point24x26, grid_point25x27,vert); + vertical(grid_point28x30, grid_point29x31,vert); + } + if(horizontalMirror){ + horizontal(grid_point0, grid_point2,horiz); + horizontal(grid_point1, grid_point3,horiz); + horizontal(grid_point4, grid_point6,horiz); + horizontal(grid_point5, grid_point7,horiz); + horizontal(grid_point8x9, grid_point10x11,horiz); + horizontal(grid_point12, grid_point14,horiz); + horizontal(grid_point13, grid_point15,horiz); + horizontal(grid_point16, grid_point18,horiz); + horizontal(grid_point17, grid_point19,horiz); + horizontal(grid_point20x21, grid_point22x23,horiz); + } SPLPEItem * item = const_cast<SPLPEItem*>(lpeitem); item->apply_to_clippath(item); item->apply_to_mask(item); @@ -367,36 +465,31 @@ LPELattice2::setDefaults() void LPELattice2::resetGrid() { - grid_point0.param_set_and_write_default(); - grid_point1.param_set_and_write_default(); - grid_point2.param_set_and_write_default(); - grid_point3.param_set_and_write_default(); - grid_point4.param_set_and_write_default(); - grid_point5.param_set_and_write_default(); - grid_point6.param_set_and_write_default(); - grid_point7.param_set_and_write_default(); - grid_point8x9.param_set_and_write_default(); - grid_point10x11.param_set_and_write_default(); - grid_point12.param_set_and_write_default(); - grid_point13.param_set_and_write_default(); - grid_point14.param_set_and_write_default(); - grid_point15.param_set_and_write_default(); - grid_point16.param_set_and_write_default(); - grid_point17.param_set_and_write_default(); - grid_point18.param_set_and_write_default(); - grid_point19.param_set_and_write_default(); - grid_point20x21.param_set_and_write_default(); - grid_point22x23.param_set_and_write_default(); - grid_point24x26.param_set_and_write_default(); - grid_point25x27.param_set_and_write_default(); - grid_point28x30.param_set_and_write_default(); - grid_point29x31.param_set_and_write_default(); - grid_point32x33x34x35.param_set_and_write_default(); - //todo:this hack is only to reposition the knots on reser grid button - //Better update path effect in LPEITEM - SPDesktop * desktop = SP_ACTIVE_DESKTOP; - tools_switch(desktop, TOOLS_SELECT); - tools_switch(desktop, TOOLS_NODES); + grid_point0.param_set_default(); + grid_point1.param_set_default(); + grid_point2.param_set_default(); + grid_point3.param_set_default(); + grid_point4.param_set_default(); + grid_point5.param_set_default(); + grid_point6.param_set_default(); + grid_point7.param_set_default(); + grid_point8x9.param_set_default(); + grid_point10x11.param_set_default(); + grid_point12.param_set_default(); + grid_point13.param_set_default(); + grid_point14.param_set_default(); + grid_point15.param_set_default(); + grid_point16.param_set_default(); + grid_point17.param_set_default(); + grid_point18.param_set_default(); + grid_point19.param_set_default(); + grid_point20x21.param_set_default(); + grid_point22x23.param_set_default(); + grid_point24x26.param_set_default(); + grid_point25x27.param_set_default(); + grid_point28x30.param_set_default(); + grid_point29x31.param_set_default(); + grid_point32x33x34x35.param_set_default(); } void diff --git a/src/live_effects/lpe-lattice2.h b/src/live_effects/lpe-lattice2.h index 461f835c6..086bdab7e 100644 --- a/src/live_effects/lpe-lattice2.h +++ b/src/live_effects/lpe-lattice2.h @@ -18,10 +18,10 @@ * * Released under GNU GPL, read the file 'COPYING' for more information */ - +#include <gtkmm.h> #include "live_effects/parameter/enum.h" #include "live_effects/effect.h" -#include "live_effects/parameter/pointreseteable.h" +#include "live_effects/parameter/point.h" #include "live_effects/lpegroupbbox.h" namespace Inkscape { @@ -43,8 +43,14 @@ public: virtual void calculateCurve(Geom::Point a,Geom::Point b, SPCurve *c, bool horizontal, bool move); + virtual void vertical(PointParam ¶mA,PointParam ¶mB, Geom::Line vert); + + virtual void horizontal(PointParam ¶mA,PointParam ¶mB,Geom::Line horiz); + virtual void setDefaults(); + virtual void on_expander_changed(); + virtual void resetGrid(); //virtual void original_bbox(SPLPEItem const* lpeitem, bool absolute = false); @@ -56,31 +62,36 @@ protected: void addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector<Geom::PathVector> &hp_vec); private: - PointReseteableParam grid_point0; - PointReseteableParam grid_point1; - PointReseteableParam grid_point2; - PointReseteableParam grid_point3; - PointReseteableParam grid_point4; - PointReseteableParam grid_point5; - PointReseteableParam grid_point6; - PointReseteableParam grid_point7; - PointReseteableParam grid_point8x9; - PointReseteableParam grid_point10x11; - PointReseteableParam grid_point12; - PointReseteableParam grid_point13; - PointReseteableParam grid_point14; - PointReseteableParam grid_point15; - PointReseteableParam grid_point16; - PointReseteableParam grid_point17; - PointReseteableParam grid_point18; - PointReseteableParam grid_point19; - PointReseteableParam grid_point20x21; - PointReseteableParam grid_point22x23; - PointReseteableParam grid_point24x26; - PointReseteableParam grid_point25x27; - PointReseteableParam grid_point28x30; - PointReseteableParam grid_point29x31; - PointReseteableParam grid_point32x33x34x35; + BoolParam horizontalMirror; + BoolParam verticalMirror; + PointParam grid_point0; + PointParam grid_point1; + PointParam grid_point2; + PointParam grid_point3; + PointParam grid_point4; + PointParam grid_point5; + PointParam grid_point6; + PointParam grid_point7; + PointParam grid_point8x9; + PointParam grid_point10x11; + PointParam grid_point12; + PointParam grid_point13; + PointParam grid_point14; + PointParam grid_point15; + PointParam grid_point16; + PointParam grid_point17; + PointParam grid_point18; + PointParam grid_point19; + PointParam grid_point20x21; + PointParam grid_point22x23; + PointParam grid_point24x26; + PointParam grid_point25x27; + PointParam grid_point28x30; + PointParam grid_point29x31; + PointParam grid_point32x33x34x35; + + bool expanded; + Gtk::Expander * expander; LPELattice2(const LPELattice2&); LPELattice2& operator=(const LPELattice2&); diff --git a/src/live_effects/lpe-offset.cpp b/src/live_effects/lpe-offset.cpp index dc91775b7..ba7179476 100644 --- a/src/live_effects/lpe-offset.cpp +++ b/src/live_effects/lpe-offset.cpp @@ -42,7 +42,9 @@ LPEOffset::~LPEOffset() void LPEOffset::doOnApply(SPLPEItem const* lpeitem) { - offset_pt.param_set_and_write_new_value(*(SP_SHAPE(lpeitem)->_curve->first_point())); + Geom::Point offset = *(SP_SHAPE(lpeitem)->_curve->first_point()); + offset_pt.param_update_default(offset); + offset_pt.param_setValue(offset,true); } static void append_half_circle(Geom::Piecewise<Geom::D2<Geom::SBasis> > &pwd2, diff --git a/src/live_effects/lpe-parallel.cpp b/src/live_effects/lpe-parallel.cpp index bb37fd42c..aa7405607 100644 --- a/src/live_effects/lpe-parallel.cpp +++ b/src/live_effects/lpe-parallel.cpp @@ -72,8 +72,9 @@ LPEParallel::doOnApply (SPLPEItem const* lpeitem) A = *(curve->first_point()); B = *(curve->last_point()); dir = unit_vector(B - A); - - offset_pt.param_set_and_write_new_value((A + B)/2 + dir.ccw() * 100); + Geom::Point offset = (A + B)/2 + dir.ccw() * 100; + offset_pt.param_update_default(offset); + offset_pt.param_setValue(offset, true); } Geom::Piecewise<Geom::D2<Geom::SBasis> > diff --git a/src/live_effects/lpe-perspective-envelope.cpp b/src/live_effects/lpe-perspective-envelope.cpp index b5ef26e2f..d60a13c23 100644 --- a/src/live_effects/lpe-perspective-envelope.cpp +++ b/src/live_effects/lpe-perspective-envelope.cpp @@ -19,9 +19,7 @@ #include "helper/geom.h" #include "display/curve.h" #include "svg/svg.h" -#include "ui/tools-switch.h" #include <gsl/gsl_linalg.h> -#include "desktop.h" using namespace Geom; @@ -44,10 +42,10 @@ LPEPerspectiveEnvelope::LPEPerspectiveEnvelope(LivePathEffectObject *lpeobject) Effect(lpeobject), // initialise your parameters here: deform_type(_("Type"), _("Select the type of deformation"), "deform_type", DeformationTypeConverter, &wr, this, DEFORMATION_PERSPECTIVE), - Up_Left_Point(_("Top Left"), _("Top Left - Ctrl+Alt+Click to reset"), "Up_Left_Point", &wr, this), - Up_Right_Point(_("Top Right"), _("Top Right - Ctrl+Alt+Click to reset"), "Up_Right_Point", &wr, this), - Down_Left_Point(_("Down Left"), _("Down Left - Ctrl+Alt+Click to reset"), "Down_Left_Point", &wr, this), - Down_Right_Point(_("Down Right"), _("Down Right - Ctrl+Alt+Click to reset"), "Down_Right_Point", &wr, this) + Up_Left_Point(_("Top Left"), _("Top Left - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"), "Up_Left_Point", &wr, this), + Up_Right_Point(_("Top Right"), _("Top Right - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"), "Up_Right_Point", &wr, this), + Down_Left_Point(_("Down Left"), _("Down Left - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"), "Down_Left_Point", &wr, this), + Down_Right_Point(_("Down Right"), _("Down Right - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"), "Down_Right_Point", &wr, this) { // register all your parameters here, so Inkscape knows which parameters this effect has: registerParameter( dynamic_cast<Parameter *>(&deform_type)); @@ -298,7 +296,7 @@ LPEPerspectiveEnvelope::newWidget() Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false,0)); Gtk::Button* resetButton = Gtk::manage(new Gtk::Button(Gtk::Stock::CLEAR)); resetButton->signal_clicked().connect(sigc::mem_fun (*this,&LPEPerspectiveEnvelope::resetGrid)); - resetButton->set_size_request(140,45); + resetButton->set_size_request(140,30); vbox->pack_start(*hbox, true,true,2); hbox->pack_start(*resetButton, false, false,2); return dynamic_cast<Gtk::Widget *>(vbox); @@ -331,15 +329,10 @@ LPEPerspectiveEnvelope::setDefaults() void LPEPerspectiveEnvelope::resetGrid() { - Up_Left_Point.param_set_and_write_default(); - Up_Right_Point.param_set_and_write_default(); - Down_Right_Point.param_set_and_write_default(); - Down_Left_Point.param_set_and_write_default(); - //todo:this hack is only to reposition the knots on reser grid button - //Better update path effect in LPEITEM - SPDesktop * desktop = SP_ACTIVE_DESKTOP; - tools_switch(desktop, TOOLS_SELECT); - tools_switch(desktop, TOOLS_NODES); + Up_Left_Point.param_set_default(); + Up_Right_Point.param_set_default(); + Down_Right_Point.param_set_default(); + Down_Left_Point.param_set_default(); } void @@ -347,8 +340,8 @@ LPEPerspectiveEnvelope::resetDefaults(SPItem const* item) { Effect::resetDefaults(item); original_bbox(SP_LPE_ITEM(item)); - setDefaults(); resetGrid(); + setDefaults(); } void diff --git a/src/live_effects/lpe-perspective-envelope.h b/src/live_effects/lpe-perspective-envelope.h index 2f253882e..d3ff76445 100644 --- a/src/live_effects/lpe-perspective-envelope.h +++ b/src/live_effects/lpe-perspective-envelope.h @@ -19,7 +19,7 @@ #include "live_effects/parameter/enum.h" #include "live_effects/effect.h" -#include "live_effects/parameter/pointreseteable.h" +#include "live_effects/parameter/point.h" #include "live_effects/lpegroupbbox.h" namespace Inkscape { @@ -55,10 +55,10 @@ protected: private: EnumParam<unsigned> deform_type; - PointReseteableParam Up_Left_Point; - PointReseteableParam Up_Right_Point; - PointReseteableParam Down_Left_Point; - PointReseteableParam Down_Right_Point; + PointParam Up_Left_Point; + PointParam Up_Right_Point; + PointParam Down_Left_Point; + PointParam Down_Right_Point; LPEPerspectiveEnvelope(const LPEPerspectiveEnvelope&); LPEPerspectiveEnvelope& operator=(const LPEPerspectiveEnvelope&); diff --git a/src/live_effects/lpe-show_handles.cpp b/src/live_effects/lpe-show_handles.cpp index 7b2b445b7..2d8148730 100644 --- a/src/live_effects/lpe-show_handles.cpp +++ b/src/live_effects/lpe-show_handles.cpp @@ -25,15 +25,20 @@ LPEShowHandles::LPEShowHandles(LivePathEffectObject *lpeobject) nodes(_("Show nodes"), _("Show nodes"), "nodes", &wr, this, true), handles(_("Show handles"), _("Show handles"), "handles", &wr, this, true), originalPath(_("Show path"), _("Show path"), "originalPath", &wr, this, true), - scaleNodesAndHandles(_("Scale nodes and handles"), _("Scale nodes and handles"), "scaleNodesAndHandles", &wr, this, 10) + scaleNodesAndHandles(_("Scale nodes and handles"), _("Scale nodes and handles"), "scaleNodesAndHandles", &wr, this, 10), + rotateNodes(_("Rotate nodes"), _("Rotate nodes"), "rotateNodes", &wr, this, 0) { registerParameter(dynamic_cast<Parameter *>(&nodes)); registerParameter(dynamic_cast<Parameter *>(&handles)); registerParameter(dynamic_cast<Parameter *>(&originalPath)); registerParameter(dynamic_cast<Parameter *>(&scaleNodesAndHandles)); + registerParameter(dynamic_cast<Parameter *>(&rotateNodes)); scaleNodesAndHandles.param_set_range(0, 500.); scaleNodesAndHandles.param_set_increments(1, 1); scaleNodesAndHandles.param_set_digits(2); + rotateNodes.param_set_range(0, 365); + rotateNodes.param_set_increments(1, 1); + rotateNodes.param_set_digits(0); strokeWidth = 1.0; } @@ -158,10 +163,11 @@ LPEShowHandles::drawNode(Geom::Point p) if(strokeWidth * scaleNodesAndHandles > 0.0) { double diameter = strokeWidth * scaleNodesAndHandles; char const * svgd; - svgd = "M 0.55,0.5 A 0.05,0.05 0 0 1 0.5,0.55 0.05,0.05 0 0 1 0.45,0.5 0.05,0.05 0 0 1 0.5,0.45 0.05,0.05 0 0 1 0.55,0.5 Z M 0,0 1,0 1,1 0,1 Z"; + svgd = "M 0.05,0 A 0.05,0.05 0 0 1 0,0.05 0.05,0.05 0 0 1 -0.05,0 0.05,0.05 0 0 1 0,-0.05 0.05,0.05 0 0 1 0.05,0 Z M -0.5,-0.5 0.5,-0.5 0.5,0.5 -0.5,0.5 Z"; Geom::PathVector pathv = sp_svg_read_pathv(svgd); - pathv *= Geom::Affine(diameter,0,0,diameter,0,0); - pathv += p - Geom::Point(diameter/2,diameter/2); + pathv *= Geom::Rotate::from_degrees(rotateNodes); + pathv *= Geom::Scale (diameter); + pathv += p; outlinepath.push_back(pathv[0]); outlinepath.push_back(pathv[1]); } @@ -175,8 +181,8 @@ LPEShowHandles::drawHandle(Geom::Point p) char const * svgd; svgd = "M 0.7,0.35 A 0.35,0.35 0 0 1 0.35,0.7 0.35,0.35 0 0 1 0,0.35 0.35,0.35 0 0 1 0.35,0 0.35,0.35 0 0 1 0.7,0.35 Z"; Geom::PathVector pathv = sp_svg_read_pathv(svgd); - pathv *= Geom::Affine(diameter,0,0,diameter,0,0); - pathv += p - Geom::Point(diameter * 0.35,diameter * 0.35); + pathv *= Geom::Scale (diameter); + pathv += p-Geom::Point(diameter * 0.35,diameter * 0.35); outlinepath.push_back(pathv[0]); } } diff --git a/src/live_effects/lpe-show_handles.h b/src/live_effects/lpe-show_handles.h index 278908bb5..a405c26ee 100644 --- a/src/live_effects/lpe-show_handles.h +++ b/src/live_effects/lpe-show_handles.h @@ -44,6 +44,7 @@ private: BoolParam handles; BoolParam originalPath; ScalarParam scaleNodesAndHandles; + ScalarParam rotateNodes; double strokeWidth; static bool alertsOff; diff --git a/src/live_effects/lpe-simplify.cpp b/src/live_effects/lpe-simplify.cpp index 2b2efb1a9..1fe18dd5e 100644 --- a/src/live_effects/lpe-simplify.cpp +++ b/src/live_effects/lpe-simplify.cpp @@ -20,6 +20,7 @@ #include <2geom/generic-rect.h> #include <2geom/interval.h> #include "ui/icon-names.h" +#include "util/units.h" namespace Inkscape { namespace LivePathEffect { @@ -28,32 +29,37 @@ LPESimplify::LPESimplify(LivePathEffectObject *lpeobject) : Effect(lpeobject), steps(_("Steps:"),_("Change number of simplify steps "), "steps", &wr, this,1), threshold(_("Roughly threshold:"), _("Roughly threshold:"), "threshold", &wr, this, 0.003), - helper_size(_("Helper size:"), _("Helper size"), "helper_size", &wr, this, 2.), - nodes(_("Helper nodes"), _("Show helper nodes"), "nodes", &wr, this, false, - "", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), - handles(_("Helper handles"), _("Show helper handles"), "handles", &wr, this, false, - "", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), + smooth_angles(_("Smooth angles:"), _("Max degree difference on handles to preform a smooth"), "smooth_angles", &wr, this, 20.), + helper_size(_("Helper size:"), _("Helper size"), "helper_size", &wr, this, 5), simplifyindividualpaths(_("Paths separately"), _("Simplifying paths (separately)"), "simplifyindividualpaths", &wr, this, false, "", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), simplifyJustCoalesce(_("Just coalesce"), _("Simplify just coalesce"), "simplifyJustCoalesce", &wr, this, false, "", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")) { - registerParameter(dynamic_cast<Parameter *>(&steps)); - registerParameter(dynamic_cast<Parameter *>(&threshold)); - registerParameter(dynamic_cast<Parameter *>(&helper_size)); - registerParameter(dynamic_cast<Parameter *>(&nodes)); - registerParameter(dynamic_cast<Parameter *>(&handles)); - registerParameter(dynamic_cast<Parameter *>(&simplifyindividualpaths)); - registerParameter(dynamic_cast<Parameter *>(&simplifyJustCoalesce)); + registerParameter(&steps); + registerParameter(&threshold); + registerParameter(&smooth_angles); + registerParameter(&helper_size); + registerParameter(&simplifyindividualpaths); + registerParameter(&simplifyJustCoalesce); + threshold.param_set_range(0.0001, Geom::infinity()); threshold.param_set_increments(0.0001, 0.0001); threshold.param_set_digits(6); + steps.param_set_range(0, 100); steps.param_set_increments(1, 1); steps.param_set_digits(0); - helper_size.param_set_range(0.1, 100); - helper_size.param_set_increments(1, 1); - helper_size.param_set_digits(1); + + smooth_angles.param_set_range(0.0, 365.0); + smooth_angles.param_set_increments(10, 10); + smooth_angles.param_set_digits(2); + + helper_size.param_set_range(0.0, 999.0); + helper_size.param_set_increments(5, 5); + helper_size.param_set_digits(2); + + radiusHelperNodes = 6.0; } LPESimplify::~LPESimplify() {} @@ -66,9 +72,9 @@ LPESimplify::doBeforeEffect (SPLPEItem const* lpeitem) } bbox = SP_ITEM(lpeitem)->visualBounds(); SPLPEItem * item = const_cast<SPLPEItem*>(lpeitem); + radiusHelperNodes = helper_size; item->apply_to_clippath(item); item->apply_to_mask(item); - } Gtk::Widget * @@ -81,7 +87,6 @@ LPESimplify::newWidget() vbox->set_spacing(2); std::vector<Parameter *>::iterator it = param_vector.begin(); Gtk::HBox * buttons = Gtk::manage(new Gtk::HBox(true,0)); - Gtk::HBox * buttonsTwo = Gtk::manage(new Gtk::HBox(true,0)); while (it != param_vector.end()) { if ((*it)->widget_is_visible) { Parameter * param = *it; @@ -91,19 +96,6 @@ LPESimplify::newWidget() { Glib::ustring * tip = param->param_getTooltip(); if (widg) { - buttonsTwo->pack_start(*widg, true, true, 2); - if (tip) { - widg->set_tooltip_text(*tip); - } else { - widg->set_tooltip_text(""); - widg->set_has_tooltip(false); - } - } - } else if (param->param_key == "nodes" || - param->param_key == "handles") - { - Glib::ustring * tip = param->param_getTooltip(); - if (widg) { buttons->pack_start(*widg, true, true, 2); if (tip) { widg->set_tooltip_text(*tip); @@ -112,7 +104,7 @@ LPESimplify::newWidget() widg->set_has_tooltip(false); } } - }else{ + } else{ Glib::ustring * tip = param->param_getTooltip(); if (widg) { Gtk::HBox * scalarParameter = dynamic_cast<Gtk::HBox *>(widg); @@ -133,7 +125,6 @@ LPESimplify::newWidget() ++it; } vbox->pack_start(*buttons,true, true, 2); - vbox->pack_start(*buttonsTwo,true, true, 2); return dynamic_cast<Gtk::Widget *>(vbox); } @@ -154,9 +145,9 @@ LPESimplify::doEffect(SPCurve *curve) { pathliv->Simplify(threshold * size); } } - Geom::PathVector outres = Geom::parse_svg_path(pathliv->svg_dump_path()); - generateHelperPath(outres); - curve->set_pathvector(outres); + Geom::PathVector result = Geom::parse_svg_path(pathliv->svg_dump_path()); + generateHelperPathAndSmooth(result); + curve->set_pathvector(result); SPDesktop* desktop = SP_ACTIVE_DESKTOP; if(desktop && INK_IS_NODE_TOOL(desktop->event_context)){ Inkscape::UI::Tools::NodeTool *nt = static_cast<Inkscape::UI::Tools::NodeTool*>(desktop->event_context); @@ -165,16 +156,12 @@ LPESimplify::doEffect(SPCurve *curve) { } void -LPESimplify::generateHelperPath(Geom::PathVector result) +LPESimplify::generateHelperPathAndSmooth(Geom::PathVector &result) { - if(!handles && !nodes){ - return; - } - if(steps < 1){ return; } - + Geom::PathVector tmpPath; Geom::CubicBezier const *cubic = NULL; for (Geom::PathVector::iterator path_it = result.begin(); path_it != result.end(); ++path_it) { //Si está vacío... @@ -183,11 +170,9 @@ LPESimplify::generateHelperPath(Geom::PathVector result) } //Itreadores Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve - Geom::Path::const_iterator curve_it2 = - ++(path_it->begin()); // outgoing curve - Geom::Path::const_iterator curve_endit = - path_it->end_default(); // this determines when the loop has to stop - + Geom::Path::const_iterator curve_it2 = ++(path_it->begin());// outgoing curve + Geom::Path::const_iterator curve_endit = path_it->end_default(); // this determines when the loop has to stop + SPCurve *nCurve = new SPCurve(); if (path_it->closed()) { // if the path is closed, maybe we have to stop a bit earlier because the // closing line segment has zerolength. @@ -202,13 +187,50 @@ LPESimplify::generateHelperPath(Geom::PathVector result) curve_endit = path_it->end_open(); } } - if(nodes){ + if(helper_size > 0){ drawNode(curve_it1->initialPoint()); } + nCurve->moveto(curve_it1->initialPoint()); + Geom::Point start = Geom::Point(0,0); while (curve_it1 != curve_endit) { cubic = dynamic_cast<Geom::CubicBezier const *>(&*curve_it1); + Geom::Point pointAt1 = curve_it1->initialPoint(); + Geom::Point pointAt2 = curve_it1->finalPoint(); + Geom::Point pointAt3 = curve_it1->finalPoint(); + Geom::Point pointAt4 = curve_it1->finalPoint(); + if (cubic) { + pointAt1 = (*cubic)[1]; + pointAt2 = (*cubic)[2]; + } + if(start == Geom::Point(0,0)){ + start = pointAt1; + } + + if(path_it->closed() && curve_it2 == curve_endit){ + pointAt4 = start; + } + if(curve_it2 != curve_endit){ + cubic = dynamic_cast<Geom::CubicBezier const *>(&*curve_it2); + if (cubic) { + pointAt4 = (*cubic)[1]; + } + } + Geom::Ray ray1(pointAt2, pointAt3); + Geom::Ray ray2(pointAt3, pointAt4); + double angle1 = Geom::rad_to_deg(ray1.angle()); + double angle2 = Geom::rad_to_deg(ray2.angle()); + if((smooth_angles >= angle2 - angle1) && !are_near(pointAt4,pointAt3) && !are_near(pointAt2,pointAt3)){ + double dist = Geom::distance(pointAt2,pointAt3); + Geom::Angle angleFixed = ray2.angle(); + angleFixed -= Geom::Angle::from_degrees(180.0); + pointAt2 = Geom::Point::polar(angleFixed,dist) + pointAt3; + } + nCurve->curveto(pointAt1, pointAt2, curve_it1->finalPoint()); + cubic = dynamic_cast<Geom::CubicBezier const *>(nCurve->last_segment()); if (cubic) { - if(handles) { + pointAt1 = (*cubic)[1]; + pointAt2 = (*cubic)[2]; + if(helper_size > 0) { if(!are_near((*cubic)[0],(*cubic)[1])){ drawHandle((*cubic)[1]); drawHandleLine((*cubic)[0],(*cubic)[1]); @@ -219,21 +241,26 @@ LPESimplify::generateHelperPath(Geom::PathVector result) } } } - if(nodes) { + if(helper_size > 0) { drawNode(curve_it1->finalPoint()); } ++curve_it1; - if(curve_it2 != curve_endit){ - ++curve_it2; - } + ++curve_it2; + } + if (path_it->closed()) { + nCurve->closepath_current(); } + tmpPath.push_back(nCurve->get_pathvector()[0]); + nCurve->reset(); + delete nCurve; } + result = tmpPath; } void LPESimplify::drawNode(Geom::Point p) { - double r = helper_size/0.67; + double r = radiusHelperNodes; char const * svgd; svgd = "M 0.55,0.5 A 0.05,0.05 0 0 1 0.5,0.55 0.05,0.05 0 0 1 0.45,0.5 0.05,0.05 0 0 1 0.5,0.45 0.05,0.05 0 0 1 0.55,0.5 Z M 0,0 1,0 1,1 0,1 Z"; Geom::PathVector pathv = sp_svg_read_pathv(svgd); @@ -246,7 +273,7 @@ LPESimplify::drawNode(Geom::Point p) void LPESimplify::drawHandle(Geom::Point p) { - double r = helper_size/0.67; + double r = radiusHelperNodes; char const * svgd; svgd = "M 0.7,0.35 A 0.35,0.35 0 0 1 0.35,0.7 0.35,0.35 0 0 1 0,0.35 0.35,0.35 0 0 1 0.35,0 0.35,0.35 0 0 1 0.7,0.35 Z"; Geom::PathVector pathv = sp_svg_read_pathv(svgd); @@ -261,8 +288,8 @@ LPESimplify::drawHandleLine(Geom::Point p,Geom::Point p2) { Geom::Path path; path.start( p ); - double diameter = helper_size/0.67; - if(helper_size > 0.0 && Geom::distance(p,p2) > (diameter * 0.35)){ + double diameter = radiusHelperNodes; + if(helper_size > 0 && Geom::distance(p,p2) > (diameter * 0.35)){ Geom::Ray ray2(p, p2); p2 = p2 - Geom::Point::polar(ray2.angle(),(diameter * 0.35)); } diff --git a/src/live_effects/lpe-simplify.h b/src/live_effects/lpe-simplify.h index 6acf2f2d4..c18c3ecdf 100644 --- a/src/live_effects/lpe-simplify.h +++ b/src/live_effects/lpe-simplify.h @@ -24,7 +24,7 @@ public: virtual void doBeforeEffect (SPLPEItem const* lpeitem); - virtual void generateHelperPath(Geom::PathVector result); + virtual void generateHelperPathAndSmooth(Geom::PathVector &result); virtual Gtk::Widget * newWidget(); @@ -40,12 +40,12 @@ protected: private: ScalarParam steps; ScalarParam threshold; + ScalarParam smooth_angles; ScalarParam helper_size; - ToggleButtonParam nodes; - ToggleButtonParam handles; ToggleButtonParam simplifyindividualpaths; ToggleButtonParam simplifyJustCoalesce; + double radiusHelperNodes; Geom::PathVector hp; Geom::OptRect bbox; diff --git a/src/live_effects/lpe-sketch.cpp b/src/live_effects/lpe-sketch.cpp index 8ad0e616f..551dbe16a 100644 --- a/src/live_effects/lpe-sketch.cpp +++ b/src/live_effects/lpe-sketch.cpp @@ -240,7 +240,7 @@ LPESketch::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_ for (unsigned i = 0; i<nbiter_approxstrokes; i++){ //Basic steps: - //- Choose a rdm seg [s0,s1], find coresponding [t0,t1], + //- Choose a rdm seg [s0,s1], find corresponding [t0,t1], //- Pick a rdm perturbation delta(s), collect 'piece(t)+delta(s(t))' over [t0,t1] into output. // pick a point where to start the stroke (s0 = dist from start). diff --git a/src/live_effects/lpe-taperstroke.cpp b/src/live_effects/lpe-taperstroke.cpp index b595b8d55..7a024147c 100644 --- a/src/live_effects/lpe-taperstroke.cpp +++ b/src/live_effects/lpe-taperstroke.cpp @@ -71,12 +71,12 @@ static const Util::EnumDataConverter<unsigned> JoinTypeConverter(JoinType, sizeo LPETaperStroke::LPETaperStroke(LivePathEffectObject *lpeobject) : Effect(lpeobject), - line_width(_("Stroke width"), _("The (non-tapered) width of the path"), "stroke_width", &wr, this, 1.), - attach_start(_("Start offset"), _("Taper distance from path start"), "attach_start", &wr, this, 0.2), - attach_end(_("End offset"), _("The ending position of the taper"), "end_offset", &wr, this, 0.2), - smoothing(_("Taper smoothing"), _("Amount of smoothing to apply to the tapers"), "smoothing", &wr, this, 0.5), - join_type(_("Join type"), _("Join type for non-smooth nodes"), "jointype", JoinTypeConverter, &wr, this, LINEJOIN_EXTRAPOLATED), - miter_limit(_("Miter limit"), _("Limit for miter joins"), "miter_limit", &wr, this, 100.) + line_width(_("Stroke width:"), _("The (non-tapered) width of the path"), "stroke_width", &wr, this, 1.), + attach_start(_("Start offset:"), _("Taper distance from path start"), "attach_start", &wr, this, 0.2), + attach_end(_("End offset:"), _("The ending position of the taper"), "end_offset", &wr, this, 0.2), + smoothing(_("Taper smoothing:"), _("Amount of smoothing to apply to the tapers"), "smoothing", &wr, this, 0.5), + join_type(_("Join type:"), _("Join type for non-smooth nodes"), "jointype", JoinTypeConverter, &wr, this, LINEJOIN_EXTRAPOLATED), + miter_limit(_("Miter limit:"), _("Limit for miter joins"), "miter_limit", &wr, this, 100.) { show_orig_path = true; _provides_knotholder_entities = true; diff --git a/src/live_effects/lpe-test-doEffect-stack.cpp b/src/live_effects/lpe-test-doEffect-stack.cpp index 03e3e7997..c6787aae1 100644 --- a/src/live_effects/lpe-test-doEffect-stack.cpp +++ b/src/live_effects/lpe-test-doEffect-stack.cpp @@ -28,6 +28,7 @@ LPEdoEffectStackTest::LPEdoEffectStackTest(LivePathEffectObject *lpeobject) : registerParameter( dynamic_cast<Parameter *>(&path) ); point.set_oncanvas_looks(SP_KNOT_SHAPE_SQUARE, SP_KNOT_MODE_XOR, 0x00ff0000); + point.param_setValue(point,true); } LPEdoEffectStackTest::~LPEdoEffectStackTest() diff --git a/src/live_effects/lpeobject.cpp b/src/live_effects/lpeobject.cpp index d92c94d01..8e5ae568f 100644 --- a/src/live_effects/lpeobject.cpp +++ b/src/live_effects/lpeobject.cpp @@ -20,16 +20,6 @@ //#define LIVEPATHEFFECT_VERBOSE -#include "sp-factory.h" - -namespace { - SPObject* createLivepatheffect() { - return new LivePathEffectObject(); - } - - bool livepatheffectRegistered = SPFactory::instance().registerObject("inkscape:path-effect", createLivepatheffect); -} - static void livepatheffect_on_repr_attr_changed (Inkscape::XML::Node * repr, const gchar *key, const gchar *oldval, const gchar *newval, bool is_interactive, void * data); static Inkscape::XML::NodeEventVector const livepatheffect_repr_events = { diff --git a/src/live_effects/parameter/Makefile_insert b/src/live_effects/parameter/Makefile_insert index f990f41c7..bd1c5b600 100644 --- a/src/live_effects/parameter/Makefile_insert +++ b/src/live_effects/parameter/Makefile_insert @@ -11,8 +11,6 @@ ink_common_sources += \ live_effects/parameter/random.h \ live_effects/parameter/point.cpp \ live_effects/parameter/point.h \ - live_effects/parameter/pointreseteable.cpp \ - live_effects/parameter/pointreseteable.h \ live_effects/parameter/enum.h \ live_effects/parameter/path-reference.cpp \ live_effects/parameter/path-reference.h \ diff --git a/src/live_effects/parameter/filletchamferpointarray.cpp b/src/live_effects/parameter/filletchamferpointarray.cpp index 7d8c8e9b0..e9d375b93 100644 --- a/src/live_effects/parameter/filletchamferpointarray.cpp +++ b/src/live_effects/parameter/filletchamferpointarray.cpp @@ -354,7 +354,7 @@ void FilletChamferPointArrayParam::set_pwd2( last_pwd2_normal = pwd2_normal_in; } -void FilletChamferPointArrayParam::set_document_unit(Glib::ustring const * value_document_unit) +void FilletChamferPointArrayParam::set_document_unit(Glib::ustring value_document_unit) { documentUnit = value_document_unit; } @@ -779,19 +779,19 @@ void FilletChamferPointArrayParamKnotHolderEntity::knot_click(guint state) sp_lpe_item_update_patheffect(SP_LPE_ITEM(item), false, false); const gchar *tip; if (type >=3000 && type < 4000){ - tip = _("<b>Chamfer</b>: <b>Ctrl+Click</b> toogle type, " + tip = _("<b>Chamfer</b>: <b>Ctrl+Click</b> toggle type, " "<b>Shift+Click</b> open dialog, " "<b>Ctrl+Alt+Click</b> reset"); } else if (type >=4000 && type < 5000) { - tip = _("<b>Inverse Chamfer</b>: <b>Ctrl+Click</b> toogle type, " + tip = _("<b>Inverse Chamfer</b>: <b>Ctrl+Click</b> toggle type, " "<b>Shift+Click</b> open dialog, " "<b>Ctrl+Alt+Click</b> reset"); } else if (type == 2) { - tip = _("<b>Inverse Fillet</b>: <b>Ctrl+Click</b> toogle type, " + tip = _("<b>Inverse Fillet</b>: <b>Ctrl+Click</b> toggle type, " "<b>Shift+Click</b> open dialog, " "<b>Ctrl+Alt+Click</b> reset"); } else { - tip = _("<b>Fillet</b>: <b>Ctrl+Click</b> toogle type, " + tip = _("<b>Fillet</b>: <b>Ctrl+Click</b> toggle type, " "<b>Shift+Click</b> open dialog, " "<b>Ctrl+Alt+Click</b> reset"); } @@ -840,19 +840,19 @@ void FilletChamferPointArrayParam::addKnotHolderEntities(KnotHolder *knotholder, } const gchar *tip; if (_vector[i][Y] >=3000 && _vector[i][Y] < 4000){ - tip = _("<b>Chamfer</b>: <b>Ctrl+Click</b> toogle type, " + tip = _("<b>Chamfer</b>: <b>Ctrl+Click</b> toggle type, " "<b>Shift+Click</b> open dialog, " "<b>Ctrl+Alt+Click</b> reset"); } else if (_vector[i][Y] >=4000 && _vector[i][Y] < 5000) { - tip = _("<b>Inverse Chamfer</b>: <b>Ctrl+Click</b> toogle type, " + tip = _("<b>Inverse Chamfer</b>: <b>Ctrl+Click</b> toggle type, " "<b>Shift+Click</b> open dialog, " "<b>Ctrl+Alt+Click</b> reset"); } else if (_vector[i][Y] == 2) { - tip = _("<b>Inverse Fillet</b>: <b>Ctrl+Click</b> toogle type, " + tip = _("<b>Inverse Fillet</b>: <b>Ctrl+Click</b> toggle type, " "<b>Shift+Click</b> open dialog, " "<b>Ctrl+Alt+Click</b> reset"); } else { - tip = _("<b>Fillet</b>: <b>Ctrl+Click</b> toogle type, " + tip = _("<b>Fillet</b>: <b>Ctrl+Click</b> toggle type, " "<b>Shift+Click</b> open dialog, " "<b>Ctrl+Alt+Click</b> reset"); } diff --git a/src/live_effects/parameter/filletchamferpointarray.h b/src/live_effects/parameter/filletchamferpointarray.h index 6e5cce353..7849d5afb 100644 --- a/src/live_effects/parameter/filletchamferpointarray.h +++ b/src/live_effects/parameter/filletchamferpointarray.h @@ -53,7 +53,7 @@ public: virtual void set_helper_size(int hs); virtual void set_use_distance(bool use_knot_distance); virtual void set_chamfer_steps(int value_chamfer_steps); - virtual void set_document_unit(Glib::ustring const * value_document_unit); + virtual void set_document_unit(Glib::ustring value_document_unit); virtual void set_unit(const gchar *abbr); virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector<Geom::PathVector> &hp_vec); @@ -90,7 +90,7 @@ private: int chamfer_steps; bool use_distance; const gchar *unit; - Glib::ustring const * documentUnit; + Glib::ustring documentUnit; Geom::PathVector hp; Geom::Piecewise<Geom::D2<Geom::SBasis> > last_pwd2; diff --git a/src/live_effects/parameter/originalpath.cpp b/src/live_effects/parameter/originalpath.cpp index 6c4f2a100..0884c4c9c 100644 --- a/src/live_effects/parameter/originalpath.cpp +++ b/src/live_effects/parameter/originalpath.cpp @@ -27,7 +27,7 @@ #include "live_effects/effect.h" #include "inkscape.h" -#include "desktop-handles.h" +#include "desktop.h" #include "selection.h" #include "ui/icon-names.h" @@ -128,7 +128,7 @@ OriginalPathParam::on_select_original_button_click() if (desktop == NULL || original == NULL) { return; } - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); selection->clear(); selection->set(original); } diff --git a/src/live_effects/parameter/path.cpp b/src/live_effects/parameter/path.cpp index 2a14d4208..ba95affd9 100644 --- a/src/live_effects/parameter/path.cpp +++ b/src/live_effects/parameter/path.cpp @@ -30,7 +30,7 @@ // needed for on-canvas editting: #include "ui/tools-switch.h" #include "ui/shape-editor.h" -#include "desktop-handles.h" + #include "selection.h" // clipboard support #include "ui/clipboard.h" @@ -414,7 +414,7 @@ PathParam::linked_modified_callback(SPObject *linked_obj, guint /*flags*/) void PathParam::on_edit_button_click() { - SPItem * item = sp_desktop_selection(SP_ACTIVE_DESKTOP)->singleItem(); + SPItem * item = SP_ACTIVE_DESKTOP->getSelection()->singleItem(); if (item != NULL) { param_editOncanvas(item, SP_ACTIVE_DESKTOP); } diff --git a/src/live_effects/parameter/point.cpp b/src/live_effects/parameter/point.cpp index 302818e55..4c4d2cd9c 100644 --- a/src/live_effects/parameter/point.cpp +++ b/src/live_effects/parameter/point.cpp @@ -26,7 +26,9 @@ namespace LivePathEffect { PointParam::PointParam( const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, Effect* effect, const gchar *htip, Geom::Point default_value) - : Geom::Point(default_value), Parameter(label, tip, key, wr, effect), defvalue(default_value) + : Parameter(label, tip, key, wr, effect), + defvalue(default_value), + knoth(NULL) { knot_shape = SP_KNOT_SHAPE_DIAMOND; knot_mode = SP_KNOT_MODE_XOR; @@ -43,7 +45,34 @@ PointParam::~PointParam() void PointParam::param_set_default() { - param_setValue(defvalue); + param_setValue(defvalue,true); +} + +Geom::Point +PointParam::param_get_default() const{ + return defvalue; +} + +void +PointParam::param_update_default(Geom::Point newpoint) +{ + defvalue = newpoint; +} + +void +PointParam::param_setValue(Geom::Point newpoint, bool write) +{ + *dynamic_cast<Geom::Point *>( this ) = newpoint; + if(write){ + Inkscape::SVGOStringStream os; + os << newpoint; + gchar * str = g_strdup(os.str().c_str()); + param_write_to_repr(str); + g_free(str); + } + if(knoth){ + knoth->update_knots(); + } } bool @@ -70,6 +99,12 @@ PointParam::param_getSVGValue() const return str; } +void +PointParam::param_transform_multiply(Geom::Affine const& postmul, bool /*set*/) +{ + param_setValue( (*this) * postmul, true); +} + Gtk::Widget * PointParam::param_newWidget() { @@ -96,29 +131,6 @@ PointParam::param_newWidget() } void -PointParam::param_setValue(Geom::Point newpoint) -{ - *dynamic_cast<Geom::Point *>( this ) = newpoint; -} - -void -PointParam::param_set_and_write_new_value (Geom::Point newpoint) -{ - Inkscape::SVGOStringStream os; - os << newpoint; - gchar * str = g_strdup(os.str().c_str()); - param_write_to_repr(str); - g_free(str); -} - -void -PointParam::param_transform_multiply(Geom::Affine const& postmul, bool /*set*/) -{ - param_set_and_write_new_value( (*this) * postmul ); -} - - -void PointParam::set_oncanvas_looks(SPKnotShapeType shape, SPKnotModeType mode, guint32 color) { knot_shape = shape; @@ -129,7 +141,7 @@ PointParam::set_oncanvas_looks(SPKnotShapeType shape, SPKnotModeType mode, guint class PointParamKnotHolderEntity : public KnotHolderEntity { public: PointParamKnotHolderEntity(PointParam *p) { this->pparam = p; } - virtual ~PointParamKnotHolderEntity() {} + virtual ~PointParamKnotHolderEntity() { this->pparam->knoth = NULL;} virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); virtual Geom::Point knot_get() const; @@ -140,11 +152,25 @@ private: }; void -PointParamKnotHolderEntity::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state) +PointParamKnotHolderEntity::knot_set(Geom::Point const &p, Geom::Point const &origin, guint state) { - Geom::Point const s = snap_knot_position(p, state); - pparam->param_setValue(s); - sp_lpe_item_update_patheffect(SP_LPE_ITEM(item), false, false); + Geom::Point s = snap_knot_position(p, state); + if (state & GDK_CONTROL_MASK) { + Geom::Point A(origin[Geom::X],p[Geom::Y]); + Geom::Point B(p[Geom::X],origin[Geom::Y]); + double distanceA = Geom::distance(A,p); + double distanceB = Geom::distance(B,p); + if(distanceA > distanceB){ + s = B; + } else { + s = A; + } + } + pparam->param_setValue(s, true); + SPLPEItem * splpeitem = dynamic_cast<SPLPEItem *>(item); + if(splpeitem){ + sp_lpe_item_update_patheffect(splpeitem, false, false); + } } Geom::Point @@ -154,19 +180,27 @@ PointParamKnotHolderEntity::knot_get() const } void -PointParamKnotHolderEntity::knot_click(guint /*state*/) +PointParamKnotHolderEntity::knot_click(guint state) { - g_print ("This is the handle associated to parameter '%s'\n", pparam->param_key.c_str()); + if (state & GDK_CONTROL_MASK) { + if (state & GDK_MOD1_MASK) { + this->pparam->param_set_default(); + SPLPEItem * splpeitem = dynamic_cast<SPLPEItem *>(item); + if(splpeitem){ + sp_lpe_item_update_patheffect(splpeitem, false, false); + } + } + } } void PointParam::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) { + knoth = knotholder; PointParamKnotHolderEntity *e = new PointParamKnotHolderEntity(this); // TODO: can we ditch handleTip() etc. because we have access to handle_tip etc. itself??? e->create(desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, handleTip(), knot_shape, knot_mode, knot_color); knotholder->add(e); - } } /* namespace LivePathEffect */ diff --git a/src/live_effects/parameter/point.h b/src/live_effects/parameter/point.h index 319835bb3..471fbc993 100644 --- a/src/live_effects/parameter/point.h +++ b/src/live_effects/parameter/point.h @@ -20,6 +20,7 @@ namespace Inkscape { namespace LivePathEffect { +class PointParamKnotHolderEntity; class PointParam : public Geom::Point, public Parameter { public: @@ -37,12 +38,10 @@ public: bool param_readSVGValue(const gchar * strvalue); gchar * param_getSVGValue() const; inline const gchar *handleTip() const { return handle_tip ? handle_tip : param_tooltip.c_str(); } - - void param_setValue(Geom::Point newpoint); + void param_setValue(Geom::Point newpoint, bool write = false); void param_set_default(); - - void param_set_and_write_new_value(Geom::Point newpoint); - + Geom::Point param_get_default() const; + void param_update_default(Geom::Point newpoint); virtual void param_transform_multiply(Geom::Affine const& /*postmul*/, bool /*set*/); void set_oncanvas_looks(SPKnotShapeType shape, SPKnotModeType mode, guint32 color); @@ -50,12 +49,12 @@ public: virtual bool providesKnotHolderEntities() const { return true; } virtual void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item); + friend class PointParamKnotHolderEntity; private: PointParam(const PointParam&); PointParam& operator=(const PointParam&); - Geom::Point defvalue; - + KnotHolder *knoth; SPKnotShapeType knot_shape; SPKnotModeType knot_mode; guint32 knot_color; diff --git a/src/live_effects/parameter/pointreseteable.cpp b/src/live_effects/parameter/pointreseteable.cpp deleted file mode 100644 index c0f8858b8..000000000 --- a/src/live_effects/parameter/pointreseteable.cpp +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl> - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#include "ui/widget/registered-widget.h" -#include "live_effects/parameter/pointreseteable.h" -#include "live_effects/effect.h" -#include "svg/svg.h" -#include "svg/stringstream.h" -#include "ui/widget/point.h" -#include "widgets/icon.h" -#include "inkscape.h" -#include "verbs.h" -#include "knotholder.h" -#include <glibmm/i18n.h> -#include "ui/tools-switch.h" -#include "ui/tools/node-tool.h" - -// needed for on-canvas editting: -#include "desktop.h" - -namespace Inkscape { - -namespace LivePathEffect { - -PointReseteableParam::PointReseteableParam( const Glib::ustring& label, const Glib::ustring& tip, - const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, - Effect* effect, const gchar *htip, Geom::Point default_value) - : Geom::Point(default_value), Parameter(label, tip, key, wr, effect), defvalue(default_value) -{ - knot_shape = SP_KNOT_SHAPE_DIAMOND; - knot_mode = SP_KNOT_MODE_XOR; - knot_color = 0xffffff00; - handle_tip = g_strdup(htip); -} - -PointReseteableParam::~PointReseteableParam() -{ - if (handle_tip) - g_free(handle_tip); -} - -void -PointReseteableParam::param_set_default() -{ - param_setValue(defvalue); -} - -void -PointReseteableParam::param_set_and_write_default() -{ - param_set_and_write_new_value(defvalue); -} - -void -PointReseteableParam::param_update_default(Geom::Point newpoint) -{ - this->defvalue = newpoint; -} - -bool -PointReseteableParam::param_readSVGValue(const gchar * strvalue) -{ - gchar ** strarray = g_strsplit(strvalue, ",", 2); - double newx, newy; - unsigned int success = sp_svg_number_read_d(strarray[0], &newx); - success += sp_svg_number_read_d(strarray[1], &newy); - g_strfreev (strarray); - if (success == 2) { - param_setValue( Geom::Point(newx, newy) ); - return true; - } - return false; -} - -gchar * -PointReseteableParam::param_getSVGValue() const -{ - Inkscape::SVGOStringStream os; - os << *dynamic_cast<Geom::Point const *>( this ); - gchar * str = g_strdup(os.str().c_str()); - return str; -} - -Gtk::Widget * -PointReseteableParam::param_newWidget() -{ - Inkscape::UI::Widget::RegisteredTransformedPoint * pointwdg = Gtk::manage( - new Inkscape::UI::Widget::RegisteredTransformedPoint( param_label, - param_tooltip, - param_key, - *param_wr, - param_effect->getRepr(), - param_effect->getSPDoc() ) ); - // TODO: fix to get correct desktop (don't use SP_ACTIVE_DESKTOP) - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - Geom::Affine transf = desktop->doc2dt(); - pointwdg->setTransform(transf); - pointwdg->setValue( *this ); - pointwdg->clearProgrammatically(); - pointwdg->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change point parameter")); - - Gtk::HBox * hbox = Gtk::manage( new Gtk::HBox() ); - static_cast<Gtk::HBox*>(hbox)->pack_start(*pointwdg, true, true); - static_cast<Gtk::HBox*>(hbox)->show_all_children(); - - return dynamic_cast<Gtk::Widget *> (hbox); -} - -void -PointReseteableParam::param_setValue(Geom::Point newpoint) -{ - *dynamic_cast<Geom::Point *>( this ) = newpoint; - if(SP_ACTIVE_DESKTOP){ - SPDesktop* desktop = SP_ACTIVE_DESKTOP; - if (tools_isactive( desktop, TOOLS_NODES)) { - Inkscape::UI::Tools::NodeTool *nt = static_cast<Inkscape::UI::Tools::NodeTool*>( desktop->event_context); - nt->update_helperpath(); - } - } -} - -void -PointReseteableParam::param_set_and_write_new_value (Geom::Point newpoint) -{ - Inkscape::SVGOStringStream os; - os << newpoint; - gchar * str = g_strdup(os.str().c_str()); - param_write_to_repr(str); - g_free(str); -} - -void -PointReseteableParam::param_transform_multiply(Geom::Affine const& postmul, bool /*set*/) -{ - param_set_and_write_new_value( (*this) * postmul ); -} - - -void -PointReseteableParam::set_oncanvas_looks(SPKnotShapeType shape, SPKnotModeType mode, guint32 color) -{ - knot_shape = shape; - knot_mode = mode; - knot_color = color; -} - -class PointReseteableParamKnotHolderEntity : public KnotHolderEntity { -public: - PointReseteableParamKnotHolderEntity(PointReseteableParam *p) { this->pparam = p; } - virtual ~PointReseteableParamKnotHolderEntity() {} - - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); - virtual Geom::Point knot_get() const; - virtual void knot_click(guint state); - -private: - PointReseteableParam *pparam; -}; - -void -PointReseteableParamKnotHolderEntity::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state) -{ - Geom::Point const s = snap_knot_position(p, state); - pparam->param_setValue(s); - sp_lpe_item_update_patheffect(SP_LPE_ITEM(item), false, false); -} - -Geom::Point -PointReseteableParamKnotHolderEntity::knot_get() const -{ - return *pparam; -} - -void -PointReseteableParamKnotHolderEntity::knot_click(guint state) -{ - if (state & GDK_CONTROL_MASK) { - if (state & GDK_MOD1_MASK) { - this->pparam->param_set_default(); - sp_lpe_item_update_patheffect(SP_LPE_ITEM(item), false, false); - } - } -} - -void -PointReseteableParam::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) -{ - PointReseteableParamKnotHolderEntity *e = new PointReseteableParamKnotHolderEntity(this); - // TODO: can we ditch handleTip() etc. because we have access to handle_tip etc. itself??? - e->create(desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, handleTip(), knot_shape, knot_mode, knot_color); - knotholder->add(e); -} - -} /* namespace LivePathEffect */ - -} /* namespace Inkscape */ - -/* - 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/live_effects/parameter/pointreseteable.h b/src/live_effects/parameter/pointreseteable.h deleted file mode 100644 index 5ae1fdf02..000000000 --- a/src/live_effects/parameter/pointreseteable.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef INKSCAPE_LIVEPATHEFFECT_PARAMETER_POINT_RESETEABLE_H -#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_POINT_RESETEABLE_H - -/* - * Inkscape::LivePathEffectParameters - * -* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl> - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#include <glib.h> -#include <2geom/point.h> - -#include "live_effects/parameter/parameter.h" - -#include "knot-holder-entity.h" - -namespace Inkscape { - -namespace LivePathEffect { - -class PointReseteableParamKnotHolderEntity; - -class PointReseteableParam : public Geom::Point, public Parameter { -public: - PointReseteableParam( const Glib::ustring& label, - const Glib::ustring& tip, - const Glib::ustring& key, - Inkscape::UI::Widget::Registry* wr, - Effect* effect, - const gchar *handle_tip = NULL, - Geom::Point default_value = Geom::Point(0,0) ); // tip for automatically associated on-canvas handle - virtual ~PointReseteableParam(); - - virtual Gtk::Widget * param_newWidget(); - - bool param_readSVGValue(const gchar * strvalue); - gchar * param_getSVGValue() const; - inline const gchar *handleTip() const { return handle_tip ? handle_tip : param_tooltip.c_str(); } - - void param_setValue(Geom::Point newpoint); - void param_set_default(); - void param_set_and_write_default(); - void param_update_default(Geom::Point newpoint); - - void param_set_and_write_new_value(Geom::Point newpoint); - - virtual void param_transform_multiply(Geom::Affine const& /*postmul*/, bool /*set*/); - - void set_oncanvas_looks(SPKnotShapeType shape, SPKnotModeType mode, guint32 color); - - virtual bool providesKnotHolderEntities() const { return true; } - virtual void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item); - - friend class PointReseteableParamKnotHolderEntity; -private: - PointReseteableParam(const PointReseteableParam&); - PointReseteableParam& operator=(const PointReseteableParam&); - - Geom::Point defvalue; - - SPKnotShapeType knot_shape; - SPKnotModeType knot_mode; - guint32 knot_color; - gchar *handle_tip; -}; - - -} //namespace LivePathEffect - -} //namespace Inkscape - -#endif diff --git a/src/live_effects/parameter/text.cpp b/src/live_effects/parameter/text.cpp index 956a001ad..234a6174d 100644 --- a/src/live_effects/parameter/text.cpp +++ b/src/live_effects/parameter/text.cpp @@ -19,6 +19,7 @@ #include "inkscape.h" #include "verbs.h" #include "display/canvas-text.h" + #include <2geom/sbasis-geometric.h> namespace Inkscape { @@ -32,8 +33,8 @@ TextParam::TextParam( const Glib::ustring& label, const Glib::ustring& tip, value(default_value), defvalue(default_value) { - SPDesktop *desktop = inkscape_active_desktop(); // FIXME: we shouldn't use this! - canvas_text = (SPCanvasText *) sp_canvastext_new(sp_desktop_tempgroup(desktop), desktop, Geom::Point(0,0), ""); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; // FIXME: we shouldn't use this! + canvas_text = (SPCanvasText *) sp_canvastext_new(desktop->getTempGroup(), desktop, Geom::Point(0,0), ""); sp_canvastext_set_text (canvas_text, default_value.c_str()); sp_canvastext_set_coords (canvas_text, 0, 0); } diff --git a/src/main-cmdlineact.cpp b/src/main-cmdlineact.cpp index 6af616e34..ade83dfda 100644 --- a/src/main-cmdlineact.cpp +++ b/src/main-cmdlineact.cpp @@ -9,7 +9,6 @@ #include <ui/view/view.h> #include <desktop.h> -#include <desktop-handles.h> #include <helper/action.h> #include <helper/action-context.h> #include <selection.h> @@ -82,7 +81,7 @@ CmdLineAction::doList (ActionContext const & context) { bool CmdLineAction::idle (void) { std::list<SPDesktop *> desktops; - inkscape_get_all_desktops(desktops); + INKSCAPE.get_all_desktops(desktops); // We're going to assume one desktop per document, because no one // should have had time to make more at this point. diff --git a/src/main.cpp b/src/main.cpp index 12ddb76e6..415118407 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -52,7 +52,7 @@ #include <glib-object.h> #include <gtk/gtk.h> -#include "gc-core.h" +#include "inkgc/gc-core.h" #ifdef AND #undef AND @@ -74,7 +74,7 @@ #include "svg/svg-color.h" #include "svg/stringstream.h" -#include "inkscape-private.h" +#include "inkscape.h" #include "inkscape-version.h" #include "sp-namedview.h" @@ -933,9 +933,9 @@ guint get_group0_keyval(GdkEventKey const* event); static void snooper(GdkEvent *event, gpointer /*data*/) { - if (inkscape_mapalt()) /* returns the map of the keyboard modifier to map to Alt, zero if no mapping */ + if (INKSCAPE.mapalt()) /* returns the map of the keyboard modifier to map to Alt, zero if no mapping */ { - GdkModifierType mapping=(GdkModifierType)inkscape_mapalt(); + GdkModifierType mapping=(GdkModifierType)INKSCAPE.mapalt(); switch (event->type) { case GDK_MOTION_NOTIFY: if(event->motion.state & mapping) { @@ -957,7 +957,7 @@ snooper(GdkEvent *event, gpointer /*data*/) { } } - if (inkscape_trackalt()) { + if (INKSCAPE.trackalt()) { // MacOS X with X11 has some problem with the default // xmodmapping. A ~/.xmodmap solution does not work reliably due // to the way we package our executable in a .app that can launch @@ -1042,7 +1042,7 @@ sp_main_gui(int argc, char const **argv) } // Add our icon directory to the search path for icon theme lookups. - gchar *usericondir = profile_path("icons"); + gchar *usericondir = Inkscape::Application::profile_path("icons"); gtk_icon_theme_append_search_path(gtk_icon_theme_get_default(), usericondir); gtk_icon_theme_append_search_path(gtk_icon_theme_get_default(), INKSCAPE_PIXMAPDIR); g_free(usericondir); @@ -1059,7 +1059,7 @@ sp_main_gui(int argc, char const **argv) gboolean create_new = TRUE; /// \todo FIXME BROKEN - non-UTF-8 sneaks in here. - inkscape_application_init(argv[0], true); + Inkscape::Application::create(argv[0], true); while (fl) { if (sp_file_open((gchar *)fl->data,NULL)) { @@ -1125,14 +1125,14 @@ static int sp_process_file_list(GSList *fl) retVal++; } else { - inkscape_add_document(doc); + INKSCAPE.add_document(doc); if (sp_vacuum_defs) { doc->vacuumDocument(); } // Execute command-line actions (selections and verbs) using our local models - bool has_performed_actions = Inkscape::CmdLineAction::doList(inkscape_active_action_context()); + bool has_performed_actions = Inkscape::CmdLineAction::doList(INKSCAPE.active_action_context()); #ifdef WITH_DBUS // If we've been asked to listen for D-Bus messages, enter a main loop here @@ -1221,7 +1221,7 @@ static int sp_process_file_list(GSList *fl) do_query_dimension (doc, false, sp_query_x? Geom::X : Geom::Y, sp_query_id); } - inkscape_remove_document(doc); + INKSCAPE.remove_document(doc); delete doc; } @@ -1335,7 +1335,7 @@ int sp_main_console(int argc, char const **argv) exit(0); } - inkscape_application_init(argv[0], false); + Inkscape::Application::create(argv[0], false); if (sp_shell) { int retVal = sp_main_shell(argv[0]); // Run as interactive shell @@ -1722,15 +1722,11 @@ static int do_export_ps_pdf(SPDocument* doc, gchar const* uri, char const* mime) } if (sp_export_text_to_path) { - (*i)->set_param_bool("textToPath", TRUE); + (*i)->set_param_optiongroup("textToPath", "paths"); + } else if (sp_export_latex) { + (*i)->set_param_optiongroup("textToPath", "LaTeX"); } else { - (*i)->set_param_bool("textToPath", FALSE); - } - - if (sp_export_latex) { - (*i)->set_param_bool("textToLaTeX", TRUE); - } else { - (*i)->set_param_bool("textToLaTeX", FALSE); + (*i)->set_param_optiongroup("textToPath", "embed"); } if (sp_export_ignore_filters) { diff --git a/src/menus-skeleton.h b/src/menus-skeleton.h index 18a26d82c..f5e815bf6 100644 --- a/src/menus-skeleton.h +++ b/src/menus-skeleton.h @@ -14,10 +14,8 @@ static char const menus_skeleton[] = " xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\">\n" "\n" " <submenu name=\"" N_("_File") "\">\n" -" <submenu name=\"" N_("_New") "\">\n" -" <verb verb-id=\"FileNew\" />\n" -" <verb verb-id=\"FileTemplates\" />\n" -" </submenu>\n" +" <verb verb-id=\"FileNew\" />\n" +" <verb verb-id=\"FileTemplates\" />\n" " <verb verb-id=\"FileOpen\" />\n" " <recent-file-list/>\n" " <verb verb-id=\"FileRevert\" />\n" diff --git a/src/message-stack.h b/src/message-stack.h index 42bf4e8a7..ed0315cf5 100644 --- a/src/message-stack.h +++ b/src/message-stack.h @@ -22,7 +22,7 @@ #include <glibmm/ustring.h> #include <sigc++/sigc++.h> -#include "gc-managed.h" +#include "inkgc/gc-managed.h" #include "gc-finalized.h" #include "gc-anchored.h" #include "message.h" diff --git a/src/object-test.h b/src/object-test.h index d6a9dbbd3..06363c372 100644 --- a/src/object-test.h +++ b/src/object-test.h @@ -208,6 +208,7 @@ public: end = clock(); std::cout << "Took " << double(end - begin) / double(CLOCKS_PER_SEC) << " seconds to ungroup a <g> with " << num_elements << " elements\n"; + std::cout << " Note: sp_item_group_ungroup_handle_clones() is responsible\n for most of the time as it is linear in number of elements\n which results in quadratic behavior for ungrouping." << std::endl; begin = clock(); // Remove those elements diff --git a/src/path-chemistry.cpp b/src/path-chemistry.cpp index 0c3f9cde7..5f6e1495b 100644 --- a/src/path-chemistry.cpp +++ b/src/path-chemistry.cpp @@ -35,7 +35,7 @@ #include "document-undo.h" #include "message-stack.h" #include "selection.h" -#include "desktop-handles.h" + #include "box3d.h" #include <2geom/pathvector.h> #include "selection-chemistry.h" @@ -47,11 +47,11 @@ using Inkscape::DocumentUndo; void sp_selected_path_combine(SPDesktop *desktop) { - Inkscape::Selection *selection = sp_desktop_selection(desktop); - SPDocument *doc = sp_desktop_document(desktop); + Inkscape::Selection *selection = desktop->getSelection(); + SPDocument *doc = desktop->getDocument(); if (g_slist_length((GSList *) selection->itemList()) < 1) { - sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to combine.")); + desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to combine.")); return; } @@ -170,7 +170,7 @@ sp_selected_path_combine(SPDesktop *desktop) // move to the position of the topmost, reduced by the number of deleted items repr->setPosition(position > 0 ? position : 0); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_SELECTION_COMBINE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_SELECTION_COMBINE, _("Combine")); selection->set(repr); @@ -178,7 +178,7 @@ sp_selected_path_combine(SPDesktop *desktop) Inkscape::GC::release(repr); } else { - sp_desktop_message_stack(desktop)->flash(Inkscape::ERROR_MESSAGE, _("<b>No path(s)</b> to combine in the selection.")); + desktop->getMessageStack()->flash(Inkscape::ERROR_MESSAGE, _("<b>No path(s)</b> to combine in the selection.")); } desktop->clearWaitingCursor(); @@ -187,10 +187,10 @@ sp_selected_path_combine(SPDesktop *desktop) void sp_selected_path_break_apart(SPDesktop *desktop) { - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (selection->isEmpty()) { - sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select <b>path(s)</b> to break apart.")); + desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>path(s)</b> to break apart.")); return; } @@ -283,10 +283,10 @@ sp_selected_path_break_apart(SPDesktop *desktop) desktop->clearWaitingCursor(); if (did) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_SELECTION_BREAK_APART, + DocumentUndo::done(desktop->getDocument(), SP_VERB_SELECTION_BREAK_APART, _("Break apart")); } else { - sp_desktop_message_stack(desktop)->flash(Inkscape::ERROR_MESSAGE, _("<b>No path(s)</b> to break apart in the selection.")); + desktop->getMessageStack()->flash(Inkscape::ERROR_MESSAGE, _("<b>No path(s)</b> to break apart in the selection.")); } } @@ -296,7 +296,7 @@ sp_selected_path_to_curves(Inkscape::Selection *selection, SPDesktop *desktop, b { if (selection->isEmpty()) { if (interactive && desktop) - sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to convert to path.")); + desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to convert to path.")); return; } @@ -323,10 +323,10 @@ sp_selected_path_to_curves(Inkscape::Selection *selection, SPDesktop *desktop, b if (interactive && desktop) { desktop->clearWaitingCursor(); if (did) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_OBJECT_TO_CURVE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_OBJECT_TO_CURVE, _("Object to path")); } else { - sp_desktop_message_stack(desktop)->flash(Inkscape::ERROR_MESSAGE, _("<b>No objects</b> to convert to path in the selection.")); + desktop->getMessageStack()->flash(Inkscape::ERROR_MESSAGE, _("<b>No objects</b> to convert to path in the selection.")); return; } } @@ -335,7 +335,7 @@ sp_selected_path_to_curves(Inkscape::Selection *selection, SPDesktop *desktop, b /** Converts the selected items to LPEItems if they are not already so; e.g. SPRects) */ void sp_selected_to_lpeitems(SPDesktop *desktop) { - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (selection->isEmpty()) { return; @@ -500,11 +500,12 @@ sp_selected_item_to_curved_repr(SPItem *item, guint32 /*text_grouping_policy*/) /* Rotation center */ g_repr->setAttribute("inkscape:transform-center-x", item->getRepr()->attribute("inkscape:transform-center-x"), false); g_repr->setAttribute("inkscape:transform-center-y", item->getRepr()->attribute("inkscape:transform-center-y"), false); + /* Whole text's style */ - gchar *style_str = sp_style_write_difference(item->style, - item->parent ? item->parent->style : NULL); // TODO investigate posibility - g_repr->setAttribute("style", style_str); - g_free(style_str); + Glib::ustring style_str = + item->style->write( SP_STYLE_FLAG_IFDIFF, item->parent ? item->parent->style : NULL); // TODO investigate posibility + g_repr->setAttribute("style", style_str.c_str()); + Inkscape::Text::Layout::iterator iter = te_get_layout(item)->begin(); do { Inkscape::Text::Layout::iterator iter_next = iter; @@ -522,19 +523,17 @@ sp_selected_item_to_curved_repr(SPItem *item, guint32 /*text_grouping_policy*/) while (dynamic_cast<SPString const *>(pos_obj) && pos_obj->parent) { pos_obj = pos_obj->parent; // SPStrings don't have style } - gchar *style_str = sp_style_write_difference(pos_obj->style, - pos_obj->parent ? pos_obj->parent->style : NULL); // TODO investigate posibility + Glib::ustring style_str = + pos_obj->style->write( SP_STYLE_FLAG_IFDIFF, pos_obj->parent ? pos_obj->parent->style : NULL); // TODO investigate posibility // get path from iter to iter_next: SPCurve *curve = te_get_layout(item)->convertToCurves(iter, iter_next); iter = iter_next; // shift to next glyph if (!curve) { // error converting this glyph - g_free (style_str); continue; } if (curve->is_empty()) { // whitespace glyph? curve->unref(); - g_free (style_str); continue; } @@ -545,8 +544,7 @@ sp_selected_item_to_curved_repr(SPItem *item, guint32 /*text_grouping_policy*/) g_free(def_str); curve->unref(); - p_repr->setAttribute("style", style_str); - g_free(style_str); + p_repr->setAttribute("style", style_str.c_str()); g_repr->appendChild(p_repr); Inkscape::GC::release(p_repr); @@ -565,7 +563,7 @@ sp_selected_item_to_curved_repr(SPItem *item, guint32 /*text_grouping_policy*/) if (shape) { curve = shape->getCurve(); } - } + } if (!curve) return NULL; @@ -581,11 +579,11 @@ sp_selected_item_to_curved_repr(SPItem *item, guint32 /*text_grouping_policy*/) Inkscape::XML::Node *repr = xml_doc->createElement("svg:path"); /* Transformation */ repr->setAttribute("transform", item->getRepr()->attribute("transform")); + /* Style */ - gchar *style_str = sp_style_write_difference(item->style, - item->parent ? item->parent->style : NULL); // TODO investigate posibility - repr->setAttribute("style", style_str); - g_free(style_str); + Glib::ustring style_str = + item->style->write( SP_STYLE_FLAG_IFDIFF, item->parent ? item->parent->style : NULL); // TODO investigate posibility + repr->setAttribute("style", style_str.c_str()); /* Mask */ gchar *mask_str = (gchar *) item->getRepr()->attribute("mask"); @@ -613,11 +611,11 @@ sp_selected_item_to_curved_repr(SPItem *item, guint32 /*text_grouping_policy*/) void sp_selected_path_reverse(SPDesktop *desktop) { - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); GSList *items = (GSList *) selection->itemList(); if (!items) { - sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select <b>path(s)</b> to reverse.")); + desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>path(s)</b> to reverse.")); return; } @@ -660,10 +658,10 @@ sp_selected_path_reverse(SPDesktop *desktop) desktop->clearWaitingCursor(); if (did) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_SELECTION_REVERSE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_SELECTION_REVERSE, _("Reverse path")); } else { - sp_desktop_message_stack(desktop)->flash(Inkscape::ERROR_MESSAGE, _("<b>No paths</b> to reverse in the selection.")); + desktop->getMessageStack()->flash(Inkscape::ERROR_MESSAGE, _("<b>No paths</b> to reverse in the selection.")); } } diff --git a/src/persp3d.cpp b/src/persp3d.cpp index b10e5f23b..dc0975d12 100644 --- a/src/persp3d.cpp +++ b/src/persp3d.cpp @@ -19,9 +19,11 @@ #include "vanishing-point.h" #include "ui/tools/box3d-tool.h" #include "box3d.h" +#include "svg/stringstream.h" #include "xml/document.h" #include "xml/node-event-vector.h" -#include "desktop-handles.h" +#include "desktop.h" + #include <glibmm/i18n.h> #include "verbs.h" #include "util/units.h" @@ -30,21 +32,8 @@ using Inkscape::DocumentUndo; static void persp3d_on_repr_attr_changed (Inkscape::XML::Node * repr, const gchar *key, const gchar *oldval, const gchar *newval, bool is_interactive, void * data); -static void persp3d_update_with_point (Persp3DImpl *persp_impl, Proj::Axis const axis, Proj::Pt2 const &new_image); -static gchar * persp3d_pt_to_str (Persp3DImpl *persp_impl, Proj::Axis const axis); - static int global_counter = 0; -#include "sp-factory.h" - -namespace { - SPObject* createPersp3D() { - return new Persp3D(); - } - - bool persp3DRegistered = SPFactory::instance().registerObject("inkscape:persp3d", createPersp3D); -} - /* Constructor/destructor for the internal class */ Persp3DImpl::Persp3DImpl() { @@ -102,36 +91,48 @@ void Persp3D::release() { // FIXME: Currently we only read the finite positions of vanishing points; // should we move VPs into their own repr (as it's done for SPStop, e.g.)? void Persp3D::set(unsigned key, gchar const *value) { - Persp3DImpl *persp_impl = this->perspective_impl; + + // Read values are in 'user units'. + double scale_x = 1.0; + double scale_y = 1.0; + SPRoot *root = document->getRoot(); + if( root->viewBox_set ) { + scale_x = root->width.computed / root->viewBox.width(); + scale_y = root->height.computed / root->viewBox.height(); + } switch (key) { case SP_ATTR_INKSCAPE_PERSP3D_VP_X: { if (value) { - Proj::Pt2 new_image (value); - persp3d_update_with_point (persp_impl, Proj::X, new_image); + Proj::Pt2 pt (value); + Proj::Pt2 ptn ( pt[0]*scale_x, pt[1]*scale_y, pt[2] ); + perspective_impl->tmat.set_image_pt( Proj::X, ptn ); } break; } case SP_ATTR_INKSCAPE_PERSP3D_VP_Y: { if (value) { - Proj::Pt2 new_image (value); - persp3d_update_with_point (persp_impl, Proj::Y, new_image); - break; + Proj::Pt2 pt (value); + Proj::Pt2 ptn ( pt[0]*scale_x, pt[1]*scale_y, pt[2] ); + perspective_impl->tmat.set_image_pt( Proj::Y, ptn ); } + break; } case SP_ATTR_INKSCAPE_PERSP3D_VP_Z: { if (value) { - Proj::Pt2 new_image (value); - persp3d_update_with_point (persp_impl, Proj::Z, new_image); - break; + Proj::Pt2 pt (value); + Proj::Pt2 ptn ( pt[0]*scale_x, pt[1]*scale_y, pt[2] ); + perspective_impl->tmat.set_image_pt( Proj::Z, ptn ); } + break; } case SP_ATTR_INKSCAPE_PERSP3D_ORIGIN: { if (value) { - Proj::Pt2 new_image (value); - persp3d_update_with_point (persp_impl, Proj::W, new_image); - break; + Proj::Pt2 pt (value); + Proj::Pt2 ptn ( pt[0]*scale_x, pt[1]*scale_y, pt[2] ); + perspective_impl->tmat.set_image_pt( Proj::W, ptn ); } + break; } default: { SPObject::set(key, value); @@ -140,7 +141,7 @@ void Persp3D::set(unsigned key, gchar const *value) { } // FIXME: Is this the right place for resetting the draggers? - Inkscape::UI::Tools::ToolBase *ec = inkscape_active_event_context(); + Inkscape::UI::Tools::ToolBase *ec = INKSCAPE.active_event_context(); if (SP_IS_BOX3D_CONTEXT(ec)) { Inkscape::UI::Tools::Box3dTool *bc = SP_BOX3D_CONTEXT(ec); bc->_vpdrag->updateDraggers(); @@ -169,10 +170,19 @@ Persp3D *persp3d_create_xml_element(SPDocument *document, Persp3DImpl *dup) {// repr = xml_doc->createElement("inkscape:perspective"); repr->setAttribute("sodipodi:type", "inkscape:persp3d"); - Proj::Pt2 proj_vp_x = Proj::Pt2 (0.0, document->getHeight().value("px")/2, 1.0); - Proj::Pt2 proj_vp_y = Proj::Pt2 (0.0, 1000.0, 0.0); - Proj::Pt2 proj_vp_z = Proj::Pt2 (document->getWidth().value("px"), document->getHeight().value("px")/2, 1.0); - Proj::Pt2 proj_origin = Proj::Pt2 (document->getWidth().value("px")/2, document->getHeight().value("px")/3, 1.0); + // Use 'user-units' + double width = document->getWidth().value("px"); + double height = document->getHeight().value("px"); + if( document->getRoot()->viewBox_set ) { + Geom::Rect vb = document->getRoot()->viewBox; + width = vb.width(); + height = vb.height(); + } + + Proj::Pt2 proj_vp_x = Proj::Pt2 (0.0, height/2.0, 1.0); + Proj::Pt2 proj_vp_y = Proj::Pt2 (0.0, 1000.0, 0.0); + Proj::Pt2 proj_vp_z = Proj::Pt2 (width, height/2.0, 1.0); + Proj::Pt2 proj_origin = Proj::Pt2 (width/2.0, height/3.0, 1.0 ); if (dup) { proj_vp_x = dup->tmat.column (Proj::X); @@ -217,7 +227,6 @@ Persp3D *persp3d_document_first_persp(SPDocument *document) * Virtual write: write object attributes to repr. */ Inkscape::XML::Node* Persp3D::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { - Persp3DImpl *persp_impl = this->perspective_impl; if ((flags & SP_OBJECT_WRITE_BUILD & SP_OBJECT_WRITE_EXT) && !repr) { // this is where we end up when saving as plain SVG (also in other circumstances?); @@ -226,18 +235,39 @@ Inkscape::XML::Node* Persp3D::write(Inkscape::XML::Document *xml_doc, Inkscape:: } if (flags & SP_OBJECT_WRITE_EXT) { - gchar *str = NULL; // FIXME: Should this be freed each time we set an attribute or only in the end or at all? - str = persp3d_pt_to_str (persp_impl, Proj::X); - repr->setAttribute("inkscape:vp_x", str); - str = persp3d_pt_to_str (persp_impl, Proj::Y); - repr->setAttribute("inkscape:vp_y", str); - - str = persp3d_pt_to_str (persp_impl, Proj::Z); - repr->setAttribute("inkscape:vp_z", str); - - str = persp3d_pt_to_str (persp_impl, Proj::W); - repr->setAttribute("inkscape:persp3d-origin", str); + // Written values are in 'user units'. + double scale_x = 1.0; + double scale_y = 1.0; + SPRoot *root = document->getRoot(); + if( root->viewBox_set ) { + scale_x = root->viewBox.width() / root->width.computed; + scale_y = root->viewBox.height() / root->height.computed; + } + { + Proj::Pt2 pt = perspective_impl->tmat.column( Proj::X ); + Inkscape::SVGOStringStream os; + os << pt[0] * scale_x << " : " << pt[1] * scale_y << " : " << pt[2]; + repr->setAttribute("inkscape:vp_x", os.str().c_str()); + } + { + Proj::Pt2 pt = perspective_impl->tmat.column( Proj::Y ); + Inkscape::SVGOStringStream os; + os << pt[0] * scale_x << " : " << pt[1] * scale_y << " : " << pt[2]; + repr->setAttribute("inkscape:vp_y", os.str().c_str()); + } + { + Proj::Pt2 pt = perspective_impl->tmat.column( Proj::Z ); + Inkscape::SVGOStringStream os; + os << pt[0] * scale_x << " : " << pt[1] * scale_y << " : " << pt[2]; + repr->setAttribute("inkscape:vp_z", os.str().c_str()); + } + { + Proj::Pt2 pt = perspective_impl->tmat.column( Proj::W ); + Inkscape::SVGOStringStream os; + os << pt[0] * scale_x << " : " << pt[1] * scale_y << " : " << pt[2]; + repr->setAttribute("inkscape:persp3d-origin", os.str().c_str()); + } } SPObject::write(xml_doc, repr, flags); @@ -289,7 +319,7 @@ persp3d_toggle_VP (Persp3D *persp, Proj::Axis axis, bool set_undo) { persp3d_update_box_reprs (persp); persp->updateRepr(SP_OBJECT_WRITE_EXT); if (set_undo) { - DocumentUndo::done(sp_desktop_document(inkscape_active_desktop()), SP_VERB_CONTEXT_3DBOX, + DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_CONTEXT_3DBOX, _("Toggle vanishing point")); } } @@ -300,7 +330,7 @@ persp3d_toggle_VPs (std::list<Persp3D *> p, Proj::Axis axis) { for (std::list<Persp3D *>::iterator i = p.begin(); i != p.end(); ++i) { persp3d_toggle_VP((*i), axis, false); } - DocumentUndo::done(sp_desktop_document(inkscape_active_desktop()), SP_VERB_CONTEXT_3DBOX, + DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_CONTEXT_3DBOX, _("Toggle multiple vanishing points")); } @@ -329,23 +359,12 @@ persp3d_rotate_VP (Persp3D *persp, Proj::Axis axis, double angle, bool alt_press } void -persp3d_update_with_point (Persp3DImpl *persp_impl, Proj::Axis const axis, Proj::Pt2 const &new_image) { - persp_impl->tmat.set_image_pt (axis, new_image); -} - -void persp3d_apply_affine_transformation (Persp3D *persp, Geom::Affine const &xform) { persp->perspective_impl->tmat *= xform; persp3d_update_box_reprs(persp); persp->updateRepr(SP_OBJECT_WRITE_EXT); } -gchar * -persp3d_pt_to_str (Persp3DImpl *persp_impl, Proj::Axis const axis) -{ - return persp_impl->tmat.pt_to_str(axis); -} - void persp3d_add_box (Persp3D *persp, SPBox3D *box) { Persp3DImpl *persp_impl = persp->perspective_impl; @@ -527,7 +546,7 @@ persp3d_print_all_selected() { g_print ("\n======================================\n"); g_print ("Selected perspectives and their boxes:\n"); - std::list<Persp3D *> sel_persps = sp_desktop_selection(inkscape_active_desktop())->perspList(); + std::list<Persp3D *> sel_persps = SP_ACTIVE_DESKTOP->getSelection()->perspList(); for (std::list<Persp3D *>::iterator j = sel_persps.begin(); j != sel_persps.end(); ++j) { Persp3D *persp = SP_PERSP3D(*j); diff --git a/src/preferences.cpp b/src/preferences.cpp index d0c3783b5..e5a5fe7f0 100644 --- a/src/preferences.cpp +++ b/src/preferences.cpp @@ -91,11 +91,13 @@ Preferences::Preferences() : _hasError(false) { // profile_path essentailly returns the argument prefixed by the profile directory. - gchar *path = profile_path(NULL); + // \TODO this is kinda hackish, but the alternative (strrchr) is worse + + gchar *path = Inkscape::Application::profile_path(NULL); _prefs_dir = path; g_free(path); - path = profile_path(_prefs_basename.c_str()); + path = Inkscape::Application::profile_path(_prefs_basename.c_str()); _prefs_filename = path; g_free(path); @@ -155,7 +157,7 @@ void Preferences::_load() // create some subdirectories for user stuff char const *user_dirs[] = {"keys", "templates", "icons", "extensions", "palettes", NULL}; for (int i=0; user_dirs[i]; ++i) { - char *dir = profile_path(user_dirs[i]); + char *dir = Inkscape::Application::profile_path(user_dirs[i]); g_mkdir(dir, 0755); g_free(dir); } diff --git a/src/rubberband.cpp b/src/rubberband.cpp index 6ec4b3e45..4a171f4a1 100644 --- a/src/rubberband.cpp +++ b/src/rubberband.cpp @@ -12,7 +12,7 @@ #include "display/sodipodi-ctrlrect.h" #include "desktop.h" -#include "desktop-handles.h" + #include "rubberband.h" #include "display/sp-canvas.h" #include "display/sp-canvas-item.h" @@ -98,7 +98,7 @@ void Inkscape::Rubberband::move(Geom::Point const &p) if (_mode == RUBBERBAND_MODE_RECT) { if (_rect == NULL) { - _rect = static_cast<CtrlRect *>(sp_canvas_item_new(sp_desktop_controls(_desktop), SP_TYPE_CTRLRECT, NULL)); + _rect = static_cast<CtrlRect *>(sp_canvas_item_new(_desktop->getControls(), SP_TYPE_CTRLRECT, NULL)); _rect->setShadow(1, 0xffffffff); } _rect->setRectangle(Geom::Rect(_start, _end)); @@ -109,7 +109,7 @@ void Inkscape::Rubberband::move(Geom::Point const &p) } else if (_mode == RUBBERBAND_MODE_TOUCHPATH) { if (_touchpath == NULL) { - _touchpath = sp_canvas_bpath_new(sp_desktop_sketch(_desktop), NULL); + _touchpath = sp_canvas_bpath_new(_desktop->getSketch(), NULL); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(_touchpath), 0xff0000ff, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(_touchpath), 0, SP_WIND_RULE_NONZERO); } diff --git a/src/satisfied-guide-cns.cpp b/src/satisfied-guide-cns.cpp index 588c78ce0..028a22405 100644 --- a/src/satisfied-guide-cns.cpp +++ b/src/satisfied-guide-cns.cpp @@ -1,5 +1,5 @@ #include <2geom/coord.h> -#include "desktop-handles.h" +#include "desktop.h" #include "sp-guide.h" #include "sp-guide-constraint.h" #include "sp-namedview.h" @@ -9,7 +9,7 @@ void satisfied_guide_cns(SPDesktop const &desktop, std::vector<Inkscape::SnapCandidatePoint> const &snappoints, std::vector<SPGuideConstraint> &cns) { - SPNamedView const &nv = *sp_desktop_namedview(&desktop); + SPNamedView const &nv = *desktop.getNamedView(); for (GSList const *l = nv.guides; l != NULL; l = l->next) { SPGuide &g = *SP_GUIDE(l->data); for (unsigned int i = 0; i < snappoints.size(); ++i) { diff --git a/src/selcue.cpp b/src/selcue.cpp index 805629636..d2fa0970a 100644 --- a/src/selcue.cpp +++ b/src/selcue.cpp @@ -13,7 +13,8 @@ #include <string.h> -#include "desktop-handles.h" +#include "desktop.h" + #include "selection.h" #include "display/sp-canvas-util.h" #include "display/sodipodi-ctrl.h" @@ -40,7 +41,7 @@ Inkscape::SelCue::SelCue(SPDesktop *desktop) : _desktop(desktop), _bounding_box_prefs_observer(*this) { - _selection = sp_desktop_selection(_desktop); + _selection = _desktop->getSelection(); _sel_changed_connection = _selection->connectChanged( sigc::hide(sigc::mem_fun(*this, &Inkscape::SelCue::_newItemBboxes)) @@ -154,7 +155,7 @@ void Inkscape::SelCue::_newItemBboxes() if (b) { if (mode == MARK) { - box = sp_canvas_item_new(sp_desktop_controls(_desktop), + box = sp_canvas_item_new(_desktop->getControls(), SP_TYPE_CTRL, "mode", SP_CTRL_MODE_XOR, "shape", SP_CTRL_SHAPE_DIAMOND, @@ -170,7 +171,7 @@ void Inkscape::SelCue::_newItemBboxes() sp_canvas_item_move_to_z(box, 0); // just low enough to not get in the way of other draggable knots } else if (mode == BBOX) { - box = sp_canvas_item_new(sp_desktop_controls(_desktop), + box = sp_canvas_item_new(_desktop->getControls(), SP_TYPE_CTRLRECT, NULL); @@ -207,7 +208,7 @@ void Inkscape::SelCue::_newTextBaselines() if (layout != NULL && layout->outputExists()) { boost::optional<Geom::Point> pt = layout->baselineAnchorPoint(); if (pt) { - baseline_point = sp_canvas_item_new(sp_desktop_controls(_desktop), SP_TYPE_CTRL, + baseline_point = sp_canvas_item_new(_desktop->getControls(), SP_TYPE_CTRL, "mode", SP_CTRL_MODE_XOR, "size", 4.0, "filled", 0, diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index ffa149cee..5e8fd5e07 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -38,7 +38,7 @@ SPCycleType SP_CYCLING = SP_CYCLE_FOCUS; #include "layer-model.h" #include "selection.h" #include "ui/tools-switch.h" -#include "desktop-handles.h" + #include "message-stack.h" #include "sp-item-transform.h" #include "sp-marker.h" @@ -99,7 +99,7 @@ SPCycleType SP_CYCLING = SP_CYCLE_FOCUS; #include "display/curve.h" #include "display/canvas-bpath.h" #include "display/cairo-utils.h" -#include "inkscape-private.h" +#include "inkscape.h" #include "path-chemistry.h" #include "ui/tool/control-point-selection.h" #include "ui/tool/multi-path-manipulator.h" @@ -177,8 +177,8 @@ void SelectionHelper::selectNone(SPDesktop *dt) if (nt && !nt->_selected_nodes->empty()) { nt->_selected_nodes->clear(); - } else if (!sp_desktop_selection(dt)->isEmpty()) { - sp_desktop_selection(dt)->clear(); + } else if (!dt->getSelection()->isEmpty()) { + dt->getSelection()->clear(); } else { // If nothing selected switch to selection tool tools_switch(dt, TOOLS_SELECT); @@ -202,7 +202,7 @@ void SelectionHelper::selectSameStrokeColor(SPDesktop *dt) void SelectionHelper::selectSameStrokeStyle(SPDesktop *dt) { - sp_select_same_stroke_style(dt); + sp_select_same_fill_stroke_style(dt, false, false, true); } void SelectionHelper::selectSameObjectType(SPDesktop *dt) @@ -277,7 +277,7 @@ void SelectionHelper::fixSelection(SPDesktop *dt) if(!dt) return; - Inkscape::Selection *selection = sp_desktop_selection(dt); + Inkscape::Selection *selection = dt->getSelection(); GSList *items = NULL; @@ -402,12 +402,12 @@ void sp_selection_delete(SPDesktop *desktop) if (tools_isactive(desktop, TOOLS_TEXT)) if (Inkscape::UI::Tools::sp_text_delete_selection(desktop->event_context)) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("Delete text")); return; } - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); // check if something is selected if (selection->isEmpty()) { @@ -429,7 +429,7 @@ void sp_selection_delete(SPDesktop *desktop) */ tools_switch( desktop, tools_active( desktop ) ); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_EDIT_DELETE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_DELETE, _("Delete")); } @@ -454,7 +454,7 @@ void sp_selection_duplicate(SPDesktop *desktop, bool suppressDone) SPDocument *doc = desktop->doc(); Inkscape::XML::Document* xml_doc = doc->getReprDoc(); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); // check if something is selected if (selection->isEmpty()) { @@ -521,11 +521,9 @@ void sp_selection_duplicate(SPDesktop *desktop, bool suppressDone) if (!strcmp(orig->getId(), old_ids[j])) { // we have both orig and clone in selection, relink // std::cout << id << " old, its ori: " << orig->getId() << "; will relink:" << new_ids[i] << " to " << new_ids[j] << "\n"; - gchar *newref = g_strdup_printf("#%s", new_ids[j]); SPObject *new_clone = doc->getObjectById(new_ids[i]); - new_clone->getRepr()->setAttribute("xlink:href", newref); + new_clone->getRepr()->setAttribute("xlink:href", Glib::ustring("#") + new_ids[j]); new_clone->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - g_free(newref); } } } else { @@ -534,9 +532,7 @@ void sp_selection_duplicate(SPDesktop *desktop, bool suppressDone) for (guint j = 0; j < old_ids.size(); j++) { gchar *source_href = offset->sourceHref; if (source_href && source_href[0]=='#' && !strcmp(source_href+1, old_ids[j])) { - gchar *newref = g_strdup_printf("#%s", new_ids[j]); - doc->getObjectById(new_ids[i])->getRepr()->setAttribute("xlink:href", newref); - g_free(newref); + doc->getObjectById(new_ids[i])->getRepr()->setAttribute("xlink:href", Glib::ustring("#") + new_ids[j]); } } } @@ -546,7 +542,7 @@ void sp_selection_duplicate(SPDesktop *desktop, bool suppressDone) if ( !suppressDone ) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_EDIT_DUPLICATE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_DUPLICATE, _("Duplicate")); } @@ -613,7 +609,7 @@ static void sp_edit_select_all_full(SPDesktop *dt, bool force_all_layers, bool i if (!dt) return; - Inkscape::Selection *selection = sp_desktop_selection(dt); + Inkscape::Selection *selection = dt->getSelection(); g_return_if_fail(dynamic_cast<SPGroup *>(dt->currentLayer())); @@ -1146,7 +1142,7 @@ sp_undo(SPDesktop *desktop, SPDocument *) // No re/undo while dragging, too dangerous. if(desktop->getCanvas()->is_dragging) return; - if (!DocumentUndo::undo(sp_desktop_document(desktop))) { + if (!DocumentUndo::undo(desktop->getDocument())) { desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Nothing to undo.")); } } @@ -1157,7 +1153,7 @@ sp_redo(SPDesktop *desktop, SPDocument *) // No re/undo while dragging, too dangerous. if(desktop->getCanvas()->is_dragging) return; - if (!DocumentUndo::redo(sp_desktop_document(desktop))) { + if (!DocumentUndo::redo(desktop->getDocument())) { desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Nothing to redo.")); } } @@ -1230,7 +1226,7 @@ void sp_selection_paste(SPDesktop *desktop, bool in_place) { Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); if (cm->paste(desktop, in_place)) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_EDIT_PASTE, _("Paste")); + DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_PASTE, _("Paste")); } } @@ -1238,7 +1234,7 @@ void sp_selection_paste_style(SPDesktop *desktop) { Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); if (cm->pasteStyle(desktop)) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_EDIT_PASTE_STYLE, _("Paste style")); + DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_PASTE_STYLE, _("Paste style")); } } @@ -1247,7 +1243,7 @@ void sp_selection_paste_livepatheffect(SPDesktop *desktop) { Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); if (cm->pastePathEffect(desktop)) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_EDIT_PASTE_LIVEPATHEFFECT, + DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_PASTE_LIVEPATHEFFECT, _("Paste live path effect")); } } @@ -1266,7 +1262,7 @@ void sp_selection_remove_livepatheffect(SPDesktop *desktop) { if (desktop == NULL) return; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); // check if something is selected if (selection->isEmpty()) { @@ -1281,7 +1277,7 @@ void sp_selection_remove_livepatheffect(SPDesktop *desktop) } - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_EDIT_REMOVE_LIVEPATHEFFECT, + DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_REMOVE_LIVEPATHEFFECT, _("Remove live path effect")); } @@ -1289,7 +1285,7 @@ void sp_selection_remove_filter(SPDesktop *desktop) { if (desktop == NULL) return; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); // check if something is selected if (selection->isEmpty()) { @@ -1302,7 +1298,7 @@ void sp_selection_remove_filter(SPDesktop *desktop) sp_desktop_set_style(desktop, css); sp_repr_css_attr_unref(css); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_EDIT_REMOVE_FILTER, + DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_REMOVE_FILTER, _("Remove filter")); } @@ -1311,7 +1307,7 @@ void sp_selection_paste_size(SPDesktop *desktop, bool apply_x, bool apply_y) { Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); if (cm->pasteSize(desktop, false, apply_x, apply_y)) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_EDIT_PASTE_SIZE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_PASTE_SIZE, _("Paste size")); } } @@ -1320,14 +1316,33 @@ void sp_selection_paste_size_separately(SPDesktop *desktop, bool apply_x, bool a { Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); if (cm->pasteSize(desktop, true, apply_x, apply_y)) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_EDIT_PASTE_SIZE_SEPARATELY, + DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_PASTE_SIZE_SEPARATELY, _("Paste size separately")); } } +/** + * Ensures that the clones of objects are not modified when moving objects between layers. + * Calls the same function as ungroup + */ +void sp_selection_change_layer_maintain_clones(GSList const *items,SPObject *where) +{ + for (const GSList *i = items; i != NULL; i = i->next) { + SPItem *item = dynamic_cast<SPItem *>(SP_OBJECT(i->data)); + if (item) { + SPItem *oldparent = dynamic_cast<SPItem *>(item->parent); + SPItem *newparent = dynamic_cast<SPItem *>(where); + sp_item_group_ungroup_handle_clones(item, + (oldparent->i2doc_affine()) + *((newparent->i2doc_affine()).inverse())); + } + } +} + + void sp_selection_to_next_layer(SPDesktop *dt, bool suppressDone) { - Inkscape::Selection *selection = sp_desktop_selection(dt); + Inkscape::Selection *selection = dt->getSelection(); // check if something is selected if (selection->isEmpty()) { @@ -1340,15 +1355,16 @@ void sp_selection_to_next_layer(SPDesktop *dt, bool suppressDone) bool no_more = false; // Set to true, if no more layers above SPObject *next=Inkscape::next_layer(dt->currentRoot(), dt->currentLayer()); if (next) { + sp_selection_change_layer_maintain_clones(items,next); GSList *temp_clip = NULL; sp_selection_copy_impl(items, &temp_clip, dt->doc()->getReprDoc()); sp_selection_delete_impl(items, false, false); next=Inkscape::next_layer(dt->currentRoot(), dt->currentLayer()); // Fixes bug 1482973: crash while moving layers GSList *copied; if (next) { - copied = sp_selection_paste_impl(sp_desktop_document(dt), next, &temp_clip); + copied = sp_selection_paste_impl(dt->getDocument(), next, &temp_clip); } else { - copied = sp_selection_paste_impl(sp_desktop_document(dt), dt->currentLayer(), &temp_clip); + copied = sp_selection_paste_impl(dt->getDocument(), dt->currentLayer(), &temp_clip); no_more = true; } selection->setReprList((GSList const *) copied); @@ -1356,7 +1372,7 @@ void sp_selection_to_next_layer(SPDesktop *dt, bool suppressDone) if (temp_clip) g_slist_free(temp_clip); if (next) dt->setCurrentLayer(next); if ( !suppressDone ) { - DocumentUndo::done(sp_desktop_document(dt), SP_VERB_LAYER_MOVE_TO_NEXT, + DocumentUndo::done(dt->getDocument(), SP_VERB_LAYER_MOVE_TO_NEXT, _("Raise to next layer")); } } else { @@ -1372,7 +1388,7 @@ void sp_selection_to_next_layer(SPDesktop *dt, bool suppressDone) void sp_selection_to_prev_layer(SPDesktop *dt, bool suppressDone) { - Inkscape::Selection *selection = sp_desktop_selection(dt); + Inkscape::Selection *selection = dt->getSelection(); // check if something is selected if (selection->isEmpty()) { @@ -1385,15 +1401,16 @@ void sp_selection_to_prev_layer(SPDesktop *dt, bool suppressDone) bool no_more = false; // Set to true, if no more layers below SPObject *next=Inkscape::previous_layer(dt->currentRoot(), dt->currentLayer()); if (next) { + sp_selection_change_layer_maintain_clones(items,next); GSList *temp_clip = NULL; sp_selection_copy_impl(items, &temp_clip, dt->doc()->getReprDoc()); // we're in the same doc, so no need to copy defs sp_selection_delete_impl(items, false, false); next=Inkscape::previous_layer(dt->currentRoot(), dt->currentLayer()); // Fixes bug 1482973: crash while moving layers GSList *copied; if (next) { - copied = sp_selection_paste_impl(sp_desktop_document(dt), next, &temp_clip); + copied = sp_selection_paste_impl(dt->getDocument(), next, &temp_clip); } else { - copied = sp_selection_paste_impl(sp_desktop_document(dt), dt->currentLayer(), &temp_clip); + copied = sp_selection_paste_impl(dt->getDocument(), dt->currentLayer(), &temp_clip); no_more = true; } selection->setReprList((GSList const *) copied); @@ -1401,7 +1418,7 @@ void sp_selection_to_prev_layer(SPDesktop *dt, bool suppressDone) if (temp_clip) g_slist_free(temp_clip); if (next) dt->setCurrentLayer(next); if ( !suppressDone ) { - DocumentUndo::done(sp_desktop_document(dt), SP_VERB_LAYER_MOVE_TO_PREV, + DocumentUndo::done(dt->getDocument(), SP_VERB_LAYER_MOVE_TO_PREV, _("Lower to previous layer")); } } else { @@ -1417,7 +1434,7 @@ void sp_selection_to_prev_layer(SPDesktop *dt, bool suppressDone) void sp_selection_to_layer(SPDesktop *dt, SPObject *moveto, bool suppressDone) { - Inkscape::Selection *selection = sp_desktop_selection(dt); + Inkscape::Selection *selection = dt->getSelection(); // check if something is selected if (selection->isEmpty()) { @@ -1428,16 +1445,17 @@ void sp_selection_to_layer(SPDesktop *dt, SPObject *moveto, bool suppressDone) GSList const *items = g_slist_copy(const_cast<GSList *>(selection->itemList())); if (moveto) { + sp_selection_change_layer_maintain_clones(items,moveto); GSList *temp_clip = NULL; sp_selection_copy_impl(items, &temp_clip, dt->doc()->getReprDoc()); // we're in the same doc, so no need to copy defs sp_selection_delete_impl(items, false, false); - GSList *copied = sp_selection_paste_impl(sp_desktop_document(dt), moveto, &temp_clip); + GSList *copied = sp_selection_paste_impl(dt->getDocument(), moveto, &temp_clip); selection->setReprList((GSList const *) copied); g_slist_free(copied); if (temp_clip) g_slist_free(temp_clip); if (moveto) dt->setCurrentLayer(moveto); if ( !suppressDone ) { - DocumentUndo::done(sp_desktop_document(dt), SP_VERB_LAYER_MOVE_TO, + DocumentUndo::done(dt->getDocument(), SP_VERB_LAYER_MOVE_TO, _("Move selection to layer")); } } @@ -1690,7 +1708,7 @@ void sp_selection_remove_transform(SPDesktop *desktop) if (desktop == NULL) return; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); GSList const *l = const_cast<GSList *>(selection->reprList()); while (l != NULL) { @@ -1698,7 +1716,7 @@ void sp_selection_remove_transform(SPDesktop *desktop) l = l->next; } - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_OBJECT_FLATTEN, + DocumentUndo::done(desktop->getDocument(), SP_VERB_OBJECT_FLATTEN, _("Remove transform")); } @@ -1788,7 +1806,7 @@ void sp_selection_move_relative(Inkscape::Selection *selection, double dx, doubl */ void sp_selection_rotate_90(SPDesktop *desktop, bool ccw) { - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (selection->isEmpty()) return; @@ -1804,7 +1822,7 @@ void sp_selection_rotate_90(SPDesktop *desktop, bool ccw) } } - DocumentUndo::done(sp_desktop_document(desktop), + DocumentUndo::done(desktop->getDocument(), ccw ? SP_VERB_OBJECT_ROTATE_90_CCW : SP_VERB_OBJECT_ROTATE_90_CW, ccw ? _("Rotate 90\xc2\xb0 CCW") : _("Rotate 90\xc2\xb0 CW")); } @@ -1822,7 +1840,7 @@ sp_selection_rotate(Inkscape::Selection *selection, gdouble const angle_degrees) sp_selection_rotate_relative(selection, *center, angle_degrees); - DocumentUndo::maybeDone(sp_desktop_document(selection->desktop()), + DocumentUndo::maybeDone(selection->desktop()->getDocument(), ( ( angle_degrees > 0 ) ? "selector:rotate:ccw" : "selector:rotate:cw" ), @@ -1856,21 +1874,22 @@ void sp_select_same_fill_stroke_style(SPDesktop *desktop, gboolean fill, gboolea GSList *all_list = get_all_items(NULL, desktop->currentRoot(), desktop, onlyvisible, onlysensitive, ingroups, NULL); GSList *all_matches = NULL; - Inkscape::Selection *selection = sp_desktop_selection (desktop); + Inkscape::Selection *selection = desktop->getSelection(); for (GSList const* sel_iter = selection->itemList(); sel_iter; sel_iter = sel_iter->next) { SPItem *sel = dynamic_cast<SPItem *>(static_cast<SPObject *>(sel_iter->data)); GSList *matches = all_list; - if (fill) { - matches = sp_get_same_fill_or_stroke_color(sel, matches, SP_FILL_COLOR); + if (fill && stroke && style) { + matches = sp_get_same_style(sel, matches); + } + else if (fill) { + matches = sp_get_same_style(sel, matches, SP_FILL_COLOR); } - if (stroke) { - matches = sp_get_same_fill_or_stroke_color(sel, matches, SP_STROKE_COLOR); + else if (stroke) { + matches = sp_get_same_style(sel, matches, SP_STROKE_COLOR); } - if (style) { - matches = sp_get_same_stroke_style(sel, matches, SP_STROKE_STYLE_WIDTH); - matches = sp_get_same_stroke_style(sel, matches, SP_STROKE_STYLE_DASHES); - matches = sp_get_same_stroke_style(sel, matches, SP_STROKE_STYLE_MARKERS); + else if (style) { + matches = sp_get_same_style(sel, matches,SP_STROKE_STYLE_ALL); } all_matches = g_slist_concat (all_matches, matches); } @@ -1909,7 +1928,7 @@ void sp_select_same_object_type(SPDesktop *desktop) GSList *all_list = get_all_items(NULL, desktop->currentRoot(), desktop, onlyvisible, onlysensitive, ingroups, NULL); GSList *matches = all_list; - Inkscape::Selection *selection = sp_desktop_selection (desktop); + Inkscape::Selection *selection = desktop->getSelection(); for (GSList const* sel_iter = selection->itemList(); sel_iter; sel_iter = sel_iter->next) { SPItem *sel = dynamic_cast<SPItem *>(static_cast<SPObject *>(sel_iter->data)); @@ -1931,49 +1950,7 @@ void sp_select_same_object_type(SPDesktop *desktop) } } -/* - * Selects all the visible items with the same stroke style as the items in the current selection - * - * Params: - * desktop - set the selection on this desktop - */ -void sp_select_same_stroke_style(SPDesktop *desktop) -{ - if (!desktop) { - return; - } - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - bool onlyvisible = prefs->getBool("/options/kbselection/onlyvisible", true); - bool onlysensitive = prefs->getBool("/options/kbselection/onlysensitive", true); - bool ingroups = TRUE; - - GSList *all_list = get_all_items(NULL, desktop->currentRoot(), desktop, onlyvisible, onlysensitive, ingroups, NULL); - GSList *matches = all_list; - - Inkscape::Selection *selection = sp_desktop_selection (desktop); - for (GSList const* sel_iter = selection->itemList(); sel_iter; sel_iter = sel_iter->next) { - SPItem *sel = dynamic_cast<SPItem *>(static_cast<SPObject *>(sel_iter->data)); - if (sel) { - matches = sp_get_same_stroke_style(sel, matches, SP_STROKE_STYLE_WIDTH); - matches = sp_get_same_stroke_style(sel, matches, SP_STROKE_STYLE_DASHES); - matches = sp_get_same_stroke_style(sel, matches, SP_STROKE_STYLE_MARKERS); - } else { - g_assert_not_reached(); - } - } - - selection->clear(); - selection->setList(matches); - - if (matches) { - g_slist_free(matches); - } - if (all_list) { - g_slist_free(all_list); - } -} /* * Find all items in src list that have the same fill or stroke style as sel @@ -2083,7 +2060,7 @@ GSList *sp_get_same_object_type(SPItem *sel, GSList *src) for (GSList *i = src; i != NULL; i = i->next) { SPItem *item = dynamic_cast<SPItem *>(static_cast<SPObject *>(i->data)); - if (item && item_type_match(sel, item)) { + if (item && item_type_match(sel, item) && !item->cloned) { matches = g_slist_prepend (matches, item); } } @@ -2091,19 +2068,24 @@ GSList *sp_get_same_object_type(SPItem *sel, GSList *src) return matches; } +GSList *sp_get_same_fill_or_stroke_color(SPItem *sel, GSList *src, SPSelectStrokeStyleType type); + /* * Find all items in src list that have the same stroke style as sel by type * Return the list of matching items */ -GSList *sp_get_same_stroke_style(SPItem *sel, GSList *src, SPSelectStrokeStyleType type) +GSList *sp_get_same_style(SPItem *sel, GSList *src, SPSelectStrokeStyleType type) { GSList *matches = NULL; - gboolean match = false; + bool match = false; SPStyle *sel_style = sel->style; - if (type == SP_FILL_COLOR || type == SP_STROKE_COLOR) { - return sp_get_same_fill_or_stroke_color(sel, src, type); + if (type == SP_FILL_COLOR || type == SP_STYLE_ALL) { + src = sp_get_same_fill_or_stroke_color(sel, src, SP_FILL_COLOR); + } + if (type == SP_STROKE_COLOR || type == SP_STYLE_ALL) { + src = sp_get_same_fill_or_stroke_color(sel, src, SP_STROKE_COLOR); } /* @@ -2112,39 +2094,42 @@ GSList *sp_get_same_stroke_style(SPItem *sel, GSList *src, SPSelectStrokeStyleTy */ GSList *objects = NULL; SPStyle *sel_style_for_width = NULL; - if (type == SP_STROKE_STYLE_WIDTH) { + if (type == SP_STROKE_STYLE_WIDTH || type == SP_STROKE_STYLE_ALL || type==SP_STYLE_ALL ) { objects = g_slist_prepend(objects, sel); - sel_style_for_width = sp_style_new (SP_ACTIVE_DOCUMENT); + sel_style_for_width = new SPStyle(SP_ACTIVE_DOCUMENT); objects_query_strokewidth (objects, sel_style_for_width); } - + bool match_g; for (GSList *i = src; i != NULL; i = i->next) { SPItem *iter = dynamic_cast<SPItem *>(static_cast<SPObject *>(i->data)); if (iter) { + match_g=true; SPStyle *iter_style = iter->style; - match = false; + match = true; - if (type == SP_STROKE_STYLE_WIDTH) { + if (type == SP_STROKE_STYLE_WIDTH|| type == SP_STROKE_STYLE_ALL|| type==SP_STYLE_ALL) { match = (sel_style->stroke_width.set == iter_style->stroke_width.set); if (sel_style->stroke_width.set && iter_style->stroke_width.set) { GSList *objects = NULL; objects = g_slist_prepend(objects, iter); - SPStyle *iter_style_for_width = sp_style_new (SP_ACTIVE_DOCUMENT); - objects_query_strokewidth (objects, iter_style_for_width); + SPStyle tmp_style(SP_ACTIVE_DOCUMENT); + objects_query_strokewidth (objects, &tmp_style); if (sel_style_for_width) { - match = (sel_style_for_width->stroke_width.computed == iter_style_for_width->stroke_width.computed); + match = (sel_style_for_width->stroke_width.computed == tmp_style.stroke_width.computed); } g_slist_free(objects); } } - else if (type == SP_STROKE_STYLE_DASHES ) { + match_g = match_g && match; + if (type == SP_STROKE_STYLE_DASHES|| type == SP_STROKE_STYLE_ALL || type==SP_STYLE_ALL) { match = (sel_style->stroke_dasharray.set == iter_style->stroke_dasharray.set); if (sel_style->stroke_dasharray.set && iter_style->stroke_dasharray.set) { match = (sel_style->stroke_dasharray.values == iter_style->stroke_dasharray.values); } } - else if (type == SP_STROKE_STYLE_MARKERS) { + match_g = match_g && match; + if (type == SP_STROKE_STYLE_MARKERS|| type == SP_STROKE_STYLE_ALL|| type==SP_STYLE_ALL) { match = true; int len = sizeof(sel_style->marker)/sizeof(SPIString); for (int i = 0; i < len; i++) { @@ -2156,8 +2141,9 @@ GSList *sp_get_same_stroke_style(SPItem *sel, GSList *src, SPSelectStrokeStyleTy } } } - - if (match) { + match_g = match_g && match; + if (match_g) { + while (iter->cloned) iter=dynamic_cast<SPItem *>(iter->parent); matches = g_slist_prepend(matches, iter); } } else { @@ -2165,6 +2151,7 @@ GSList *sp_get_same_stroke_style(SPItem *sel, GSList *src, SPSelectStrokeStyleTy } } + if( sel_style_for_width != NULL ) delete sel_style_for_width; g_slist_free(objects); return matches; @@ -2209,7 +2196,7 @@ sp_selection_rotate_screen(Inkscape::Selection *selection, gdouble angle) sp_selection_rotate_relative(selection, *center, zangle); - DocumentUndo::maybeDone(sp_desktop_document(selection->desktop()), + DocumentUndo::maybeDone(selection->desktop()->getDocument(), ( (angle > 0) ? "selector:rotate:ccw" : "selector:rotate:cw" ), @@ -2239,7 +2226,7 @@ sp_selection_scale(Inkscape::Selection *selection, gdouble grow) double const times = 1.0 + grow / max_len; sp_selection_scale_relative(selection, center, Geom::Scale(times, times)); - DocumentUndo::maybeDone(sp_desktop_document(selection->desktop()), + DocumentUndo::maybeDone(selection->desktop()->getDocument(), ( (grow > 0) ? "selector:scale:larger" : "selector:scale:smaller" ), @@ -2268,7 +2255,7 @@ sp_selection_scale_times(Inkscape::Selection *selection, gdouble times) Geom::Point const center(sel_bbox->midpoint()); sp_selection_scale_relative(selection, center, Geom::Scale(times, times)); - DocumentUndo::done(sp_desktop_document(selection->desktop()), SP_VERB_CONTEXT_SELECT, + DocumentUndo::done(selection->desktop()->getDocument(), SP_VERB_CONTEXT_SELECT, _("Scale by whole factor")); } @@ -2380,7 +2367,7 @@ void sp_selection_item_next(SPDesktop *desktop) { g_return_if_fail(desktop != NULL); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); PrefsSelectionContext inlayer = (PrefsSelectionContext)prefs->getInt("/options/kbselection/inlayer", PREFS_SELECTION_LAYER); @@ -2407,10 +2394,10 @@ sp_selection_item_next(SPDesktop *desktop) void sp_selection_item_prev(SPDesktop *desktop) { - SPDocument *document = sp_desktop_document(desktop); + SPDocument *document = desktop->getDocument(); g_return_if_fail(document != NULL); g_return_if_fail(desktop != NULL); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); PrefsSelectionContext inlayer = (PrefsSelectionContext) prefs->getInt("/options/kbselection/inlayer", PREFS_SELECTION_LAYER); @@ -2438,7 +2425,7 @@ void sp_selection_next_patheffect_param(SPDesktop * dt) { if (!dt) return; - Inkscape::Selection *selection = sp_desktop_selection(dt); + Inkscape::Selection *selection = dt->getSelection(); if ( selection && !selection->isEmpty() ) { SPItem *item = selection->singleItem(); if ( SPLPEItem *lpeitem = dynamic_cast<SPLPEItem*>(item) ) { @@ -2471,7 +2458,7 @@ void sp_selection_edit_clip_or_mask(SPDesktop * /*dt*/, bool /*clip*/) /*if (!dt) return; using namespace Inkscape::UI; - Inkscape::Selection *selection = sp_desktop_selection(dt); + Inkscape::Selection *selection = dt->getSelection(); if (!selection || selection->isEmpty()) return; GSList const *items = selection->itemList(); @@ -2611,7 +2598,7 @@ void sp_selection_clone(SPDesktop *desktop) return; } - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); @@ -2652,7 +2639,7 @@ void sp_selection_clone(SPDesktop *desktop) Inkscape::GC::release(clone); } - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_EDIT_CLONE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_CLONE, C_("Action", "Clone")); selection->setReprList(newsel); @@ -2666,7 +2653,7 @@ sp_selection_relink(SPDesktop *desktop) if (!desktop) return; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (selection->isEmpty()) { desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>clones</b> to relink.")); @@ -2701,7 +2688,7 @@ sp_selection_relink(SPDesktop *desktop) if (!relinked) { desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("<b>No clones to relink</b> in the selection.")); } else { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_EDIT_UNLINK_CLONE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_UNLINK_CLONE, _("Relink clone")); } } @@ -2713,7 +2700,7 @@ sp_selection_unlink(SPDesktop *desktop) if (!desktop) return; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (selection->isEmpty()) { desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>clones</b> to unlink.")); @@ -2775,7 +2762,7 @@ sp_selection_unlink(SPDesktop *desktop) desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("<b>No clones to unlink</b> in the selection.")); } - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_EDIT_UNLINK_CLONE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_UNLINK_CLONE, _("Unlink clone")); } @@ -2785,7 +2772,7 @@ sp_select_clone_original(SPDesktop *desktop) if (desktop == NULL) return; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); SPItem *item = selection->singleItem(); @@ -2860,7 +2847,7 @@ sp_select_clone_original(SPDesktop *desktop) curve->moveto(a->midpoint()); curve->lineto(b->midpoint()); - SPCanvasItem * canvasitem = sp_canvas_bpath_new(sp_desktop_tempgroup(desktop), curve); + SPCanvasItem * canvasitem = sp_canvas_bpath_new(desktop->getTempGroup(), curve); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(canvasitem), 0x0000ddff, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT, 5, 3); sp_canvas_item_show(canvasitem); curve->unref(); @@ -2884,17 +2871,19 @@ void sp_selection_clone_original_path_lpe(SPDesktop *desktop) if (desktop == NULL) { return; } - + + Inkscape::Selection *selection = desktop->getSelection(); + Inkscape::SVGOStringStream os; SPObject * firstItem = NULL; - for (const GSList * item = desktop->selection->itemList(); item != NULL; item = item->next) { + for (const GSList * item = selection->itemList(); item != NULL; item = item->next) { if (SP_IS_SHAPE(item->data) || SP_IS_TEXT(item->data)) { if (firstItem) { os << "|"; } else { firstItem = SP_ITEM(item->data); } - os << "#" << SP_ITEM(item->data)->getId() << ",0"; + os << '#' << SP_ITEM(item->data)->getId() << ",0"; } } if (firstItem) { @@ -2905,10 +2894,10 @@ void sp_selection_clone_original_path_lpe(SPDesktop *desktop) Inkscape::XML::Node *lpe_repr = xml_doc->createElement("inkscape:path-effect"); { lpe_repr->setAttribute("effect", "fill_between_many"); - lpe_repr->setAttribute("linkedpaths", os.str().c_str()); + lpe_repr->setAttribute("linkedpaths", os.str()); desktop->doc()->getDefs()->getRepr()->addChild(lpe_repr, NULL); // adds to <defs> and assigns the 'id' attribute } - const gchar * lpe_id = lpe_repr->attribute("id"); + std::string lpe_id_href = std::string("#") + lpe_repr->attribute("id"); Inkscape::GC::release(lpe_repr); // create the new path @@ -2920,13 +2909,15 @@ void sp_selection_clone_original_path_lpe(SPDesktop *desktop) SPObject *clone_obj = desktop->doc()->getObjectById(clone->attribute("id")); SPLPEItem *clone_lpeitem = dynamic_cast<SPLPEItem *>(clone_obj); if (clone_lpeitem) { - gchar *href = g_strdup_printf("#%s", lpe_id); - clone_lpeitem->addPathEffect(href, false); - g_free(href); + clone_lpeitem->addPathEffect(lpe_id_href, false); } } - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_EDIT_CLONE_ORIGINAL_PATH_LPE, _("Fill between many")); + DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_CLONE_ORIGINAL_PATH_LPE, _("Fill between many")); + // select the new object: + selection->set(clone); + + Inkscape::GC::release(clone); } else { desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select path(s) to fill.")); } @@ -2939,10 +2930,10 @@ void sp_selection_to_marker(SPDesktop *desktop, bool apply) return; } - SPDocument *doc = sp_desktop_document(desktop); + SPDocument *doc = desktop->getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); // check if something is selected if (selection->isEmpty()) { @@ -3040,8 +3031,8 @@ void sp_selection_to_guides(SPDesktop *desktop) if (desktop == NULL) return; - SPDocument *doc = sp_desktop_document(desktop); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + SPDocument *doc = desktop->getDocument(); + Inkscape::Selection *selection = desktop->getSelection(); // we need to copy the list because it gets reset when objects are deleted GSList *items = g_slist_copy(const_cast<GSList *>(selection->itemList())); @@ -3098,10 +3089,10 @@ void sp_selection_symbol(SPDesktop *desktop, bool /*apply*/ ) return; } - SPDocument *doc = sp_desktop_document(desktop); + SPDocument *doc = desktop->getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); // Check if something is selected. if (selection->isEmpty()) { @@ -3172,9 +3163,9 @@ void sp_selection_symbol(SPDesktop *desktop, bool /*apply*/ ) the_group->getAttribute("inkscape:transform-center-y")); the_group->setAttribute("style", NULL); - std::string id = symbol_repr->attribute("id"); + Glib::ustring id = symbol_repr->attribute("id"); id += "_transform"; - the_group->setAttribute("id", id.c_str()); + the_group->setAttribute("id", id); } @@ -3192,10 +3183,7 @@ void sp_selection_symbol(SPDesktop *desktop, bool /*apply*/ ) // Create <use> pointing to new symbol (to replace the moved objects). Inkscape::XML::Node *clone = xml_doc->createElement("svg:use"); - const gchar *symbol_id = symbol_repr->attribute("id"); - gchar *href_str = g_strdup_printf("#%s", symbol_id); - clone->setAttribute("xlink:href", href_str, false); - g_free(href_str); + clone->setAttribute("xlink:href", Glib::ustring("#")+symbol_repr->attribute("id"), false); the_parent_repr->appendChild(clone); @@ -3223,10 +3211,10 @@ void sp_selection_unsymbol(SPDesktop *desktop) return; } - SPDocument *doc = sp_desktop_document(desktop); + SPDocument *doc = desktop->getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); // Check if something is selected. if (selection->isEmpty()) { @@ -3286,11 +3274,11 @@ void sp_selection_unsymbol(SPDesktop *desktop) // Need to delete <symbol>; all <use> elements that referenced <symbol> should // auto-magically reference <g> (if <symbol> deleted after setting <g> 'id'). Glib::ustring id = symbol->getAttribute("id"); - group->setAttribute("id",id.c_str()); + group->setAttribute("id", id); symbol->deleteObject(true); // Change selection to new <g> element. - SPItem *group_item = static_cast<SPItem *>(sp_desktop_document(desktop)->getObjectByRepr(group)); + SPItem *group_item = static_cast<SPItem *>(desktop->getDocument()->getObjectByRepr(group)); selection->set(group_item); // Clean up @@ -3308,10 +3296,10 @@ sp_selection_tile(SPDesktop *desktop, bool apply) return; } - SPDocument *doc = sp_desktop_document(desktop); + SPDocument *doc = desktop->getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); // check if something is selected if (selection->isEmpty()) { @@ -3403,7 +3391,7 @@ sp_selection_tile(SPDesktop *desktop, bool apply) // restore parent and position parent->getRepr()->appendChild(rect); rect->setPosition(pos > 0 ? pos : 0); - SPItem *rectangle = static_cast<SPItem *>(sp_desktop_document(desktop)->getObjectByRepr(rect)); + SPItem *rectangle = static_cast<SPItem *>(desktop->getDocument()->getObjectByRepr(rect)); Inkscape::GC::release(rect); @@ -3423,10 +3411,10 @@ void sp_selection_untile(SPDesktop *desktop) return; } - SPDocument *doc = sp_desktop_document(desktop); + SPDocument *doc = desktop->getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); // check if something is selected if (selection->isEmpty()) { @@ -3493,7 +3481,7 @@ void sp_selection_untile(SPDesktop *desktop) if (!did) { desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("<b>No pattern fills</b> in the selection.")); } else { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_EDIT_UNTILE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_UNTILE, _("Pattern to objects")); selection->setList(new_select); } @@ -3578,10 +3566,10 @@ void sp_selection_create_bitmap_copy(SPDesktop *desktop) return; } - SPDocument *document = sp_desktop_document(desktop); + SPDocument *document = desktop->getDocument(); Inkscape::XML::Document *xml_doc = document->getReprDoc(); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); // check if something is selected if (selection->isEmpty()) { @@ -3628,7 +3616,7 @@ void sp_selection_create_bitmap_copy(SPDesktop *desktop) directory = g_path_get_dirname( document->getURI() ); } if (directory == NULL) { - directory = homedir_path(NULL); + directory = INKSCAPE.homedir_path(NULL); } gchar *filepath = g_build_filename(directory, basename, NULL); g_free(directory); @@ -3796,10 +3784,10 @@ void sp_selection_set_clipgroup(SPDesktop *desktop) if (desktop == NULL) { return; } - SPDocument* doc = sp_desktop_document(desktop); + SPDocument* doc = desktop->getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (selection->isEmpty()) { desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to create clippath or mask from.")); return; @@ -3912,10 +3900,10 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_ return; } - SPDocument *doc = sp_desktop_document(desktop); + SPDocument *doc = desktop->getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); // check if something is selected bool is_empty = selection->isEmpty(); @@ -4084,9 +4072,7 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_ Inkscape::GC::release(group); } - gchar *value_str = g_strdup_printf("url(#%s)", mask_id); - apply_mask_to->setAttribute(attributeName, value_str); - g_free(value_str); + apply_mask_to->setAttribute(attributeName, Glib::ustring("url(#") + mask_id + ')'); } @@ -4117,9 +4103,9 @@ void sp_selection_unset_mask(SPDesktop *desktop, bool apply_clip_path) { return; } - SPDocument *doc = sp_desktop_document(desktop); + SPDocument *doc = desktop->getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); // check if something is selected if (selection->isEmpty()) { @@ -4210,7 +4196,7 @@ void sp_selection_unset_mask(SPDesktop *desktop, bool apply_clip_path) { parent->appendChild(repr); repr->setPosition((pos + 1) > 0 ? (pos + 1) : 0); - SPItem *mask_item = static_cast<SPItem *>(sp_desktop_document(desktop)->getObjectByRepr(repr)); + SPItem *mask_item = static_cast<SPItem *>(desktop->getDocument()->getObjectByRepr(repr)); items_to_select = g_slist_prepend(items_to_select, mask_item); // transform mask, so it is moved the same spot where mask was applied @@ -4258,7 +4244,7 @@ bool fit_canvas_to_selection(SPDesktop *desktop, bool with_margins) { g_return_val_if_fail(desktop != NULL, false); - SPDocument *doc = sp_desktop_document(desktop); + SPDocument *doc = desktop->getDocument(); g_return_val_if_fail(doc != NULL, false); g_return_val_if_fail(desktop->selection != NULL, false); @@ -4283,7 +4269,7 @@ void verb_fit_canvas_to_selection(SPDesktop *const desktop) { if (fit_canvas_to_selection(desktop)) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_FIT_CANVAS_TO_SELECTION, + DocumentUndo::done(desktop->getDocument(), SP_VERB_FIT_CANVAS_TO_SELECTION, _("Fit Page to Selection")); } } @@ -4311,8 +4297,8 @@ fit_canvas_to_drawing(SPDocument *doc, bool with_margins) void verb_fit_canvas_to_drawing(SPDesktop *desktop) { - if (fit_canvas_to_drawing(sp_desktop_document(desktop))) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_FIT_CANVAS_TO_DRAWING, + if (fit_canvas_to_drawing(desktop->getDocument())) { + DocumentUndo::done(desktop->getDocument(), SP_VERB_FIT_CANVAS_TO_DRAWING, _("Fit Page to Drawing")); } } @@ -4324,7 +4310,7 @@ verb_fit_canvas_to_drawing(SPDesktop *desktop) */ void fit_canvas_to_selection_or_drawing(SPDesktop *desktop) { g_return_if_fail(desktop != NULL); - SPDocument *doc = sp_desktop_document(desktop); + SPDocument *doc = desktop->getDocument(); g_return_if_fail(doc != NULL); g_return_if_fail(desktop->selection != NULL); @@ -4333,7 +4319,7 @@ void fit_canvas_to_selection_or_drawing(SPDesktop *desktop) { ? fit_canvas_to_drawing(doc, true) : fit_canvas_to_selection(desktop, true) ); if (changed) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_FIT_CANVAS_TO_SELECTION_OR_DRAWING, + DocumentUndo::done(desktop->getDocument(), SP_VERB_FIT_CANVAS_TO_SELECTION_OR_DRAWING, _("Fit Page to Selection or Drawing")); } }; diff --git a/src/selection-chemistry.h b/src/selection-chemistry.h index d86906548..4ee7a5200 100644 --- a/src/selection-chemistry.h +++ b/src/selection-chemistry.h @@ -136,14 +136,14 @@ enum SPSelectStrokeStyleType { SP_STROKE_COLOR = 1, SP_STROKE_STYLE_WIDTH = 2, SP_STROKE_STYLE_DASHES = 3, - SP_STROKE_STYLE_MARKERS = 4 + SP_STROKE_STYLE_MARKERS = 4, + SP_STROKE_STYLE_ALL = 5, + SP_STYLE_ALL = 6 }; void sp_select_same_fill_stroke_style(SPDesktop *desktop, gboolean fill, gboolean strok, gboolean style); -void sp_select_same_stroke_style(SPDesktop *desktop); void sp_select_same_object_type(SPDesktop *desktop); -GSList *sp_get_same_fill_or_stroke_color(SPItem *sel, GSList *src, SPSelectStrokeStyleType type); -GSList *sp_get_same_stroke_style(SPItem *sel, GSList *src, SPSelectStrokeStyleType type); +GSList *sp_get_same_style(SPItem *sel, GSList *src, SPSelectStrokeStyleType type=SP_STYLE_ALL); GSList *sp_get_same_object_type(SPItem *sel, GSList *src); void scroll_to_show_item(SPDesktop *desktop, SPItem *item); diff --git a/src/selection-describer.cpp b/src/selection-describer.cpp index f7814fd57..2386a731e 100644 --- a/src/selection-describer.cpp +++ b/src/selection-describer.cpp @@ -233,8 +233,8 @@ void SelectionDescriber::_updateMessageFromSelection(Inkscape::Selection *select int n_terms = count_terms((GSList *)items); gchar *objects_str = g_strdup_printf(ngettext( - "<b>%i</b> objects selected of type %s", - "<b>%i</b> objects selected of types %s", n_terms), + "<b>%1$i</b> objects selected of type %2$s", + "<b>%1$i</b> objects selected of types %2$s", n_terms), objcount, terms); g_free(terms); diff --git a/src/selection.cpp b/src/selection.cpp index 17b7253f2..81139d044 100644 --- a/src/selection.cpp +++ b/src/selection.cpp @@ -20,7 +20,7 @@ # include <config.h> #endif #include "macros.h" -#include "inkscape-private.h" +#include "inkscape.h" #include "document.h" #include "layer-model.h" #include "selection.h" @@ -89,7 +89,7 @@ Selection::_emit_modified(Selection *selection) } void Selection::_emitModified(guint flags) { - inkscape_selection_modified(this, flags); + INKSCAPE.selection_modified(this, flags); _modified_signal.emit(this, flags); } @@ -104,7 +104,7 @@ void Selection::_emitChanged(bool persist_selection_context/* = false */) { _releaseContext(_selection_context); } - inkscape_selection_changed(this); + INKSCAPE.selection_changed(this); _changed_signal.emit(this); } diff --git a/src/selection.h b/src/selection.h index 5964b20e8..19e2ae1fd 100644 --- a/src/selection.h +++ b/src/selection.h @@ -19,10 +19,10 @@ #include <stddef.h> #include <sigc++/sigc++.h> -#include "gc-managed.h" +#include "inkgc/gc-managed.h" #include "gc-finalized.h" #include "gc-anchored.h" -#include "gc-soft-ptr.h" +#include "inkgc/gc-soft-ptr.h" #include "sp-item.h" diff --git a/src/seltrans.cpp b/src/seltrans.cpp index a9ae9e465..5e4c0642e 100644 --- a/src/seltrans.cpp +++ b/src/seltrans.cpp @@ -26,7 +26,7 @@ #include "document-undo.h" #include "sp-namedview.h" #include "desktop.h" -#include "desktop-handles.h" + #include "desktop-style.h" #include "knot.h" #include "message-stack.h" @@ -131,9 +131,9 @@ Inkscape::SelTrans::SelTrans(SPDesktop *desktop) : _makeHandles(); _updateHandles(); - _selection = sp_desktop_selection(desktop); + _selection = desktop->getSelection(); - _norm = sp_canvas_item_new(sp_desktop_controls(desktop), + _norm = sp_canvas_item_new(desktop->getControls(), SP_TYPE_CTRL, "anchor", SP_ANCHOR_CENTER, "mode", SP_CTRL_MODE_COLOR, @@ -146,7 +146,7 @@ Inkscape::SelTrans::SelTrans(SPDesktop *desktop) : "pixbuf", handles[12], NULL); - _grip = sp_canvas_item_new(sp_desktop_controls(desktop), + _grip = sp_canvas_item_new(desktop->getControls(), SP_TYPE_CTRL, "anchor", SP_ANCHOR_CENTER, "mode", SP_CTRL_MODE_XOR, @@ -163,7 +163,7 @@ Inkscape::SelTrans::SelTrans(SPDesktop *desktop) : sp_canvas_item_hide(_norm); for (int i = 0; i < 4; i++) { - _l[i] = ControlManager::getManager().createControlLine(sp_desktop_controls(desktop)); + _l[i] = ControlManager::getManager().createControlLine(desktop->getControls()); sp_canvas_item_hide(_l[i]); } @@ -252,7 +252,7 @@ void Inkscape::SelTrans::grab(Geom::Point const &p, gdouble x, gdouble y, bool s { // While dragging a handle, we will either scale, skew, or rotate and the "translating" parameter will be false // When dragging the selected item itself however, we will translate the selection and that parameter will be true - Inkscape::Selection *selection = sp_desktop_selection(_desktop); + Inkscape::Selection *selection = _desktop->getSelection(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); g_return_if_fail(!_grabbed); @@ -418,7 +418,7 @@ void Inkscape::SelTrans::ungrab() _desktop->snapindicator->remove_snapsource(); - Inkscape::Selection *selection = sp_desktop_selection(_desktop); + Inkscape::Selection *selection = _desktop->getSelection(); _updateVolatileState(); for (unsigned i = 0; i < _items.size(); i++) { @@ -473,16 +473,16 @@ void Inkscape::SelTrans::ungrab() // when trying to stretch a perfectly vertical line in horizontal direction, which will not be allowed // by the handles; this would be identified as a (zero) translation by isTranslation() if (_current_relative_affine.isTranslation()) { - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_CONTEXT_SELECT, _("Move")); } else if (_current_relative_affine.withoutTranslation().isScale()) { - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_CONTEXT_SELECT, _("Scale")); } else if (_current_relative_affine.withoutTranslation().isRotation()) { - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_CONTEXT_SELECT, _("Rotate")); } else { - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_CONTEXT_SELECT, _("Skew")); } } @@ -495,7 +495,7 @@ void Inkscape::SelTrans::ungrab() SPItem *it = SP_ITEM(l->data); it->updateRepr(); } - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_CONTEXT_SELECT, _("Set center")); } @@ -512,7 +512,7 @@ void Inkscape::SelTrans::ungrab() void Inkscape::SelTrans::stamp() { - Inkscape::Selection *selection = sp_desktop_selection(_desktop); + Inkscape::Selection *selection = _desktop->getSelection(); bool fixup = !_grabbed; if ( fixup && _stamp_cache ) { @@ -549,7 +549,7 @@ void Inkscape::SelTrans::stamp() // move to the saved position copy_repr->setPosition(pos > 0 ? pos : 0); - SPItem *copy_item = (SPItem *) sp_desktop_document(_desktop)->getObjectByRepr(copy_repr); + SPItem *copy_item = (SPItem *) _desktop->getDocument()->getObjectByRepr(copy_repr); Geom::Affine const *new_affine; if (_show == SHOW_OUTLINE) { @@ -570,7 +570,7 @@ void Inkscape::SelTrans::stamp() Inkscape::GC::release(copy_repr); l = l->next; } - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_CONTEXT_SELECT, _("Stamp")); } @@ -606,7 +606,7 @@ void Inkscape::SelTrans::_updateHandles() void Inkscape::SelTrans::_updateVolatileState() { - Inkscape::Selection *selection = sp_desktop_selection(_desktop); + Inkscape::Selection *selection = _desktop->getSelection(); _empty = selection->isEmpty(); if (_empty) { @@ -719,7 +719,7 @@ void Inkscape::SelTrans::handleClick(SPKnot */*knot*/, guint state, SPSelTransHa _center_is_set = false; // center has changed _updateHandles(); } - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_CONTEXT_SELECT, _("Reset center")); } break; diff --git a/src/shortcuts.cpp b/src/shortcuts.cpp index 1e43c98c6..e72c16de0 100644 --- a/src/shortcuts.cpp +++ b/src/shortcuts.cpp @@ -211,7 +211,7 @@ Inkscape::XML::Document *sp_shortcut_create_template_file(char const *filename) void sp_shortcut_get_file_names(std::vector<Glib::ustring> *names, std::vector<Glib::ustring> *paths) { std::list<gchar *> sources; - sources.push_back( profile_path("keys") ); + sources.push_back( Inkscape::Application::profile_path("keys") ); sources.push_back( g_strdup(INKSCAPE_KEYSDIR) ); // loop through possible keyboard shortcut file locations. @@ -229,7 +229,7 @@ void sp_shortcut_get_file_names(std::vector<Glib::ustring> *names, std::vector<G gchar *filename = 0; while ((filename = (gchar *) g_dir_read_name(directory)) != NULL) { gchar* lower = g_ascii_strdown(filename, -1); - if (!strcmp(dirname, profile_path("keys")) && + if (!strcmp(dirname, Inkscape::Application::profile_path("keys")) && !strcmp(lower, "default.xml")) { // Dont add the users custom keys file continue; diff --git a/src/snap.cpp b/src/snap.cpp index 8138e4546..96b5ab53c 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -33,7 +33,7 @@ #include "sp-guide.h" #include "preferences.h" #include "ui/tools/tool-base.h" -#include "util/mathfns.h" +#include "helper/mathfns.h" using std::vector; using Inkscape::Util::round_to_upper_multiple_plus; using Inkscape::Util::round_to_lower_multiple_plus; diff --git a/src/sp-anchor.cpp b/src/sp-anchor.cpp index 7b558bf08..78ba10c13 100644 --- a/src/sp-anchor.cpp +++ b/src/sp-anchor.cpp @@ -13,10 +13,6 @@ #define noSP_ANCHOR_VERBOSE -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include <glibmm/i18n.h> #include "xml/quote.h" #include "xml/repr.h" @@ -25,16 +21,6 @@ #include "ui/view/view.h" #include "document.h" -#include "sp-factory.h" - -namespace { - SPObject* createAnchor() { - return new SPAnchor(); - } - - bool anchorRegistered = SPFactory::instance().registerObject("svg:a", createAnchor); -} - SPAnchor::SPAnchor() : SPGroup() { this->href = NULL; } diff --git a/src/sp-clippath.cpp b/src/sp-clippath.cpp index 8e2e7d7a6..3c6167438 100644 --- a/src/sp-clippath.cpp +++ b/src/sp-clippath.cpp @@ -40,16 +40,6 @@ struct SPClipPathView { static SPClipPathView* sp_clippath_view_new_prepend(SPClipPathView *list, unsigned int key, Inkscape::DrawingItem *arenaitem); static SPClipPathView* sp_clippath_view_list_remove(SPClipPathView *list, SPClipPathView *view); -#include "sp-factory.h" - -namespace { - SPObject* createClipPath() { - return new SPClipPath(); - } - - bool clipPathRegistered = SPFactory::instance().registerObject("svg:clipPath", createClipPath); -} - SPClipPath::SPClipPath() : SPObjectGroup() { this->clipPathUnits_set = FALSE; this->clipPathUnits = SP_CONTENT_UNITS_USERSPACEONUSE; @@ -103,7 +93,7 @@ void SPClipPath::set(unsigned int key, const gchar* value) { break; default: if (SP_ATTRIBUTE_IS_CSS(key)) { - sp_style_read_from_object(this->style, this); + this->style->readFromObject( this ); this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); } else { SPObjectGroup::set(key, value); diff --git a/src/sp-defs.cpp b/src/sp-defs.cpp index 334570076..8dd695867 100644 --- a/src/sp-defs.cpp +++ b/src/sp-defs.cpp @@ -20,16 +20,6 @@ #include "xml/repr.h" #include "document.h" -#include "sp-factory.h" - -namespace { - SPObject* createDefs() { - return new SPDefs(); - } - - bool defsRegistered = SPFactory::instance().registerObject("svg:defs", createDefs); -} - SPDefs::SPDefs() : SPObject() { } diff --git a/src/sp-desc.cpp b/src/sp-desc.cpp index 199ae0176..3c75d087a 100644 --- a/src/sp-desc.cpp +++ b/src/sp-desc.cpp @@ -9,23 +9,9 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include "sp-desc.h" #include "xml/repr.h" -#include "sp-factory.h" - -namespace { - SPObject* createDesc() { - return new SPDesc(); - } - - bool descRegistered = SPFactory::instance().registerObject("svg:desc", createDesc); -} - SPDesc::SPDesc() : SPObject() { } diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp index a74d4687d..932a3a1b7 100644 --- a/src/sp-ellipse.cpp +++ b/src/sp-ellipse.cpp @@ -34,35 +34,6 @@ #include "svg/path-string.h" #include "xml/repr.h" -#include "sp-factory.h" - -namespace { -SPObject *create_ellipse() -{ - SPGenericEllipse *ellipse = new SPGenericEllipse(); - ellipse->type = SP_GENERIC_ELLIPSE_ELLIPSE; - return ellipse; -} - -SPObject *create_circle() -{ - SPGenericEllipse *circle = new SPGenericEllipse(); - circle->type = SP_GENERIC_ELLIPSE_CIRCLE; - return circle; -} - -SPObject *create_arc() -{ - SPGenericEllipse *arc = new SPGenericEllipse(); - arc->type = SP_GENERIC_ELLIPSE_ARC; - return arc; -} - -bool ellipse_registered = SPFactory::instance().registerObject("svg:ellipse", create_ellipse); -bool circle_registered = SPFactory::instance().registerObject("svg:circle", create_circle); -bool arc_registered = SPFactory::instance().registerObject("arc", create_arc); -} - #ifndef M_PI #define M_PI 3.14159265358979323846 @@ -124,6 +95,10 @@ void SPGenericEllipse::build(SPDocument *document, Inkscape::XML::Node *repr) std::cerr << "SPGenericEllipse::build() unknown defined type." << std::endl; } + // std::cout << " cx: " << cx.write() << std::endl; + // std::cout << " cy: " << cy.write() << std::endl; + // std::cout << " rx: " << rx.write() << std::endl; + // std::cout << " ry: " << ry.write() << std::endl; SPShape::build(document, repr); } @@ -132,29 +107,41 @@ void SPGenericEllipse::set(unsigned int key, gchar const *value) // There are multiple ways to set internal cx, cy, rx, and ry (via SVG attributes or Sodipodi // attributes) thus we don't want to unset them if a read fails (e.g., when we explicitly clear // an attribute by setting it to NULL). + + // We must update the SVGLengths immediately or nodes may be misplaced after they are moved. + double const w = viewport.width(); + double const h = viewport.height(); + double const d = hypot(w, h) / sqrt(2); // diagonal + double const em = style->font_size.computed; + double const ex = em * 0.5; + SVGLength t; switch (key) { case SP_ATTR_CX: case SP_ATTR_SODIPODI_CX: if( t.read(value) ) cx = t; + cx.update( em, ex, w ); this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; case SP_ATTR_CY: case SP_ATTR_SODIPODI_CY: if( t.read(value) ) cy = t; + cy.update( em, ex, h ); this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; case SP_ATTR_RX: case SP_ATTR_SODIPODI_RX: - if( t.read(value) && t.value > 0.0 ) this->rx = t; + if( t.read(value) && t.value > 0.0 ) rx = t; + rx.update( em, ex, w ); this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; case SP_ATTR_RY: case SP_ATTR_SODIPODI_RY: - if( t.read(value) && t.value > 0.0 ) this->ry = t; + if( t.read(value) && t.value > 0.0 ) ry = t; + ry.update( em, ex, h ); this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; @@ -162,6 +149,8 @@ void SPGenericEllipse::set(unsigned int key, gchar const *value) if( t.read(value) && t.value > 0.0 ) { this->ry = this->rx = t; } + rx.update( em, ex, d ); + ry.update( em, ex, d ); this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; @@ -225,7 +214,7 @@ Inkscape::XML::Node *SPGenericEllipse::write(Inkscape::XML::Document *xml_doc, I // << ")" << std::endl; GenericEllipseType new_type = SP_GENERIC_ELLIPSE_UNDEFINED; - if (this->_isSlice() || hasPathEffect() ) { + if (_isSlice() || hasPathEffect() ) { new_type = SP_GENERIC_ELLIPSE_ARC; } else if ( rx.computed == ry.computed ) { new_type = SP_GENERIC_ELLIPSE_CIRCLE; @@ -275,10 +264,10 @@ Inkscape::XML::Node *SPGenericEllipse::write(Inkscape::XML::Document *xml_doc, I } // std::cout << " type: " << g_quark_to_string( repr->code() ) << std::endl; - // std::cout << " cx: " << cx.computed - // << " cy: " << cy.computed - // << " rx: " << rx.computed - // << " ry: " << ry.computed << std::endl; + // std::cout << " cx: " << cx.write() << " " << cx.computed + // << " cy: " << cy.write() << " " << cy.computed + // << " rx: " << rx.write() << " " << rx.computed + // << " ry: " << ry.write() << " " << ry.computed << std::endl; switch ( type ) { case SP_GENERIC_ELLIPSE_UNDEFINED: @@ -293,17 +282,17 @@ Inkscape::XML::Node *SPGenericEllipse::write(Inkscape::XML::Document *xml_doc, I if (flags & SP_OBJECT_WRITE_EXT) { repr->setAttribute("sodipodi:type", "arc"); - sp_repr_set_svg_double(repr, "sodipodi:cx", this->cx.computed); - sp_repr_set_svg_double(repr, "sodipodi:cy", this->cy.computed); - sp_repr_set_svg_double(repr, "sodipodi:rx", this->rx.computed); - sp_repr_set_svg_double(repr, "sodipodi:ry", this->ry.computed); + sp_repr_set_svg_length(repr, "sodipodi:cx", cx); + sp_repr_set_svg_length(repr, "sodipodi:cy", cy); + sp_repr_set_svg_length(repr, "sodipodi:rx", rx); + sp_repr_set_svg_length(repr, "sodipodi:ry", ry); // write start and end only if they are non-trivial; otherwise remove - if (this->_isSlice()) { - sp_repr_set_svg_double(repr, "sodipodi:start", this->start); - sp_repr_set_svg_double(repr, "sodipodi:end", this->end); + if (_isSlice()) { + sp_repr_set_svg_double(repr, "sodipodi:start", start); + sp_repr_set_svg_double(repr, "sodipodi:end", end); - repr->setAttribute("sodipodi:open", (!this->_closed) ? "true" : NULL); + repr->setAttribute("sodipodi:open", (!_closed) ? "true" : NULL); } else { repr->setAttribute("sodipodi:end", NULL); repr->setAttribute("sodipodi:start", NULL); @@ -312,13 +301,13 @@ Inkscape::XML::Node *SPGenericEllipse::write(Inkscape::XML::Document *xml_doc, I } // write d= - this->set_elliptical_path_attribute(repr); + set_elliptical_path_attribute(repr); break; case SP_GENERIC_ELLIPSE_CIRCLE: - sp_repr_set_svg_double(repr, "cx", this->cx.computed); - sp_repr_set_svg_double(repr, "cy", this->cy.computed); - sp_repr_set_svg_double(repr, "r", this->rx.computed); + sp_repr_set_svg_length(repr, "cx", cx); + sp_repr_set_svg_length(repr, "cy", cy); + sp_repr_set_svg_length(repr, "r", rx); repr->setAttribute("rx", NULL ); repr->setAttribute("ry", NULL ); repr->setAttribute("sodipodi:cx", NULL ); @@ -333,10 +322,10 @@ Inkscape::XML::Node *SPGenericEllipse::write(Inkscape::XML::Document *xml_doc, I break; case SP_GENERIC_ELLIPSE_ELLIPSE: - sp_repr_set_svg_double(repr, "cx", this->cx.computed); - sp_repr_set_svg_double(repr, "cy", this->cy.computed); - sp_repr_set_svg_double(repr, "rx", this->rx.computed); - sp_repr_set_svg_double(repr, "ry", this->ry.computed); + sp_repr_set_svg_length(repr, "cx", cx); + sp_repr_set_svg_length(repr, "cy", cy); + sp_repr_set_svg_length(repr, "rx", rx); + sp_repr_set_svg_length(repr, "ry", ry); repr->setAttribute("r", NULL ); repr->setAttribute("sodipodi:cx", NULL ); repr->setAttribute("sodipodi:cy", NULL ); @@ -353,11 +342,10 @@ Inkscape::XML::Node *SPGenericEllipse::write(Inkscape::XML::Document *xml_doc, I std::cerr << "SPGenericEllipse::write: unknown type." << std::endl; } - this->set_shape(); // evaluate SPCurve + set_shape(); // evaluate SPCurve SPShape::write(xml_doc, repr, flags); - // std::cout << "SPGenericEllipse::write: Exit: " << g_quark_to_string(repr->code()) << "\n" << std::endl; return repr; } @@ -368,8 +356,8 @@ const char *SPGenericEllipse::displayName() const case SP_GENERIC_ELLIPSE_UNDEFINED: case SP_GENERIC_ELLIPSE_ARC: - if (this->_isSlice()) { - if (this->_closed) { + if (_isSlice()) { + if (_closed) { return _("Segment"); } else { return _("Arc"); @@ -509,11 +497,11 @@ Geom::Affine SPGenericEllipse::set_transform(Geom::Affine const &xform) } if (this->rx._set) { - this->rx = this->rx.computed * sw; + this->rx.scale( sw ); } if (this->ry._set) { - this->ry = this->ry.computed * sh; + this->ry.scale( sh ); } /* Find start in item coords */ @@ -657,10 +645,10 @@ bool SPGenericEllipse::set_elliptical_path_attribute(Inkscape::XML::Node *repr) void SPGenericEllipse::position_set(gdouble x, gdouble y, gdouble rx, gdouble ry) { - this->cx.computed = x; - this->cy.computed = y; - this->rx.computed = rx; - this->ry.computed = ry; + this->cx = x; + this->cy = y; + this->rx = rx; + this->ry = ry; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); diff --git a/src/sp-factory.cpp b/src/sp-factory.cpp new file mode 100644 index 000000000..e48646f8d --- /dev/null +++ b/src/sp-factory.cpp @@ -0,0 +1,337 @@ +/* + * Factory for SPObject tree + * + * Authors: + * Markus Engel + * + * Copyright (C) 2013 Authors + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "sp-factory.h" + +// primary +#include "box3d.h" +#include "box3d-side.h" +#include "color-profile.h" +#include "persp3d.h" +#include "sp-anchor.h" +#include "sp-clippath.h" +#include "sp-defs.h" +#include "sp-desc.h" +#include "sp-ellipse.h" +#include "sp-filter.h" +#include "sp-flowdiv.h" +#include "sp-flowregion.h" +#include "sp-flowtext.h" +#include "sp-font.h" +#include "sp-font-face.h" +#include "sp-glyph.h" +#include "sp-guide.h" +#include "sp-hatch.h" +#include "sp-hatch-path.h" +#include "sp-image.h" +#include "sp-item-group.h" +#include "sp-line.h" +#include "sp-linear-gradient.h" +#include "sp-marker.h" +#include "sp-mask.h" +#include "sp-mesh.h" +#include "sp-mesh-patch.h" +#include "sp-mesh-row.h" +#include "sp-metadata.h" +#include "sp-missing-glyph.h" +#include "sp-namedview.h" +#include "sp-object.h" +#include "sp-offset.h" +#include "sp-path.h" +#include "sp-pattern.h" +#include "sp-polygon.h" +#include "sp-polyline.h" +#include "sp-radial-gradient.h" +#include "sp-rect.h" +#include "sp-root.h" +#include "sp-script.h" +#include "sp-solid-color.h" +#include "sp-spiral.h" +#include "sp-star.h" +#include "sp-stop.h" +#include "sp-string.h" +#include "sp-style-elem.h" +#include "sp-switch.h" +#include "sp-symbol.h" +#include "sp-tag.h" +#include "sp-tag-use.h" +#include "sp-text.h" +#include "sp-textpath.h" +#include "sp-title.h" +#include "sp-tref.h" +#include "sp-tspan.h" +#include "sp-use.h" +#include "live_effects/lpeobject.h" + +// filters +#include "filters/blend.h" +#include "filters/colormatrix.h" +#include "filters/componenttransfer.h" +#include "filters/componenttransfer-funcnode.h" +#include "filters/composite.h" +#include "filters/convolvematrix.h" +#include "filters/diffuselighting.h" +#include "filters/displacementmap.h" +#include "filters/distantlight.h" +#include "filters/flood.h" +#include "filters/gaussian-blur.h" +#include "filters/image.h" +#include "filters/merge.h" +#include "filters/mergenode.h" +#include "filters/morphology.h" +#include "filters/offset.h" +#include "filters/pointlight.h" +#include "filters/specularlighting.h" +#include "filters/spotlight.h" +#include "filters/tile.h" +#include "filters/turbulence.h" + +SPObject *SPFactory::createObject(std::string const& id) +{ + SPObject *ret = NULL; + + if (id == "inkscape:box3d") + ret = new SPBox3D; + else if (id == "inkscape:box3dside") + ret = new Box3DSide; + else if (id == "svg:color-profile") + ret = new Inkscape::ColorProfile; + else if (id == "inkscape:persp3d") + ret = new Persp3D; + else if (id == "svg:a") + ret = new SPAnchor; + else if (id == "svg:clipPath") + ret = new SPClipPath; + else if (id == "svg:defs") + ret = new SPDefs; + else if (id == "svg:desc") + ret = new SPDesc; + else if (id == "svg:ellipse") { + SPGenericEllipse *e = new SPGenericEllipse; + e->type = SP_GENERIC_ELLIPSE_ELLIPSE; + ret = e; + } else if (id == "svg:circle") { + SPGenericEllipse *c = new SPGenericEllipse; + c->type = SP_GENERIC_ELLIPSE_CIRCLE; + ret = c; + } else if (id == "arc") { + SPGenericEllipse *a = new SPGenericEllipse; + a->type = SP_GENERIC_ELLIPSE_ARC; + ret = a; + } + else if (id == "svg:filter") + ret = new SPFilter; + else if (id == "svg:flowDiv") + ret = new SPFlowdiv; + else if (id == "svg:flowSpan") + ret = new SPFlowtspan; + else if (id == "svg:flowPara") + ret = new SPFlowpara; + else if (id == "svg:flowLine") + ret = new SPFlowline; + else if (id == "svg:flowRegionBreak") + ret = new SPFlowregionbreak; + else if (id == "svg:flowRegion") + ret = new SPFlowregion; + else if (id == "svg:flowRegionExclude") + ret = new SPFlowregionExclude; + else if (id == "svg:flowRoot") + ret = new SPFlowtext; + else if (id == "svg:font") + ret = new SPFont; + else if (id == "svg:font-face") + ret = new SPFontFace; + else if (id == "svg:glyph") + ret = new SPGlyph; + else if (id == "sodipodi:guide") + ret = new SPGuide; + else if (id == "svg:hatch") + ret = new SPHatch; + else if (id == "svg:hatchPath") + ret = new SPHatchPath; + else if (id == "svg:image") + ret = new SPImage; + else if (id == "svg:g") + ret = new SPGroup; + else if (id == "svg:line") + ret = new SPLine; + else if (id == "svg:linearGradient") + ret = new SPLinearGradient; + else if (id == "svg:marker") + ret = new SPMarker; + else if (id == "svg:mask") + ret = new SPMask; + else if (id == "svg:mesh") + ret = new SPMesh; + else if (id == "svg:meshpatch") + ret = new SPMeshpatch; + else if (id == "svg:meshrow") + ret = new SPMeshrow; + else if (id == "svg:metadata") + ret = new SPMetadata; + else if (id == "svg:missing-glyph") + ret = new SPMissingGlyph; + else if (id == "sodipodi:namedview") + ret = new SPNamedView; + else if (id == "inkscape:offset") + ret = new SPOffset; + else if (id == "svg:path") + ret = new SPPath; + else if (id == "svg:pattern") + ret = new SPPattern; + else if (id == "svg:polygon") + ret = new SPPolygon; + else if (id == "svg:polyline") + ret = new SPPolyLine; + else if (id == "svg:radialGradient") + ret = new SPRadialGradient; + else if (id == "svg:rect") + ret = new SPRect; + else if (id == "svg:svg") + ret = new SPRoot; + else if (id == "svg:script") + ret = new SPScript; + else if (id == "svg:solidColor") + ret = new SPSolidColor; + else if (id == "spiral") + ret = new SPSpiral; + else if (id == "star") + ret = new SPStar; + else if (id == "svg:stop") + ret = new SPStop; + else if (id == "string") + ret = new SPString; + else if (id == "svg:style") + ret = new SPStyleElem; + else if (id == "svg:switch") + ret = new SPSwitch; + else if (id == "svg:symbol") + ret = new SPSymbol; + else if (id == "inkscape:tag") + ret = new SPTag; + else if (id == "inkscape:tagref") + ret = new SPTagUse; + else if (id == "svg:text") + ret = new SPText; + else if (id == "svg:title") + ret = new SPTitle; + else if (id == "svg:tref") + ret = new SPTRef; + else if (id == "svg:tspan") + ret = new SPTSpan; + else if (id == "svg:textPath") + ret = new SPTextPath; + else if (id == "svg:use") + ret = new SPUse; + else if (id == "inkscape:path-effect") + ret = new LivePathEffectObject; + + + // filters + else if (id == "svg:feBlend") + ret = new SPFeBlend; + else if (id == "svg:feColorMatrix") + ret = new SPFeColorMatrix; + else if (id == "svg:feComponentTransfer") + ret = new SPFeComponentTransfer; + else if (id == "svg:feFuncR") + ret = new SPFeFuncNode(SPFeFuncNode::R); + else if (id == "svg:feFuncG") + ret = new SPFeFuncNode(SPFeFuncNode::G); + else if (id == "svg:feFuncB") + ret = new SPFeFuncNode(SPFeFuncNode::B); + else if (id == "svg:feFuncA") + ret = new SPFeFuncNode(SPFeFuncNode::A); + else if (id == "svg:feComposite") + ret = new SPFeComposite; + else if (id == "svg:feConvolveMatrix") + ret = new SPFeConvolveMatrix; + else if (id == "svg:feDiffuseLighting") + ret = new SPFeDiffuseLighting; + else if (id == "svg:feDisplacementMap") + ret = new SPFeDisplacementMap; + else if (id == "svg:feDistantLight") + ret = new SPFeDistantLight; + else if (id == "svg:feFlood") + ret = new SPFeFlood; + else if (id == "svg:feGaussianBlur") + ret = new SPGaussianBlur; + else if (id == "svg:feImage") + ret = new SPFeImage; + else if (id == "svg:feMerge") + ret = new SPFeMerge; + else if (id == "svg:feMergeNode") + ret = new SPFeMergeNode; + else if (id == "svg:feMorphology") + ret = new SPFeMorphology; + else if (id == "svg:feOffset") + ret = new SPFeOffset; + else if (id == "svg:fePointLight") + ret = new SPFePointLight; + else if (id == "svg:feSpecularLighting") + ret = new SPFeSpecularLighting; + else if (id == "svg:feSpotLight") + ret = new SPFeSpotLight; + else if (id == "svg:feTile") + ret = new SPFeTile; + else if (id == "svg:feTurbulence") + ret = new SPFeTurbulence; + else if (id == "inkscape:grid") + ret = new SPObject; // TODO wtf + else if (id == "rdf:RDF") // no SP node yet + {} + else if (id == "inkscape:clipboard") // SP node not necessary + {} + else if (id.empty()) // comments + {} + else { + fprintf(stderr, "WARNING: unknown type: %s", id.c_str()); + } + + return ret; +} + +std::string NodeTraits::get_type_string(Inkscape::XML::Node const &node) +{ + std::string name; + + switch (node.type()) { + case Inkscape::XML::TEXT_NODE: + name = "string"; + break; + + case Inkscape::XML::ELEMENT_NODE: { + char const *const sptype = node.attribute("sodipodi:type"); + + if (sptype) { + name = sptype; + } else { + name = node.name(); + } + break; + } + default: + name = ""; + break; + } + + return name; +} + +/* + 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/sp-factory.h b/src/sp-factory.h index 0621f77ba..040fd14ae 100644 --- a/src/sp-factory.h +++ b/src/sp-factory.h @@ -1,6 +1,6 @@ -/** @file +/* * Factory for SPObject tree - *//* + * * Authors: * Markus Engel * @@ -11,11 +11,23 @@ #ifndef SP_FACTORY_SEEN #define SP_FACTORY_SEEN -#include "factory.h" +#include <string> class SPObject; -typedef Singleton< Factory<SPObject> > SPFactory; +namespace Inkscape { +namespace XML { +class Node; +} +} + +struct SPFactory { + static SPObject *createObject(std::string const& id); +}; + +struct NodeTraits { + static std::string get_type_string(Inkscape::XML::Node const &node); +}; #endif diff --git a/src/sp-filter.cpp b/src/sp-filter.cpp index 9cb33a6f3..a70fbd5bb 100644 --- a/src/sp-filter.cpp +++ b/src/sp-filter.cpp @@ -41,15 +41,6 @@ using std::pair; static void filter_ref_changed(SPObject *old_ref, SPObject *ref, SPFilter *filter); static void filter_ref_modified(SPObject *href, guint flags, SPFilter *filter); -#include "sp-factory.h" - -namespace { - SPObject* createFilter() { - return new SPFilter(); - } - - bool filterRegistered = SPFactory::instance().registerObject("svg:filter", createFilter); -} SPFilter::SPFilter() : SPObject(), filterUnits(SP_FILTER_UNITS_OBJECTBOUNDINGBOX), filterUnits_set(FALSE), diff --git a/src/sp-flowdiv.cpp b/src/sp-flowdiv.cpp index 00ba48b06..8d9c51ab8 100644 --- a/src/sp-flowdiv.cpp +++ b/src/sp-flowdiv.cpp @@ -1,45 +1,11 @@ /* */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include "xml/repr.h" #include "sp-flowdiv.h" #include "sp-string.h" #include "document.h" -#include "sp-factory.h" - -namespace { - SPObject* createFlowdiv() { - return new SPFlowdiv(); - } - - SPObject* createFlowtspan() { - return new SPFlowtspan(); - } - - SPObject* createFlowpara() { - return new SPFlowpara(); - } - - SPObject* createFlowline() { - return new SPFlowline(); - } - - SPObject* createFlowregionbreak() { - return new SPFlowregionbreak(); - } - - bool flowdivRegistered = SPFactory::instance().registerObject("svg:flowDiv", createFlowdiv); - bool flowtspanRegistered = SPFactory::instance().registerObject("svg:flowSpan", createFlowtspan); - bool flowparaRegistered = SPFactory::instance().registerObject("svg:flowPara", createFlowpara); - bool flowlineRegistered = SPFactory::instance().registerObject("svg:flowLine", createFlowline); - bool flowregionbreakRegistered = SPFactory::instance().registerObject("svg:flowRegionBreak", createFlowregionbreak); -} - SPFlowdiv::SPFlowdiv() : SPItem() { } diff --git a/src/sp-flowregion.cpp b/src/sp-flowregion.cpp index 580945d74..5715e5eb1 100644 --- a/src/sp-flowregion.cpp +++ b/src/sp-flowregion.cpp @@ -23,20 +23,6 @@ #include "livarot/Path.h" #include "livarot/Shape.h" -#include "sp-factory.h" - -namespace { - SPObject* createFlowregion() { - return new SPFlowregion(); - } - - SPObject* createFlowregionExclude() { - return new SPFlowregionExclude(); - } - - bool flowregionRegistered = SPFactory::instance().registerObject("svg:flowRegion", createFlowregion); - bool flowregionExcludeRegistered = SPFactory::instance().registerObject("svg:flowRegionExclude", createFlowregionExclude); -} static void GetDest(SPObject* child,Shape **computed); diff --git a/src/sp-flowtext.cpp b/src/sp-flowtext.cpp index 766026980..cac3cc61d 100644 --- a/src/sp-flowtext.cpp +++ b/src/sp-flowtext.cpp @@ -14,7 +14,7 @@ #include "inkscape.h" #include "document.h" #include "selection.h" -#include "desktop-handles.h" + #include "desktop.h" #include "xml/repr.h" @@ -34,16 +34,6 @@ #include "display/drawing-text.h" -#include "sp-factory.h" - -namespace { - SPObject* createFlowtext() { - return new SPFlowtext(); - } - - bool flowtextRegistered = SPFactory::instance().registerObject("svg:flowRoot", createFlowtext); -} - SPFlowtext::SPFlowtext() : SPItem() { this->par_indent = 0; } @@ -525,10 +515,10 @@ Inkscape::XML::Node *SPFlowtext::getAsText() Glib::ustring::iterator span_text_start_iter; this->layout.getSourceOfCharacter(it, &rawptr, &span_text_start_iter); SPObject *source_obj = reinterpret_cast<SPObject *>(rawptr); - gchar *style_text = sp_style_write_difference((dynamic_cast<SPString *>(source_obj) ? source_obj->parent : source_obj)->style, this->style); - if (style_text && *style_text) { - span_tspan->setAttribute("style", style_text); - g_free(style_text); + + Glib::ustring style_text = (dynamic_cast<SPString *>(source_obj) ? source_obj->parent : source_obj)->style->write( SP_STYLE_FLAG_IFDIFF, this->style); + if (!style_text.empty()) { + span_tspan->setAttribute("style", style_text.c_str()); } SPString *str = dynamic_cast<SPString *>(source_obj); @@ -620,7 +610,7 @@ bool SPFlowtext::has_internal_frame() const SPItem *create_flowtext_with_internal_frame (SPDesktop *desktop, Geom::Point p0, Geom::Point p1) { - SPDocument *doc = sp_desktop_document (desktop); + SPDocument *doc = desktop->getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); Inkscape::XML::Node *root_repr = xml_doc->createElement("svg:flowRoot"); diff --git a/src/sp-font-face.cpp b/src/sp-font-face.cpp index 9782f0c83..afd2a9dee 100644 --- a/src/sp-font-face.cpp +++ b/src/sp-font-face.cpp @@ -259,16 +259,6 @@ static std::vector<FontFaceStretchType> sp_read_fontFaceStretchType(gchar const return v; } -#include "sp-factory.h" - -namespace { - SPObject* createFontFace() { - return new SPFontFace(); - } - - bool fontFaceRegistered = SPFactory::instance().registerObject("svg:font-face", createFontFace); -} - SPFontFace::SPFontFace() : SPObject() { std::vector<FontFaceStyleType> style; style.push_back(SP_FONTFACE_STYLE_ALL); diff --git a/src/sp-font.cpp b/src/sp-font.cpp index 62cf521d3..341a6159f 100644 --- a/src/sp-font.cpp +++ b/src/sp-font.cpp @@ -23,15 +23,6 @@ #include "display/nr-svgfonts.h" -#include "sp-factory.h" - -namespace { - SPObject* createFont() { - return new SPFont(); - } - - bool fontRegistered = SPFactory::instance().registerObject("svg:font", createFont); -} //I think we should have extra stuff here and in the set method in order to set default value as specified at http://www.w3.org/TR/SVG/fonts.html diff --git a/src/sp-glyph.cpp b/src/sp-glyph.cpp index eaa69d486..4829aae51 100644 --- a/src/sp-glyph.cpp +++ b/src/sp-glyph.cpp @@ -20,15 +20,6 @@ #include "document.h" #include <cstring> -#include "sp-factory.h" - -namespace { - SPObject* createGlyph() { - return new SPGlyph(); - } - bool glyphRegistered = SPFactory::instance().registerObject("svg:glyph", createGlyph); -} - SPGlyph::SPGlyph() : SPObject() //TODO: correct these values: diff --git a/src/sp-gradient.cpp b/src/sp-gradient.cpp index b3e885560..854d53dc4 100644 --- a/src/sp-gradient.cpp +++ b/src/sp-gradient.cpp @@ -1,6 +1,6 @@ /** \file * SPGradient, SPStop, SPLinearGradient, SPRadialGradient, - * SPMeshGradient, SPMeshRow, SPMeshPatch + * SPMesh, SPMeshRow, SPMeshPatch */ /* * Authors: @@ -44,7 +44,7 @@ #include "sp-gradient-reference.h" #include "sp-linear-gradient.h" #include "sp-radial-gradient.h" -#include "sp-mesh-gradient.h" +#include "sp-mesh.h" #include "sp-mesh-row.h" #include "sp-mesh-patch.h" #include "sp-stop.h" @@ -121,7 +121,7 @@ bool SPGradient::isEquivalent(SPGradient *that) else if ( (SP_IS_LINEARGRADIENT(this) && SP_IS_LINEARGRADIENT(that)) || (SP_IS_RADIALGRADIENT(this) && SP_IS_RADIALGRADIENT(that)) || - (SP_IS_MESHGRADIENT(this) && SP_IS_MESHGRADIENT(that))) { + (SP_IS_MESH(this) && SP_IS_MESH(that))) { if(!this->isAligned(that))break; } else { break; } // this should never happen, some unhandled type of gradient @@ -206,9 +206,9 @@ bool SPGradient::isAligned(SPGradient *that) (sg->fy.computed != tg->fy.computed) ) { break; } } else if( sg->cx._set || sg->cy._set || sg->fx._set || sg->fy._set || sg->r._set ) { break; } // some mix of set and not set // none set? assume aligned and fall through - } else if (SP_IS_MESHGRADIENT(this) && SP_IS_MESHGRADIENT(that)) { - SPMeshGradient *sg=SP_MESHGRADIENT(this); - SPMeshGradient *tg=SP_MESHGRADIENT(that); + } else if (SP_IS_MESH(this) && SP_IS_MESH(that)) { + SPMesh *sg=SP_MESH(this); + SPMesh *tg=SP_MESH(that); if( sg->x._set != !tg->x._set) { break; } if( sg->y._set != !tg->y._set) { break; } @@ -508,9 +508,9 @@ void SPGradient::modified(guint flags) if (flags & SP_OBJECT_CHILD_MODIFIED_FLAG) { // CPPIFY // This comparison has never worked (i. e. always evaluated to false), - // the right value would have been SP_TYPE_MESHGRADIENT + // the right value would have been SP_TYPE_MESH //if( this->get_type() != SP_GRADIENT_TYPE_MESH ) { -// if (!SP_IS_MESHGRADIENT(this)) { +// if (!SP_IS_MESH(this)) { // this->invalidateVector(); // } else { // this->invalidateArray(); @@ -522,7 +522,7 @@ void SPGradient::modified(guint flags) // CPPIFY // see above //if( this->get_type() != SP_GRADIENT_TYPE_MESH ) { -// if (!SP_IS_MESHGRADIENT(this)) { +// if (!SP_IS_MESH(this)) { // this->ensureVector(); // } else { // this->ensureArray(); @@ -1014,12 +1014,12 @@ void SPGradient::rebuildArray() { // std::cout << "SPGradient::rebuildArray()" << std::endl; - if( !SP_IS_MESHGRADIENT(this) ) { + if( !SP_IS_MESH(this) ) { g_warning( "SPGradient::rebuildArray() called for non-mesh gradient" ); return; } - array.read( SP_MESHGRADIENT( this ) ); + array.read( SP_MESH( this ) ); has_patches = false; for ( SPObject *ro = firstChild() ; ro ; ro = ro->getNext() ) { @@ -1139,7 +1139,7 @@ sp_gradient_create_preview_pattern(SPGradient *gr, double width) // CPPIFY //if( gr->get_type() != SP_GRADIENT_TYPE_MESH ) { - if (!SP_IS_MESHGRADIENT(gr)) { + if (!SP_IS_MESH(gr)) { gr->ensureVector(); pat = cairo_pattern_create_linear(0, 0, width, 0); diff --git a/src/sp-gradient.h b/src/sp-gradient.h index fbb48df62..ab45d6f08 100644 --- a/src/sp-gradient.h +++ b/src/sp-gradient.h @@ -39,12 +39,6 @@ enum SPGradientType { SP_GRADIENT_TYPE_MESH }; -enum SPGradientMeshType { - SP_GRADIENT_MESH_TYPE_UNKNOWN, - SP_GRADIENT_MESH_TYPE_NORMAL, - SP_GRADIENT_MESH_TYPE_CONICAL -}; - enum SPGradientState { SP_GRADIENT_STATE_UNKNOWN, SP_GRADIENT_STATE_VECTOR, @@ -141,7 +135,8 @@ public: /** Composed array (for mesh gradients) */ SPMeshNodeArray array; - + SPMeshNodeArray array_smoothed; // Smoothed version of array + bool hasPatches() const; @@ -215,7 +210,7 @@ sp_gradient_pattern_common_setup(cairo_pattern_t *cp, void sp_gradient_repr_write_vector(SPGradient *gr); void sp_gradient_repr_clear_vector(SPGradient *gr); -void sp_meshgradient_repr_write(SPMeshGradient *mg); +void sp_mesh_repr_write(SPMesh *mg); cairo_pattern_t *sp_gradient_create_preview_pattern(SPGradient *gradient, double width); diff --git a/src/sp-guide.cpp b/src/sp-guide.cpp index 74a0d829c..4e1c5913d 100644 --- a/src/sp-guide.cpp +++ b/src/sp-guide.cpp @@ -22,7 +22,7 @@ #include <algorithm> #include <cstring> #include <string> -#include "desktop-handles.h" + #include "display/sp-canvas.h" #include "display/guideline.h" #include "svg/svg.h" @@ -37,6 +37,7 @@ #include <remove-last.h> #include "inkscape.h" #include "desktop.h" +#include "sp-root.h" #include "sp-namedview.h" #include <2geom/angle.h> #include "document.h" @@ -46,16 +47,6 @@ using Inkscape::DocumentUndo; using std::vector; -#include "sp-factory.h" - -namespace { - SPObject* createGuide() { - return new SPGuide(); - } - - bool guideRegistered = SPFactory::instance().registerObject("sodipodi:guide", createGuide); -} - SPGuide::SPGuide() : SPObject() , label(NULL) @@ -152,6 +143,19 @@ void SPGuide::set(unsigned int key, const gchar *value) { success += sp_svg_number_read_d(strarray[1], &newy); g_strfreev (strarray); if (success == 2) { + // If root viewBox set, interpret guides in terms of viewBox (90/96) + SPRoot *root = document->getRoot(); + if( root->viewBox_set ) { + if(Geom::are_near((root->width.computed * root->viewBox.height()) / (root->viewBox.width() * root->height.computed), 1.0, Geom::EPSILON)) { + // for uniform scaling, try to reduce numerical error + double vbunit2px = (root->width.computed / root->viewBox.width() + root->height.computed / root->viewBox.height())/2.0; + newx = newx * vbunit2px; + newy = newy * vbunit2px; + } else { + newx = newx * root->width.computed / root->viewBox.width(); + newy = newy * root->height.computed / root->viewBox.height(); + } + } this->point_on_line = Geom::Point(newx, newy); } else if (success == 1) { // before 0.46 style guideline definition. @@ -185,7 +189,24 @@ SPGuide *SPGuide::createSPGuide(SPDocument *doc, Geom::Point const &pt1, Geom::P Geom::Point n = Geom::rot90(pt2 - pt1); - sp_repr_set_point(repr, "position", pt1); + // If root viewBox set, interpret guides in terms of viewBox (90/96) + double newx = pt1.x(); + double newy = pt1.y(); + + SPRoot *root = doc->getRoot(); + if( root->viewBox_set ) { + // check to see if scaling is uniform + if(Geom::are_near((root->viewBox.width() * root->height.computed) / (root->width.computed * root->viewBox.height()), 1.0, Geom::EPSILON)) { + double px2vbunit = (root->viewBox.width()/root->width.computed + root->viewBox.height()/root->height.computed)/2.0; + newx = newx * px2vbunit; + newy = newy * px2vbunit; + } else { + newx = newx * root->viewBox.width() / root->width.computed; + newy = newy * root->viewBox.height() / root->height.computed; + } + } + + sp_repr_set_point(repr, "position", Geom::Point( newx, newy )); sp_repr_set_point(repr, "orientation", n); SPNamedView *namedview = sp_document_namedview(doc, NULL); @@ -207,7 +228,7 @@ void sp_guide_pt_pairs_to_guides(SPDocument *doc, std::list<std::pair<Geom::Poin void sp_guide_create_guides_around_page(SPDesktop *dt) { - SPDocument *doc=sp_desktop_document(dt); + SPDocument *doc=dt->getDocument(); std::list<std::pair<Geom::Point, Geom::Point> > pts; Geom::Point A(0, 0); @@ -227,7 +248,7 @@ void sp_guide_create_guides_around_page(SPDesktop *dt) void sp_guide_delete_all_guides(SPDesktop *dt) { - SPDocument *doc=sp_desktop_document(dt); + SPDocument *doc=dt->getDocument(); const GSList *current; while ( (current = doc->getResourceList("guide")) ) { SPGuide* guide = SP_GUIDE(current->data); @@ -318,8 +339,25 @@ void SPGuide::moveto(Geom::Point const point_on_line, bool const commit) /* Calling sp_repr_set_point must precede calling sp_item_notify_moveto in the commit case, so that the guide's new position is available for sp_item_rm_unsatisfied_cns. */ if (commit) { + // If root viewBox set, interpret guides in terms of viewBox (90/96) + double newx = point_on_line.x(); + double newy = point_on_line.y(); + + SPRoot *root = document->getRoot(); + if( root->viewBox_set ) { + // check to see if scaling is uniform + if(Geom::are_near((root->viewBox.width() * root->height.computed) / (root->width.computed * root->viewBox.height()), 1.0, Geom::EPSILON)) { + double px2vbunit = (root->viewBox.width()/root->width.computed + root->viewBox.height()/root->height.computed)/2.0; + newx = newx * px2vbunit; + newy = newy * px2vbunit; + } else { + newx = newx * root->viewBox.width() / root->width.computed; + newy = newy * root->viewBox.height() / root->height.computed; + } + } + //XML Tree being used here directly while it shouldn't be. - sp_repr_set_point(getRepr(), "position", point_on_line); + sp_repr_set_point(getRepr(), "position", Geom::Point(newx, newy) ); } /* DISABLED CODE BECAUSE SPGuideAttachment IS NOT USE AT THE MOMENT (johan) diff --git a/src/sp-hatch-path.cpp b/src/sp-hatch-path.cpp index 8558b67f2..32a514dcb 100644 --- a/src/sp-hatch-path.cpp +++ b/src/sp-hatch-path.cpp @@ -12,10 +12,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include <cstring> #include <string> #include <2geom/path.h> @@ -37,19 +33,6 @@ #include "svg/css-ostringstream.h" #include "xml/repr.h" -#include "sp-factory.h" - -namespace { - -SPObject* createHatchPath() -{ - return new SPHatchPath(); -} - -bool hatchRegistered = SPFactory::instance().registerObject("svg:hatchPath", createHatchPath); - -} // namespace - SPHatchPath::SPHatchPath() : offset(), _display(), @@ -128,7 +111,7 @@ void SPHatchPath::set(unsigned int key, const gchar* value) default: if (SP_ATTRIBUTE_IS_CSS(key)) { - sp_style_read_from_object(style, this); + style->readFromObject( this ); requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); } else { SPObject::set(key, value); diff --git a/src/sp-hatch.cpp b/src/sp-hatch.cpp index 4a8707e08..ea4c5865a 100644 --- a/src/sp-hatch.cpp +++ b/src/sp-hatch.cpp @@ -12,10 +12,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include <cstring> #include <string> #include <2geom/transforms.h> @@ -35,18 +31,6 @@ #include "sp-hatch-path.h" #include "xml/repr.h" -#include "sp-factory.h" - -namespace { - -SPObject* createHatch() { - return new SPHatch(); -} - -bool hatchRegistered = SPFactory::instance().registerObject("svg:hatch", createHatch); - -} // namespace - SPHatch::SPHatch() : SPPaintServer(), href(), @@ -238,7 +222,7 @@ void SPHatch::set(unsigned int key, const gchar* value) default: if (SP_ATTRIBUTE_IS_CSS(key)) { - sp_style_read_from_object(style, this); + style->readFromObject( this ); requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); } else { SPPaintServer::set(key, value); diff --git a/src/sp-image.cpp b/src/sp-image.cpp index b6177fae6..bf5b9ebcd 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -42,7 +42,6 @@ #include "snap-candidate.h" #include "preferences.h" #include "io/sys.h" -#include "sp-factory.h" #if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) #include "cms-system.h" @@ -112,14 +111,6 @@ extern guint update_in_progress; #define DEBUG_MESSAGE_SCISLAC(key, ...) #endif // DEBUG_LCMS -namespace { -SPObject* createImage() { - return new SPImage(); -} - -bool imageRegistered = SPFactory::instance().registerObject("svg:image", createImage); -} - SPImage::SPImage() : SPItem(), SPViewBox() { this->x.unset(); diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 992bca631..55857dacf 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -40,7 +40,7 @@ #include "box3d.h" #include "persp3d.h" #include "inkscape.h" -#include "desktop-handles.h" + #include "selection.h" #include "live_effects/effect.h" #include "live_effects/lpeobject.h" @@ -58,16 +58,6 @@ using Inkscape::DocumentUndo; static void sp_group_perform_patheffect(SPGroup *group, SPGroup *topgroup, bool write); -#include "sp-factory.h" - -namespace { - SPObject* createGroup() { - return new SPGroup(); - } - - bool groupRegistered = SPFactory::instance().registerObject("svg:g", createGroup); -} - SPGroup::SPGroup() : SPLPEItem() { this->_layer_mode = SPGroup::GROUP; } @@ -159,6 +149,7 @@ void SPGroup::order_changed (Inkscape::XML::Node *child, Inkscape::XML::Node *ol } void SPGroup::update(SPCtx *ctx, unsigned int flags) { + // std::cout << "SPGroup::update(): " << (getId()?getId():"null") << std::endl; SPItemCtx *ictx, cctx; ictx = (SPItemCtx *) ctx; @@ -199,12 +190,16 @@ void SPGroup::update(SPCtx *ctx, unsigned int flags) { if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { for (SPItemView *v = this->display; v != NULL; v = v->next) { Inkscape::DrawingGroup *group = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); - group->setStyle(this->style); + if( this->parent ) { + this->context_style = this->parent->context_style; + } + group->setStyle(this->style, this->context_style); } } } void SPGroup::modified(guint flags) { + // std::cout << "SPGroup::modified(): " << (getId()?getId():"null") << std::endl; SPLPEItem::modified(flags); SPObject *child; @@ -352,11 +347,15 @@ void SPGroup::set(unsigned int key, gchar const* value) { } Inkscape::DrawingItem *SPGroup::show (Inkscape::Drawing &drawing, unsigned int key, unsigned int flags) { + // std::cout << "SPGroup::show(): " << (getId()?getId():"null") << std::endl; Inkscape::DrawingGroup *ai; ai = new Inkscape::DrawingGroup(drawing); ai->setPickChildren(this->effectiveLayerMode(key) == SPGroup::LAYER); - ai->setStyle(this->style); + if( this->parent ) { + this->context_style = this->parent->context_style; + } + ai->setStyle(this->style, this->context_style); this->_showChildren(drawing, ai, key, flags); return ai; @@ -390,6 +389,22 @@ void SPGroup::snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape: } } +void sp_item_group_ungroup_handle_clones(SPItem *parent, Geom::Affine const g) +{ + for(std::list<SPObject*>::const_iterator refd=parent->hrefList.begin();refd!=parent->hrefList.end();refd++){ + SPItem *citem = dynamic_cast<SPItem *>(*refd); + if (citem) { + SPUse *useitem = dynamic_cast<SPUse *>(citem); + if (useitem && useitem->get_original() == parent) { + Geom::Affine ctrans; + ctrans = g.inverse() * citem->transform; + gchar *affinestr = sp_svg_transform_write(ctrans); + citem->setAttribute("transform", affinestr); + g_free(affinestr); + } + } + } +} void sp_item_group_ungroup (SPGroup *group, GSList **children, bool do_done) @@ -426,8 +441,14 @@ sp_item_group_ungroup (SPGroup *group, GSList **children, bool do_done) /* Step 1 - generate lists of children objects */ GSList *items = NULL; GSList *objects = NULL; - for (SPObject *child = group->firstChild() ; child; child = child->getNext() ) { + Geom::Affine const g(group->transform); + for (SPObject *child = group->firstChild() ; child; child = child->getNext() ) + if (SPItem *citem = dynamic_cast<SPItem *>(child)) + sp_item_group_ungroup_handle_clones(citem,g); + + + for (SPObject *child = group->firstChild() ; child; child = child->getNext() ) { SPItem *citem = dynamic_cast<SPItem *>(child); if (citem) { /* Merging of style */ @@ -435,7 +456,7 @@ sp_item_group_ungroup (SPGroup *group, GSList **children, bool do_done) // it here _before_ the new transform is set, so as to use the pre-transform bbox citem->adjust_paint_recursive (Geom::identity(), Geom::identity(), false); - sp_style_merge_from_dying_parent(child->style, group->style); + child->style->merge( group->style ); /* * fixme: We currently make no allowance for the case where child is cloned * and the group has any style settings. @@ -444,9 +465,8 @@ sp_item_group_ungroup (SPGroup *group, GSList **children, bool do_done) * version of inkscape without using the XML editor: we usually apply group * style changes to children rather than to the group itself.) * - * If the group has no style settings, then - * sp_style_merge_from_dying_parent should be a no-op. Otherwise (i.e. if - * we change the child's style to compensate for its parent going away) + * If the group has no style settings, then style->merge() should be a no-op. Otherwise + * (i.e. if we change the child's style to compensate for its parent going away) * then those changes will typically be reflected in any clones of child, * whereas we'd prefer for Ungroup not to affect the visual appearance. * @@ -464,13 +484,6 @@ sp_item_group_ungroup (SPGroup *group, GSList **children, bool do_done) // Merging transform Geom::Affine ctrans; - Geom::Affine const g(group->transform); - SPUse *useitem = dynamic_cast<SPUse *>(citem); - if (useitem && useitem->get_original() && - useitem->get_original()->parent == dynamic_cast<SPObject *>(group)) { - // make sure a clone's effective transform is the same as was under group - ctrans = g.inverse() * citem->transform * g; - } else { // We should not apply the group's transformation to both a linked offset AND to its source if (dynamic_cast<SPOffset *>(citem)) { // Do we have an offset at hand (whether it's dynamic or linked)? SPItem *source = sp_offset_get_source(dynamic_cast<SPOffset *>(citem)); @@ -489,7 +502,6 @@ sp_item_group_ungroup (SPGroup *group, GSList **children, bool do_done) } else { ctrans = citem->transform * g; } - } // FIXME: constructing a transform that would fully preserve the appearance of a // textpath if it is ungrouped with its path seems to be impossible in general @@ -701,26 +713,21 @@ void SPGroup::scaleChildItemsRec(Geom::Scale const &sc, Geom::Point const &p, bo subItem = dynamic_cast<SPItem *>(item->clip_ref->getObject()->firstChild()); } if (subItem != NULL) { - Geom::Affine tdoc2dt = Geom::Scale(1, -1) * Geom::Translate(p); // re-create doc2dt() - Geom::Affine ti2doc = item->i2doc_affine(); - subItem->set_i2d_affine(ti2doc * sc * ti2doc.inverse() * tdoc2dt); - subItem->doWriteTransform(subItem->getRepr(), subItem->transform, NULL, true); + subItem->doWriteTransform(subItem->getRepr(), subItem->transform*sc, NULL, true); } subItem = NULL; if (item->mask_ref->getObject()) { subItem = dynamic_cast<SPItem *>(item->mask_ref->getObject()->firstChild()); } if (subItem != NULL) { - Geom::Affine tdoc2dt = Geom::Scale(1, -1) * Geom::Translate(p); // re-create doc2dt() - Geom::Affine ti2doc = item->i2doc_affine(); - subItem->set_i2d_affine(ti2doc * sc * ti2doc.inverse() * tdoc2dt); - subItem->doWriteTransform(item->getRepr(), item->transform, NULL, true); + subItem->doWriteTransform(subItem->getRepr(), subItem->transform*sc, NULL, true); } + item->doWriteTransform(item->getRepr(), sc.inverse()*item->transform*sc, NULL, true); group->scaleChildItemsRec(sc, p, false); } } else { - Geom::OptRect bbox = item->desktopVisualBounds(); - if (bbox) { +// Geom::OptRect bbox = item->desktopVisualBounds(); +// if (bbox) { // test not needed, this was causing a failure to scale <circle> and <rect> in the clipboard, see LP Bug 1365451 // Scale item Geom::Translate const s(p); Geom::Affine final = s.inverse() * sc * s; @@ -769,8 +776,7 @@ void SPGroup::scaleChildItemsRec(Geom::Scale const &sc, Geom::Point const &p, bo Geom::Affine move = final.inverse() * item->transform * final; item->doWriteTransform(item->getRepr(), move, &move, true); } else { - item->set_i2d_affine(item->i2dt_affine() * final); - item->doWriteTransform(item->getRepr(), item->transform, NULL, true); + item->doWriteTransform(item->getRepr(), item->transform*sc, NULL, true); } if (conn_type != NULL) { @@ -781,7 +787,7 @@ void SPGroup::scaleChildItemsRec(Geom::Scale const &sc, Geom::Point const &p, bo item->scaleCenter(sc); // All coordinates have been scaled, so also the center must be scaled item->updateRepr(); } - } +// } } } } @@ -837,7 +843,7 @@ void SPGroup::update_patheffect(bool write) { LivePathEffectObject *lpeobj = (*it)->lpeobject; if (lpeobj && lpeobj->get_lpe()) { - lpeobj->get_lpe()->doBeforeEffect(this); + lpeobj->get_lpe()->doBeforeEffect_impl(this); } } diff --git a/src/sp-item-group.h b/src/sp-item-group.h index 15bb58f22..f9a8b88f5 100644 --- a/src/sp-item-group.h +++ b/src/sp-item-group.h @@ -95,6 +95,15 @@ public: virtual void update_patheffect(bool write); }; +/** + * finds clones of a child of the group going out of the group; and inverse the group transform on its clones + * Also called when moving objects between different layers + * @param group current group + * @param parent original parent + * @param g transform + */ +void sp_item_group_ungroup_handle_clones(SPItem *parent, Geom::Affine const g); + void sp_item_group_ungroup (SPGroup *group, GSList **children, bool do_done = true); diff --git a/src/sp-item-transform.cpp b/src/sp-item-transform.cpp index 86beee907..767f0ed91 100644 --- a/src/sp-item-transform.cpp +++ b/src/sp-item-transform.cpp @@ -181,7 +181,9 @@ Geom::Affine get_scale_transform_for_uniform_stroke(Geom::Rect const &bbox_visua if (B*B - 4*A*C < 0) { g_message("stroke scaling error : %d, %f, %f, %f, %f, %f", preserve, r0, w0, h0, w1, h1); } else { - r1 = fabs((-B - sqrt(B*B - 4*A*C))/(2*A)); + r1 = -C/B; + if (!Geom::are_near(A*C/B/B, 0.0, Geom::EPSILON)) + r1 = fabs((-B - sqrt(B*B - 4*A*C))/(2*A)); // If w1 < 0 then the scale will be wrong if we just assume that scale_x = (w1 - r1)/(w0 - r0); // Therefore we here need the absolute values of w0, w1, h0, h1, and r0, as taken care of earlier scale_x = (w1 - r1)/(w0 - r0); @@ -339,7 +341,9 @@ Geom::Affine get_scale_transform_for_variable_stroke(Geom::Rect const &bbox_visu if (B*B - 4*A*C < 0) { g_message("variable stroke scaling error : %d, %d, %f, %f, %f, %f, %f, %f", transform_stroke, preserve, r0w, r0h, w0, h0, w1, h1); } else { - gdouble det = (-B + sqrt(B*B - 4*A*C))/(2*A); + gdouble det = -C/B; + if (!Geom::are_near(A*C/B/B, 0.0, Geom::EPSILON)) + det = (-B + sqrt(B*B - 4*A*C))/(2*A); r1w = r0w*det; r1h = r0h*det; // If w1 < 0 then the scale will be wrong if we just assume that scale_x = (w1 - r1)/(w0 - r0); diff --git a/src/sp-item.cpp b/src/sp-item.cpp index 73347fc4e..8c99e9bcf 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -25,7 +25,7 @@ #include "uri.h" #include "inkscape.h" #include "desktop.h" -#include "desktop-handles.h" + #include "style.h" #include <glibmm/i18n.h> @@ -75,18 +75,6 @@ static SPItemView* sp_item_view_list_remove(SPItemView *list, SPItem::SPItem() : SPObject() { - this->sensitive = 0; - this->clip_ref = NULL; - this->avoidRef = NULL; - this->_is_evaluated = false; - this->stop_paint = 0; - this->_evaluated_status = StatusUnknown; - this->bbox_valid = 0; - this->freeze_stroke_width = false; - this->transform_center_x = 0; - this->transform_center_y = 0; - this->display = NULL; - this->mask_ref = NULL; sensitive = TRUE; bbox_valid = FALSE; @@ -96,12 +84,13 @@ SPItem::SPItem() : SPObject() { transform_center_x = 0; transform_center_y = 0; + freeze_stroke_width = false; + _is_evaluated = true; _evaluated_status = StatusUnknown; transform = Geom::identity(); - doc_bbox = Geom::OptRect(); - freeze_stroke_width = false; + // doc_bbox = Geom::OptRect(); display = NULL; @@ -555,7 +544,7 @@ void SPItem::set(unsigned int key, gchar const* value) { } default: if (SP_ATTRIBUTE_IS_CSS(key)) { - sp_style_read_from_object(object->style, object); + style->readFromObject( this ); object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); } else { SPObject::set(key, value); @@ -670,54 +659,56 @@ void SPItem::stroke_ps_ref_changed(SPObject *old_ps, SPObject *ps, SPItem *item) } } -void SPItem::update(SPCtx* /*ctx*/, guint flags) { - SPItem *item = this; - SPItem* object = item; +void SPItem::update(SPCtx* ctx, guint flags) { -// SPObject::onUpdate(ctx, flags); + SPItemCtx const *ictx = reinterpret_cast<SPItemCtx const *>(ctx); - // any of the modifications defined in sp-object.h might change bbox, + // Any of the modifications defined in sp-object.h might change bbox, // so we invalidate it unconditionally - item->bbox_valid = FALSE; + bbox_valid = FALSE; + + viewport = ictx->viewport; // Cache viewport - if (flags & (SP_OBJECT_CHILD_MODIFIED_FLAG | SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG)) { + if (flags & (SP_OBJECT_CHILD_MODIFIED_FLAG | + SP_OBJECT_MODIFIED_FLAG | + SP_OBJECT_STYLE_MODIFIED_FLAG) ) { if (flags & SP_OBJECT_MODIFIED_FLAG) { - for (SPItemView *v = item->display; v != NULL; v = v->next) { - v->arenaitem->setTransform(item->transform); + for (SPItemView *v = display; v != NULL; v = v->next) { + v->arenaitem->setTransform(transform); } } - SPClipPath *clip_path = item->clip_ref ? item->clip_ref->getObject() : NULL; - SPMask *mask = item->mask_ref ? item->mask_ref->getObject() : NULL; + SPClipPath *clip_path = clip_ref ? clip_ref->getObject() : NULL; + SPMask *mask = mask_ref ? mask_ref->getObject() : NULL; if ( clip_path || mask ) { - Geom::OptRect bbox = item->geometricBounds(); + Geom::OptRect bbox = geometricBounds(); if (clip_path) { - for (SPItemView *v = item->display; v != NULL; v = v->next) { + for (SPItemView *v = display; v != NULL; v = v->next) { clip_path->setBBox(v->arenaitem->key(), bbox); } } if (mask) { - for (SPItemView *v = item->display; v != NULL; v = v->next) { + for (SPItemView *v = display; v != NULL; v = v->next) { mask->sp_mask_set_bbox(v->arenaitem->key(), bbox); } } } if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { - for (SPItemView *v = item->display; v != NULL; v = v->next) { - v->arenaitem->setOpacity(SP_SCALE24_TO_FLOAT(object->style->opacity.value)); - v->arenaitem->setAntialiasing(object->style->shape_rendering.computed != SP_CSS_SHAPE_RENDERING_CRISPEDGES); - v->arenaitem->setIsolation( object->style->isolation.value ); - v->arenaitem->setBlendMode( object->style->mix_blend_mode.value ); - v->arenaitem->setVisible(!item->isHidden()); + for (SPItemView *v = display; v != NULL; v = v->next) { + v->arenaitem->setOpacity(SP_SCALE24_TO_FLOAT(style->opacity.value)); + v->arenaitem->setAntialiasing(style->shape_rendering.computed != SP_CSS_SHAPE_RENDERING_CRISPEDGES); + v->arenaitem->setIsolation( style->isolation.value ); + v->arenaitem->setBlendMode( style->mix_blend_mode.value ); + v->arenaitem->setVisible(!isHidden()); } } } /* Update bounding box in user space, used for filter and objectBoundingBox units */ - if (item->style->filter.set && item->display) { - Geom::OptRect item_bbox = item->geometricBounds(); - SPItemView *itemview = item->display; + if (style->filter.set && display) { + Geom::OptRect item_bbox = geometricBounds(); + SPItemView *itemview = display; do { if (itemview->arenaitem) itemview->arenaitem->setItemBounds(item_bbox); @@ -725,8 +716,8 @@ void SPItem::update(SPCtx* /*ctx*/, guint flags) { } // Update libavoid with item geometry (for connector routing). - if (item->avoidRef) - item->avoidRef->handleSettingChange(); + if (avoidRef) + avoidRef->handleSettingChange(); } void SPItem::modified(unsigned int /*flags*/) @@ -1006,7 +997,7 @@ void SPItem::getSnappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscap clips_and_masks.push_back(clip_ref->getObject()); clips_and_masks.push_back(mask_ref->getObject()); - SPDesktop *desktop = inkscape_active_desktop(); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; for (std::list<SPObject const *>::const_iterator o = clips_and_masks.begin(); o != clips_and_masks.end(); ++o) { if (*o) { // obj is a group object, the children are the actual clippers @@ -1299,7 +1290,7 @@ void SPItem::adjust_stroke( gdouble ex ) SPStyle *style = this->style; - if (style && !style->stroke.isNone() && !Geom::are_near(ex, 1.0, Geom::EPSILON)) { + if (style && !Geom::are_near(ex, 1.0, Geom::EPSILON)) { style->stroke_width.computed *= ex; style->stroke_width.set = TRUE; @@ -1607,7 +1598,7 @@ Geom::Affine SPItem::i2doc_affine() const Geom::Affine SPItem::i2dt_affine() const { Geom::Affine ret; - SPDesktop const *desktop = inkscape_active_desktop(); + SPDesktop const *desktop = SP_ACTIVE_DESKTOP; if ( desktop ) { ret = i2doc_affine() * desktop->doc2dt(); } else { @@ -1625,7 +1616,7 @@ void SPItem::set_i2d_affine(Geom::Affine const &i2dt) if (parent) { dt2p = static_cast<SPItem *>(parent)->i2dt_affine().inverse(); } else { - SPDesktop *dt = inkscape_active_desktop(); + SPDesktop *dt = SP_ACTIVE_DESKTOP; dt2p = dt->dt2doc(); } diff --git a/src/sp-item.h b/src/sp-item.h index b9d71c551..bdc6a0ad9 100644 --- a/src/sp-item.h +++ b/src/sp-item.h @@ -145,6 +145,7 @@ public: Geom::Affine transform; mutable Geom::OptRect doc_bbox; + Geom::Rect viewport; // Cache viewport information SPClipPathReference *clip_ref; SPMaskReference *mask_ref; diff --git a/src/sp-line.cpp b/src/sp-line.cpp index 8af95b4ce..cf21be912 100644 --- a/src/sp-line.cpp +++ b/src/sp-line.cpp @@ -11,9 +11,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif #include "attributes.h" #include "style.h" #include "sp-line.h" @@ -24,16 +21,6 @@ #include "document.h" #include "inkscape.h" -#include "sp-factory.h" - -namespace { - SPObject* createLine() { - return new SPLine(); - } - - bool lineRegistered = SPFactory::instance().registerObject("svg:line", createLine); -} - SPLine::SPLine() : SPShape() { this->x1.unset(); this->y1.unset(); diff --git a/src/sp-linear-gradient.cpp b/src/sp-linear-gradient.cpp index 6e9f5e6dd..29579b617 100644 --- a/src/sp-linear-gradient.cpp +++ b/src/sp-linear-gradient.cpp @@ -5,17 +5,6 @@ #include "attributes.h" #include "xml/repr.h" -#include "sp-factory.h" - -namespace { - SPObject* createLinearGradient() { - return new SPLinearGradient(); - } - - bool linearGradientRegistered = SPFactory::instance().registerObject("svg:linearGradient", createLinearGradient); -} - - /* * Linear Gradient */ diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 019d15162..12d85b3ed 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -58,8 +58,8 @@ static void sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem); static void sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem); typedef std::list<std::string> HRefList; -static std::string patheffectlist_write_svg(PathEffectList const & list); -static std::string hreflist_write_svg(HRefList const & list); +static std::string patheffectlist_svg_string(PathEffectList const & list); +static std::string hreflist_svg_string(HRefList const & list); SPLPEItem::SPLPEItem() : SPItem() @@ -195,8 +195,7 @@ void SPLPEItem::modified(unsigned int flags) { Inkscape::XML::Node* SPLPEItem::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { if (flags & SP_OBJECT_WRITE_EXT) { if ( hasPathEffect() ) { - std::string href = patheffectlist_write_svg(*this->path_effect_list); - repr->setAttribute("inkscape:path-effect", href.c_str()); + repr->setAttribute("inkscape:path-effect", patheffectlist_svg_string(*this->path_effect_list)); } else { repr->setAttribute("inkscape:path-effect", NULL); } @@ -264,7 +263,7 @@ bool SPLPEItem::performPathEffect(SPCurve *curve) { } if (!SP_IS_GROUP(this)) { lpe->doAfterEffect(this); - } + } } } } @@ -418,9 +417,9 @@ sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem) } } -void SPLPEItem::addPathEffect(gchar *value, bool reset) +void SPLPEItem::addPathEffect(std::string value, bool reset) { - if (value) { + if (!value.empty()) { // Apply the path effects here because in the casse of a group, lpe->resetDefaults // needs that all the subitems have their effects applied sp_lpe_item_update_patheffect(this, false, true); @@ -434,10 +433,9 @@ void SPLPEItem::addPathEffect(gchar *value, bool reset) { hreflist.push_back( std::string((*it)->lpeobject_href) ); } - hreflist.push_back( std::string(value) ); - std::string hrefs = hreflist_write_svg(hreflist); + hreflist.push_back(value); // C++11: should be emplace_back std::move'd (also the reason why passed by value to addPathEffect) - this->getRepr()->setAttribute("inkscape:path-effect", hrefs.c_str()); + this->getRepr()->setAttribute("inkscape:path-effect", hreflist_svg_string(hreflist)); // Make sure that ellipse is stored as <svg:path> if( SP_IS_GENERICELLIPSE(this)) { @@ -501,13 +499,7 @@ void SPLPEItem::removeCurrentPathEffect(bool keep_paths) } PathEffectList new_list = *this->path_effect_list; new_list.remove(lperef); //current lpe ref is always our 'own' pointer from the path_effect_list - std::string r = patheffectlist_write_svg(new_list); - - if (!r.empty()) { - this->getRepr()->setAttribute("inkscape:path-effect", r.c_str()); - } else { - this->getRepr()->setAttribute("inkscape:path-effect", NULL); - } + this->getRepr()->setAttribute("inkscape:path-effect", patheffectlist_svg_string(new_list)); if (!keep_paths) { // Make sure that ellipse is stored as <svg:circle> or <svg:ellipse> if possible. @@ -551,8 +543,8 @@ void SPLPEItem::downCurrentPathEffect() std::iter_swap(cur_it, down_it); } } - std::string r = patheffectlist_write_svg(new_list); - this->getRepr()->setAttribute("inkscape:path-effect", r.c_str()); + + this->getRepr()->setAttribute("inkscape:path-effect", patheffectlist_svg_string(new_list)); sp_lpe_item_cleanup_original_path_recursive(this); } @@ -570,9 +562,8 @@ void SPLPEItem::upCurrentPathEffect() --up_it; std::iter_swap(cur_it, up_it); } - std::string r = patheffectlist_write_svg(new_list); - this->getRepr()->setAttribute("inkscape:path-effect", r.c_str()); + this->getRepr()->setAttribute("inkscape:path-effect", patheffectlist_svg_string(new_list)); sp_lpe_item_cleanup_original_path_recursive(this); } @@ -862,16 +853,16 @@ void SPLPEItem::remove_child(Inkscape::XML::Node * child) { SPItem::remove_child(child); } -static std::string patheffectlist_write_svg(PathEffectList const & list) +static std::string patheffectlist_svg_string(PathEffectList const & list) { HRefList hreflist; for (PathEffectList::const_iterator it = list.begin(); it != list.end(); ++it) { - hreflist.push_back( std::string((*it)->lpeobject_href) ); + hreflist.push_back( std::string((*it)->lpeobject_href) ); // C++11: use emplace_back } - return hreflist_write_svg(hreflist); + return hreflist_svg_string(hreflist); } /** @@ -881,7 +872,7 @@ static std::string patheffectlist_write_svg(PathEffectList const & list) * - populate the templist with the effects from the old list that you want to have and their order * - call this function with temp list as param */ -static std::string hreflist_write_svg(HRefList const & list) +static std::string hreflist_svg_string(HRefList const & list) { std::string r; bool semicolon_first = false; @@ -968,8 +959,7 @@ void SPLPEItem::replacePathEffects( std::vector<LivePathEffectObject const *> co } } - std::string r = hreflist_write_svg(hreflist); - this->getRepr()->setAttribute("inkscape:path-effect", r.c_str()); + this->getRepr()->setAttribute("inkscape:path-effect", hreflist_svg_string(hreflist)); } /** diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index 9c052b7b1..902271430 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -15,6 +15,7 @@ */ #include <list> +#include <string> #include "sp-item.h" #define SP_LPE_ITEM(obj) (dynamic_cast<SPLPEItem*>((SPObject*)obj)) @@ -88,7 +89,7 @@ public: bool setCurrentPathEffect(Inkscape::LivePathEffect::LPEObjectReference* lperef); void removeCurrentPathEffect(bool keep_paths); void removeAllPathEffects(bool keep_paths); - void addPathEffect(char *value, bool reset); + void addPathEffect(std::string value, bool reset); void addPathEffect(LivePathEffectObject * new_lpeobj); void apply_to_mask(SPItem * item); void apply_to_clippath(SPItem * item); diff --git a/src/sp-marker.cpp b/src/sp-marker.cpp index e955594ab..d3cf50fa7 100644 --- a/src/sp-marker.cpp +++ b/src/sp-marker.cpp @@ -29,23 +29,19 @@ #include "document-private.h" #include "preferences.h" -struct SPMarkerView { - SPMarkerView *next; - unsigned int key; - std::vector<Inkscape::DrawingItem *> items; -}; - -static void sp_marker_view_remove (SPMarker *marker, SPMarkerView *view, unsigned int destroyitems); +class SPMarkerView { -#include "sp-factory.h" - -namespace { - SPObject* createMarker() { - return new SPMarker(); - } +public: - bool markerRegistered = SPFactory::instance().registerObject("svg:marker", createMarker); -} + SPMarkerView() {}; + ~SPMarkerView() { + for (unsigned int i = 0; i < items.size(); ++i) { + delete items[i]; + } + items.clear(); + } + std::vector<Inkscape::DrawingItem *> items; +}; SPMarker::SPMarker() : SPGroup(), SPViewBox() { @@ -55,8 +51,6 @@ SPMarker::SPMarker() : SPGroup(), SPViewBox() { this->orient_mode = MARKER_ORIENT_ANGLE; this->orient_set = 0; this->orient = 0; - - this->views = NULL; } /** @@ -90,20 +84,6 @@ void SPMarker::build(SPDocument *document, Inkscape::XML::Node *repr) { SPGroup::build(document, repr); } -void SPMarker::release() { - while (this->views) { - // Destroy all DrawingItems etc. - // Parent class ::hide method - //reinterpret_cast<SPItemClass *>(parent_class)->hide(marker, marker->views->key); - // CPPIFY: correct one? - SPGroup::hide(this->views->key); - - - sp_marker_view_remove (this, this->views, TRUE); - } - - SPGroup::release(); -} /** * Removes, releases and unrefs all children of object @@ -117,6 +97,17 @@ void SPMarker::release() { * * \see SPObject::release() */ +void SPMarker::release() { + + std::map<unsigned int, SPMarkerView>::iterator it; + for (it = views_map.begin(); it != views_map.end(); ++it) { + SPGroup::hide( it->first ); + } + views_map.clear(); + + SPGroup::release(); +} + void SPMarker::set(unsigned int key, const gchar* value) { switch (key) { @@ -168,9 +159,12 @@ void SPMarker::set(unsigned int key, const gchar* value) { } else if (!strcmp (value, "auto-start-reverse")) { this->orient_mode = MARKER_ORIENT_AUTO_START_REVERSE; this->orient_set = TRUE; - } else if (sp_svg_number_read_f (value, &this->orient)) { - this->orient_mode = MARKER_ORIENT_ANGLE; - this->orient_set = TRUE; + } else { + orient.readOrUnset(value); + if (orient._set) { + this->orient_mode = MARKER_ORIENT_ANGLE; + this->orient_set = orient._set; + } } } @@ -218,10 +212,11 @@ void SPMarker::update(SPCtx *ctx, guint flags) { SPGroup::update((SPCtx *) &rctx, flags); // As last step set additional transform of drawing group - for (SPMarkerView *v = this->views; v != NULL; v = v->next) { - for (unsigned i = 0 ; i < v->items.size() ; i++) { - if (v->items[i]) { - Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->items[i]); + std::map<unsigned int, SPMarkerView>::iterator it; + for (it = views_map.begin(); it != views_map.end(); ++it) { + for (unsigned i = 0 ; i < it->second.items.size() ; ++i) { + if (it->second.items[i]) { + Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(it->second.items[i]); g->setChildTransform(this->c2p); } } @@ -273,7 +268,7 @@ Inkscape::XML::Node* SPMarker::write(Inkscape::XML::Document *xml_doc, Inkscape: } else if (this->orient_mode == MARKER_ORIENT_AUTO_START_REVERSE) { repr->setAttribute("orient", "auto-start-reverse"); } else { - sp_repr_set_css_double(repr, "orient", this->orient); + sp_repr_set_css_double(repr, "orient", this->orient.computed); } } else { repr->setAttribute("orient", NULL); @@ -325,31 +320,26 @@ void SPMarker::print(SPPrintContext* /*ctx*/) { * \param key Key to give each SPMarkerView. * \param size Number of DrawingItems to put in the SPMarkerView. */ +// If marker views are always created in order, then this function could be eliminated +// by doing the push_back in sp_marker_show_instance. void sp_marker_show_dimension (SPMarker *marker, unsigned int key, unsigned int size) { - SPMarkerView *view; - - for (view = marker->views; view != NULL; view = view->next) { - if (view->key == key) break; - } - if (view && (view->items.size() != size)) { - /* Free old view and allocate new */ - /* Parent class ::hide method */ - marker->hide(key); - - sp_marker_view_remove (marker, view, TRUE); - view = NULL; - } - if (!view) { - view = new SPMarkerView(); - view->items.clear(); - for (unsigned int i = 0; i < size; i++) { - view->items.push_back(NULL); + std::map<unsigned int, SPMarkerView>::iterator it = marker->views_map.find(key); + if (it != marker->views_map.end()) { + if (it->second.items.size() != size ) { + // Need to change size of vector! (We should not really need to do this.) + marker->hide(key); + it->second.items.clear(); + for (unsigned int i = 0; i < size; ++i) { + it->second.items.push_back(NULL); + } + } + } else { + marker->views_map[key] = SPMarkerView(); + for (unsigned int i = 0; i < size; ++i) { + marker->views_map[key].items.push_back(NULL); } - view->next = marker->views; - marker->views = view; - view->key = key; } } @@ -362,51 +352,58 @@ sp_marker_show_instance ( SPMarker *marker, Inkscape::DrawingItem *parent, unsigned int key, unsigned int pos, Geom::Affine const &base, float linewidth) { - // do not show marker if linewidth == 0 and markerUnits == strokeWidth + // Do not show marker if linewidth == 0 and markerUnits == strokeWidth // otherwise Cairo will fail to render anything on the tile - // that contains the "degenerate" marker + // that contains the "degenerate" marker. if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH && linewidth == 0) { return NULL; } - for (SPMarkerView *v = marker->views; v != NULL; v = v->next) { - if (v->key == key) { - if (pos >= v->items.size()) { - return NULL; - } - if (!v->items[pos]) { - /* Parent class ::show method */ - v->items[pos] = marker->private_show(parent->drawing(), key, SP_ITEM_REFERENCE_FLAGS); - - if (v->items[pos]) { - /* fixme: Position (Lauris) */ - parent->prependChild(v->items[pos]); - Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->items[pos]); - if (g) g->setChildTransform(marker->c2p); - } - } - if (v->items[pos]) { - Geom::Affine m; - if (marker->orient_mode == MARKER_ORIENT_AUTO) { - m = base; - } else if (marker->orient_mode == MARKER_ORIENT_AUTO_START_REVERSE) { - m = Geom::Rotate::from_degrees( 180.0 ) * base; - m = base; - } else { - /* fixme: Orient units (Lauris) */ - m = Geom::Rotate::from_degrees(marker->orient); - m *= Geom::Translate(base.translation()); - } - if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { - m = Geom::Scale(linewidth) * m; - } - v->items[pos]->setTransform(m); - } - return v->items[pos]; + std::map<unsigned int, SPMarkerView>::iterator it = marker->views_map.find(key); + if (it == marker->views_map.end()) { + // Key not found + return NULL; + } + + SPMarkerView *view = &(it->second); + if (pos >= view->items.size() ) { + // Position index too large, doesn't exist. + return NULL; + } + + // If not already created + if (view->items[pos] == NULL) { + + /* Parent class ::show method */ + view->items[pos] = marker->private_show(parent->drawing(), key, SP_ITEM_REFERENCE_FLAGS); + + if (view->items[pos]) { + /* fixme: Position (Lauris) */ + parent->prependChild(view->items[pos]); + Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(view->items[pos]); + if (g) g->setChildTransform(marker->c2p); } } - return NULL; + if (view->items[pos]) { + Geom::Affine m; + if (marker->orient_mode == MARKER_ORIENT_AUTO) { + m = base; + } else if (marker->orient_mode == MARKER_ORIENT_AUTO_START_REVERSE) { + m = Geom::Rotate::from_degrees( 180.0 ) * base; + m = base; + } else { + /* fixme: Orient units (Lauris) */ + m = Geom::Rotate::from_degrees(marker->orient.computed); + m *= Geom::Translate(base.translation()); + } + if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { + m = Geom::Scale(linewidth) * m; + } + view->items[pos]->setTransform(m); + } + + return view->items[pos]; } /** @@ -417,46 +414,10 @@ sp_marker_show_instance ( SPMarker *marker, Inkscape::DrawingItem *parent, void sp_marker_hide (SPMarker *marker, unsigned int key) { - SPMarkerView *v; - - v = marker->views; - while (v != NULL) { - SPMarkerView *next; - next = v->next; - if (v->key == key) { - /* Parent class ::hide method */ - marker->hide(key); - - sp_marker_view_remove (marker, v, TRUE); - return; - } - v = next; - } + marker->hide(key); + marker->views_map.erase(key); } -/** - * Removes a given view. Also will destroy sub-items in the view if destroyitems - * is set to a non-zero value. - */ -static void -sp_marker_view_remove (SPMarker *marker, SPMarkerView *view, unsigned int destroyitems) -{ - if (view == marker->views) { - marker->views = view->next; - } else { - SPMarkerView *v; - for (v = marker->views; v->next != view; v = v->next) if (!v->next) return; - v->next = view->next; - } - if (destroyitems) { - for (unsigned int i = 0; i < view->items.size(); i++) { - /* We have to walk through the whole array because there may be hidden items */ - delete view->items[i]; - } - } - view->items.clear(); - delete view; -} const gchar *generate_marker(GSList *reprs, Geom::Rect bounds, SPDocument *document, Geom::Point center, Geom::Affine move) { diff --git a/src/sp-marker.h b/src/sp-marker.h index b58523251..e804fd7dc 100644 --- a/src/sp-marker.h +++ b/src/sp-marker.h @@ -21,13 +21,16 @@ #define SP_MARKER(obj) (dynamic_cast<SPMarker*>((SPObject*)obj)) #define SP_IS_MARKER(obj) (dynamic_cast<const SPMarker*>((SPObject*)obj) != NULL) -struct SPMarkerView; +class SPMarkerView; + +#include <map> #include <2geom/rect.h> #include <2geom/affine.h> #include "enums.h" #include "svg/svg-length.h" +#include "svg/svg-angle.h" #include "sp-item-group.h" #include "uri-references.h" #include "viewbox.h" @@ -58,10 +61,15 @@ public: /* orient */ unsigned int orient_set : 1; markerOrient orient_mode : 2; - float orient; - - /* Private views */ - SPMarkerView *views; + SVGAngle orient; + + /* Private views indexed by key that corresponds to a + * particular marker type (start, mid, end) on a particular + * path. SPMarkerView is a wrapper for a vector of pointers to + * Inkscape::DrawingItem instances, one pointer for each + * rendered marker. + */ + std::map<unsigned int, SPMarkerView> views_map; virtual void build(SPDocument *document, Inkscape::XML::Node *repr); virtual void release(); diff --git a/src/sp-mask.cpp b/src/sp-mask.cpp index 9707c9d8e..d60473e1d 100644 --- a/src/sp-mask.cpp +++ b/src/sp-mask.cpp @@ -37,16 +37,6 @@ struct SPMaskView { SPMaskView *sp_mask_view_new_prepend (SPMaskView *list, unsigned int key, Inkscape::DrawingItem *arenaitem); SPMaskView *sp_mask_view_list_remove (SPMaskView *list, SPMaskView *view); -#include "sp-factory.h" - -namespace { - SPObject* createMask() { - return new SPMask(); - } - - bool maskRegistered = SPFactory::instance().registerObject("svg:mask", createMask); -} - SPMask::SPMask() : SPObjectGroup() { this->maskUnits_set = FALSE; this->maskUnits = SP_CONTENT_UNITS_OBJECTBOUNDINGBOX; diff --git a/src/sp-mesh-array.cpp b/src/sp-mesh-array.cpp index 8bfe23656..445c9a8f6 100644 --- a/src/sp-mesh-array.cpp +++ b/src/sp-mesh-array.cpp @@ -32,7 +32,7 @@ * Authors: * Tavmjong Bah <tavmjong@free.fr> * - * Copyrigt (C) 2012 Tavmjong Bah + * Copyright (C) 2012, 2015 Tavmjong Bah * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -46,8 +46,8 @@ #include "document.h" #include "sp-root.h" +#include "sp-mesh.h" #include "sp-mesh-array.h" -#include "sp-mesh-gradient.h" #include "sp-mesh-row.h" #include "sp-mesh-patch.h" #include "sp-stop.h" @@ -289,7 +289,7 @@ bool SPMeshPatchI::tensorIsSet() { /** Return if tensor control point for "corner" i is set. */ -bool SPMeshPatchI::tensorIsSet( guint i ) { +bool SPMeshPatchI::tensorIsSet( unsigned int i ) { assert( i < 4 ); @@ -574,13 +574,54 @@ void SPMeshPatchI::setOpacity( guint i, gdouble opacity ) { }; -SPMeshNodeArray::SPMeshNodeArray( SPMeshGradient *mg ) { +SPMeshNodeArray::SPMeshNodeArray( SPMesh *mg ) { read( mg ); }; -void SPMeshNodeArray::read( SPMeshGradient *mg_in ) { + +// Copy constructor +SPMeshNodeArray::SPMeshNodeArray( const SPMeshNodeArray& rhs ) { + + built = false; + mg = NULL; + drag_valid = false; + + nodes = rhs.nodes; // This only copies the pointers but it does size the vector of vectors. + + for( unsigned i=0; i < nodes.size(); ++i ) { + for( unsigned j=0; j < nodes[i].size(); ++j ) { + nodes[i][j] = new SPMeshNode( *rhs.nodes[i][j] ); // Copy data. + } + } +}; + + +// Copy assignment operator +SPMeshNodeArray& SPMeshNodeArray::operator=( const SPMeshNodeArray& rhs ) { + + if( this == &rhs ) return *this; + + clear(); // Clear any existing array. + + built = false; + mg = NULL; + drag_valid = false; + + nodes = rhs.nodes; // This only copies the pointers but it does size the vector of vectors. + + for( unsigned i=0; i < nodes.size(); ++i ) { + for( unsigned j=0; j < nodes[i].size(); ++j ) { + nodes[i][j] = new SPMeshNode( *rhs.nodes[i][j] ); // Copy data. + } + } + + return *this; +}; + + +void SPMeshNodeArray::read( SPMesh *mg_in ) { mg = mg_in; @@ -600,7 +641,7 @@ void SPMeshNodeArray::read( SPMeshGradient *mg_in ) { if (SP_IS_MESHPATCH(po)) { - SPMeshPatch *patch = SP_MESHPATCH(po); + SPMeshpatch *patch = SP_MESHPATCH(po); // std::cout << "SPMeshNodeArray::read: row size: " << nodes.size() << std::endl; SPMeshPatchI new_patch( &nodes, irow, icolumn ); // Adds new nodes. @@ -797,7 +838,7 @@ void SPMeshNodeArray::read( SPMeshGradient *mg_in ) { /** Write repr using our array. */ -void SPMeshNodeArray::write( SPMeshGradient *mg ) { +void SPMeshNodeArray::write( SPMesh *mg ) { // std::cout << "SPMeshNodeArray::write: entrance:" << std::endl; // print(); @@ -848,14 +889,14 @@ void SPMeshNodeArray::write( SPMeshGradient *mg ) { for( guint i = 0; i < rows; ++i ) { // Write row - Inkscape::XML::Node *row = xml_doc->createElement("svg:meshRow"); + Inkscape::XML::Node *row = xml_doc->createElement("svg:meshrow"); mesh->appendChild( row ); // No attributes guint columns = array->patch_columns(); for( guint j = 0; j < columns; ++j ) { // Write patch - Inkscape::XML::Node *patch = xml_doc->createElement("svg:meshPatch"); + Inkscape::XML::Node *patch = xml_doc->createElement("svg:meshpatch"); SPMeshPatchI patchi( &(array->nodes), i, j ); @@ -926,10 +967,10 @@ void SPMeshNodeArray::write( SPMeshGradient *mg ) { break; case 'z': case 'Z': - std::cout << "sp_meshgradient_repr_write: bad path type" << path_type << std::endl; + std::cout << "sp_mesh_repr_write: bad path type" << path_type << std::endl; break; default: - std::cout << "sp_meshgradient_repr_write: unhandled path type" << path_type << std::endl; + std::cout << "sp_mesh_repr_write: unhandled path type" << path_type << std::endl; } stop->setAttribute("path", is.str().c_str()); // std::cout << "SPMeshNodeArray::write: path: " << is.str().c_str() << std::endl; @@ -998,7 +1039,7 @@ static SPColor default_color( SPItem *item ) { /** Create a default mesh. */ -void SPMeshNodeArray::create( SPMeshGradient *mg, SPItem *item, Geom::OptRect bbox ) { +void SPMeshNodeArray::create( SPMesh *mg, SPItem *item, Geom::OptRect bbox ) { // std::cout << "SPMeshNodeArray::create: Entrance" << std::endl; @@ -1036,10 +1077,10 @@ void SPMeshNodeArray::create( SPMeshGradient *mg, SPItem *item, Geom::OptRect bb guint prows = prefs->getInt("/tools/mesh/mesh_rows", 1); guint pcols = prefs->getInt("/tools/mesh/mesh_cols", 1); - SPGradientMeshType mesh_type = - (SPGradientMeshType) prefs->getInt("/tools/mesh/mesh_type", SP_GRADIENT_MESH_TYPE_NORMAL); + SPMeshGeometry mesh_type = + (SPMeshGeometry) prefs->getInt("/tools/mesh/mesh_geometry", SP_MESH_GEOMETRY_NORMAL); - if( mesh_type == SP_GRADIENT_MESH_TYPE_CONICAL ) { + if( mesh_type == SP_MESH_GEOMETRY_CONICAL ) { // Conical gradient.. for any shape/path using geometric bounding box. @@ -1382,6 +1423,346 @@ void SPMeshNodeArray::print() { }; + +/* +double hermite( const double p0, const double p1, const double m0, const double m1, const double t ) { + double t2 = t*t; + double t3 = t2*t; + + double result = (2.0*t3 - 3.0*t2 +1.0) * p0 + + (t3 - 2.0*t2 + t) * m0 + + (-2.0*t3 + 3.0*t2) * p1 + + (t3 -t2) * m1; + + return result; +} +*/ + +class SPMeshSmoothCorner { + + enum { + AMP, + DX_LEFT, + DX_RIGHT, + DY_TOP, + DY_BOTTOM, + DXY_LT, + DXY_RT, + DXY_LB, + DXY_RB + }; + +public: + SPMeshSmoothCorner() { + for( unsigned i = 0; i < 3; ++i ) { + for( unsigned j = 0; j < 4; ++j ) { + g[i][j] = 0; + } + } + } + + double g[3][8]; // 3 colors, 8 parameters: see enum. + Geom::Point p; // Location of point +}; + +// Find slope at point 1 given values at previous and next points +// Return value is slope in user space +double find_slope1( const double &p0, const double &p1, const double &p2, + const double &d01, const double &d12 ) { + + double slope = 0; + + if( d01 > 0 && d12 > 0 ) { + slope = 0.5 * ( (p1 - p0)/d01 + (p2 - p1)/d12 ); + + if( ( p0 > p1 && p1 < p2 ) || + ( p0 < p1 && p1 > p2 ) ) { + // At minimum or maximum, use slope of zero + slope = 0; + } else { + // Ensure we don't overshoot + if( fabs(slope) > fabs(3*(p1-p0)/d01) ) { + slope = 3*(p1-p0)/d01; + } + if( fabs(slope) > fabs(3*(p2-p1)/d12) ) { + slope = 3*(p2-p1)/d12; + } + } + } else { + // Do something clever + } + return slope; +}; + + +/* +// Find slope at point 0 given values at previous and next points +// TO DO: TAKE DISTANCE BETWEEN POINTS INTO ACCOUNT +double find_slope2( double pmm, double ppm, double pmp, double ppp, double p0 ) { + + // pmm == d[i-1][j-1], ... 'm' is minus, 'p' is plus + double slope = (ppp - ppm - pmp + pmm)/2.0; + if( (ppp > p0 && ppm > p0 && pmp > p0 && pmm > 0) || + (ppp < p0 && ppm < p0 && pmp < p0 && pmm < 0) ) { + // At minimum or maximum, use slope of zero + slope = 0; + } else { + // Don't really know what to do here + if( fabs(slope) > fabs(3*(ppp-p0)) ) { + slope = 3*(ppp-p0); + } + if( fabs(slope) > fabs(3*(pmp-p0)) ) { + slope = 3*(pmp-p0); + } + if( fabs(slope) > fabs(3*(ppm-p0)) ) { + slope = 3*(ppm-p0); + } + if( fabs(slope) > fabs(3*(pmm-p0)) ) { + slope = 3*(pmm-p0); + } + } + return slope; +} +*/ + +// https://en.wikipedia.org/wiki/Bicubic_interpolation +void invert( const double v[16], double alpha[16] ) { + + const double A[16][16] = { + + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + {-3, 3, 0, 0, -2,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 2,-2, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, -3, 3, 0, 0, -2,-1, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 2,-2, 0, 0, 1, 1, 0, 0 }, + {-3, 0, 3, 0, 0, 0, 0, 0, -2, 0,-1, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, -3, 0, 3, 0, 0, 0, 0, 0, -2, 0,-1, 0 }, + { 9,-9,-9, 9, 6, 3,-6,-3, 6,-6, 3,-3, 4, 2, 2, 1 }, + {-6, 6, 6,-6, -3,-3, 3, 3, -4, 4,-2, 2, -2,-2,-1,-1 }, + { 2, 0,-2, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 2, 0,-2, 0, 0, 0, 0, 0, 1, 0, 1, 0 }, + {-6, 6, 6,-6, -4,-2, 4, 2, -3, 3,-3, 3, -2,-1,-2,-1 }, + { 4,-4,-4, 4, 2, 2,-2,-2, 2,-2, 2,-2, 1, 1, 1, 1 } + }; + + for( unsigned i = 0; i < 16; ++i ) { + alpha[i] = 0; + for( unsigned j = 0; j < 16; ++j ) { + alpha[i] += A[i][j]*v[j]; + } + } +} + +double sum( const double alpha[16], const double& x, const double& y ) { + + double result = 0; + + double xx = x*x; + double xxx = xx * x; + double yy = y*y; + double yyy = yy * y; + + result += alpha[ 0 ]; + result += alpha[ 1 ] * x; + result += alpha[ 2 ] * xx; + result += alpha[ 3 ] * xxx; + result += alpha[ 4 ] * y; + result += alpha[ 5 ] * y * x; + result += alpha[ 6 ] * y * xx; + result += alpha[ 7 ] * y * xxx; + result += alpha[ 8 ] * yy; + result += alpha[ 9 ] * yy * x; + result += alpha[ 10 ] * yy * xx; + result += alpha[ 11 ] * yy * xxx; + result += alpha[ 12 ] * yyy; + result += alpha[ 13 ] * yyy * x; + result += alpha[ 14 ] * yyy * xx; + result += alpha[ 15 ] * yyy * xxx; + + return result; +} + +/** + Fill 'smooth' with a smoothed version of the array by subdividing each patch into smaller patches. +*/ +void SPMeshNodeArray::bicubic( SPMeshNodeArray* smooth, SPMeshType type ) { + + + *smooth = *this; // Deep copy via copy assignment constructor, smooth cleared before copy + // std::cout << "SPMeshNodeArray::smooth2(): " << this->patch_rows() << " " << smooth->patch_columns() << std::endl; + // std::cout << " " << smooth << " " << this << std::endl; + + // Find derivatives at corners + + // Create array of corner points + std::vector< std::vector <SPMeshSmoothCorner> > d; + d.resize( smooth->patch_rows() + 1 ); + for( unsigned i = 0; i < d.size(); ++i ) { + d[i].resize( smooth->patch_columns() + 1 ); + for( unsigned j = 0; j < d[i].size(); ++j ) { + float rgb_color[3]; + sp_color_get_rgb_floatv( &this->nodes[ i*3 ][ j*3 ]->color, rgb_color ); + d[i][j].g[0][0] = rgb_color[ 0 ]; + d[i][j].g[1][0] = rgb_color[ 1 ]; + d[i][j].g[2][0] = rgb_color[ 2 ]; + d[i][j].p = this->nodes[ i*3 ][ j*3 ]->p; + } + } + + // Calculate interior derivatives + for( unsigned i = 0; i < d.size(); ++i ) { + for( unsigned j = 0; j < d[i].size(); ++j ) { + for( unsigned k = 0; k < 3; ++k ) { // Loop over colors + + // dx + + if( i != 0 && i != d.size()-1 ) { + double lm = Geom::distance( d[i-1][j].p, d[i][j].p ); + double lp = Geom::distance( d[i+1][j].p, d[i][j].p ); + d[i][j].g[k][1] = find_slope1( d[i-1][j].g[k][0], d[i][j].g[k][0], d[i+1][j].g[k][0], lm, lp ); + } + + // dy + if( j != 0 && j != d[i].size()-1 ) { + double lm = Geom::distance( d[i][j-1].p, d[i][j].p ); + double lp = Geom::distance( d[i][j+1].p, d[i][j].p ); + d[i][j].g[k][2] = find_slope1( d[i][j-1].g[k][0], d[i][j].g[k][0], d[i][j+1].g[k][0], lm, lp ); + } + + // dxdy if needed, need to take lengths into account + // if( i != 0 && i != d.size()-1 && j != 0 && j != d[i].size()-1 ) { + // d[i][j].g[k][3] = find_slope2( d[i-1][j-1].g[k][0], d[i+1][j-1].g[k][0], + // d[i-1][j+1].g[k][0], d[i-1][j-1].g[k][0], + // d[i][j].g[k][0] ); + // } + + } + } + } + + // Calculate exterior derivatives + // We need to do this after calculating interior derivatives as we need to already + // have the non-exterior derivative calculated for finding the parabola. + for( unsigned j = 0; j< d[0].size(); ++j ) { + for( unsigned k = 0; k < 3; ++k ) { // Loop over colors + + // Parabolic + double d0 = Geom::distance( d[1][j].p, d[0 ][j].p ); + if( d0 > 0 ) { + d[0][j].g[k][1] = 2.0*(d[1][j].g[k][0] - d[0 ][j].g[k][0])/d0 - d[1][j].g[k][1]; + } else { + d[0][j].g[k][1] = 0; + } + + unsigned z = d.size()-1; + double dz = Geom::distance( d[z][j].p, d[z-1][j].p ); + if( dz > 0 ) { + d[z][j].g[k][1] = 2.0*(d[z][j].g[k][0] - d[z-1][j].g[k][0])/dz - d[z-1][j].g[k][1]; + } else { + d[z][j].g[k][1] = 0; + } + } + } + + for( unsigned i = 0; i< d.size(); ++i ) { + for( unsigned k = 0; k < 3; ++k ) { // Loop over colors + + // Parabolic + double d0 = Geom::distance( d[i][1].p, d[i][0 ].p ); + if( d0 > 0 ) { + d[i][0].g[k][2] = 2.0*(d[i][1].g[k][0] - d[i][0 ].g[k][0])/d0 - d[i][1].g[k][2]; + } else { + d[i][0].g[k][2] = 0; + } + + unsigned z = d[0].size()-1; + double dz = Geom::distance( d[i][z].p, d[i][z-1].p ); + if( dz > 0 ) { + d[i][z].g[k][2] = 2.0*(d[i][z].g[k][0] - d[i][z-1].g[k][0])/dz - d[i][z-1].g[k][2]; + } else { + d[i][z].g[k][2] = 0; + } + } + } + + // Leave outside corner cross-derivatives at zero. + + // Next split each patch into 8x8 smaller patches. + + // Split each row into eight rows. + // Must do it from end so inserted rows don't mess up indexing + for( int i = smooth->patch_rows() - 1; i >= 0; --i ) { + smooth->split_row( i, unsigned(8) ); + } + + // Split each column into eight columns. + // Must do it from end so inserted columns don't mess up indexing + for( int i = smooth->patch_columns() - 1; i >= 0; --i ) { + smooth->split_column( i, (unsigned)8 ); + } + + // Fill new patches + for( unsigned i = 0; i < this->patch_rows(); ++i ) { + for( unsigned j = 0; j < this->patch_columns(); ++j ) { + + double dx0 = Geom::distance( d[i ][j ].p, d[i+1][j ].p ); + double dx1 = Geom::distance( d[i ][j+1].p, d[i+1][j+1].p ); + double dy0 = Geom::distance( d[i ][j ].p, d[i ][j+1].p ); + double dy1 = Geom::distance( d[i+1][j ].p, d[i+1][j+1].p ); + + // Temp loop over 0..8 to get last column/row edges + float r[3][9][9]; // result + for( unsigned m = 0; m < 3; ++m ) { + + double v[16]; + v[ 0] = d[i ][j ].g[m][0]; + v[ 1] = d[i+1][j ].g[m][0]; + v[ 2] = d[i ][j+1].g[m][0]; + v[ 3] = d[i+1][j+1].g[m][0]; + v[ 4] = d[i ][j ].g[m][1]*dx0; + v[ 5] = d[i+1][j ].g[m][1]*dx0; + v[ 6] = d[i ][j+1].g[m][1]*dx1; + v[ 7] = d[i+1][j+1].g[m][1]*dx1; + v[ 8] = d[i ][j ].g[m][2]*dy0; + v[ 9] = d[i+1][j ].g[m][2]*dy1; + v[10] = d[i ][j+1].g[m][2]*dy0; + v[11] = d[i+1][j+1].g[m][2]*dy1; + v[12] = d[i ][j ].g[m][3]; + v[13] = d[i+1][j ].g[m][3]; + v[14] = d[i ][j+1].g[m][3]; + v[15] = d[i+1][j+1].g[m][3]; + + double alpha[16]; + invert( v, alpha ); + + for( unsigned k = 0; k < 9; ++k ) { + for( unsigned l = 0; l < 9; ++l ) { + double x = k/8.0; + double y = l/8.0; + r[m][k][l] = sum( alpha, x, y ); + // Clamp to allowed values + if( r[m][k][l] > 1.0 ) + r[m][k][l] = 1.0; + if( r[m][k][l] < 0.0 ) + r[m][k][l] = 0.0; + } + } + + } // Loop over colors + + for( unsigned k = 0; k < 9; ++k ) { + for( unsigned l = 0; l < 9; ++l ) { + // Every third node is a corner node + smooth->nodes[ (i*8+k)*3 ][(j*8+l)*3 ]->color.set( r[0][k][l], r[1][k][l], r[2][k][l] ); + } + } + } + } +} + /** Number of patch rows. */ @@ -2239,7 +2620,7 @@ guint32 average_color(guint32 c1, guint32 c2, gdouble p); /** Split a row into n equal parts. */ -void SPMeshNodeArray::split_row( guint row, guint n ) { +void SPMeshNodeArray::split_row( unsigned int row, unsigned int n ) { double nn = n; if( n > 1 ) split_row( row, (nn-1)/nn ); @@ -2249,7 +2630,7 @@ void SPMeshNodeArray::split_row( guint row, guint n ) { /** Split a column into n equal parts. */ -void SPMeshNodeArray::split_column( guint col, guint n ) { +void SPMeshNodeArray::split_column( unsigned int col, unsigned int n ) { double nn = n; if( n > 1 ) split_column( col, (nn-1)/nn ); @@ -2259,7 +2640,7 @@ void SPMeshNodeArray::split_column( guint col, guint n ) { /** Split a row into two rows at coord (fraction of row height). */ -void SPMeshNodeArray::split_row( guint row, double coord ) { +void SPMeshNodeArray::split_row( unsigned int row, double coord ) { // std::cout << "Splitting row: " << row << " at " << coord << std::endl; // print(); @@ -2382,7 +2763,7 @@ void SPMeshNodeArray::split_row( guint row, double coord ) { /** Split a column into two columns at coord (fraction of column width). */ -void SPMeshNodeArray::split_column( guint col, double coord ) { +void SPMeshNodeArray::split_column( unsigned int col, double coord ) { // std::cout << "Splitting column: " << col << " at " << coord << std::endl; // print(); diff --git a/src/sp-mesh-array.h b/src/sp-mesh-array.h index 330f6d87b..b078b221e 100644 --- a/src/sp-mesh-array.h +++ b/src/sp-mesh-array.h @@ -45,6 +45,16 @@ // For color picking #include "sp-item.h" +enum SPMeshType { + SP_MESH_TYPE_COONS, + SP_MESH_TYPE_BICUBIC +}; + +enum SPMeshGeometry { + SP_MESH_GEOMETRY_NORMAL, + SP_MESH_GEOMETRY_CONICAL +}; + enum NodeType { MG_NODE_TYPE_UNKNOWN, MG_NODE_TYPE_CORNER, @@ -125,14 +135,14 @@ public: void setOpacity( unsigned int i, double o ); }; -class SPMeshGradient; +class SPMesh; // An array of mesh nodes. class SPMeshNodeArray { // Should be private public: - SPMeshGradient *mg; + SPMesh *mg; std::vector< std::vector< SPMeshNode* > > nodes; public: @@ -147,16 +157,22 @@ public: friend class SPMeshPatchI; SPMeshNodeArray() { built = false; mg = NULL; drag_valid = false; }; - SPMeshNodeArray( SPMeshGradient *mg ); + SPMeshNodeArray( SPMesh *mg ); + SPMeshNodeArray( const SPMeshNodeArray& rhs ); + SPMeshNodeArray& operator=(const SPMeshNodeArray& rhs); + ~SPMeshNodeArray() { clear(); }; bool built; - void read( SPMeshGradient *mg ); - void write( SPMeshGradient *mg ); - void create( SPMeshGradient *mg, SPItem *item, Geom::OptRect bbox ); + void read( SPMesh *mg ); + void write( SPMesh *mg ); + void create( SPMesh *mg, SPItem *item, Geom::OptRect bbox ); void clear(); void print(); + // Fill 'smooth' with a smoothed version by subdividing each patch. + void bicubic( SPMeshNodeArray* smooth, SPMeshType type); + // Get size of patch unsigned int patch_rows(); unsigned int patch_columns(); diff --git a/src/sp-mesh-gradient.cpp b/src/sp-mesh-gradient.cpp deleted file mode 100644 index bf28164a9..000000000 --- a/src/sp-mesh-gradient.cpp +++ /dev/null @@ -1,216 +0,0 @@ -#include <glibmm.h> - -#include "attributes.h" -#include "display/cairo-utils.h" -#include "xml/repr.h" - -#include "sp-mesh-gradient.h" - -#include "sp-factory.h" - -namespace { - SPObject* createMeshGradient() { - return new SPMeshGradient(); - } - - bool meshGradientRegistered = SPFactory::instance().registerObject("svg:meshGradient", createMeshGradient); -} - - -/* - * Mesh Gradient - */ -//#define MESH_DEBUG -SPMeshGradient::SPMeshGradient() : SPGradient() { - // Start coordinate of mesh - this->x.unset(SVGLength::NONE, 0.0, 0.0); - this->y.unset(SVGLength::NONE, 0.0, 0.0); -} - -SPMeshGradient::~SPMeshGradient() { -} - -void SPMeshGradient::build(SPDocument *document, Inkscape::XML::Node *repr) { - SPGradient::build(document, repr); - - // Start coordinate of mesh - this->readAttr( "x" ); - this->readAttr( "y" ); -} - - -void SPMeshGradient::set(unsigned key, gchar const *value) { - switch (key) { - case SP_ATTR_X: - if (!this->x.read(value)) { - this->x.unset(SVGLength::NONE, 0.0, 0.0); - } - - this->requestModified(SP_OBJECT_MODIFIED_FLAG); - break; - - case SP_ATTR_Y: - if (!this->y.read(value)) { - this->y.unset(SVGLength::NONE, 0.0, 0.0); - } - - this->requestModified(SP_OBJECT_MODIFIED_FLAG); - break; - - default: - SPGradient::set(key, value); - break; - } -} - -/** - * Write mesh gradient attributes to associated repr. - */ -Inkscape::XML::Node* SPMeshGradient::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { -#ifdef MESH_DEBUG - std::cout << "sp_meshgradient_write() ***************************" << std::endl; -#endif - - if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { - repr = xml_doc->createElement("svg:meshGradient"); - } - - if ((flags & SP_OBJECT_WRITE_ALL) || this->x._set) { - sp_repr_set_svg_double(repr, "x", this->x.computed); - } - - if ((flags & SP_OBJECT_WRITE_ALL) || this->y._set) { - sp_repr_set_svg_double(repr, "y", this->y.computed); - } - - SPGradient::write(xml_doc, repr, flags); - - return repr; -} - -void -sp_meshgradient_repr_write(SPMeshGradient *mg) -{ - mg->array.write( mg ); -} - - -cairo_pattern_t* SPMeshGradient::pattern_new(cairo_t * /*ct*/, -#if defined(MESH_DEBUG) || (CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 11, 4)) - Geom::OptRect const &bbox, - double opacity -#else - Geom::OptRect const & /*bbox*/, - double /*opacity*/ -#endif - ) -{ - using Geom::X; - using Geom::Y; - -#ifdef MESH_DEBUG - std::cout << "sp_meshgradient_create_pattern: (" << bbox->x0 << "," << bbox->y0 << ") (" << bbox->x1 << "," << bbox->y1 << ") " << opacity << std::endl; -#endif - - this->ensureArray(); - - cairo_pattern_t *cp = NULL; - -#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 11, 4) - SPMeshNodeArray* array = &(this->array); - - cp = cairo_pattern_create_mesh(); - - for( unsigned int i = 0; i < array->patch_rows(); ++i ) { - for( unsigned int j = 0; j < array->patch_columns(); ++j ) { - - SPMeshPatchI patch( &(array->nodes), i, j ); - - cairo_mesh_pattern_begin_patch( cp ); - cairo_mesh_pattern_move_to( cp, patch.getPoint( 0, 0 )[X], patch.getPoint( 0, 0 )[Y] ); - - for( unsigned int k = 0; k < 4; ++k ) { -#ifdef DEBUG_MESH - std::cout << i << " " << j << " " - << patch.getPathType( k ) << " ("; - for( int p = 0; p < 4; ++p ) { - std::cout << patch.getPoint( k, p ); - } - std::cout << ") " - << patch.getColor( k ).toString() << std::endl; -#endif - - switch ( patch.getPathType( k ) ) { - case 'l': - case 'L': - case 'z': - case 'Z': - cairo_mesh_pattern_line_to( cp, - patch.getPoint( k, 3 )[X], - patch.getPoint( k, 3 )[Y] ); - break; - case 'c': - case 'C': - { - std::vector< Geom::Point > pts = patch.getPointsForSide( k ); - cairo_mesh_pattern_curve_to( cp, - pts[1][X], pts[1][Y], - pts[2][X], pts[2][Y], - pts[3][X], pts[3][Y] ); - break; - } - default: - // Shouldn't happen - std::cout << "sp_meshgradient_create_pattern: path error" << std::endl; - } - - if( patch.tensorIsSet(k) ) { - // Tensor point defined relative to corner. - Geom::Point t = patch.getTensorPoint(k); - cairo_mesh_pattern_set_control_point( cp, k, t[X], t[Y] ); - //std::cout << " sp_meshgradient_create_pattern: tensor " << k - // << " set to " << t << "." << std::endl; - } else { - // Geom::Point t = patch.coonsTensorPoint(k); - //std::cout << " sp_meshgradient_create_pattern: tensor " << k - // << " calculated as " << t << "." <<std::endl; - } - - cairo_mesh_pattern_set_corner_color_rgba( - cp, k, - patch.getColor( k ).v.c[0], - patch.getColor( k ).v.c[1], - patch.getColor( k ).v.c[2], - patch.getOpacity( k ) * opacity ); - } - - cairo_mesh_pattern_end_patch( cp ); - } - } - - // set pattern matrix - Geom::Affine gs2user = this->gradientTransform; - if (this->getUnits() == SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX) { - Geom::Affine bbox2user(bbox->width(), 0, 0, bbox->height(), bbox->left(), bbox->top()); - gs2user *= bbox2user; - } - ink_cairo_pattern_set_matrix(cp, gs2user.inverse()); - -#else - static bool shown = false; - if( !shown ) { - std::cout << "sp_meshgradient_create_pattern: needs cairo >= 1.11.4, using " - << cairo_version_string() << std::endl; - shown = true; - } -#endif - -/* - cairo_pattern_t *cp = cairo_pattern_create_radial( - rg->fx.computed, rg->fy.computed, 0, - rg->cx.computed, rg->cy.computed, rg->r.computed); - sp_gradient_pattern_common_setup(cp, gr, bbox, opacity); -*/ - - return cp; -} diff --git a/src/sp-mesh-patch.cpp b/src/sp-mesh-patch.cpp index 216de8270..834c09935 100644 --- a/src/sp-mesh-patch.cpp +++ b/src/sp-mesh-patch.cpp @@ -20,19 +20,9 @@ #include "attributes.h" #include "xml/repr.h" -#include "sp-factory.h" - -namespace { - SPObject* createMeshPatch() { - return new SPMeshPatch(); - } - - bool meshPatchRegistered = SPFactory::instance().registerObject("svg:meshPatch", createMeshPatch); -} - -SPMeshPatch* SPMeshPatch::getNextMeshPatch() +SPMeshpatch* SPMeshpatch::getNextMeshpatch() { - SPMeshPatch *result = 0; + SPMeshpatch *result = 0; for (SPObject* obj = getNext(); obj && !result; obj = obj->getNext()) { if (SP_IS_MESHPATCH(obj)) { @@ -43,19 +33,19 @@ SPMeshPatch* SPMeshPatch::getNextMeshPatch() return result; } -SPMeshPatch* SPMeshPatch::getPrevMeshPatch() +SPMeshpatch* SPMeshpatch::getPrevMeshpatch() { - SPMeshPatch *result = 0; + SPMeshpatch *result = 0; for (SPObject* obj = getPrev(); obj; obj = obj->getPrev()) { - // The closest previous SPObject that is an SPMeshPatch *should* be ourself. + // The closest previous SPObject that is an SPMeshpatch *should* be ourself. if (SP_IS_MESHPATCH(obj)) { - SPMeshPatch* meshpatch = SP_MESHPATCH(obj); + SPMeshpatch* meshpatch = SP_MESHPATCH(obj); // Sanity check to ensure we have a proper sibling structure. - if (meshpatch->getNextMeshPatch() == this) { + if (meshpatch->getNextMeshpatch() == this) { result = meshpatch; } else { - g_warning("SPMeshPatch previous/next relationship broken"); + g_warning("SPMeshpatch previous/next relationship broken"); } break; } @@ -69,14 +59,14 @@ SPMeshPatch* SPMeshPatch::getPrevMeshPatch() * Mesh Patch */ -SPMeshPatch::SPMeshPatch() : SPObject() { +SPMeshpatch::SPMeshpatch() : SPObject() { this->tensor_string = NULL; } -SPMeshPatch::~SPMeshPatch() { +SPMeshpatch::~SPMeshpatch() { } -void SPMeshPatch::build(SPDocument* doc, Inkscape::XML::Node* repr) { +void SPMeshpatch::build(SPDocument* doc, Inkscape::XML::Node* repr) { SPObject::build(doc, repr); this->readAttr( "tensor" ); @@ -86,7 +76,7 @@ void SPMeshPatch::build(SPDocument* doc, Inkscape::XML::Node* repr) { * Virtual build: set meshpatch attributes from its associated XML node. */ -void SPMeshPatch::set(unsigned int key, const gchar* value) { +void SPMeshpatch::set(unsigned int key, const gchar* value) { switch (key) { case SP_ATTR_TENSOR: { if (value) { @@ -105,9 +95,9 @@ void SPMeshPatch::set(unsigned int key, const gchar* value) { * Virtual set: set attribute to value. */ -Inkscape::XML::Node* SPMeshPatch::write(Inkscape::XML::Document* xml_doc, Inkscape::XML::Node* repr, guint flags) { +Inkscape::XML::Node* SPMeshpatch::write(Inkscape::XML::Document* xml_doc, Inkscape::XML::Node* repr, guint flags) { if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { - repr = xml_doc->createElement("svg:meshPatch"); + repr = xml_doc->createElement("svg:meshpatch"); } SPObject::write(xml_doc, repr, flags); diff --git a/src/sp-mesh-patch.h b/src/sp-mesh-patch.h index e57ad1699..88d6325c3 100644 --- a/src/sp-mesh-patch.h +++ b/src/sp-mesh-patch.h @@ -2,7 +2,7 @@ #define SEEN_SP_MESHPATCH_H /** \file - * SPMeshPatch: SVG <meshpatch> implementation. + * SPMeshpatch: SVG <meshpatch> implementation. */ /* * Authors: Tavmjong Bah @@ -15,17 +15,17 @@ #include <glibmm/ustring.h> #include "sp-object.h" -#define SP_MESHPATCH(obj) (dynamic_cast<SPMeshPatch*>((SPObject*)obj)) -#define SP_IS_MESHPATCH(obj) (dynamic_cast<const SPMeshPatch*>((SPObject*)obj) != NULL) +#define SP_MESHPATCH(obj) (dynamic_cast<SPMeshpatch*>((SPObject*)obj)) +#define SP_IS_MESHPATCH(obj) (dynamic_cast<const SPMeshpatch*>((SPObject*)obj) != NULL) -/** Gradient MeshPatch. */ -class SPMeshPatch : public SPObject { +/** Gradient Meshpatch. */ +class SPMeshpatch : public SPObject { public: - SPMeshPatch(); - virtual ~SPMeshPatch(); + SPMeshpatch(); + virtual ~SPMeshpatch(); - SPMeshPatch* getNextMeshPatch(); - SPMeshPatch* getPrevMeshPatch(); + SPMeshpatch* getNextMeshpatch(); + SPMeshpatch* getPrevMeshpatch(); Glib::ustring * tensor_string; //SVGLength tx[4]; // Tensor points //SVGLength ty[4]; // Tensor points diff --git a/src/sp-mesh-row.cpp b/src/sp-mesh-row.cpp index 07747f7f5..dd7948bdf 100644 --- a/src/sp-mesh-row.cpp +++ b/src/sp-mesh-row.cpp @@ -1,5 +1,5 @@ /** @file - * @gradient meshpatch class. + * @gradient meshrow class. */ /* Authors: * Lauris Kaplinski <lauris@kaplinski.com> @@ -19,19 +19,9 @@ #include "xml/repr.h" -#include "sp-factory.h" - -namespace { - SPObject* createMeshRow() { - return new SPMeshRow(); - } - - bool meshRowRegistered = SPFactory::instance().registerObject("svg:meshRow", createMeshRow); -} - -SPMeshRow* SPMeshRow::getNextMeshRow() +SPMeshrow* SPMeshrow::getNextMeshrow() { - SPMeshRow *result = 0; + SPMeshrow *result = 0; for (SPObject* obj = getNext(); obj && !result; obj = obj->getNext()) { if (SP_IS_MESHROW(obj)) { @@ -42,19 +32,19 @@ SPMeshRow* SPMeshRow::getNextMeshRow() return result; } -SPMeshRow* SPMeshRow::getPrevMeshRow() +SPMeshrow* SPMeshrow::getPrevMeshrow() { - SPMeshRow *result = 0; + SPMeshrow *result = 0; for (SPObject* obj = getPrev(); obj; obj = obj->getPrev()) { - // The closest previous SPObject that is an SPMeshRow *should* be ourself. + // The closest previous SPObject that is an SPMeshrow *should* be ourself. if (SP_IS_MESHROW(obj)) { - SPMeshRow* meshrow = SP_MESHROW(obj); + SPMeshrow* meshrow = SP_MESHROW(obj); // Sanity check to ensure we have a proper sibling structure. - if (meshrow->getNextMeshRow() == this) { + if (meshrow->getNextMeshrow() == this) { result = meshrow; } else { - g_warning("SPMeshRow previous/next relationship broken"); + g_warning("SPMeshrow previous/next relationship broken"); } break; } @@ -67,13 +57,13 @@ SPMeshRow* SPMeshRow::getPrevMeshRow() /* * Mesh Row */ -SPMeshRow::SPMeshRow() : SPObject() { +SPMeshrow::SPMeshrow() : SPObject() { } -SPMeshRow::~SPMeshRow() { +SPMeshrow::~SPMeshrow() { } -void SPMeshRow::build(SPDocument* doc, Inkscape::XML::Node* repr) { +void SPMeshrow::build(SPDocument* doc, Inkscape::XML::Node* repr) { SPObject::build(doc, repr); } @@ -81,16 +71,16 @@ void SPMeshRow::build(SPDocument* doc, Inkscape::XML::Node* repr) { * Virtual build: set meshrow attributes from its associated XML node. */ -void SPMeshRow::set(unsigned int /*key*/, const gchar* /*value*/) { +void SPMeshrow::set(unsigned int /*key*/, const gchar* /*value*/) { } /** * Virtual set: set attribute to value. */ -Inkscape::XML::Node* SPMeshRow::write(Inkscape::XML::Document* xml_doc, Inkscape::XML::Node* repr, guint flags) { +Inkscape::XML::Node* SPMeshrow::write(Inkscape::XML::Document* xml_doc, Inkscape::XML::Node* repr, guint flags) { if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { - repr = xml_doc->createElement("svg:meshRow"); + repr = xml_doc->createElement("svg:meshrow"); } SPObject::write(xml_doc, repr, flags); diff --git a/src/sp-mesh-row.h b/src/sp-mesh-row.h index 793b5a645..ffb3efa6b 100644 --- a/src/sp-mesh-row.h +++ b/src/sp-mesh-row.h @@ -2,7 +2,7 @@ #define SEEN_SP_MESHROW_H /** \file - * SPMeshRow: SVG <meshRow> implementation. + * SPMeshrow: SVG <meshrow> implementation. */ /* * Authors: Tavmjong Bah @@ -13,17 +13,17 @@ #include "sp-object.h" -#define SP_MESHROW(obj) (dynamic_cast<SPMeshRow*>((SPObject*)obj)) -#define SP_IS_MESHROW(obj) (dynamic_cast<const SPMeshRow*>((SPObject*)obj) != NULL) +#define SP_MESHROW(obj) (dynamic_cast<SPMeshrow*>((SPObject*)obj)) +#define SP_IS_MESHROW(obj) (dynamic_cast<const SPMeshrow*>((SPObject*)obj) != NULL) -/** Gradient MeshRow. */ -class SPMeshRow : public SPObject { +/** Gradient Meshrow. */ +class SPMeshrow : public SPObject { public: - SPMeshRow(); - virtual ~SPMeshRow(); + SPMeshrow(); + virtual ~SPMeshrow(); - SPMeshRow* getNextMeshRow(); - SPMeshRow* getPrevMeshRow(); + SPMeshrow* getNextMeshrow(); + SPMeshrow* getPrevMeshrow(); protected: virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); diff --git a/src/sp-mesh.cpp b/src/sp-mesh.cpp new file mode 100644 index 000000000..e04c29e8e --- /dev/null +++ b/src/sp-mesh.cpp @@ -0,0 +1,252 @@ +#include <glibmm.h> + +#include "attributes.h" +#include "display/cairo-utils.h" +#include "xml/repr.h" + +#include "sp-mesh.h" + +/* + * Mesh Gradient + */ +//#define MESH_DEBUG +SPMesh::SPMesh() : SPGradient(), type( SP_MESH_TYPE_COONS ), type_set(false) { + // Start coordinate of mesh + this->x.unset(SVGLength::NONE, 0.0, 0.0); + this->y.unset(SVGLength::NONE, 0.0, 0.0); +} + +SPMesh::~SPMesh() { +} + +void SPMesh::build(SPDocument *document, Inkscape::XML::Node *repr) { + SPGradient::build(document, repr); + + // Start coordinate of mesh + this->readAttr( "x" ); + this->readAttr( "y" ); + + this->readAttr( "type" ); +} + + +void SPMesh::set(unsigned key, gchar const *value) { + switch (key) { + case SP_ATTR_X: + if (!this->x.read(value)) { + this->x.unset(SVGLength::NONE, 0.0, 0.0); + } + + this->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + + case SP_ATTR_Y: + if (!this->y.read(value)) { + this->y.unset(SVGLength::NONE, 0.0, 0.0); + } + + this->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + + case SP_ATTR_TYPE: + if (value) { + if (!strcmp(value, "coons")) { + this->type = SP_MESH_TYPE_COONS; + } else if (!strcmp(value, "bicubic")) { + this->type = SP_MESH_TYPE_BICUBIC; + } else { + std::cerr << "SPMesh::set(): invalid value " << value << std::endl; + } + this->type_set = TRUE; + } else { + // std::cout << "SPMesh::set() No value " << std::endl; + this->type = SP_MESH_TYPE_COONS; + this->type_set = FALSE; + } + + this->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + + default: + SPGradient::set(key, value); + break; + } +} + +/** + * Write mesh gradient attributes to associated repr. + */ +Inkscape::XML::Node* SPMesh::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { +#ifdef MESH_DEBUG + std::cout << "sp_mesh_write() ***************************" << std::endl; +#endif + + if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { + repr = xml_doc->createElement("svg:mesh"); + } + + if ((flags & SP_OBJECT_WRITE_ALL) || this->x._set) { + sp_repr_set_svg_double(repr, "x", this->x.computed); + } + + if ((flags & SP_OBJECT_WRITE_ALL) || this->y._set) { + sp_repr_set_svg_double(repr, "y", this->y.computed); + } + + if ((flags & SP_OBJECT_WRITE_ALL) || this->type_set) { + switch (this->type) { + case SP_MESH_TYPE_COONS: + repr->setAttribute("type", "coons"); + break; + case SP_MESH_TYPE_BICUBIC: + repr->setAttribute("type", "bicubic"); + break; + default: + // Do nothing + break; + } + } + + SPGradient::write(xml_doc, repr, flags); + + return repr; +} + +void +sp_mesh_repr_write(SPMesh *mg) +{ + mg->array.write( mg ); +} + + +cairo_pattern_t* SPMesh::pattern_new(cairo_t * /*ct*/, +#if defined(MESH_DEBUG) || (CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 11, 4)) + Geom::OptRect const &bbox, + double opacity +#else + Geom::OptRect const & /*bbox*/, + double /*opacity*/ +#endif + ) +{ + using Geom::X; + using Geom::Y; + +#ifdef MESH_DEBUG + std::cout << "sp_mesh_create_pattern: (" << bbox->x0 << "," << bbox->y0 << ") (" << bbox->x1 << "," << bbox->y1 << ") " << opacity << std::endl; +#endif + + this->ensureArray(); + + cairo_pattern_t *cp = NULL; + +#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 11, 4) + SPMeshNodeArray* my_array = &array; + + if( type_set ) { + switch (type) { + case SP_MESH_TYPE_COONS: + // std::cout << "SPMesh::pattern_new: Coons" << std::endl; + break; + case SP_MESH_TYPE_BICUBIC: + array.bicubic( &array_smoothed, type ); + my_array = &array_smoothed; + break; + } + } + + cp = cairo_pattern_create_mesh(); + + for( unsigned int i = 0; i < my_array->patch_rows(); ++i ) { + for( unsigned int j = 0; j < my_array->patch_columns(); ++j ) { + + SPMeshPatchI patch( &(my_array->nodes), i, j ); + + cairo_mesh_pattern_begin_patch( cp ); + cairo_mesh_pattern_move_to( cp, patch.getPoint( 0, 0 )[X], patch.getPoint( 0, 0 )[Y] ); + + for( unsigned int k = 0; k < 4; ++k ) { +#ifdef DEBUG_MESH + std::cout << i << " " << j << " " + << patch.getPathType( k ) << " ("; + for( int p = 0; p < 4; ++p ) { + std::cout << patch.getPoint( k, p ); + } + std::cout << ") " + << patch.getColor( k ).toString() << std::endl; +#endif + + switch ( patch.getPathType( k ) ) { + case 'l': + case 'L': + case 'z': + case 'Z': + cairo_mesh_pattern_line_to( cp, + patch.getPoint( k, 3 )[X], + patch.getPoint( k, 3 )[Y] ); + break; + case 'c': + case 'C': + { + std::vector< Geom::Point > pts = patch.getPointsForSide( k ); + cairo_mesh_pattern_curve_to( cp, + pts[1][X], pts[1][Y], + pts[2][X], pts[2][Y], + pts[3][X], pts[3][Y] ); + break; + } + default: + // Shouldn't happen + std::cout << "sp_mesh_create_pattern: path error" << std::endl; + } + + if( patch.tensorIsSet(k) ) { + // Tensor point defined relative to corner. + Geom::Point t = patch.getTensorPoint(k); + cairo_mesh_pattern_set_control_point( cp, k, t[X], t[Y] ); + //std::cout << " sp_mesh_create_pattern: tensor " << k + // << " set to " << t << "." << std::endl; + } else { + // Geom::Point t = patch.coonsTensorPoint(k); + //std::cout << " sp_mesh_create_pattern: tensor " << k + // << " calculated as " << t << "." <<std::endl; + } + + cairo_mesh_pattern_set_corner_color_rgba( + cp, k, + patch.getColor( k ).v.c[0], + patch.getColor( k ).v.c[1], + patch.getColor( k ).v.c[2], + patch.getOpacity( k ) * opacity ); + } + + cairo_mesh_pattern_end_patch( cp ); + } + } + + // set pattern matrix + Geom::Affine gs2user = this->gradientTransform; + if (this->getUnits() == SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX) { + Geom::Affine bbox2user(bbox->width(), 0, 0, bbox->height(), bbox->left(), bbox->top()); + gs2user *= bbox2user; + } + ink_cairo_pattern_set_matrix(cp, gs2user.inverse()); + +#else + static bool shown = false; + if( !shown ) { + std::cout << "sp_mesh_create_pattern: needs cairo >= 1.11.4, using " + << cairo_version_string() << std::endl; + shown = true; + } +#endif + + /* + cairo_pattern_t *cp = cairo_pattern_create_radial( + rg->fx.computed, rg->fy.computed, 0, + rg->cx.computed, rg->cy.computed, rg->r.computed); + sp_gradient_pattern_common_setup(cp, gr, bbox, opacity); + */ + + return cp; +} diff --git a/src/sp-mesh-gradient.h b/src/sp-mesh.h index 4df753f62..6f992d034 100644 --- a/src/sp-mesh-gradient.h +++ b/src/sp-mesh.h @@ -1,25 +1,26 @@ -#ifndef SP_MESH_GRADIENT_H -#define SP_MESH_GRADIENT_H +#ifndef SP_MESH_H +#define SP_MESH_H /** \file - * SPMeshGradient: SVG <meshgradient> implementation. + * SPMesh: SVG <mesh> implementation. */ #include "svg/svg-length.h" #include "sp-gradient.h" -#define SP_MESHGRADIENT(obj) (dynamic_cast<SPMeshGradient*>((SPObject*)obj)) -#define SP_IS_MESHGRADIENT(obj) (dynamic_cast<const SPMeshGradient*>((SPObject*)obj) != NULL) +#define SP_MESH(obj) (dynamic_cast<SPMesh*>((SPObject*)obj)) +#define SP_IS_MESH(obj) (dynamic_cast<const SPMesh*>((SPObject*)obj) != NULL) /** Mesh gradient. */ -class SPMeshGradient : public SPGradient { +class SPMesh : public SPGradient { public: - SPMeshGradient(); - virtual ~SPMeshGradient(); + SPMesh(); + virtual ~SPMesh(); SVGLength x; // Upper left corner of mesh SVGLength y; // Upper right corner of mesh - + SPMeshType type; + bool type_set; virtual cairo_pattern_t* pattern_new(cairo_t *ct, Geom::OptRect const &bbox, double opacity); protected: @@ -28,7 +29,7 @@ protected: virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); }; -#endif /* !SP_MESH_GRADIENT_H */ +#endif /* !SP_MESH_H */ /* Local Variables: diff --git a/src/sp-metadata.cpp b/src/sp-metadata.cpp index bf4ce27a1..6bdc2f0b9 100644 --- a/src/sp-metadata.cpp +++ b/src/sp-metadata.cpp @@ -33,16 +33,6 @@ /* Metadata base class */ -#include "sp-factory.h" - -namespace { - SPObject* createMetadata() { - return new SPMetadata(); - } - - bool metadataRegistered = SPFactory::instance().registerObject("svg:metadata", createMetadata); -} - SPMetadata::SPMetadata() : SPObject() { } diff --git a/src/sp-missing-glyph.cpp b/src/sp-missing-glyph.cpp index 06b741165..75de55693 100644 --- a/src/sp-missing-glyph.cpp +++ b/src/sp-missing-glyph.cpp @@ -19,16 +19,6 @@ #include "sp-missing-glyph.h" #include "document.h" -#include "sp-factory.h" - -namespace { - SPObject* createMissingGlyph() { - return new SPMissingGlyph(); - } - - bool missingGlyphRegistered = SPFactory::instance().registerObject("svg:missing-glyph", createMissingGlyph); -} - SPMissingGlyph::SPMissingGlyph() : SPObject() { //TODO: correct these values: this->d = NULL; diff --git a/src/sp-namedview.cpp b/src/sp-namedview.cpp index 09d383e3c..3154c9e7b 100644 --- a/src/sp-namedview.cpp +++ b/src/sp-namedview.cpp @@ -29,7 +29,7 @@ #include "document.h" #include "document-undo.h" #include "desktop-events.h" -#include "desktop-handles.h" + #include "sp-guide.h" #include "sp-item-group.h" #include "sp-namedview.h" @@ -56,16 +56,6 @@ static void sp_namedview_show_single_guide(SPGuide* guide, bool show); static gboolean sp_str_to_bool(const gchar *str); static gboolean sp_nv_read_opacity(const gchar *str, guint32 *color); -#include "sp-factory.h" - -namespace { - SPObject* createNamedView() { - return new SPNamedView(); - } - - bool namedViewRegistered = SPFactory::instance().registerObject("sodipodi:namedview", createNamedView); -} - SPNamedView::SPNamedView() : SPObjectGroup(), snap_manager(this) { this->zoom = 0; this->guidecolor = 0; @@ -271,6 +261,8 @@ void SPNamedView::build(SPDocument *document, Inkscape::XML::Node *repr) { Geom::Rect viewbox = document->getRoot()->viewBox; double factor = svgwidth.value(unit_table.primary(Inkscape::Util::UNIT_TYPE_LINEAR)) / viewbox.width(); svg_units = unit_table.findUnit(factor, Inkscape::Util::UNIT_TYPE_LINEAR); + } else { // force the document units to be px + repr->setAttribute("inkscape:document-units", "px"); } } @@ -561,7 +553,7 @@ void SPNamedView::set(unsigned int key, const gchar* value) { static Inkscape::Util::Unit const *px = unit_table.getUnit("px"); Inkscape::Util::Unit const *new_unit = px; - if (value) { + if (value && document->getRoot()->viewBox_set) { Inkscape::Util::Unit const *const req_unit = unit_table.getUnit(value); if ( !unit_table.hasUnit(value) ) { g_warning("Unrecognized unit `%s'", value); @@ -676,7 +668,7 @@ void SPNamedView::child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *r g->SPGuide::showSPGuide(static_cast<SPDesktop*>(l->data)->guides, (GCallback) sp_dt_guide_event); if (static_cast<SPDesktop*>(l->data)->guides_active) { - g->sensitize(sp_desktop_canvas(static_cast<SPDesktop*> (l->data)), TRUE); + g->sensitize((static_cast<SPDesktop*> (l->data))->getCanvas(), TRUE); } sp_namedview_show_single_guide(SP_GUIDE(g), this->showguides); @@ -734,7 +726,7 @@ void SPNamedView::show(SPDesktop *desktop) for (GSList *l = guides; l != NULL; l = l->next) { SP_GUIDE(l->data)->showSPGuide( desktop->guides, (GCallback) sp_dt_guide_event); if (desktop->guides_active) { - SP_GUIDE(l->data)->sensitize(sp_desktop_canvas(desktop), TRUE); + SP_GUIDE(l->data)->sensitize(desktop->getCanvas(), TRUE); } sp_namedview_show_single_guide(SP_GUIDE(l->data), showguides); } @@ -840,7 +832,7 @@ void sp_namedview_window_from_document(SPDesktop *desktop) && nv->cx != HUGE_VAL && !IS_NAN(nv->cx) && nv->cy != HUGE_VAL && !IS_NAN(nv->cy)) { desktop->zoom_absolute(nv->cx, nv->cy, nv->zoom); - } else if (sp_desktop_document(desktop)) { // document without saved zoom, zoom to its page + } else if (desktop->getDocument()) { // document without saved zoom, zoom to its page desktop->zoom_page(); } @@ -900,8 +892,8 @@ void sp_namedview_document_from_window(SPDesktop *desktop) Geom::Rect const r = desktop->get_display_area(); // saving window geometry is not undoable - bool saved = DocumentUndo::getUndoSensitive(sp_desktop_document(desktop)); - DocumentUndo::setUndoSensitive(sp_desktop_document(desktop), false); + bool saved = DocumentUndo::getUndoSensitive(desktop->getDocument()); + DocumentUndo::setUndoSensitive(desktop->getDocument(), false); if (save_viewport_in_file) { sp_repr_set_svg_double(view, "inkscape:zoom", desktop->current_zoom()); @@ -922,7 +914,7 @@ void sp_namedview_document_from_window(SPDesktop *desktop) view->setAttribute("inkscape:current-layer", desktop->currentLayer()->getId()); // restore undoability - DocumentUndo::setUndoSensitive(sp_desktop_document(desktop), saved); + DocumentUndo::setUndoSensitive(desktop->getDocument(), saved); } void SPNamedView::hide(SPDesktop const *desktop) @@ -931,7 +923,7 @@ void SPNamedView::hide(SPDesktop const *desktop) g_assert(g_slist_find(views, desktop)); for (GSList *l = guides; l != NULL; l = l->next) { - SP_GUIDE(l->data)->hideSPGuide(sp_desktop_canvas(desktop)); + SP_GUIDE(l->data)->hideSPGuide(desktop->getCanvas()); } views = g_slist_remove(views, desktop); @@ -945,7 +937,7 @@ void SPNamedView::activateGuides(void* desktop, bool active) SPDesktop *dt = static_cast<SPDesktop*>(desktop); for (GSList *l = guides; l != NULL; l = l->next) { - SP_GUIDE(l->data)->sensitize( sp_desktop_canvas(dt), active); + SP_GUIDE(l->data)->sensitize(dt->getCanvas(), active); } } @@ -1130,11 +1122,11 @@ double SPNamedView::getMarginLength(gchar const * const key, /** * Returns namedview's default unit. - * If no default unit is set, "pt" is returned + * If no default unit is set, "px" is returned */ -Inkscape::Util::Unit const * SPNamedView::getDefaultUnit() const +Inkscape::Util::Unit const * SPNamedView::getDisplayUnit() const { - return display_units ? display_units : unit_table.getUnit("pt"); + return display_units ? display_units : unit_table.getUnit("px"); } Inkscape::Util::Unit const & SPNamedView::getSVGUnit() const diff --git a/src/sp-namedview.h b/src/sp-namedview.h index 64bf14a8b..f1ecc12d3 100644 --- a/src/sp-namedview.h +++ b/src/sp-namedview.h @@ -86,7 +86,7 @@ public: char const *getName() const; unsigned int getViewCount(); GSList const *getViewList() const; - Inkscape::Util::Unit const * getDefaultUnit() const; + Inkscape::Util::Unit const * getDisplayUnit() const; Inkscape::Util::Unit const & getSVGUnit() const; void translateGuides(Geom::Translate const &translation); diff --git a/src/sp-object.cpp b/src/sp-object.cpp index 024fce85a..343db435e 100644 --- a/src/sp-object.cpp +++ b/src/sp-object.cpp @@ -61,14 +61,6 @@ using std::strstr; # define debug(f, a...) /* */ #endif -namespace { - SPObject* createObject() { - return new SPObject(); - } - - bool gridRegistered = SPFactory::instance().registerObject("inkscape:grid", createObject); -} - guint update_in_progress = 0; // guard against update-during-update Inkscape::XML::NodeEventVector object_event_vector = { @@ -115,7 +107,7 @@ static gchar *sp_object_get_unique_id(SPObject *object, SPObject::SPObject() : cloned(0), uflags(0), mflags(0), hrefcount(0), _total_hrefcount(0), document(NULL), parent(NULL), children(NULL), _last_child(NULL), - next(NULL), id(NULL), repr(NULL), refCount(1), + next(NULL), id(NULL), repr(NULL), refCount(1),hrefList(std::list<SPObject*>()), _successor(NULL), _collection_policy(SPObject::COLLECT_WITH_PARENT), _label(NULL), _default_label(NULL) { @@ -130,7 +122,8 @@ SPObject::SPObject() // vg, g, defs, desc, title, symbol, use, image, switch, path, rect, circle, ellipse, line, polyline, // polygon, text, tspan, tref, textPath, altGlyph, glyphRef, marker, linearGradient, radialGradient, // stop, pattern, clipPath, mask, filter, feImage, a, font, glyph, missing-glyph, foreignObject - this->style = sp_style_new_from_object(this); + this->style = new SPStyle( NULL, this ); // Is it necessary to call with "this"? + this->context_style = NULL; } SPObject::~SPObject() { @@ -144,6 +137,24 @@ SPObject::~SPObject() { sp_object_unref(this->_successor, NULL); this->_successor = NULL; } + + if( style == NULL ) { + // style pointer could be NULL if unreffed too many times. + // Conjecture: style pointer is never NULL. + std::cerr << "SPObject::~SPObject(): style pointer is NULL" << std::endl; + } else if( style->refCount() > 1 ) { + // Conjecture: style pointer should be unreffed by other classes before reaching here. + // Conjecture is false for SPTSpan where ref is held by InputStreamTextSource. + // As an additional note: + // The outer tspan of a nested tspan will result in a ref count of five: one for the + // TSpan itself, one for the InputStreamTextSource instance before the inner tspan and + // one for the one after, along with one for each corresponding DrawingText instance. + // std::cerr << "SPObject::~SPObject(): someone else still holding ref to style" << std::endl; + // + sp_style_unref( this->style ); + } else { + delete this->style; + } } // CPPIFY: make pure virtual @@ -235,7 +246,7 @@ SPObject *sp_object_unref(SPObject *object, SPObject *owner) return NULL; } -SPObject *sp_object_href(SPObject *object, gpointer /*owner*/) +SPObject *sp_object_href(SPObject *object, SPObject* owner) { g_return_val_if_fail(object != NULL, NULL); g_return_val_if_fail(SP_IS_OBJECT(object), NULL); @@ -243,10 +254,13 @@ SPObject *sp_object_href(SPObject *object, gpointer /*owner*/) object->hrefcount++; object->_updateTotalHRefCount(1); + if(owner) + object->hrefList.push_front(owner); + return object; } -SPObject *sp_object_hunref(SPObject *object, gpointer /*owner*/) +SPObject *sp_object_hunref(SPObject *object, SPObject* owner) { g_return_val_if_fail(object != NULL, NULL); g_return_val_if_fail(SP_IS_OBJECT(object), NULL); @@ -255,6 +269,9 @@ SPObject *sp_object_hunref(SPObject *object, gpointer /*owner*/) object->hrefcount--; object->_updateTotalHRefCount(-1); + if(owner) + object->hrefList.remove(owner); + return NULL; } @@ -604,7 +621,7 @@ void SPObject::child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *ref) const std::string type_string = NodeTraits::get_type_string(*child); - SPObject* ochild = SPFactory::instance().createObject(type_string); + SPObject* ochild = SPFactory::createObject(type_string); if (ochild == NULL) { // Currenty, there are many node types that do not have // corresponding classes in the SPObject tree. @@ -663,7 +680,7 @@ void SPObject::build(SPDocument *document, Inkscape::XML::Node *repr) { for (Inkscape::XML::Node *rchild = repr->firstChild() ; rchild != NULL; rchild = rchild->next()) { const std::string typeString = NodeTraits::get_type_string(*rchild); - SPObject* child = SPFactory::instance().createObject(typeString); + SPObject* child = SPFactory::createObject(typeString); if (child == NULL) { // Currenty, there are many node types that do not have // corresponding classes in the SPObject tree. @@ -795,9 +812,10 @@ void SPObject::releaseReferences() { g_assert(!this->id); } - if (this->style) { - this->style = sp_style_unref(this->style); - } + // style belongs to SPObject, we should not need to unref here. + // if (this->style) { + // this->style = sp_style_unref(this->style); + // } this->document = NULL; this->repr = NULL; @@ -914,7 +932,7 @@ void SPObject::set(unsigned int key, gchar const* value) { object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); break; case SP_ATTR_STYLE: - sp_style_read_from_object(object->style, object); + object->style->readFromObject( object ); object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); break; default: @@ -1006,9 +1024,8 @@ Inkscape::XML::Node* SPObject::write(Inkscape::XML::Document *doc, Inkscape::XML repr->setAttribute("inkscape:collect", NULL); } - SPStyle const *const obj_style = this->style; - if (obj_style) { - gchar *s = sp_style_write_string(obj_style, SP_STYLE_FLAG_IFSET); + if (style) { + Glib::ustring s = style->write(SP_STYLE_FLAG_IFSET); // Check for valid attributes. This may be time consuming. // It is useful, though, for debugging Inkscape code. @@ -1016,17 +1033,14 @@ Inkscape::XML::Node* SPObject::write(Inkscape::XML::Document *doc, Inkscape::XML if( prefs->getBool("/options/svgoutput/check_on_editing") ) { unsigned int flags = sp_attribute_clean_get_prefs(); - Glib::ustring s_cleaned = sp_attribute_clean_style( repr, s, flags ); - g_free( s ); - s = (s_cleaned.empty() ? NULL : g_strdup (s_cleaned.c_str())); + Glib::ustring s_cleaned = sp_attribute_clean_style( repr, s.c_str(), flags ); } - if( s == NULL || strcmp(s,"") == 0 ) { + if( s.empty() ) { repr->setAttribute("style", NULL); } else { - repr->setAttribute("style", s); + repr->setAttribute("style", s.c_str()); } - g_free(s); } else { /** \todo I'm not sure what to do in this case. Bug #1165868 @@ -1148,7 +1162,7 @@ void SPObject::updateDisplay(SPCtx *ctx, unsigned int flags) */ if ((flags & SP_OBJECT_STYLE_MODIFIED_FLAG) && (flags & SP_OBJECT_PARENT_MODIFIED_FLAG)) { if (this->style && this->parent) { - sp_style_merge_from_parent(this->style, this->parent->style); + style->cascade( this->parent->style ); } } @@ -1254,6 +1268,16 @@ void SPObject::setAttribute(gchar const *key, gchar const *value, SPException *e //XML Tree being used here. getRepr()->setAttribute(key, value, false); } +void SPObject::setAttribute(char const *key, Glib::ustring const &value, SPException *ex) +{ + setAttribute(key, value.empty() ? NULL : value.c_str(), ex); +} +void SPObject::setAttribute(Glib::ustring const &key, Glib::ustring const &value, SPException *ex) +{ + setAttribute( key.empty() ? NULL : key.c_str(), + value.empty() ? NULL : value.c_str(), ex); +} + void SPObject::removeAttribute(gchar const *key, SPException *ex) { @@ -1513,6 +1537,22 @@ char* SPObject::textualContent() const return g_string_free(text, FALSE); } +// For debugging: Print SP tree structure. +void SPObject::recursivePrintTree( unsigned level ) +{ + if (level == 0) { + std::cout << "SP Object Tree" << std::endl; + } + std::cout << "SP: "; + for (unsigned i = 0; i < level; ++i) { + std::cout << " "; + } + std::cout << (getId()?getId():"No object id") << std::endl; + for (SPObject *child = children; child; child = child->next) { + child->recursivePrintTree( level+1 ); + } +} + /* Local Variables: mode:c++ diff --git a/src/sp-object.h b/src/sp-object.h index 575198f36..ab0b444b6 100644 --- a/src/sp-object.h +++ b/src/sp-object.h @@ -67,6 +67,9 @@ struct Document; } } +namespace Glib { + class ustring; +} typedef enum { SP_NO_EXCEPTION, @@ -154,7 +157,7 @@ SPObject *sp_object_unref(SPObject *object, SPObject *owner=NULL); * \pre object points to real object * @todo need to move this to be a member of SPObject. */ -SPObject *sp_object_href(SPObject *object, void* owner); +SPObject *sp_object_href(SPObject *object, SPObject* owner); /** * Decrease weak refcount. @@ -166,7 +169,7 @@ SPObject *sp_object_href(SPObject *object, void* owner); * \pre object points to real object and hrefcount>0 * @todo need to move this to be a member of SPObject. */ -SPObject *sp_object_hunref(SPObject *object, void* owner); +SPObject *sp_object_hunref(SPObject *object, SPObject* owner); /** * SPObject is an abstract base class of all of the document nodes at the @@ -215,6 +218,7 @@ private: Inkscape::XML::Node *repr; /* Our xml representation */ public: int refCount; + std::list<SPObject*> hrefList; /** * Returns the objects current ID string. @@ -264,6 +268,11 @@ public: */ SPStyle *style; + /** + * Represents the style that should be used to resolve 'context-fill' and 'context-stroke' + */ + SPStyle *context_style; + /// Switch containing next() method. struct ParentIteratorStrategy { static SPObject const *next(SPObject const *object) { @@ -703,7 +712,9 @@ public: */ void setKeyValue(unsigned int key, char const *value); - void setAttribute(char const *key, char const *value, SPException *ex=NULL); + void setAttribute( char const *key, char const *value, SPException *ex=NULL); + void setAttribute( char const *key, Glib::ustring const &value, SPException *ex=NULL); + void setAttribute(Glib::ustring const &key, Glib::ustring const &value, SPException *ex=NULL); /** * Read value of key attribute from XML node into object. @@ -849,6 +860,8 @@ protected: public: virtual void read_content(); + + void recursivePrintTree(unsigned level = 0); // For debugging }; diff --git a/src/sp-offset.cpp b/src/sp-offset.cpp index 3aa1e4eb6..15d3821c7 100644 --- a/src/sp-offset.cpp +++ b/src/sp-offset.cpp @@ -43,16 +43,6 @@ class SPDocument; -#include "sp-factory.h" - -namespace { - SPObject* createOffset() { - return new SPOffset(); - } - - bool offsetRegistered = SPFactory::instance().registerObject("inkscape:offset", createOffset); -} - #define noOFFSET_VERBOSE /** \note diff --git a/src/sp-path.cpp b/src/sp-path.cpp index 5c076b7cb..42883588b 100644 --- a/src/sp-path.cpp +++ b/src/sp-path.cpp @@ -41,7 +41,7 @@ #include "document.h" #include "desktop.h" -#include "desktop-handles.h" + #include "desktop-style.h" #include "ui/tools/tool-base.h" #include "inkscape.h" @@ -51,16 +51,6 @@ #define noPATH_VERBOSE -#include "sp-factory.h" - -namespace { - SPObject* createPath() { - return new SPPath(); - } - - bool pathRegistered = SPFactory::instance().registerObject("svg:path", createPath); -} - gint SPPath::nodesInPath() const { return _curve ? _curve->nodes_in_path() : 0; @@ -140,10 +130,29 @@ void SPPath::build(SPDocument *document, Inkscape::XML::Node *repr) { SPShape::build(document, repr); - // this->readAttr( "inkscape:original-d" ); // lp1299948 + // this->readAttr( "inkscape:original-d" ); // bug #1299948 + // Why we take the long way of doing this probably needs some explaining: + // + // Normally upon being built, reading the inkscape:original-d attribute + // will cause the path to actually _write to its repr_ in response to this. + // This is bad, bad news if the attached effect refers to a path which + // hasn't been constructed yet. + // + // What will happen is the effect parameter will cause the effect to + // recalculate with a completely different value due to the parameter being + // "empty" -- even worse, an undo event might be created with the bad value, + // and undoing the current action could cause it to revert to the "bad" + // state. (After that, the referred object will be constructed and the + // reference will trigger the path effect to update and commit the right + // value to "d".) + // + // This mild nastiness here (don't recalculate effects on build) prevents a + // plethora of issues with effects with linked parameters doing wild and + // stupid things on new documents upon a mere undo. + if (gchar const* s = this->getRepr()->attribute("inkscape:original-d")) { - // write it to XML, and to my curve, but don't update patheffects + // Write the value to _curve_before_lpe, do not recalculate effects Geom::PathVector pv = sp_svg_read_pathv(s); SPCurve *curve = new SPCurve(pv); @@ -158,10 +167,17 @@ void SPPath::build(SPDocument *document, Inkscape::XML::Node *repr) { this->readAttr( "d" ); /* d is a required attribute */ - gchar const *d = this->getAttribute("d", NULL); + char const *d = this->getAttribute("d", NULL); if (d == NULL) { - this->setKeyValue( sp_attribute_lookup("d"), ""); + // First see if calculating the path effect will generate "d": + this->update_patheffect(true); + d = this->getAttribute("d", NULL); + + // I guess that didn't work, now we have nothing useful to write ("") + if (d == NULL) { + this->setKeyValue( sp_attribute_lookup("d"), ""); + } } } diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index 961ab0f84..987a86fe4 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -45,16 +45,6 @@ static void pattern_ref_changed(SPObject *old_ref, SPObject *ref, SPPattern *pat); static void pattern_ref_modified (SPObject *ref, guint flags, SPPattern *pattern); -#include "sp-factory.h" - -namespace { - SPObject* createPattern() { - return new SPPattern(); - } - - bool patternRegistered = SPFactory::instance().registerObject("svg:pattern", createPattern); -} - SPPattern::SPPattern() : SPPaintServer(), SPViewBox() { this->href = NULL; diff --git a/src/sp-polygon.cpp b/src/sp-polygon.cpp index 302905a62..af71280d5 100644 --- a/src/sp-polygon.cpp +++ b/src/sp-polygon.cpp @@ -11,8 +11,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include "config.h" - #include "attributes.h" #include "sp-polygon.h" #include "display/curve.h" @@ -25,16 +23,6 @@ #include "xml/repr.h" #include "document.h" -#include "sp-factory.h" - -namespace { - SPObject* createPolygon() { - return new SPPolygon(); - } - - bool polygonRegistered = SPFactory::instance().registerObject("svg:polygon", createPolygon); -} - SPPolygon::SPPolygon() : SPShape() { } diff --git a/src/sp-polyline.cpp b/src/sp-polyline.cpp index c80190097..a12f927b5 100644 --- a/src/sp-polyline.cpp +++ b/src/sp-polyline.cpp @@ -20,16 +20,6 @@ #include "xml/repr.h" #include "document.h" -#include "sp-factory.h" - -namespace { - SPObject* createPolyLine() { - return new SPPolyLine(); - } - - bool polyLineRegistered = SPFactory::instance().registerObject("svg:polyline", createPolyLine); -} - SPPolyLine::SPPolyLine() : SPShape() { } diff --git a/src/sp-radial-gradient.cpp b/src/sp-radial-gradient.cpp index 2c2b17b7d..8fb230ba7 100644 --- a/src/sp-radial-gradient.cpp +++ b/src/sp-radial-gradient.cpp @@ -5,17 +5,7 @@ #include "attributes.h" #include "xml/repr.h" -#include "2geom/transforms.h" - -#include "sp-factory.h" - -namespace { - SPObject* createRadialGradient() { - return new SPRadialGradient(); - } - - bool radialGradientRegistered = SPFactory::instance().registerObject("svg:radialGradient", createRadialGradient); -} +#include <2geom/transforms.h> /* * Radial Gradient diff --git a/src/sp-rect.cpp b/src/sp-rect.cpp index af3e2bfb4..e17d7373c 100644 --- a/src/sp-rect.cpp +++ b/src/sp-rect.cpp @@ -31,16 +31,6 @@ #define noRECT_VERBOSE -#include "sp-factory.h" - -namespace { - SPObject* createRect() { - return new SPRect(); - } - - bool rectRegistered = SPFactory::instance().registerObject("svg:rect", createRect); -} - SPRect::SPRect() : SPShape() { } @@ -62,22 +52,30 @@ void SPRect::build(SPDocument* doc, Inkscape::XML::Node* repr) { void SPRect::set(unsigned key, gchar const *value) { /* fixme: We need real error processing some time */ + // We must update the SVGLengths immediately or nodes may be misplaced after they are moved. + double const w = viewport.width(); + double const h = viewport.height(); + double const em = style->font_size.computed; + double const ex = em * 0.5; + switch (key) { case SP_ATTR_X: - this->x.readOrUnset(value); - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + this->x.readOrUnset(value); + this->x.update( ex, em, w ); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; case SP_ATTR_Y: - this->y.readOrUnset(value); - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + this->y.readOrUnset(value); + this->y.update( ex, em, h ); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; case SP_ATTR_WIDTH: if (!this->width.read(value) || this->width.value < 0.0) { this->width.unset(); } - + this->width.update( ex, em, w ); this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; @@ -85,7 +83,7 @@ void SPRect::set(unsigned key, gchar const *value) { if (!this->height.read(value) || this->height.value < 0.0) { this->height.unset(); } - + this->height.update( ex, em, h ); this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; @@ -93,7 +91,7 @@ void SPRect::set(unsigned key, gchar const *value) { if (!this->rx.read(value) || this->rx.value <= 0.0) { this->rx.unset(); } - + this->rx.update( ex, em, w ); this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; @@ -101,7 +99,7 @@ void SPRect::set(unsigned key, gchar const *value) { if (!this->ry.read(value) || this->ry.value <= 0.0) { this->ry.unset(); } - + this->ry.update( ex, em, h ); this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; @@ -139,19 +137,19 @@ Inkscape::XML::Node * SPRect::write(Inkscape::XML::Document *xml_doc, Inkscape:: repr = xml_doc->createElement("svg:rect"); } - sp_repr_set_svg_double(repr, "width", this->width.computed); - sp_repr_set_svg_double(repr, "height", this->height.computed); + sp_repr_set_svg_length(repr, "width", this->width); + sp_repr_set_svg_length(repr, "height", this->height); if (this->rx._set) { - sp_repr_set_svg_double(repr, "rx", this->rx.computed); + sp_repr_set_svg_length(repr, "rx", this->rx); } if (this->ry._set) { - sp_repr_set_svg_double(repr, "ry", this->ry.computed); + sp_repr_set_svg_length(repr, "ry", this->ry); } - sp_repr_set_svg_double(repr, "x", this->x.computed); - sp_repr_set_svg_double(repr, "y", this->y.computed); + sp_repr_set_svg_length(repr, "x", this->x); + sp_repr_set_svg_length(repr, "y", this->y); this->set_shape(); // evaluate SPCurve SPShape::write(xml_doc, repr, flags); @@ -245,29 +243,29 @@ void SPRect::set_shape() { /* fixme: Think (Lauris) */ void SPRect::setPosition(gdouble x, gdouble y, gdouble width, gdouble height) { - this->x.computed = x; - this->y.computed = y; - this->width.computed = width; - this->height.computed = height; + this->x = x; + this->y = y; + this->width = width; + this->height = height; this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } void SPRect::setRx(bool set, gdouble value) { - this->rx._set = set; + this->rx._set = set; if (set) { - this->rx.computed = value; + this->rx = value; } this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } void SPRect::setRy(bool set, gdouble value) { - this->ry._set = set; + this->ry._set = set; if (set) { - this->ry.computed = value; + this->ry = value; } this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); @@ -299,16 +297,16 @@ Geom::Affine SPRect::set_transform(Geom::Affine const& xform) { ret[3] = 1.0; } - /* fixme: Would be nice to preserve units here */ - this->width = this->width.computed * sw; - this->height = this->height.computed * sh; + /* Preserve units */ + this->width.scale( sw ); + this->height.scale( sh ); if (this->rx._set) { - this->rx = this->rx.computed * sw; + this->rx.scale( sw ); } if (this->ry._set) { - this->ry = this->ry.computed * sh; + this->ry.scale( sh ); } /* Find start in item coords */ @@ -346,15 +344,12 @@ gdouble SPRect::vectorStretch(Geom::Point p0, Geom::Point p1, Geom::Affine xform void SPRect::setVisibleRx(gdouble rx) { if (rx == 0) { - this->rx.computed = 0; - this->rx._set = false; + this->rx.unset(); } else { - this->rx.computed = rx / SPRect::vectorStretch( + this->rx = rx / SPRect::vectorStretch( Geom::Point(this->x.computed + 1, this->y.computed), Geom::Point(this->x.computed, this->y.computed), - this->transform); - - this->rx._set = true; + this->i2doc_affine()); } this->updateRepr(); @@ -362,15 +357,12 @@ void SPRect::setVisibleRx(gdouble rx) { void SPRect::setVisibleRy(gdouble ry) { if (ry == 0) { - this->ry.computed = 0; - this->ry._set = false; + this->ry.unset(); } else { - this->ry.computed = ry / SPRect::vectorStretch( + this->ry = ry / SPRect::vectorStretch( Geom::Point(this->x.computed, this->y.computed + 1), Geom::Point(this->x.computed, this->y.computed), - this->transform); - - this->ry._set = true; + this->i2doc_affine()); } this->updateRepr(); @@ -384,7 +376,7 @@ gdouble SPRect::getVisibleRx() const { return this->rx.computed * SPRect::vectorStretch( Geom::Point(this->x.computed + 1, this->y.computed), Geom::Point(this->x.computed, this->y.computed), - this->transform); + this->i2doc_affine()); } gdouble SPRect::getVisibleRy() const { @@ -395,7 +387,7 @@ gdouble SPRect::getVisibleRy() const { return this->ry.computed * SPRect::vectorStretch( Geom::Point(this->x.computed, this->y.computed + 1), Geom::Point(this->x.computed, this->y.computed), - this->transform); + this->i2doc_affine()); } Geom::Rect SPRect::getRect() const { @@ -428,37 +420,33 @@ void SPRect::compensateRxRy(Geom::Affine xform) { // This is needed because if we just set them the same length in SVG, they might end up unequal because of transform if ((this->rx._set && !this->ry._set) || (this->ry._set && !this->rx._set)) { gdouble r = MAX(this->rx.computed, this->ry.computed); - this->rx.computed = r / eX; - this->ry.computed = r / eY; + this->rx = r / eX; + this->ry = r / eY; } else { - this->rx.computed = this->rx.computed / eX; - this->ry.computed = this->ry.computed / eY; + this->rx = this->rx.computed / eX; + this->ry = this->ry.computed / eY; } // Note that a radius may end up larger than half-side if the rect is scaled down; // that's ok because this preserves the intended radii in case the rect is enlarged again, // and set_shape will take care of trimming too large radii when generating d= - - this->rx._set = this->ry._set = true; } void SPRect::setVisibleWidth(gdouble width) { - this->width.computed = width / SPRect::vectorStretch( + this->width = width / SPRect::vectorStretch( Geom::Point(this->x.computed + 1, this->y.computed), Geom::Point(this->x.computed, this->y.computed), - this->transform); + this->i2doc_affine()); - this->width._set = true; - this->updateRepr(); + this->updateRepr(); } void SPRect::setVisibleHeight(gdouble height) { - this->height.computed = height / SPRect::vectorStretch( + this->height = height / SPRect::vectorStretch( Geom::Point(this->x.computed, this->y.computed + 1), Geom::Point(this->x.computed, this->y.computed), - this->transform); + this->i2doc_affine()); - this->height._set = true; this->updateRepr(); } @@ -470,7 +458,7 @@ gdouble SPRect::getVisibleWidth() const { return this->width.computed * SPRect::vectorStretch( Geom::Point(this->x.computed + 1, this->y.computed), Geom::Point(this->x.computed, this->y.computed), - this->transform); + this->i2doc_affine()); } gdouble SPRect::getVisibleHeight() const { @@ -481,7 +469,7 @@ gdouble SPRect::getVisibleHeight() const { return this->height.computed * SPRect::vectorStretch( Geom::Point(this->x.computed, this->y.computed + 1), Geom::Point(this->x.computed, this->y.computed), - this->transform); + this->i2doc_affine()); } void SPRect::snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs) const { diff --git a/src/sp-root.cpp b/src/sp-root.cpp index 12570e03e..8bedec0a5 100644 --- a/src/sp-root.cpp +++ b/src/sp-root.cpp @@ -13,10 +13,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include <string> #include <2geom/transforms.h> @@ -30,17 +26,7 @@ #include "svg/stringstream.h" #include "svg/svg.h" #include "xml/repr.h" - -#include "sp-factory.h" - -namespace { -SPObject *createRoot() -{ - return new SPRoot(); -} - -bool rootRegistered = SPFactory::instance().registerObject("svg:svg", createRoot); -} +#include "util/units.h" SPRoot::SPRoot() : SPGroup(), SPViewBox() { @@ -298,7 +284,7 @@ void SPRoot::update(SPCtx *ctx, guint flags) SPItemCtx rctx = *ictx; rctx.viewport = Geom::Rect::from_xywh( this->x.computed, this->y.computed, this->width.computed, this->height.computed ); - rctx = get_rctx( &rctx ); + rctx = get_rctx( &rctx, Inkscape::Util::Quantity::convert(1, this->document->getDisplayUnit(), "px") ); /* And invoke parent method */ SPGroup::update((SPCtx *) &rctx, flags); @@ -375,6 +361,15 @@ Inkscape::DrawingItem *SPRoot::show(Inkscape::Drawing &drawing, unsigned int key g->setChildTransform(this->c2p); } + // Uncomment to print out XML tree + // getRepr()->recursivePrintTree(0); + + // Uncomment to print out SP Object tree + // recursivePrintTree(0); + + // Uncomment to print out Display Item tree + // ai->recursivePrintTree(0); + return ai; } diff --git a/src/sp-script.cpp b/src/sp-script.cpp index 260b3dcfd..f1ea9c9bd 100644 --- a/src/sp-script.cpp +++ b/src/sp-script.cpp @@ -16,16 +16,6 @@ #include <cstring> #include "document.h" -#include "sp-factory.h" - -namespace { - SPObject* createScript() { - return new SPScript(); - } - - bool scriptRegistered = SPFactory::instance().registerObject("svg:script", createScript); -} - SPScript::SPScript() : SPObject() { this->xlinkhref = NULL; } diff --git a/src/sp-shape.cpp b/src/sp-shape.cpp index 8b7e735e0..78135d459 100644 --- a/src/sp-shape.cpp +++ b/src/sp-shape.cpp @@ -47,7 +47,7 @@ #include "bad-uri-exception.h" #include "xml/repr.h" -#include "util/mathfns.h" // for triangle_area() +#include "helper/mathfns.h" // for triangle_area() #include "splivarot.h" // for bounding box calculation @@ -126,6 +126,7 @@ Inkscape::XML::Node* SPShape::write(Inkscape::XML::Document *xml_doc, Inkscape:: } void SPShape::update(SPCtx* ctx, guint flags) { + // std::cout << "SPShape::update(): " << (getId()?getId():"null") << std::endl; SPLPEItem::update(ctx, flags); /* This stanza checks that an object's marker style agrees with @@ -145,7 +146,15 @@ void SPShape::update(SPCtx* ctx, guint flags) { for (SPItemView *v = ((SPItem *) (this))->display; v != NULL; v = v->next) { Inkscape::DrawingShape *sh = dynamic_cast<Inkscape::DrawingShape *>(v->arenaitem); - sh->setStyle(this->style); + if (hasMarkers()) { + this->context_style = this->style; + sh->setStyle(this->style, this->context_style); + // Done at end: + // sh->setChildrenStyle(this->context_style); //Resolve 'context-xxx' in children. + } else if (this->parent) { + this->context_style = this->parent->context_style; + sh->setStyle(this->style, this->context_style); + } } } } @@ -163,6 +172,7 @@ void SPShape::update(SPCtx* ctx, guint flags) { } if (this->hasMarkers ()) { + /* Dimension marker views */ for (SPItemView *v = this->display; v != NULL; v = v->next) { if (!v->arenaitem->key()) { @@ -182,6 +192,13 @@ void SPShape::update(SPCtx* ctx, guint flags) { for (SPItemView *v = this->display; v != NULL; v = v->next) { sp_shape_update_marker_view (this, v->arenaitem); } + + // Marker selector needs this here or marker previews are not rendered. + for (SPItemView *v = this->display; v != NULL; v = v->next) { + Inkscape::DrawingShape *sh = dynamic_cast<Inkscape::DrawingShape *>(v->arenaitem); + + sh->setChildrenStyle(this->context_style); // Resolve 'context-xxx' in children. + } } } @@ -382,12 +399,23 @@ sp_shape_update_marker_view(SPShape *shape, Inkscape::DrawingItem *ai) } void SPShape::modified(unsigned int flags) { + // std::cout << "SPShape::modified(): " << (getId()?getId():"null") << std::endl; SPLPEItem::modified(flags); if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { for (SPItemView *v = this->display; v != NULL; v = v->next) { Inkscape::DrawingShape *sh = dynamic_cast<Inkscape::DrawingShape *>(v->arenaitem); - sh->setStyle(this->style); + if (hasMarkers()) { + this->context_style = this->style; + sh->setStyle(this->style, this->context_style); + // Note: marker selector preview does not trigger SP_OBJECT_STYLE_MODIFIED_FLAG so + // this is not called when marker previews are generated, however there is code in + // SPShape::update() that calls this routine so we don't worry about it here. + sh->setChildrenStyle(this->context_style); // Resolve 'context-xxx' in children. + } else if (this->parent) { + this->context_style = this->parent->context_style; + sh->setStyle(this->style, this->context_style); + } } } } @@ -434,7 +462,7 @@ Geom::OptRect SPShape::bbox(Geom::Affine const &transform, SPItem::BBoxType bbox tr = Geom::Rotate::from_degrees( 180.0 ) * tr; } else if (_marker[i]->orient_mode == MARKER_ORIENT_ANGLE) { Geom::Point transl = tr.translation(); - tr = Geom::Rotate::from_degrees(_marker[i]->orient) * Geom::Translate(transl); + tr = Geom::Rotate::from_degrees(_marker[i]->orient.computed) * Geom::Translate(transl); } if (_marker[i]->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { @@ -472,7 +500,7 @@ Geom::OptRect SPShape::bbox(Geom::Affine const &transform, SPItem::BBoxType bbox if (marker->orient_mode == MARKER_ORIENT_ANGLE) { Geom::Point transl = tr.translation(); - tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(transl); + tr = Geom::Rotate::from_degrees(marker->orient.computed) * Geom::Translate(transl); } if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { @@ -502,7 +530,7 @@ Geom::OptRect SPShape::bbox(Geom::Affine const &transform, SPItem::BBoxType bbox if (marker->orient_mode == MARKER_ORIENT_ANGLE) { Geom::Point transl = tr.translation(); - tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(transl); + tr = Geom::Rotate::from_degrees(marker->orient.computed) * Geom::Translate(transl); } if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { @@ -525,7 +553,7 @@ Geom::OptRect SPShape::bbox(Geom::Affine const &transform, SPItem::BBoxType bbox if (marker->orient_mode == MARKER_ORIENT_ANGLE) { Geom::Point transl = tr.translation(); - tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(transl); + tr = Geom::Rotate::from_degrees(marker->orient.computed) * Geom::Translate(transl); } if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { @@ -560,7 +588,7 @@ Geom::OptRect SPShape::bbox(Geom::Affine const &transform, SPItem::BBoxType bbox if (marker->orient_mode == MARKER_ORIENT_ANGLE) { Geom::Point transl = tr.translation(); - tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(transl); + tr = Geom::Rotate::from_degrees(marker->orient.computed) * Geom::Translate(transl); } if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { @@ -718,8 +746,11 @@ void SPShape::print(SPPrintContext* ctx) { } Inkscape::DrawingItem* SPShape::show(Inkscape::Drawing &drawing, unsigned int /*key*/, unsigned int /*flags*/) { + // std::cout << "SPShape::show(): " << (getId()?getId():"null") << std::endl; Inkscape::DrawingShape *s = new Inkscape::DrawingShape(drawing); - s->setStyle(this->style); + + bool has_markers = this->hasMarkers(); + s->setPath(this->_curve); /* This stanza checks that an object's marker style agrees with @@ -731,7 +762,7 @@ Inkscape::DrawingItem* SPShape::show(Inkscape::Drawing &drawing, unsigned int /* sp_shape_set_marker (this, i, this->style->marker_ptrs[i]->value); } - if (this->hasMarkers ()) { + if (has_markers) { /* provide key and dimension the marker views */ if (!s->key()) { s->setKey(SPItem::display_key_new (SP_MARKER_LOC_QTY)); @@ -747,8 +778,14 @@ Inkscape::DrawingItem* SPShape::show(Inkscape::Drawing &drawing, unsigned int /* /* Update marker views */ sp_shape_update_marker_view (this, s); - } + this->context_style = this->style; + s->setStyle(this->style, this->context_style); + s->setChildrenStyle(this->context_style); // Resolve 'context-xxx' in children. + } else if (this->parent) { + this->context_style = this->parent->context_style; + s->setStyle(this->style, this->context_style); + } return s; } diff --git a/src/sp-solid-color.cpp b/src/sp-solid-color.cpp index 0d6b96b62..f319410b0 100644 --- a/src/sp-solid-color.cpp +++ b/src/sp-solid-color.cpp @@ -16,18 +16,9 @@ #include "style.h" #include "xml/repr.h" -#include "sp-factory.h" #include "sp-item.h" #include "style-internal.h" -namespace { - SPObject* createSolidColor() { - return new SPSolidColor(); - } - - bool solidColorRegistered = SPFactory::instance().registerObject("svg:solidColor", createSolidColor); -} - /* * Solid Color @@ -53,7 +44,7 @@ void SPSolidColor::build(SPDocument* doc, Inkscape::XML::Node* repr) { void SPSolidColor::set(unsigned int key, const gchar* value) { if (SP_ATTRIBUTE_IS_CSS(key)) { - sp_style_read_from_object(this->style, this); + style->readFromObject( this ); this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); } else { SPPaintServer::set(key, value); diff --git a/src/sp-spiral.cpp b/src/sp-spiral.cpp index 9ef73d56d..5dbd7dfa0 100644 --- a/src/sp-spiral.cpp +++ b/src/sp-spiral.cpp @@ -28,16 +28,6 @@ #include "sp-spiral.h" -#include "sp-factory.h" - -namespace { - SPObject* createSpiral() { - return new SPSpiral(); - } - - bool spiralRegistered = SPFactory::instance().registerObject("spiral", createSpiral); -} - SPSpiral::SPSpiral() : SPShape() , cx(0) diff --git a/src/sp-star.cpp b/src/sp-star.cpp index 97a690520..51d5e6254 100644 --- a/src/sp-star.cpp +++ b/src/sp-star.cpp @@ -32,16 +32,6 @@ #include "sp-star.h" -#include "sp-factory.h" - -namespace { - SPObject* createStar() { - return new SPStar(); - } - - bool starRegistered = SPFactory::instance().registerObject("star", createStar); -} - SPStar::SPStar() : SPPolygon() { this->sides = 5; this->center = Geom::Point(0, 0); diff --git a/src/sp-stop.cpp b/src/sp-stop.cpp index d644a9b4b..5e8fed86c 100644 --- a/src/sp-stop.cpp +++ b/src/sp-stop.cpp @@ -24,16 +24,6 @@ #include "svg/css-ostringstream.h" #include "xml/repr.h" -#include "sp-factory.h" - -namespace { - SPObject* createStop() { - return new SPStop(); - } - - bool stopRegistered = SPFactory::instance().registerObject("svg:stop", createStop); -} - SPStop::SPStop() : SPObject() { this->path_string = NULL; @@ -210,16 +200,14 @@ SPStop* SPStop::getPrevStop() { SPColor SPStop::readStopColor(Glib::ustring const &styleStr, guint32 dfl) { SPColor color(dfl); - SPStyle* style = sp_style_new(0); SPIPaint paint; - paint.read( styleStr.c_str(), *style ); + + paint.read( styleStr.c_str() ); if ( paint.isColor() ) { color = paint.value.color; } - sp_style_unref(style); - return color; } diff --git a/src/sp-string.cpp b/src/sp-string.cpp index b561187d0..26bb44006 100644 --- a/src/sp-string.cpp +++ b/src/sp-string.cpp @@ -22,30 +22,13 @@ * */ - - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - - #include "sp-string.h" #include "style.h" #include "xml/repr.h" -#include "sp-factory.h" - #include <iostream> -namespace { - SPObject* createString() { - return new SPString(); - } - - bool stringRegistered = SPFactory::instance().registerObject("string", createString); -} - /*##################################################### # SPSTRING #####################################################*/ diff --git a/src/sp-style-elem.cpp b/src/sp-style-elem.cpp index da17b08d9..80e45677c 100644 --- a/src/sp-style-elem.cpp +++ b/src/sp-style-elem.cpp @@ -7,16 +7,6 @@ #include "style.h" using Inkscape::XML::TEXT_NODE; -#include "sp-factory.h" - -namespace { - SPObject* createStyle() { - return new SPStyleElem(); - } - - bool styleRegistered = SPFactory::instance().registerObject("svg:style", createStyle); -} - SPStyleElem::SPStyleElem() : SPObject() { media_set_all(this->media); this->is_css = false; @@ -319,13 +309,14 @@ void SPStyleElem::read_content() { //requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); // Style references via class= do not, and actually cannot, use autoupdating URIReferences. - // Therefore, if an object refers to a stylesheet which has not yet loaded when the object is being loaded - // (e.g. if the stylesheet is below or inside the object in XML), its class= has no effect (bug 1491639). - // Below is a partial hack that fixes this for a single case: when the <style> is a child of the object - // that uses a style from it. It just forces the parent of <style> to reread its style as soon as the stylesheet - // is fully loaded. Naturally, this won't work if the user of the stylesheet is its grandparent or precedent. + // Therefore, if an object refers to a stylesheet which has not yet loaded when the object is + // being loaded (e.g. if the stylesheet is below or inside the object in XML), its class= has + // no effect (bug 1491639). Below is a partial hack that fixes this for a single case: when + // the <style> is a child of the object that uses a style from it. It just forces the parent of + // <style> to reread its style as soon as the stylesheet is fully loaded. Naturally, this won't + // work if the user of the stylesheet is its grandparent or precedent. if ( parent ) { - sp_style_read_from_object(parent->style, parent); + parent->style->readFromObject( parent ); } } diff --git a/src/sp-switch.cpp b/src/sp-switch.cpp index db6db9909..66cec3637 100644 --- a/src/sp-switch.cpp +++ b/src/sp-switch.cpp @@ -12,10 +12,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include <glibmm/i18n.h> #include "sp-switch.h" @@ -25,16 +21,6 @@ #include <sigc++/functors/ptr_fun.h> #include <sigc++/adaptors/bind.h> -#include "sp-factory.h" - -namespace { - SPObject* createSwitch() { - return new SPSwitch(); - } - - bool switchRegistered = SPFactory::instance().registerObject("svg:switch", createSwitch); -} - SPSwitch::SPSwitch() : SPGroup() { this->_cached_item = 0; } diff --git a/src/sp-symbol.cpp b/src/sp-symbol.cpp index 3156680b3..62fb232a3 100644 --- a/src/sp-symbol.cpp +++ b/src/sp-symbol.cpp @@ -26,16 +26,6 @@ #include "sp-symbol.h" #include "document.h" -#include "sp-factory.h" - -namespace { - SPObject* createSymbol() { - return new SPSymbol(); - } - - bool symbolRegistered = SPFactory::instance().registerObject("svg:symbol", createSymbol); -} - SPSymbol::SPSymbol() : SPGroup(), SPViewBox() { } diff --git a/src/sp-tag-use-reference.cpp b/src/sp-tag-use-reference.cpp index 50c011812..220cd16d1 100644 --- a/src/sp-tag-use-reference.cpp +++ b/src/sp-tag-use-reference.cpp @@ -20,16 +20,6 @@ #include "sp-text.h" #include "uri.h" -#if 0 -namespace { - SPObject* createTagUseReference() { - return new SPTag(); - } - bool tagUseReferencesRegistered = SPFactory::instance().registerObject("inkscape:tag", createTag); -} -// this SPObject doesn't need to be registered -#endif - bool SPTagUseReference::_acceptObject(SPObject * const obj) const { diff --git a/src/sp-tag-use.cpp b/src/sp-tag-use.cpp index 5851598f2..935f7429e 100644 --- a/src/sp-tag-use.cpp +++ b/src/sp-tag-use.cpp @@ -10,10 +10,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - #include <cstring> #include <string> @@ -30,13 +26,6 @@ #include "sp-tag-use.h" #include "sp-tag-use-reference.h" -namespace { - SPObject* createTagUse() { - return new SPTagUse(); - } - bool tagUseRegistered = SPFactory::instance().registerObject("inkscape:tagref", createTagUse); -} - SPTagUse::SPTagUse() { href = NULL; @@ -173,7 +162,7 @@ SPTagUse::href_changed(SPObject */*old_ref*/, SPObject */*ref*/) Inkscape::XML::Node *childrepr = refobj->getRepr(); const std::string typeString = NodeTraits::get_type_string(*childrepr); - SPObject* child_ = SPFactory::instance().createObject(typeString); + SPObject* child_ = SPFactory::createObject(typeString); if (child_) { child = child_; attach(child_, lastChild()); diff --git a/src/sp-tag.cpp b/src/sp-tag.cpp index c4b40417f..d331e6b18 100644 --- a/src/sp-tag.cpp +++ b/src/sp-tag.cpp @@ -10,23 +10,11 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include "attributes.h" -#include "sp-factory.h" #include "sp-tag.h" #include "xml/repr.h" #include <cstring> -namespace { - SPObject* createTag() { - return new SPTag(); - } - bool tagsRegistered = SPFactory::instance().registerObject("inkscape:tag", createTag); -} - /* * Move this SPItem into or after another SPItem in the doc * \param target - the SPItem to move into or after diff --git a/src/sp-text.cpp b/src/sp-text.cpp index 8922d3c73..0dca42bb4 100644 --- a/src/sp-text.cpp +++ b/src/sp-text.cpp @@ -23,10 +23,6 @@ * */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include <2geom/affine.h> #include <libnrtype/FontFactory.h> #include <libnrtype/font-instance.h> @@ -38,7 +34,7 @@ #include "attributes.h" #include "document.h" #include "preferences.h" -#include "desktop-handles.h" +#include "desktop.h" #include "sp-namedview.h" #include "style.h" #include "inkscape.h" @@ -55,15 +51,11 @@ #include "text-editing.h" -#include "sp-factory.h" - -namespace { - SPObject* createText() { - return new SPText(); - } - - bool textRegistered = SPFactory::instance().registerObject("svg:text", createText); -} +// For SVG 2 text flow +#include "livarot/Path.h" +#include "livarot/Shape.h" +#include "sp-shape.h" +#include "display/curve.h" /*##################################################### # SPTEXT @@ -81,6 +73,10 @@ void SPText::build(SPDocument *doc, Inkscape::XML::Node *repr) { this->readAttr( "dy" ); this->readAttr( "rotate" ); + // textLength and friends + this->readAttr( "textLength" ); + this->readAttr( "lengthAdjust" ); + // SVG 2 Auto wrapped text this->readAttr( "width" ); this->readAttr( "height" ); @@ -195,7 +191,7 @@ void SPText::update(SPCtx *ctx, guint flags) { for (SPItemView* v = this->display; v != NULL; v = v->next) { Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); this->_clearFlow(g); - g->setStyle(this->style); + g->setStyle(this->style, this->parent->style); // pass the bbox of the this this as paintbox (used for paintserver fills) this->layout.show(g, paintbox); } @@ -221,7 +217,7 @@ void SPText::modified(guint flags) { for (SPItemView* v = this->display; v != NULL; v = v->next) { Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); this->_clearFlow(g); - g->setStyle(this->style); + g->setStyle(this->style, this->parent->style); this->layout.show(g, paintbox); } } @@ -333,7 +329,7 @@ Geom::OptRect SPText::bbox(Geom::Affine const &transform, SPItem::BBoxType type) Inkscape::DrawingItem* SPText::show(Inkscape::Drawing &drawing, unsigned /*key*/, unsigned /*flags*/) { Inkscape::DrawingGroup *flowed = new Inkscape::DrawingGroup(drawing); flowed->setPickChildren(false); - flowed->setStyle(this->style); + flowed->setStyle(this->style, this->parent->style); // pass the bbox of the text object as paintbox (used for paintserver fills) this->layout.show(flowed, this->geometricBounds()); @@ -362,7 +358,7 @@ gchar* SPText::description() const { char *n = xml_quote_strdup( style->font_family.value ); Inkscape::Util::Quantity q = Inkscape::Util::Quantity(style->font_size.computed, "px"); - GString *xs = g_string_new(q.string(sp_desktop_namedview(SP_ACTIVE_DESKTOP)->display_units).c_str()); + GString *xs = g_string_new(q.string(SP_ACTIVE_DESKTOP->getNamedView()->display_units).c_str()); char const *trunc = ""; Inkscape::Text::Layout const *layout = te_get_layout((SPItem *) this); @@ -403,6 +399,10 @@ Geom::Affine SPText::set_transform(Geom::Affine const &xform) { } } + // we cannot optimize text with textLength because it may show different size than specified + if (this->attributes.getTextLength()->_set) + return xform; + /* This function takes care of scaling & translation only, we return whatever parts we can't handle. */ @@ -464,8 +464,71 @@ unsigned SPText::_buildLayoutInput(SPObject *root, Inkscape::Text::Layout::Optio int child_attrs_offset = 0; Inkscape::Text::Layout::OptionalTextTagAttrs optional_attrs; + // Test SVG 2 text in shape implementation + // To do: follow SPItem clip_ref/mask_ref code + if (style->shape_inside.set ) { + + // Extract out id + Glib::ustring shape_url = style->shape_inside.value; + if ( shape_url.compare(0,5,"url(#") != 0 || shape_url.compare(shape_url.size()-1,1,")") != 0 ){ + std::cerr << "SPText::_buildLayoutInput(): Invalid shape-inside value: " << shape_url << std::endl; + } else { + shape_url.erase(0,5); + shape_url.erase(shape_url.size()-1,1); + // std::cout << "SPText::_buildLayoutInput(): shape-inside: " << shape_url << std::endl; + SPShape *shape = dynamic_cast<SPShape *>(document->getObjectById( shape_url )); + if ( shape ) { + + // This code adapted from sp-flowregion.cpp: GetDest() + if (!(shape->_curve)) { + shape->set_shape(); + } + SPCurve *curve = shape->getCurve(); + + if ( curve ) { + Path *temp = new Path; + Path *padded = new Path; + temp->LoadPathVector( curve->get_pathvector(), shape->transform, true ); + if( style->shape_padding.set ) { + // std::cout << " padding: " << style->shape_padding.computed << std::endl; + temp->OutsideOutline ( padded, style->shape_padding.computed, join_round, butt_straight, 20.0 ); + } else { + // std::cout << " no padding" << std::endl; + padded->Copy( temp ); + } + padded->Convert( 0.25 ); // Convert to polyline + Shape* sh = new Shape; + padded->Fill( sh, 0 ); + // for( unsigned i = 0; i < temp->pts.size(); ++i ) { + // std::cout << " ........ " << temp->pts[i].p << std::endl; + // } + // std::cout << " ...... shape: " << sh->numberOfPoints() << std::endl; + Shape *uncross = new Shape; + uncross->ConvertToShape( sh ); + layout.appendWrapShape( uncross ); + + delete temp; + delete padded; + delete sh; + // delete uncross; + } else { + std::cerr << "SPText::_buildLayoutInput(): Failed to get curve." << std::endl; + } + } else { + std::cerr << "SPText::_buildLayoutInput(): Failed to find shape." << std::endl; + } + } + } + if (SP_IS_TEXT(root)) { SP_TEXT(root)->attributes.mergeInto(&optional_attrs, parent_optional_attrs, parent_attrs_offset, true, true); + if (SP_TEXT(root)->attributes.getTextLength()->_set) { // set textLength on the entire layout, see note in TNG-Layout.h + layout.textLength._set = true; + layout.textLength.value = SP_TEXT(root)->attributes.getTextLength()->value; + layout.textLength.computed = SP_TEXT(root)->attributes.getTextLength()->computed; + layout.textLength.unit = SP_TEXT(root)->attributes.getTextLength()->unit; + layout.lengthAdjust = (Inkscape::Text::Layout::LengthAdjust) SP_TEXT(root)->attributes.getLengthAdjust(); + } } else if (SP_IS_TSPAN(root)) { SPTSpan *tspan = SP_TSPAN(root); @@ -488,7 +551,7 @@ unsigned SPText::_buildLayoutInput(SPObject *root, Inkscape::Text::Layout::Optio child_attrs_offset = parent_attrs_offset; } - if (SP_IS_TSPAN(root)) + if (SP_IS_TSPAN(root)) { if (SP_TSPAN(root)->role != SP_TSPAN_ROLE_UNSPECIFIED) { // we need to allow the first line not to have role=line, but still set the source_cookie to the right value SPObject *prev_object = root->getPrev(); @@ -507,13 +570,17 @@ unsigned SPText::_buildLayoutInput(SPObject *root, Inkscape::Text::Layout::Optio // start position. Very confusing. child_attrs_offset--; } - + } + for (SPObject *child = root->firstChild() ; child ; child = child->getNext() ) { - if (SP_IS_STRING(child)) { - Glib::ustring const &string = SP_STRING(child)->string; + SPString *str = dynamic_cast<SPString *>(child); + if (str) { + Glib::ustring const &string = str->string; + // std::cout << " Appending: " << string << std::endl; layout.appendText(string, root->style, child, &optional_attrs, child_attrs_offset + length); length += string.length(); - } /*XML Tree being directly used here while it shouldn't be.*/ else if (!sp_repr_is_meta_element(child->getRepr())) { + } else if (!sp_repr_is_meta_element(child->getRepr())) { + /* ^^^^ XML Tree being directly used here while it shouldn't be.*/ length += _buildLayoutInput(child, optional_attrs, child_attrs_offset + length, in_textpath); } } @@ -611,6 +678,8 @@ void TextTagAttributes::readFrom(Inkscape::XML::Node const *node) readSingleAttribute(SP_ATTR_DX, node->attribute("dx")); readSingleAttribute(SP_ATTR_DY, node->attribute("dy")); readSingleAttribute(SP_ATTR_ROTATE, node->attribute("rotate")); + readSingleAttribute(SP_ATTR_TEXTLENGTH, node->attribute("textLength")); + readSingleAttribute(SP_ATTR_LENGTHADJUST, node->attribute("lengthAdjust")); } bool TextTagAttributes::readSingleAttribute(unsigned key, gchar const *value) @@ -622,6 +691,16 @@ bool TextTagAttributes::readSingleAttribute(unsigned key, gchar const *value) case SP_ATTR_DX: attr_vector = &attributes.dx; break; case SP_ATTR_DY: attr_vector = &attributes.dy; break; case SP_ATTR_ROTATE: attr_vector = &attributes.rotate; break; + case SP_ATTR_TEXTLENGTH: + attributes.textLength.readOrUnset(value); + return true; + break; + case SP_ATTR_LENGTHADJUST: + attributes.lengthAdjust = (value && !strcmp(value, "spacingAndGlyphs")? + Inkscape::Text::Layout::LENGTHADJUST_SPACINGANDGLYPHS : + Inkscape::Text::Layout::LENGTHADJUST_SPACING); // default is "spacing" + return true; + break; default: return false; } @@ -632,14 +711,34 @@ bool TextTagAttributes::readSingleAttribute(unsigned key, gchar const *value) void TextTagAttributes::writeTo(Inkscape::XML::Node *node) const { - writeSingleAttribute(node, "x", attributes.x); - writeSingleAttribute(node, "y", attributes.y); - writeSingleAttribute(node, "dx", attributes.dx); - writeSingleAttribute(node, "dy", attributes.dy); - writeSingleAttribute(node, "rotate", attributes.rotate); + writeSingleAttributeVector(node, "x", attributes.x); + writeSingleAttributeVector(node, "y", attributes.y); + writeSingleAttributeVector(node, "dx", attributes.dx); + writeSingleAttributeVector(node, "dy", attributes.dy); + writeSingleAttributeVector(node, "rotate", attributes.rotate); + + writeSingleAttributeLength(node, "textLength", attributes.textLength); + + if (attributes.textLength._set) { + if (attributes.lengthAdjust == Inkscape::Text::Layout::LENGTHADJUST_SPACING) { + node->setAttribute("lengthAdjust", "spacing"); + } else if (attributes.lengthAdjust == Inkscape::Text::Layout::LENGTHADJUST_SPACINGANDGLYPHS) { + node->setAttribute("lengthAdjust", "spacingAndGlyphs"); + } + } +} + +void TextTagAttributes::writeSingleAttributeLength(Inkscape::XML::Node *node, gchar const *key, const SVGLength &length) +{ + if (length._set) { + gchar single_value_string[32]; + g_ascii_formatd(single_value_string, sizeof (single_value_string), "%.8g", length.computed); + node->setAttribute(key, single_value_string); + } else + node->setAttribute(key, NULL); } -void TextTagAttributes::writeSingleAttribute(Inkscape::XML::Node *node, gchar const *key, std::vector<SVGLength> const &attr_vector) +void TextTagAttributes::writeSingleAttributeVector(Inkscape::XML::Node *node, gchar const *key, std::vector<SVGLength> const &attr_vector) { if (attr_vector.empty()) node->setAttribute(key, NULL); @@ -697,6 +796,13 @@ void TextTagAttributes::mergeInto(Inkscape::Text::Layout::OptionalTextTagAttrs * mergeSingleAttribute(&output->dx, parent_attrs.dx, parent_attrs_offset, copy_dxdyrotate ? &attributes.dx : NULL); mergeSingleAttribute(&output->dy, parent_attrs.dy, parent_attrs_offset, copy_dxdyrotate ? &attributes.dy : NULL); mergeSingleAttribute(&output->rotate, parent_attrs.rotate, parent_attrs_offset, copy_dxdyrotate ? &attributes.rotate : NULL); + if (attributes.textLength._set) { // only from current node, this is not inherited from parent + output->textLength.value = attributes.textLength.value; + output->textLength.computed = attributes.textLength.computed; + output->textLength.unit = attributes.textLength.unit; + output->textLength._set = attributes.textLength._set; + output->lengthAdjust = attributes.lengthAdjust; + } } void TextTagAttributes::mergeSingleAttribute(std::vector<SVGLength> *output_list, std::vector<SVGLength> const &parent_list, unsigned parent_offset, std::vector<SVGLength> const *overlay_list) diff --git a/src/sp-title.cpp b/src/sp-title.cpp index 4ecfcfa8e..ba5ae754a 100644 --- a/src/sp-title.cpp +++ b/src/sp-title.cpp @@ -9,23 +9,9 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include "sp-title.h" #include "xml/repr.h" -#include "sp-factory.h" - -namespace { - SPObject* createTitle() { - return new SPTitle(); - } - - bool titleRegistered = SPFactory::instance().registerObject("svg:title", createTitle); -} - SPTitle::SPTitle() : SPObject() { } diff --git a/src/sp-tref.cpp b/src/sp-tref.cpp index 0f6eb106f..aef18462a 100644 --- a/src/sp-tref.cpp +++ b/src/sp-tref.cpp @@ -16,10 +16,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include <glibmm/i18n.h> #include "attributes.h" @@ -35,14 +31,6 @@ #include "xml/node.h" #include "xml/repr.h" -namespace { - SPObject* createTRef() { - return new SPTRef(); - } - - bool trefRegistered = SPFactory::instance().registerObject("svg:tref", createTRef); -} - //#define DEBUG_TREF #ifdef DEBUG_TREF # define debug(f, a...) { g_message("%s(%d) %s:", \ @@ -413,7 +401,7 @@ void sp_tref_update_text(SPTRef *tref) Inkscape::XML::Document *xml_doc = tref->document->getReprDoc(); Inkscape::XML::Node *newStringRepr = xml_doc->createTextNode(charData.c_str()); - tref->stringChild = SPFactory::instance().createObject(NodeTraits::get_type_string(*newStringRepr)); + tref->stringChild = SPFactory::createObject(NodeTraits::get_type_string(*newStringRepr)); // Add this SPString as a child of the tref tref->attach(tref->stringChild, tref->lastChild()); @@ -492,12 +480,8 @@ sp_tref_convert_to_tspan(SPObject *obj) //SPObject * new_string_child = document->getObjectByRepr(new_string_repr); // Merge style from the tref - SPStyle *new_tspan_sty = new_tspan->style; - SPStyle const *tref_sty = tref->style; - sp_style_merge_from_dying_parent(new_tspan_sty, tref_sty); - sp_style_merge_from_parent(new_tspan_sty, new_tspan->parent->style); - - + new_tspan->style->merge( tref->style ); + new_tspan->style->cascade( new_tspan->parent->style ); new_tspan->updateRepr(); // Hold onto our SPObject and repr for now. diff --git a/src/sp-tspan.cpp b/src/sp-tspan.cpp index c3f7689e7..7582cb9e6 100644 --- a/src/sp-tspan.cpp +++ b/src/sp-tspan.cpp @@ -42,21 +42,7 @@ #include "style.h" #include "xml/repr.h" #include "document.h" - -#include "sp-factory.h" - -namespace { - SPObject* createTSpan() { - return new SPTSpan(); - } - - SPObject* createTextPath() { - return new SPTextPath(); - } - - bool tspanRegistered = SPFactory::instance().registerObject("svg:tspan", createTSpan); - bool textPathRegistered = SPFactory::instance().registerObject("svg:textPath", createTextPath); -} +#include "2geom/transforms.h" /*##################################################### # SPTSPAN @@ -447,7 +433,8 @@ void sp_textpath_to_text(SPObject *tp) } Geom::Point xy = bbox->min(); - + xy *= tp->document->getDocumentScale().inverse(); // Convert to user-units. + // make a list of textpath children GSList *tp_reprs = NULL; @@ -468,7 +455,7 @@ void sp_textpath_to_text(SPObject *tp) tp->deleteObject(); g_slist_free(tp_reprs); - // set x/y on text + // set x/y on text (to be near where it was when on path) /* fixme: Yuck, is this really the right test? */ if (xy[Geom::X] != 1e18 && xy[Geom::Y] != 1e18) { sp_repr_set_svg_double(text->getRepr(), "x", xy[Geom::X]); diff --git a/src/sp-use.cpp b/src/sp-use.cpp index 2bd6757ff..239f487a4 100644 --- a/src/sp-use.cpp +++ b/src/sp-use.cpp @@ -13,10 +13,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - #include <cstring> #include <string> @@ -35,20 +31,13 @@ #include "preferences.h" #include "style.h" #include "sp-symbol.h" +#include "sp-root.h" #include "sp-use.h" #include "sp-use-reference.h" #include "sp-shape.h" #include "sp-text.h" #include "sp-flowtext.h" -namespace { - SPObject* createUse() { - return new SPUse(); - } - - bool useRegistered = SPFactory::instance().registerObject("svg:use", createUse); -} - SPUse::SPUse() : SPItem(), child(NULL), @@ -94,7 +83,7 @@ void SPUse::build(SPDocument *document, Inkscape::XML::Node *repr) { // We don't need to create child here: // reading xlink:href will attach ref, and that will cause the changed signal to be emitted, - // which will call sp_use_href_changed, and that will take care of the child + // which will call SPUse::href_changed, and that will take care of the child } void SPUse::release() { @@ -145,7 +134,7 @@ void SPUse::set(unsigned int key, const gchar* value) { this->href = NULL; if (value) { - // First, set the href field, because sp_use_href_changed will need it. + // First, set the href field, because SPUse::href_changed will need it. this->href = g_strdup(value); // Now do the attaching, which emits the changed signal. @@ -251,6 +240,8 @@ gchar* SPUse::description() const { if ( dynamic_cast<SPSymbol *>(child) ) { if (child->title()) { return g_strdup_printf(_("called %s"), Glib::Markup::escape_text(Glib::ustring( g_dpgettext2(NULL, "Symbol", child->title()))).c_str()); + } else if (child->getAttribute("id")) { + return g_strdup_printf(_("called %s"), Glib::Markup::escape_text(Glib::ustring( g_dpgettext2(NULL, "Symbol", child->getAttribute("id")))).c_str()); } else { return g_strdup_printf(_("called %s"), _("Unnamed Symbol")); } @@ -280,10 +271,13 @@ gchar* SPUse::description() const { } Inkscape::DrawingItem* SPUse::show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags) { + + // std::cout << "SPUse::show: " << (getId()?getId():"null") << std::endl; Inkscape::DrawingGroup *ai = new Inkscape::DrawingGroup(drawing); ai->setPickChildren(false); - ai->setStyle(this->style); - + this->context_style = this->style; + ai->setStyle(this->style, this->context_style); + if (this->child) { Inkscape::DrawingItem *ac = this->child->invoke_show(drawing, key, flags); @@ -476,7 +470,7 @@ void SPUse::href_changed() { if (refobj) { Inkscape::XML::Node *childrepr = refobj->getRepr(); - SPObject* obj = SPFactory::instance().createObject(NodeTraits::get_type_string(*childrepr)); + SPObject* obj = SPFactory::createObject(NodeTraits::get_type_string(*childrepr)); SPItem *item = dynamic_cast<SPItem *>(obj); if (item) { @@ -529,6 +523,7 @@ void SPUse::delete_self() { } void SPUse::update(SPCtx *ctx, unsigned flags) { + // std::cout << "SPUse::update: " << (getId()?getId():"null") << std::endl; SPItemCtx *ictx = (SPItemCtx *) ctx; SPItemCtx cctx = *ictx; @@ -556,13 +551,17 @@ void SPUse::update(SPCtx *ctx, unsigned flags) { this->height.computed = this->height.value * ictx->viewport.height(); } - cctx.viewport = Geom::Rect::from_xywh(0, 0, this->width.computed, this->height.computed); - cctx.i2vp = Geom::identity(); childflags &= ~SP_OBJECT_USER_MODIFIED_FLAG_B; if (this->child) { sp_object_ref(this->child); + // viewport is only changed if referencing a symbol or svg element + if( SP_IS_SYMBOL(this->child) || SP_IS_ROOT(this->child) ) { + cctx.viewport = Geom::Rect::from_xywh(0, 0, this->width.computed, this->height.computed); + cctx.i2vp = Geom::identity(); + } + if (childflags || (this->child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { SPItem const *chi = dynamic_cast<SPItem const *>(child); g_assert(chi != NULL); @@ -579,7 +578,8 @@ void SPUse::update(SPCtx *ctx, unsigned flags) { if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { for (SPItemView *v = this->display; v != NULL; v = v->next) { Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); - g->setStyle(this->style); + this->context_style = this->style; + g->setStyle(this->style, this->context_style); } } @@ -592,6 +592,7 @@ void SPUse::update(SPCtx *ctx, unsigned flags) { } void SPUse::modified(unsigned int flags) { + // std::cout << "SPUse::modified: " << (getId()?getId():"null") << std::endl; if (flags & SP_OBJECT_MODIFIED_FLAG) { flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; } @@ -601,7 +602,8 @@ void SPUse::modified(unsigned int flags) { if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { for (SPItemView *v = this->display; v != NULL; v = v->next) { Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); - g->setStyle(this->style); + this->context_style = this->style; + g->setStyle(this->style, this->context_style); } } @@ -657,11 +659,8 @@ SPItem *SPUse::unlink() { SPObject *unlinked = document->getObjectByRepr(copy); // Merge style from the use. - SPStyle *unli_sty = unlinked->style; - SPStyle const *use_sty = this->style; - sp_style_merge_from_dying_parent(unli_sty, use_sty); - sp_style_merge_from_parent(unli_sty, unlinked->parent->style); - + unlinked->style->merge( this->style ); + unlinked->style->cascade( unlinked->parent->style ); unlinked->updateRepr(); // Hold onto our SPObject and repr for now. diff --git a/src/splivarot.cpp b/src/splivarot.cpp index 1a75a6f29..46279cbce 100644 --- a/src/splivarot.cpp +++ b/src/splivarot.cpp @@ -37,7 +37,7 @@ #include "layer-model.h" #include "message-stack.h" #include "selection.h" -#include "desktop-handles.h" + #include "desktop.h" #include "display/canvas-bpath.h" #include "display/curve.h" @@ -1151,7 +1151,7 @@ Geom::PathVector* item_outline(SPItem const *item, bool bbox_only) void sp_selected_path_outline(SPDesktop *desktop) { - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (selection->isEmpty()) { desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>stroked path(s)</b> to convert stroke to path.")); @@ -1343,7 +1343,7 @@ sp_selected_path_outline(SPDesktop *desktop) if (res->descr_cmd.size() > 1) { // if there's 0 or 1 node left, drop this path altogether - SPDocument * doc = sp_desktop_document(desktop); + SPDocument * doc = desktop->getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); Inkscape::XML::Node *repr = xml_doc->createElement("svg:path"); @@ -1482,7 +1482,7 @@ sp_selected_path_outline(SPDesktop *desktop) // restore title, description, id, transform repr->setAttribute("id", id); - SPItem *newitem = (SPItem *) sp_desktop_document(desktop)->getObjectByRepr(repr); + SPItem *newitem = (SPItem *) desktop->getDocument()->getObjectByRepr(repr); newitem->doWriteTransform(repr, transform); if (title) { newitem->setTitle(title); @@ -1512,7 +1512,7 @@ sp_selected_path_outline(SPDesktop *desktop) } if (did) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_SELECTION_OUTLINE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_SELECTION_OUTLINE, _("Convert stroke to path")); } else { // TRANSLATORS: "to outline" means "to convert stroke to path" @@ -1583,7 +1583,7 @@ void sp_selected_path_create_updating_inset(SPDesktop *desktop) void sp_selected_path_create_offset_object(SPDesktop *desktop, int expand, bool updating) { SPCurve *curve = NULL; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); SPItem *item = selection->singleItem(); if (item == NULL || ( !SP_IS_SHAPE(item) && !SP_IS_TEXT(item) ) ) { @@ -1675,7 +1675,7 @@ void sp_selected_path_create_offset_object(SPDesktop *desktop, int expand, bool { // pas vraiment de points sur le resultat // donc il ne reste rien - DocumentUndo::done(sp_desktop_document(desktop), + DocumentUndo::done(desktop->getDocument(), (updating ? SP_VERB_SELECTION_LINKED_OFFSET : SP_VERB_SELECTION_DYNAMIC_OFFSET), (updating ? _("Create linked offset") @@ -1723,11 +1723,13 @@ void sp_selected_path_create_offset_object(SPDesktop *desktop, int expand, bool // move to the saved position repr->setPosition(pos > 0 ? pos : 0); - SPItem *nitem = reinterpret_cast<SPItem *>(sp_desktop_document(desktop)->getObjectByRepr(repr)); + SPItem *nitem = reinterpret_cast<SPItem *>(desktop->getDocument()->getObjectByRepr(repr)); if ( !updating ) { // delete original, apply the transform to the offset + const char *n_id = item->getRepr()->attribute("id"); item->deleteObject(false); + repr->setAttribute("id", n_id); nitem->doWriteTransform(repr, transform); } @@ -1740,7 +1742,7 @@ void sp_selected_path_create_offset_object(SPDesktop *desktop, int expand, bool selection->set(nitem); } - DocumentUndo::done(sp_desktop_document(desktop), + DocumentUndo::done(desktop->getDocument(), (updating ? SP_VERB_SELECTION_LINKED_OFFSET : SP_VERB_SELECTION_DYNAMIC_OFFSET), (updating ? _("Create linked offset") @@ -1766,7 +1768,7 @@ void sp_selected_path_create_offset_object(SPDesktop *desktop, int expand, bool void sp_selected_path_do_offset(SPDesktop *desktop, bool expand, double prefOffset) { - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (selection->isEmpty()) { desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>path(s)</b> to inset/outset.")); @@ -1946,7 +1948,7 @@ sp_selected_path_do_offset(SPDesktop *desktop, bool expand, double prefOffset) // move to the saved position repr->setPosition(pos > 0 ? pos : 0); - SPItem *newitem = (SPItem *) sp_desktop_document(desktop)->getObjectByRepr(repr); + SPItem *newitem = (SPItem *) desktop->getDocument()->getObjectByRepr(repr); // reapply the transform newitem->doWriteTransform(repr, transform); @@ -1963,7 +1965,7 @@ sp_selected_path_do_offset(SPDesktop *desktop, bool expand, double prefOffset) } if (did) { - DocumentUndo::done(sp_desktop_document(desktop), + DocumentUndo::done(desktop->getDocument(), (expand ? SP_VERB_SELECTION_OFFSET : SP_VERB_SELECTION_INSET), (expand ? _("Outset path") : _("Inset path"))); } else { @@ -2089,7 +2091,7 @@ sp_selected_path_simplify_item(SPDesktop *desktop, // move to the saved position repr->setPosition(pos > 0 ? pos : 0); - SPItem *newitem = (SPItem *) sp_desktop_document(desktop)->getObjectByRepr(repr); + SPItem *newitem = (SPItem *) desktop->getDocument()->getObjectByRepr(repr); // reapply the transform newitem->doWriteTransform(repr, transform); @@ -2191,7 +2193,7 @@ static void sp_selected_path_simplify_selection(SPDesktop *desktop, float threshold, bool justCoalesce, float angleLimit, bool breakableAngles) { - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (selection->isEmpty()) { desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, @@ -2208,7 +2210,7 @@ sp_selected_path_simplify_selection(SPDesktop *desktop, float threshold, bool ju breakableAngles, true); if (didSomething) - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_SELECTION_SIMPLIFY, + DocumentUndo::done(desktop->getDocument(), SP_VERB_SELECTION_SIMPLIFY, _("Simplify")); else desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("<b>No paths</b> to simplify in the selection.")); diff --git a/src/style-internal.cpp b/src/style-internal.cpp index b858e5cb6..915282301 100644 --- a/src/style-internal.cpp +++ b/src/style-internal.cpp @@ -984,7 +984,7 @@ SPIPaint::read( gchar const *str ) { if (streq(str, "currentColor")) { set = true; - currentcolor = true; + paintOrigin = SP_CSS_PAINT_ORIGIN_CURRENT_COLOR; if (style) { setColor( style->color.value.color ); } else { @@ -995,6 +995,12 @@ SPIPaint::read( gchar const *str ) { std::cerr << "SPIPaint::read(): value is 'currentColor' but 'color' not available." << std::endl; setColor( 0 ); } + } else if (streq(str, "context-fill")) { + set = true; + paintOrigin = SP_CSS_PAINT_ORIGIN_CONTEXT_FILL; + } else if (streq(str, "context-stroke")) { + set = true; + paintOrigin = SP_CSS_PAINT_ORIGIN_CONTEXT_STROKE; } else if (streq(str, "none")) { set = true; noneSet = true; @@ -1058,14 +1064,28 @@ SPIPaint::write( guint const flags, SPIBase const *const base) const { css << "none"; } - if ( this->currentcolor ) { + if ( this->paintOrigin == SP_CSS_PAINT_ORIGIN_CURRENT_COLOR ) { if ( !css.str().empty() ) { css << " "; } css << "currentColor"; } - if ( this->colorSet && !this->currentcolor ) { + if ( this->paintOrigin == SP_CSS_PAINT_ORIGIN_CONTEXT_FILL ) { + if ( !css.str().empty() ) { + css << " "; + } + css << "context-fill"; + } + + if ( this->paintOrigin == SP_CSS_PAINT_ORIGIN_CONTEXT_STROKE ) { + if ( !css.str().empty() ) { + css << " "; + } + css << "context-stroke"; + } + + if ( this->colorSet && this->paintOrigin == SP_CSS_PAINT_ORIGIN_NORMAL ) { if ( !css.str().empty() ) { css << " "; } @@ -1074,7 +1094,7 @@ SPIPaint::write( guint const flags, SPIBase const *const base) const { css << color_buf; } - if (this->value.color.icc && !this->currentcolor) { + if ( this->value.color.icc && this->paintOrigin == SP_CSS_PAINT_ORIGIN_NORMAL ) { if ( !css.str().empty() ) { css << " "; } @@ -1107,7 +1127,7 @@ SPIPaint::reset( bool init ) { // std::cout << "SPIPaint::reset(): " << name << " " << init << std::endl; SPIBase::clear(); - currentcolor = false; + paintOrigin = SP_CSS_PAINT_ORIGIN_NORMAL; colorSet = false; noneSet = false; value.color.set( false ); @@ -1147,8 +1167,8 @@ SPIPaint::cascade( const SPIBase* const parent ) { setColor( p->value.color ); } else if( p->isNoneSet() ) { noneSet = true; - } else if( p->currentcolor ) { - currentcolor = true; + } else if( p->paintOrigin == SP_CSS_PAINT_ORIGIN_CURRENT_COLOR ) { + paintOrigin = SP_CSS_PAINT_ORIGIN_CURRENT_COLOR; setColor( style->color.value.color ); } else if( isNone() ) { // @@ -1156,7 +1176,7 @@ SPIPaint::cascade( const SPIBase* const parent ) { g_assert_not_reached(); } } else { - if( currentcolor ) { + if( paintOrigin == SP_CSS_PAINT_ORIGIN_CURRENT_COLOR ) { // Update in case color value changed. setColor( style->color.value.color ); } @@ -1187,7 +1207,7 @@ SPIPaint::operator==(const SPIBase& rhs) { if ( (this->isColor() != r->isColor() ) || (this->isPaintserver() != r->isPaintserver() ) || - (this->currentcolor != r->currentcolor ) ) { + (this->paintOrigin != r->paintOrigin ) ) { return false; } diff --git a/src/style-internal.h b/src/style-internal.h index faae76ac5..a8f0c5096 100644 --- a/src/style-internal.h +++ b/src/style-internal.h @@ -628,6 +628,15 @@ public: #define SP_STYLE_FILL_SERVER(s) ((const_cast<SPStyle *> (s))->getFillPaintServer()) #define SP_STYLE_STROKE_SERVER(s) ((const_cast<SPStyle *> (s))->getStrokePaintServer()) +// SVG 2 +enum SPPaintOrigin { + SP_CSS_PAINT_ORIGIN_NORMAL, + SP_CSS_PAINT_ORIGIN_CURRENT_COLOR, + SP_CSS_PAINT_ORIGIN_CONTEXT_FILL, + SP_CSS_PAINT_ORIGIN_CONTEXT_STROKE +}; + + /// Paint type internal to SPStyle. class SPIPaint : public SPIBase { @@ -635,7 +644,7 @@ class SPIPaint : public SPIBase public: SPIPaint() : SPIBase( "anonymous_paint" ), - currentcolor(false), + paintOrigin( SP_CSS_PAINT_ORIGIN_NORMAL ), colorSet(false), noneSet(false) { value.href = NULL; @@ -644,7 +653,6 @@ public: SPIPaint( Glib::ustring const &name ) : SPIBase( name ), - currentcolor(false), colorSet(false), noneSet(false) { value.href = NULL; @@ -663,7 +671,7 @@ public: SPIPaint& operator=(const SPIPaint& rhs) { SPIBase::operator=(rhs); - currentcolor = rhs.currentcolor; + paintOrigin = rhs.paintOrigin; colorSet = rhs.colorSet; noneSet = rhs.noneSet; value.color = rhs.value.color; @@ -677,7 +685,7 @@ public: } bool isSameType( SPIPaint const & other ) const { - return (isPaintserver() == other.isPaintserver()) && (colorSet == other.colorSet) && (currentcolor == other.currentcolor); + return (isPaintserver() == other.isPaintserver()) && (colorSet == other.colorSet) && (paintOrigin == other.paintOrigin); } bool isNoneSet() const { @@ -685,7 +693,7 @@ public: } bool isNone() const { - return !currentcolor && !colorSet && !isPaintserver(); + return (paintOrigin == SP_CSS_PAINT_ORIGIN_NORMAL) && !colorSet && !isPaintserver(); } // TODO refine bool isColor() const { @@ -712,7 +720,7 @@ public: // To do: make private public: - bool currentcolor : 1; + SPPaintOrigin paintOrigin : 2; bool colorSet : 1; bool noneSet : 1; struct { diff --git a/src/style-test.h b/src/style-test.h index e14ed4db7..cd6769b24 100644 --- a/src/style-test.h +++ b/src/style-test.h @@ -214,32 +214,25 @@ public: for ( gint i = 0; cases[i].src; i++ ) { // std::cout << "Test one: " << i << std::endl; - SPStyle *style = sp_style_new(_doc); - TS_ASSERT(style); - if ( style ) { - sp_style_merge_from_style_string( style, cases[i].src ); - - if ( cases[i].uri ) { - TSM_ASSERT( cases[i].src, style->fill.value.href ); - if ( style->fill.value.href ) { - TS_ASSERT_EQUALS( style->fill.value.href->getURI()->toString(), std::string(cases[i].uri) ); - } - } else { - TS_ASSERT( !style->fill.value.href || !style->fill.value.href->getObject() ); + SPStyle style(_doc); + style.mergeString( cases[i].src ); + if ( cases[i].uri ) { + TSM_ASSERT( cases[i].src, style.fill.value.href ); + if ( style.fill.value.href ) { + TS_ASSERT_EQUALS( style.fill.value.href->getURI()->toString(), std::string(cases[i].uri) ); } + } else { + TS_ASSERT( !style.fill.value.href || !style.fill.value.href->getObject() ); + } - gchar *str0_set = sp_style_write_string( style, SP_STYLE_FLAG_IFSET ); - //printf("<<%s>>\n", str0_set); - if ( cases[i].dst ) { - // std::cout << " " << std::string(str0_set) << " " << std::string(cases[i].dst) << std::endl; - TS_ASSERT_EQUALS( std::string(str0_set), std::string(cases[i].dst) ); - } else { - // std::cout << " " << std::string(str0_set) << " " << std::string(cases[i].src) << std::endl; - TS_ASSERT_EQUALS( std::string(str0_set), std::string(cases[i].src) ); - } + std::string str0_set = style.write(SP_STYLE_FLAG_IFSET ); - g_free(str0_set); - sp_style_unref(style); + if ( cases[i].dst ) { + // std::cout << " " << str0_set << " " << std::string(cases[i].dst) << std::endl; + TS_ASSERT_EQUALS( str0_set, std::string(cases[i].dst) ); + } else { + // std::cout << " " << str0_set << " " << std::string(cases[i].src) << std::endl; + TS_ASSERT_EQUALS( str0_set, std::string(cases[i].src) ); } } } @@ -366,26 +359,22 @@ public: }; for ( gint i = 0; cases[i].src; i++ ) { // std::cout << "Test two: " << i << std::endl; - SPStyle *style_src = sp_style_new(_doc); - TS_ASSERT(style_src); - SPStyle *style_dst = sp_style_new(_doc); - TS_ASSERT(style_dst); - - if ( style_src && style_dst ) { - sp_style_merge_from_style_string( style_src, cases[i].src ); - sp_style_merge_from_style_string( style_dst, cases[i].dst ); - // std::cout << "Test:" << std::endl; - // std::cout << " C: |" << cases[i].src << "| |" << cases[i].dst << "|" << std::endl; - // std::cout << " S: |" << style_src->write( SP_STYLE_FLAG_IFSET, NULL ) << "| |" - // << style_dst->write( SP_STYLE_FLAG_IFSET, NULL ) << "|" <<std::endl; - TS_ASSERT( (*style_src == *style_dst) == cases[i].match ); - sp_style_unref(style_src); - sp_style_unref(style_dst); - // std::cout << "End Test\n" << std::endl; - } + SPStyle style_src(_doc); + SPStyle style_dst(_doc); + + style_src.mergeString( cases[i].src ); + style_dst.mergeString( cases[i].dst ); + + // std::cout << "Test:" << std::endl; + // std::cout << " C: |" << cases[i].src << "| |" << cases[i].dst << "|" << std::endl; + // std::cout << " S: |" << style_src.write( SP_STYLE_FLAG_IFSET, NULL ) << "| |" + // << style_dst.write( SP_STYLE_FLAG_IFSET, NULL ) << "|" <<std::endl; + TS_ASSERT( (style_src == style_dst) == cases[i].match ); + // std::cout << "End Test\n" << std::endl; } } + // Test of cascade void testThree() { @@ -477,37 +466,29 @@ public: }; for ( gint i = 0; cases[i].parent; i++ ) { // std::cout << "Test three: " << i << std::endl; - SPStyle *style_parent = sp_style_new(_doc); - TS_ASSERT(style_parent); - SPStyle *style_child = sp_style_new(_doc); - TS_ASSERT(style_child); - SPStyle *style_result = sp_style_new(_doc); - TS_ASSERT(style_result); - - if ( style_parent && style_child && style_result ) { - sp_style_merge_from_style_string( style_parent, cases[i].parent ); - sp_style_merge_from_style_string( style_child, cases[i].child ); - sp_style_merge_from_style_string( style_result, cases[i].result ); - // std::cout << "Test:" << std::endl; - // std::cout << " Input: "; - // std::cout << " Parent: " << cases[i].parent - // << " Child: " << cases[i].child - // << " Result: " << cases[i].result << std::endl; - // std::cout << " Write: "; - // std::cout << " Parent: " << style_parent->write( SP_STYLE_FLAG_IFSET ) - // << " Child: " << style_child->write( SP_STYLE_FLAG_IFSET ) - // << " Result: " << style_result->write( SP_STYLE_FLAG_IFSET ) << std::endl; - - //sp_style_merge_from_parent( style_child, style_parent ); - style_child->cascade( style_parent ); - - TS_ASSERT(*style_child == *style_result ); - - sp_style_unref(style_child); - sp_style_unref(style_parent); - sp_style_unref(style_result); - // std::cout << "End Test: *************\n" << std::endl; - } + SPStyle style_parent(_doc); + SPStyle style_child( _doc); + SPStyle style_result(_doc); + + style_parent.mergeString( cases[i].parent ); + style_child.mergeString( cases[i].child ); + style_result.mergeString( cases[i].result ); + + // std::cout << "Test:" << std::endl; + // std::cout << " Input: "; + // std::cout << " Parent: " << cases[i].parent + // << " Child: " << cases[i].child + // << " Result: " << cases[i].result << std::endl; + // std::cout << " Write: "; + // std::cout << " Parent: " << style_parent.write( SP_STYLE_FLAG_IFSET ) + // << " Child: " << style_child.write( SP_STYLE_FLAG_IFSET ) + // << " Result: " << style_result.write( SP_STYLE_FLAG_IFSET ) << std::endl; + + style_child.cascade( &style_parent ); + + TS_ASSERT(style_child == style_result ); + + // std::cout << "End Test: *************\n" << std::endl; } } diff --git a/src/style.cpp b/src/style.cpp index a7e50b17a..b65bff53f 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -133,6 +133,12 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : text_anchor( "text-anchor", enum_text_anchor, SP_CSS_TEXT_ANCHOR_START ), white_space( "white-space", enum_white_space, SP_CSS_WHITE_SPACE_NORMAL ), + // SVG 2 Text Wrapping + shape_inside( "shape-inside" ), // SPIString + //shape_outside( "shape-outside" ), // SPIString + shape_padding( "shape-padding", 0.0 ), // SPILength for now + //shape_margin( "shape-margin", 0.0 ), // SPILength for now + text_decoration(), text_decoration_line(), text_decoration_style(), @@ -243,6 +249,7 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : word_spacing.setStylePointer( this ); stroke_width.setStylePointer( this ); stroke_dashoffset.setStylePointer( this ); + shape_padding.setStylePointer( this ); // Properties that depend on 'color' text_decoration_color.setStylePointer( this ); @@ -300,6 +307,9 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : _properties.push_back( &text_anchor ); _properties.push_back( &white_space ); + _properties.push_back( &shape_inside ); + _properties.push_back( &shape_padding ); + _properties.push_back( &clip_rule ); _properties.push_back( &display ); _properties.push_back( &overflow ); @@ -383,6 +393,10 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : // _propmap.insert( std::make_pair( text_anchor.name, reinterpret_cast<SPIBasePtr>(&SPStyle::text_anchor ) ) ); // _propmap.insert( std::make_pair( white_space.name, reinterpret_cast<SPIBasePtr>(&SPStyle::white_space ) ) ); + + // _propmap.insert( std::make_pair( shape_inside.name, reinterpret_cast<SPIBasePtr>(&SPStyle::shape_inside ) ) ); + // _propmap.insert( std::make_pair( shape_padding.name, reinterpret_cast<SPIBasePtr>(&SPStyle::shape_padding ) ) ); + // _propmap.insert( std::make_pair( clip_rule.name, reinterpret_cast<SPIBasePtr>(&SPStyle::clip_rule ) ) ); // _propmap.insert( std::make_pair( display.name, reinterpret_cast<SPIBasePtr>(&SPStyle::display ) ) ); // _propmap.insert( std::make_pair( overflow.name, reinterpret_cast<SPIBasePtr>(&SPStyle::overflow ) ) ); @@ -458,7 +472,14 @@ SPStyle::~SPStyle() { _properties.clear(); - // std::cout << "SPStyle::~SPstyle(): Exit\n" << std::endl; + // Conjecture: all this SPStyle ref counting is not needed. SPObject creates an instance of + // SPStyle when it is constructed and deletes it when it is destructed. The refcount is + // incremented and decremented only in the files: display/drawing-item.cpp, + // display/nr-filter-primitive.cpp, and libnrtype/Layout-TNG-Input.cpp. + if( _refcount > 1 ) { + std::cerr << "SPStyle::~SPStyle: ref count greater than 1! " << _refcount << std::endl; + } + // std::cout << "SPStyle::~SPStyle(): Exit\n" << std::endl; } // Used in SPStyle::clear() @@ -476,7 +497,7 @@ SPStyle::clear() { // (this->*(i->second)).clear(); // } - // Release connection to object, created in sp_style_new_from_object() + // Release connection to object, created in constructor. release_connection.disconnect(); // href->detach() called in fill->clear()... @@ -576,7 +597,13 @@ SPStyle::read( SPObject *object, Inkscape::XML::Node *repr ) { } } -// Matches void sp_style_read_from_object(SPStyle *style, SPObject *object); +/** + * Read style properties from object's repr. + * + * 1. Reset existing object style + * 2. Load current effective object style + * 3. Load i attributes from immediate parent (which has to be up-to-date) + */ void SPStyle::readFromObject( SPObject *object ) { @@ -591,6 +618,34 @@ SPStyle::readFromObject( SPObject *object ) { read( object, repr ); } +/** + * Read style properties from preferences. + * @param path Preferences directory from which the style should be read + */ +void +SPStyle::readFromPrefs(Glib::ustring const &path) { + + g_return_if_fail(!path.empty()); + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + // not optimal: we reconstruct the node based on the prefs, then pass it to + // sp_style_read for actual processing. + Inkscape::XML::SimpleDocument *tempdoc = new Inkscape::XML::SimpleDocument; + Inkscape::XML::Node *tempnode = tempdoc->createElement("prefs"); + + std::vector<Inkscape::Preferences::Entry> attrs = prefs->getAllEntries(path); + for (std::vector<Inkscape::Preferences::Entry>::iterator i = attrs.begin(); i != attrs.end(); ++i) { + tempnode->setAttribute(i->getEntryName().data(), i->getString().data()); + } + + read( NULL, tempnode ); + + Inkscape::GC::release(tempnode); + Inkscape::GC::release(tempdoc); + delete tempdoc; +} + // Matches sp_style_merge_property(SPStyle *style, gint id, gchar const *val) void SPStyle::readIfUnset( gint id, gchar const *val ) { @@ -678,6 +733,12 @@ SPStyle::readIfUnset( gint id, gchar const *val ) { case SP_PROP_WHITE_SPACE: white_space.readIfUnset( val ); break; + case SP_PROP_SHAPE_INSIDE: + shape_inside.readIfUnset( val ); + break; + case SP_PROP_SHAPE_PADDING: + shape_padding.readIfUnset( val ); + break; case SP_PROP_BASELINE_SHIFT: baseline_shift.readIfUnset( val ); break; @@ -868,6 +929,19 @@ SPStyle::readIfUnset( gint id, gchar const *val ) { } } +/** + * Outputs the style to a CSS string. + * + * Use with SP_STYLE_FLAG_ALWAYS for copying an object's complete cascaded style to + * style_clipboard. + * + * Use with SP_STYLE_FLAG_IFDIFF and a pointer to the parent class when you need a CSS string for + * an object in the document tree. + * + * \pre flags in {IFSET, ALWAYS, IFDIFF}. + * \pre base. + * \post ret != NULL. + */ Glib::ustring SPStyle::write( guint const flags, SPStyle const *const base ) const { @@ -897,9 +971,20 @@ SPStyle::write( guint const flags, SPStyle const *const base ) const { } // Corresponds to sp_style_merge_from_parent() +/** + * Sets computed values in \a style, which may involve inheriting from (or in some other way + * calculating from) corresponding computed values of \a parent. + * + * References: http://www.w3.org/TR/SVG11/propidx.html shows what properties inherit by default. + * http://www.w3.org/TR/SVG11/styling.html#Inheritance gives general rules as to what it means to + * inherit a value. http://www.w3.org/TR/REC-CSS2/cascade.html#computed-value is more precise + * about what the computed value is (not obvious for lengths). + * + * \pre \a parent's computed values are already up-to-date. + */ void SPStyle::cascade( SPStyle const *const parent ) { - // std::cout << "SPStyle::cascade" << std::endl; + // std::cout << "SPStyle::cascade: " << (object->getId()?object->getId():"null") << std::endl; for(std::vector<SPIBase*>::size_type i = 0; i != _properties.size(); ++i) { _properties[i]->cascade( parent->_properties[i] ); } @@ -909,6 +994,23 @@ SPStyle::cascade( SPStyle const *const parent ) { } // Corresponds to sp_style_merge_from_dying_parent() +/** + * Combine \a style and \a parent style specifications into a single style specification that + * preserves (as much as possible) the effect of the existing \a style being a child of \a parent. + * + * Called when the parent repr is to be removed (e.g. the parent is a \<use\> element that is being + * unlinked), in which case we copy/adapt property values that are explicitly set in \a parent, + * trying to retain the same visual appearance once the parent is removed. Interesting cases are + * when there is unusual interaction with the parent's value (opacity, display) or when the value + * can be specified as relative to the parent computed value (font-size, font-weight etc.). + * + * Doesn't update computed values of \a style. For correctness, you should subsequently call + * sp_style_merge_from_parent against the new parent (presumably \a parent's parent) even if \a + * style was previously up-to-date wrt \a parent. + * + * \pre \a parent's computed values are already up-to-date. + * (\a style's computed values needn't be up-to-date.) + */ void SPStyle::merge( SPStyle const *const parent ) { // std::cout << "SPStyle::merge" << std::endl; @@ -920,6 +1022,14 @@ SPStyle::merge( SPStyle const *const parent ) { // } } +/** + * Parses a style="..." string and merges it with an existing SPStyle. + */ +void +SPStyle::mergeString( gchar const *const p ) { + _mergeString( p ); +} + // Mostly for unit testing bool SPStyle::operator==(const SPStyle& rhs) { @@ -1142,35 +1252,6 @@ sp_style_stroke_paint_server_ref_changed(SPObject *old_ref, SPObject *ref, SPSty sp_style_paint_server_ref_modified(ref, 0, style); } -// Called in: desktop-style.cpp, gradient-chemistry.cpp, sp-object.cpp, sp-stop.cpp, style.cpp -// text-editing.cpp, libnrtype/font-lister.cpp, widgets/dash-selector.cpp, widgets/fill-style.cpp, -// widgets/stroke-style.cpp, widgets/text-toolbar.cpp, ui/dialog/glyphs.cpp, ui/dialog/swatches.cpp, -// ui/dialog/swatches.cpp, ui/dialog/text-edit.cpp. ui/tools/freehand-base.cpp, -// ui/widget/object-composite-settings.cpp, ui/widget/selected-style.cpp, ui/widget/style-swatch.cpp -/** - * Returns a new SPStyle object with default settings. - */ -SPStyle * -sp_style_new(SPDocument *document) -{ - SPStyle *const style = new SPStyle( document ); - return style; -} - -// Called in: sp-object.cpp -/** - * Creates a new SPStyle object, and attaches it to the specified SPObject. - */ -SPStyle * -sp_style_new_from_object(SPObject *object) -{ - g_return_val_if_fail(object != NULL, NULL); - g_return_val_if_fail(SP_IS_OBJECT(object), NULL); - - SPStyle *const style = new SPStyle( NULL, object ); - return style; -} - // Called in display/drawing-item.cpp, display/nr-filter-primitive.cpp, libnrtype/Layout-TNG-Input.cpp /** * Increase refcount of style. @@ -1180,13 +1261,12 @@ sp_style_ref(SPStyle *style) { g_return_val_if_fail(style != NULL, NULL); - style->ref(); // Increase ref count + style->style_ref(); // Increase ref count return style; } -// Called in style.cpp, desktop-style.cpp, sp-object.cpp, sp-stop.cpp, text-editing.cpp -// display/drawing-group.cpp, ... +// Called in display/drawing-item.cpp, display/nr-filter-primitive.cpp, libnrtype/Layout-TNG-Input.cpp /** * Decrease refcount of style with possible destruction. */ @@ -1194,71 +1274,13 @@ SPStyle * sp_style_unref(SPStyle *style) { g_return_val_if_fail(style != NULL, NULL); - if (style->unref() < 1) { + if (style->style_unref() < 1) { delete style; return NULL; } return style; } - - -// Called in: sp-clippath.cpp, sp-item.cpp (suspicious), sp-object.cpp, sp-style-elem.cpp -/** - * Read style properties from object's repr. - * - * 1. Reset existing object style - * 2. Load current effective object style - * 3. Load i attributes from immediate parent (which has to be up-to-date) - */ -void -sp_style_read_from_object(SPStyle *style, SPObject *object) -{ - // std::cout << "sp_style_read_from_object: " << (object->getId()?object->getId():"null") << std::endl; - g_return_if_fail(style != NULL); - g_return_if_fail(object != NULL); - g_return_if_fail(SP_IS_OBJECT(object)); - - Inkscape::XML::Node *repr = object->getRepr(); - g_return_if_fail(repr != NULL); - - style->read( object, repr ); -} - -// Called in: libnrtype/font-lister.cpp, widgets/dash-selector.cpp, widgets/text-toolbar.cpp, -// ui/dialog/text-edit.cpp -// Why is this called when draging a gradient handle? -/** - * Read style properties from preferences. - * @param style The style to write to - * @param path Preferences directory from which the style should be read - */ -void -sp_style_read_from_prefs(SPStyle *style, Glib::ustring const &path) -{ - g_return_if_fail(style != NULL); - g_return_if_fail(path != ""); - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - // not optimal: we reconstruct the node based on the prefs, then pass it to - // sp_style_read for actual processing. - Inkscape::XML::SimpleDocument *tempdoc = new Inkscape::XML::SimpleDocument; - Inkscape::XML::Node *tempnode = tempdoc->createElement("prefs"); - - std::vector<Inkscape::Preferences::Entry> attrs = prefs->getAllEntries(path); - for (std::vector<Inkscape::Preferences::Entry>::iterator i = attrs.begin(); i != attrs.end(); ++i) { - tempnode->setAttribute(i->getEntryName().data(), i->getString().data()); - } - - style->read( NULL, tempnode ); - - Inkscape::GC::release(tempnode); - Inkscape::GC::release(tempdoc); - delete tempdoc; -} - - static CRSelEng * sp_repr_sel_eng() { @@ -1282,81 +1304,9 @@ sp_repr_sel_eng() return ret; } - -// Called in text-editting.cpp, ui/tools/frehand-base.cpp, ui/widget/style-swatch.cpp -/** - * Parses a style="..." string and merges it with an existing SPStyle. - */ -void -sp_style_merge_from_style_string(SPStyle *const style, gchar const *const p) -{ - // std::cout << "sp_style_merge_from_style_string: " << (p?p:"null") <<std::endl; - /* - * Reference: http://www.w3.org/TR/SVG11/styling.html#StyleAttribute: - * ``When CSS styling is used, CSS inline style is specified by including - * semicolon-separated property declarations of the form "name : value" - * within the style attribute''. - * - * That's fairly ambiguous. Is a `value' allowed to contain semicolons? - * Why does it say "including", what else is allowed in the style - * attribute value? - */ - style->_mergeString( p ); -} - /** Indexed by SP_CSS_FONT_SIZE_blah. These seem a bit small */ static float const font_size_table[] = {6.0, 8.0, 10.0, 12.0, 14.0, 18.0, 24.0}; -// Called in sp-object.cpp, sp-tref.cpp, sp-use.cpp -/** - * Sets computed values in \a style, which may involve inheriting from (or in some other way - * calculating from) corresponding computed values of \a parent. - * - * References: http://www.w3.org/TR/SVG11/propidx.html shows what properties inherit by default. - * http://www.w3.org/TR/SVG11/styling.html#Inheritance gives general rules as to what it means to - * inherit a value. http://www.w3.org/TR/REC-CSS2/cascade.html#computed-value is more precise - * about what the computed value is (not obvious for lengths). - * - * \pre \a parent's computed values are already up-to-date. - */ -void -sp_style_merge_from_parent(SPStyle *const style, SPStyle const *const parent) -{ - // std::cout << "sp_style_merge_from_parent" << std::endl; - g_return_if_fail(style != NULL); - - if (!parent) - return; - - style->cascade( parent ); - return; -} - -// Called in: sp-use.cpp, sp-tref.cpp, sp-item.cpp -/** - * Combine \a style and \a parent style specifications into a single style specification that - * preserves (as much as possible) the effect of the existing \a style being a child of \a parent. - * - * Called when the parent repr is to be removed (e.g. the parent is a \<use\> element that is being - * unlinked), in which case we copy/adapt property values that are explicitly set in \a parent, - * trying to retain the same visual appearance once the parent is removed. Interesting cases are - * when there is unusual interaction with the parent's value (opacity, display) or when the value - * can be specified as relative to the parent computed value (font-size, font-weight etc.). - * - * Doesn't update computed values of \a style. For correctness, you should subsequently call - * sp_style_merge_from_parent against the new parent (presumably \a parent's parent) even if \a - * style was previously up-to-date wrt \a parent. - * - * \pre \a parent's computed values are already up-to-date. - * (\a style's computed values needn't be up-to-date.) - */ -void -sp_style_merge_from_dying_parent(SPStyle *const style, SPStyle const *const parent) -{ - // std::cout << "sp_style_merge_from_dying_parent" << std::endl; - style->merge( parent ); -} - // The following functions should be incorporated into SPIPaint. FIXME // Called in: style.cpp, style-internal.cpp void @@ -1473,50 +1423,6 @@ sp_style_css_size_units_to_px(double size, int unit) return size * (size / sp_style_css_size_px_to_units(size, unit));; } -// Called in style.cpp, text-editing.cpp -/** - * Dumps the style to a CSS string, with either SP_STYLE_FLAG_IFSET or - * SP_STYLE_FLAG_ALWAYS flags. Used with Always for copying an object's - * complete cascaded style to style_clipboard. When you need a CSS string - * for an object in the document tree, you normally call - * sp_style_write_difference instead to take into account the object's parent. - * - * \pre style != NULL. - * \pre flags in {IFSET, ALWAYS}. - * \post ret != NULL. - */ -gchar * -sp_style_write_string(SPStyle const *const style, guint const flags) -{ - /** \todo - * Merge with write_difference, much duplicate code! - */ - g_return_val_if_fail(style != NULL, NULL); - g_return_val_if_fail(((flags == SP_STYLE_FLAG_IFSET) || - (flags == SP_STYLE_FLAG_ALWAYS) ), - NULL); - - return g_strdup( style->write( flags ).c_str() ); -} - - -// Called in style.cpp, path-chemistry, NOT in text-editting.cpp (because of bug) -/** - * Dumps style to CSS string, see sp_style_write_string() - * - * \pre from != NULL. - * \pre to != NULL. - * \post ret != NULL. - */ -gchar * -sp_style_write_difference(SPStyle const *const from, SPStyle const *const to) -{ - g_return_val_if_fail(from != NULL, NULL); - g_return_val_if_fail(to != NULL, NULL); - - return g_strdup( from->write( SP_STYLE_FLAG_IFDIFF, to ).c_str() ); -} - // FIXME: Everything below this line belongs in a different file - css-chemistry? @@ -1640,6 +1546,12 @@ sp_style_unset_property_attrs(SPObject *o) if (style->white_space.set) { repr->setAttribute("white_space", NULL); } + if (style->shape_inside.set) { + repr->setAttribute("shape_inside", NULL); + } + if (style->shape_padding.set) { + repr->setAttribute("shape_padding", NULL); + } if (style->writing_mode.set) { repr->setAttribute("writing_mode", NULL); } @@ -1677,10 +1589,9 @@ sp_css_attr_from_style(SPStyle const *const style, guint const flags) g_return_val_if_fail(((flags == SP_STYLE_FLAG_IFSET) || (flags == SP_STYLE_FLAG_ALWAYS) ), NULL); - gchar *style_str = sp_style_write_string(style, flags); + Glib::ustring style_str = style->write(flags); SPCSSAttr *css = sp_repr_css_attr_new(); - sp_repr_css_attr_add_from_string(css, style_str); - g_free(style_str); + sp_repr_css_attr_add_from_string(css, style_str.c_str()); return css; } @@ -1729,6 +1640,8 @@ sp_css_attr_unset_text(SPCSSAttr *css) sp_repr_css_set_property(css, "writing-mode", NULL); sp_repr_css_set_property(css, "text-anchor", NULL); sp_repr_css_set_property(css, "white-space", NULL); + sp_repr_css_set_property(css, "shape-inside", NULL); + sp_repr_css_set_property(css, "shape-padding", NULL); sp_repr_css_set_property(css, "kerning", NULL); // not implemented yet sp_repr_css_set_property(css, "dominant-baseline", NULL); // not implemented yet sp_repr_css_set_property(css, "alignment-baseline", NULL); // not implemented yet diff --git a/src/style.h b/src/style.h index 1b1596458..ab34476b3 100644 --- a/src/style.h +++ b/src/style.h @@ -51,18 +51,19 @@ public: void readFromObject(SPObject *object); void readFromPrefs(Glib::ustring const &path); void readIfUnset( int id, char const *val ); - Glib::ustring write( unsigned int const flags, SPStyle const *const base = NULL ) const; + Glib::ustring write( unsigned int const flags = SP_STYLE_FLAG_IFSET, + SPStyle const *const base = NULL ) const; void cascade( SPStyle const *const parent ); void merge( SPStyle const *const parent ); + void mergeString( char const *const p ); bool operator==(const SPStyle& rhs); - int ref() { ++_refcount; return _refcount; } - int unref() { --_refcount; return _refcount; } + int style_ref() { ++_refcount; return _refcount; } + int style_unref() { --_refcount; return _refcount; } + int refCount() { return _refcount; } -//FIXME: Make private -public: - void _mergeString( char const *const p ); // Rename to readFromString? private: + void _mergeString( char const *const p ); void _mergeDeclList( CRDeclaration const *const decl_list ); void _mergeDecl( CRDeclaration const *const decl ); void _mergeProps( CRPropList *const props ); @@ -141,6 +142,12 @@ public: /** white space (svg2) */ SPIEnum white_space; + /** SVG2 Text Wrapping */ + SPIString shape_inside; + // SPIString shape_outside; + SPILength shape_padding; + // SPILength shape_margin; + /* Text Decoration ----------------------- */ /** text decoration (css2 16.3.1) */ @@ -282,28 +289,10 @@ public: char const *getStrokeURI() const { return (stroke.value.href) ? stroke.value.href->getURI()->toString() : NULL; } }; -SPStyle *sp_style_new(SPDocument *document); // SPStyle::SPStyle( SPDocument *document = NULL ); - -SPStyle *sp_style_new_from_object(SPObject *object); // SPStyle::SPStyle( SPObject *object ); - SPStyle *sp_style_ref(SPStyle *style); // SPStyle::ref(); SPStyle *sp_style_unref(SPStyle *style); // SPStyle::unref(); -void sp_style_read_from_object(SPStyle *style, SPObject *object); //SPStyle::read( SPObject * object); - -void sp_style_read_from_prefs(SPStyle *style, Glib::ustring const &path); // SPStyle::read( ... ); - -void sp_style_merge_from_style_string(SPStyle *style, char const *p); // SPStyle::merge( ... );? - -void sp_style_merge_from_parent(SPStyle *style, SPStyle const *parent); // SPStyle::cascade( ... ); - -void sp_style_merge_from_dying_parent(SPStyle *style, SPStyle const *parent); // SPStyle::merge( ... ) - -char *sp_style_write_string(SPStyle const *style, unsigned int flags = SP_STYLE_FLAG_IFSET);//SPStyle::write - -char *sp_style_write_difference(SPStyle const *from, SPStyle const *to); // SPStyle::write - void sp_style_set_to_uri_string (SPStyle *style, bool isfill, const char *uri); // ? char const *sp_style_get_css_unit_string(int unit); // No change? diff --git a/src/svg/svg-color.cpp b/src/svg/svg-color.cpp index c9f22f8a4..693094048 100644 --- a/src/svg/svg-color.cpp +++ b/src/svg/svg-color.cpp @@ -32,8 +32,8 @@ #include "svg-color.h" #include "svg-icc-color.h" -#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) #include "color.h" +#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) #include "color-profile.h" #include "document.h" #include "inkscape.h" diff --git a/src/svg/svg-length-test.h b/src/svg/svg-length-test.h index 796943e45..0dac4854a 100644 --- a/src/svg/svg-length-test.h +++ b/src/svg/svg-length-test.h @@ -102,7 +102,10 @@ public: for ( int i = (static_cast<int>(SVGLength::NONE) + 1); i <= static_cast<int>(SVGLength::LAST_UNIT); i++ ) { SVGLength::Unit target = static_cast<SVGLength::Unit>(i); // PX is a special case where we don't have a unit string - if ( (target != SVGLength::PX) && (target != SVGLength::FOOT) ) { + // FOOT and MITRE are not CSS/SVG Units + if ( (target != SVGLength::PX) && + (target != SVGLength::FOOT) && + (target != SVGLength::MITRE) ) { gchar const* val = sp_svg_length_get_css_units(target); TSM_ASSERT_DIFFERS(i, val, ""); } diff --git a/src/svg/svg-length.cpp b/src/svg/svg-length.cpp index b9b475f4b..edbc59c36 100644 --- a/src/svg/svg-length.cpp +++ b/src/svg/svg-length.cpp @@ -14,6 +14,7 @@ #include <cstring> #include <string> #include <glib.h> +#include <iostream> #include "svg.h" #include "stringstream.h" @@ -462,6 +463,51 @@ unsigned int sp_svg_length_read_ldd(gchar const *str, SVGLength::Unit *unit, dou return r; } +std::string const SVGLength::write() +{ + return sp_svg_length_write_with_units(*this); +} + +void SVGLength::set(SVGLength::Unit u, float v) +{ + _set = true; + unit = u; + Glib::ustring hack("px"); + switch( unit ) { + case NONE: + case PX: + case EM: + case EX: + case PERCENT: + break; + case PT: + hack = "pt"; + break; + case PC: + hack = "pc"; + break; + case MM: + hack = "pt"; + break; + case CM: + hack = "pt"; + break; + case INCH: + hack = "pt"; + break; + case FOOT: + hack = "pt"; + break; + case MITRE: + hack = "m"; + break; + default: + break; + } + value = v; + computed = Inkscape::Util::Quantity::convert(v, hack, "px"); +} + void SVGLength::set(SVGLength::Unit u, float v, float c) { _set = true; @@ -478,6 +524,12 @@ void SVGLength::unset(SVGLength::Unit u, float v, float c) computed = c; } +void SVGLength::scale(double scale) +{ + value *= scale; + computed *= scale; +} + void SVGLength::update(double em, double ex, double scale) { if (unit == EM) { @@ -520,7 +572,8 @@ gchar const *sp_svg_length_get_css_units(SVGLength::Unit unit) case SVGLength::MM: return "mm"; case SVGLength::CM: return "cm"; case SVGLength::INCH: return "in"; - case SVGLength::FOOT: return ""; // Does not have a "foot" unit string in the SVG spec + case SVGLength::FOOT: return ""; // Not in SVG/CSS specification. + case SVGLength::MITRE: return ""; // Not in SVG/CSS specification. case SVGLength::EM: return "em"; case SVGLength::EX: return "ex"; case SVGLength::PERCENT: return "%"; @@ -539,6 +592,8 @@ std::string sp_svg_length_write_with_units(SVGLength const &length) os << 100*length.value << sp_svg_length_get_css_units(length.unit); } else if (length.unit == SVGLength::FOOT) { os << 12*length.value << sp_svg_length_get_css_units(SVGLength::INCH); + } else if (length.unit == SVGLength::MITRE) { + os << 100*length.value << sp_svg_length_get_css_units(SVGLength::CM); } else { os << length.value << sp_svg_length_get_css_units(length.unit); } diff --git a/src/svg/svg-length.h b/src/svg/svg-length.h index c34905d07..84056dd5f 100644 --- a/src/svg/svg-length.h +++ b/src/svg/svg-length.h @@ -28,6 +28,7 @@ public: CM, INCH, FOOT, + MITRE, EM, EX, PERCENT, @@ -56,9 +57,13 @@ public: bool read(char const *str); void readOrUnset(char const *str, Unit u = NONE, float v = 0, float c = 0); bool readAbsolute(char const *str); - void set(Unit u, float v, float c); + std::string const write(); + // To set 'v' use '=' + void set(Unit u, float v); // Sets computed value based on u and v. + void set(Unit u, float v, float c); // Sets all three values. void unset(Unit u = NONE, float v = 0, float c = 0); - void update(double em, double ex, double scale); + void scale(double scale); // Scales length (value, computed), leaving unit alone. + void update(double em, double ex, double scale); // Updates computed value }; #endif // SEEN_SP_SVG_LENGTH_H diff --git a/src/test-helpers.h b/src/test-helpers.h index 001356e65..d30449ebb 100644 --- a/src/test-helpers.h +++ b/src/test-helpers.h @@ -5,7 +5,7 @@ #include <cxxtest/TestSuite.h> #include "document.h" -#include "inkscape-private.h" +#include "inkscape.h" // Dummy functions to keep linker happy @@ -28,10 +28,10 @@ T* createSuiteAndDocument( void (*fun)(T*&) ) #endif Inkscape::GC::init(); - if ( !inkscape_get_instance() ) + if ( !Inkscape::Application::exists() ) { // Create the global inkscape object. - static_cast<void>(g_object_new(inkscape_get_type(), NULL)); + Inkscape::Application::create("", false); } SPDocument* tmp = SPDocument::createNewDoc( NULL, TRUE, true ); diff --git a/src/text-chemistry.cpp b/src/text-chemistry.cpp index aa2d81427..65b59f2ad 100644 --- a/src/text-chemistry.cpp +++ b/src/text-chemistry.cpp @@ -29,7 +29,7 @@ #include "message-stack.h" #include "selection.h" #include "style.h" -#include "desktop-handles.h" + #include "text-editing.h" #include "text-chemistry.h" #include "sp-flowtext.h" @@ -83,7 +83,7 @@ text_put_on_path() if (!desktop) return; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); SPItem *text = text_or_flowtext_in_selection(selection); SPItem *shape = shape_in_selection(selection); @@ -91,18 +91,18 @@ text_put_on_path() Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); if (!text || !shape || g_slist_length((GSList *) selection->itemList()) != 2) { - sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select <b>a text and a path</b> to put text on path.")); + desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>a text and a path</b> to put text on path.")); return; } if (SP_IS_TEXT_TEXTPATH(text)) { - sp_desktop_message_stack(desktop)->flash(Inkscape::ERROR_MESSAGE, _("This text object is <b>already put on a path</b>. Remove it from the path first. Use <b>Shift+D</b> to look up its path.")); + desktop->getMessageStack()->flash(Inkscape::ERROR_MESSAGE, _("This text object is <b>already put on a path</b>. Remove it from the path first. Use <b>Shift+D</b> to look up its path.")); return; } if (SP_IS_RECT(shape)) { // rect is the only SPShape which is not <path> yet, and thus SVG forbids us from putting text on it - sp_desktop_message_stack(desktop)->flash(Inkscape::ERROR_MESSAGE, _("You cannot put text on a rectangle in this version. Convert rectangle to path first.")); + desktop->getMessageStack()->flash(Inkscape::ERROR_MESSAGE, _("You cannot put text on a rectangle in this version. Convert rectangle to path first.")); return; } @@ -110,7 +110,7 @@ text_put_on_path() if (SP_IS_FLOWTEXT(text)) { if (!SP_FLOWTEXT(text)->layout.outputExists()) { - sp_desktop_message_stack(desktop)-> + desktop->getMessageStack()-> flash(Inkscape::WARNING_MESSAGE, _("The flowed text(s) must be <b>visible</b> in order to be put on a path.")); } @@ -122,14 +122,14 @@ text_put_on_path() Inkscape::XML::Node *parent = text->getRepr()->parent(); parent->appendChild(repr); - SPItem *new_item = (SPItem *) sp_desktop_document(desktop)->getObjectByRepr(repr); + SPItem *new_item = (SPItem *) desktop->getDocument()->getObjectByRepr(repr); new_item->doWriteTransform(repr, text->transform); new_item->updateRepr(); Inkscape::GC::release(repr); text->deleteObject(); // delete the orignal flowtext - sp_desktop_document(desktop)->ensureUpToDate(); + desktop->getDocument()->ensureUpToDate(); selection->clear(); @@ -181,7 +181,7 @@ text_put_on_path() text->getRepr()->setAttribute("x", NULL); text->getRepr()->setAttribute("y", NULL); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("Put text on path")); g_slist_free(text_reprs); } @@ -191,10 +191,10 @@ text_remove_from_path() { SPDesktop *desktop = SP_ACTIVE_DESKTOP; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (selection->isEmpty()) { - sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select <b>a text on path</b> to remove it from path.")); + desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>a text on path</b> to remove it from path.")); return; } @@ -215,9 +215,9 @@ text_remove_from_path() } if (!did) { - sp_desktop_message_stack(desktop)->flash(Inkscape::ERROR_MESSAGE, _("<b>No texts-on-paths</b> in the selection.")); + desktop->getMessageStack()->flash(Inkscape::ERROR_MESSAGE, _("<b>No texts-on-paths</b> in the selection.")); } else { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("Remove text from path")); selection->setList(g_slist_copy((GSList *) selection->itemList())); // reselect to update statusbar description } @@ -256,10 +256,10 @@ text_remove_all_kerns() { SPDesktop *desktop = SP_ACTIVE_DESKTOP; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (selection->isEmpty()) { - sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select <b>text(s)</b> to remove kerns from.")); + desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>text(s)</b> to remove kerns from.")); return; } @@ -280,9 +280,9 @@ text_remove_all_kerns() } if (!did) { - sp_desktop_message_stack(desktop)->flash(Inkscape::ERROR_MESSAGE, _("Select <b>text(s)</b> to remove kerns from.")); + desktop->getMessageStack()->flash(Inkscape::ERROR_MESSAGE, _("Select <b>text(s)</b> to remove kerns from.")); } else { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("Remove manual kerns")); } } @@ -294,16 +294,16 @@ text_flow_into_shape() if (!desktop) return; - SPDocument *doc = sp_desktop_document (desktop); + SPDocument *doc = desktop->getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); SPItem *text = text_or_flowtext_in_selection(selection); SPItem *shape = shape_in_selection(selection); if (!text || !shape || g_slist_length((GSList *) selection->itemList()) < 2) { - sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select <b>a text</b> and one or more <b>paths or shapes</b> to flow text into frame.")); + desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>a text</b> and one or more <b>paths or shapes</b> to flow text into frame.")); return; } @@ -375,7 +375,7 @@ text_flow_into_shape() DocumentUndo::done(doc, SP_VERB_CONTEXT_TEXT, _("Flow text into shape")); - sp_desktop_selection(desktop)->set(SP_ITEM(root_object)); + desktop->getSelection()->set(SP_ITEM(root_object)); Inkscape::GC::release(root_repr); Inkscape::GC::release(region_repr); @@ -388,14 +388,14 @@ text_unflow () if (!desktop) return; - SPDocument *doc = sp_desktop_document (desktop); + SPDocument *doc = desktop->getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (!flowtext_in_selection(selection) || g_slist_length((GSList *) selection->itemList()) < 1) { - sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select <b>a flowed text</b> to unflow it.")); + desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>a flowed text</b> to unflow it.")); return; } @@ -477,10 +477,10 @@ flowtext_to_text() { SPDesktop *desktop = SP_ACTIVE_DESKTOP; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (selection->isEmpty()) { - sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, + desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>flowed text(s)</b> to convert.")); return; } @@ -497,7 +497,7 @@ flowtext_to_text() continue; if (!SP_FLOWTEXT(item)->layout.outputExists()) { - sp_desktop_message_stack(desktop)-> + desktop->getMessageStack()-> flash(Inkscape::WARNING_MESSAGE, _("The flowed text(s) must be <b>visible</b> in order to be converted.")); return; @@ -512,7 +512,7 @@ flowtext_to_text() Inkscape::XML::Node *parent = item->getRepr()->parent(); parent->addChild(repr, item->getRepr()); - SPItem *new_item = reinterpret_cast<SPItem *>(sp_desktop_document(desktop)->getObjectByRepr(repr)); + SPItem *new_item = reinterpret_cast<SPItem *>(desktop->getDocument()->getObjectByRepr(repr)); new_item->doWriteTransform(repr, item->transform); new_item->updateRepr(); @@ -525,12 +525,12 @@ flowtext_to_text() g_slist_free(items); if (did) { - DocumentUndo::done(sp_desktop_document(desktop), + DocumentUndo::done(desktop->getDocument(), SP_VERB_OBJECT_FLOWTEXT_TO_TEXT, _("Convert flowed text to text")); selection->setReprList(reprs); } else { - sp_desktop_message_stack(desktop)-> + desktop->getMessageStack()-> flash(Inkscape::ERROR_MESSAGE, _("<b>No flowed text(s)</b> to convert in the selection.")); } diff --git a/src/text-editing.cpp b/src/text-editing.cpp index 47964880c..4a962ab4c 100644 --- a/src/text-editing.cpp +++ b/src/text-editing.cpp @@ -1321,23 +1321,23 @@ static unsigned char_index_of_iterator(Glib::ustring const &string, Glib::ustrin return n; } +// Move to style.h? /** applies the given style string on top of the existing styles for \a item, as opposed to sp_style_merge_from_style_string which merges its parameter underneath the existing styles (ie ignoring already set properties). */ static void overwrite_style_with_string(SPObject *item, gchar const *style_string) { - SPStyle *new_style = sp_style_new(item->document); - sp_style_merge_from_style_string(new_style, style_string); + SPStyle style(item->document); + style.mergeString(style_string); gchar const *item_style_string = item->getRepr()->attribute("style"); if (item_style_string && *item_style_string) { - sp_style_merge_from_style_string(new_style, item_style_string); + style.mergeString(item_style_string); } - gchar *new_style_string = sp_style_write_string(new_style); - sp_style_unref(new_style); - item->getRepr()->setAttribute("style", new_style_string && *new_style_string ? new_style_string : NULL); - g_free(new_style_string); + Glib::ustring new_style_string = style.write(); + item->getRepr()->setAttribute("style", new_style_string.empty() ? NULL : new_style_string.c_str()); } +// Move to style.h? /** Returns true if the style of \a parent and the style of \a child are equivalent (and hence the children of both will appear the same). It is a limitation of the current implementation that \a parent must be a (not @@ -1349,14 +1349,14 @@ static bool objects_have_equal_style(SPObject const *parent, SPObject const *chi // implications too large for me to feel safe fixing, but mainly because the css spec // requires that the computed value is inherited, not the specified value. g_assert(parent->isAncestorOf(child)); - gchar *parent_style = sp_style_write_string(parent->style, SP_STYLE_FLAG_ALWAYS); + + Glib::ustring parent_style = parent->style->write( SP_STYLE_FLAG_ALWAYS ); + // we have to write parent_style then read it again, because some properties format their values // differently depending on whether they're set or not (*cough*dash-offset*cough*) - SPStyle *parent_spstyle = sp_style_new(parent->document); - sp_style_merge_from_style_string(parent_spstyle, parent_style); - g_free(parent_style); - parent_style = sp_style_write_string(parent_spstyle, SP_STYLE_FLAG_ALWAYS); - sp_style_unref(parent_spstyle); + SPStyle parent_spstyle(parent->document); + parent_spstyle.mergeString(parent_style.c_str()); + parent_style = parent_spstyle.write(SP_STYLE_FLAG_ALWAYS); Glib::ustring child_style_construction; while (child != parent) { @@ -1369,13 +1369,12 @@ static bool objects_have_equal_style(SPObject const *parent, SPObject const *chi child = child->parent; } child_style_construction.insert(0, parent_style); - SPStyle *child_spstyle = sp_style_new(parent->document); - sp_style_merge_from_style_string(child_spstyle, child_style_construction.c_str()); - gchar *child_style = sp_style_write_string(child_spstyle, SP_STYLE_FLAG_ALWAYS); - sp_style_unref(child_spstyle); - bool equal = !strcmp(child_style, parent_style); - g_free(child_style); - g_free(parent_style); + + SPStyle child_spstyle(parent->document); + child_spstyle.mergeString(child_style_construction.c_str()); + Glib::ustring child_style = child_spstyle.write(SP_STYLE_FLAG_ALWAYS); + + bool equal = (child_style == parent_style); // Glib::ustring overloads == operator return equal; } diff --git a/src/text-tag-attributes.h b/src/text-tag-attributes.h index d2bfd854e..7a389ed39 100644 --- a/src/text-tag-attributes.h +++ b/src/text-tag-attributes.h @@ -54,7 +54,7 @@ public: that only fields from \a parent_attrs starting at that index will be used. Basically, the algorithm is that if a child attribute exists that will be used, otherwise the parent attribute will be used, - otherwise the vector will end. */ + otherwise the vector will end. textLength is never merged with parent. */ void mergeInto(Inkscape::Text::Layout::OptionalTextTagAttrs *output, Inkscape::Text::Layout::OptionalTextTagAttrs const &parent_attrs, unsigned parent_attrs_offset, bool copy_xy, bool copy_dxdyrotate) const; /** Deletes all the values from all the vectors beginning at @@ -127,6 +127,9 @@ public: /** Sets the first coordinates in the x and y vectors. */ void setFirstXY(Geom::Point &point); + SVGLength *getTextLength() { return &(attributes.textLength); } + int getLengthAdjust() { return attributes.lengthAdjust; } + private: /// This holds the actual values. Inkscape::Text::Layout::OptionalTextTagAttrs attributes; @@ -134,7 +137,11 @@ private: /** Does the reverse of readSingleAttribute(), converting a vector<> to its SVG string representation and writing it in to \a node. Used by writeTo(). */ - static void writeSingleAttribute(Inkscape::XML::Node *node, gchar const *key, std::vector<SVGLength> const &attr_vector); + static void writeSingleAttributeVector(Inkscape::XML::Node *node, gchar const *key, std::vector<SVGLength> const &attr_vector); + + /** Writes a single length value to \a node. Used by + writeTo(). */ + static void writeSingleAttributeLength(Inkscape::XML::Node *node, gchar const *key, const SVGLength &length); /** Does mergeInto() for one member of #attributes. If \a overlay_list is NULL then it does a simple copy of parent elements, starting at diff --git a/src/trace/potrace/inkscape-potrace.cpp b/src/trace/potrace/inkscape-potrace.cpp index 59dd6f254..e9e708f52 100644 --- a/src/trace/potrace/inkscape-potrace.cpp +++ b/src/trace/potrace/inkscape-potrace.cpp @@ -25,7 +25,7 @@ #include "trace/imagemap-gdk.h" #include <inkscape.h> -#include <desktop-handles.h> +#include "desktop.h" #include "message-stack.h" #include <sp-path.h> #include <svg/path-string.h> @@ -430,7 +430,7 @@ std::vector<TracingEngineResult> PotraceTracingEngine::traceSingle(GdkPixbuf * t if (!grayMap) return results; - long nodeCount; + long nodeCount = 0L; std::string d = grayMapToPath(grayMap, &nodeCount); grayMap->destroy(grayMap); @@ -456,7 +456,7 @@ std::vector<TracingEngineResult> PotraceTracingEngine::traceGrayMap(GrayMap *gra brightnessFloor = 0.0; //important to set this - long nodeCount; + long nodeCount = 0L; std::string d = grayMapToPath(grayMap, &nodeCount); char const *style = "fill:#000000"; @@ -489,7 +489,7 @@ std::vector<TracingEngineResult> PotraceTracingEngine::traceBrightnessMulti(GdkP brightnessThreshold += delta) { GrayMap *grayMap = filter(*this, thePixbuf); if ( grayMap ) { - long nodeCount; + long nodeCount = 0L; std::string d = grayMapToPath(grayMap, &nodeCount); grayMap->destroy(grayMap); @@ -510,7 +510,7 @@ std::vector<TracingEngineResult> PotraceTracingEngine::traceBrightnessMulti(GdkP SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (desktop) { ustring msg = ustring::compose(_("Trace: %1. %2 nodes"), traceCount++, nodeCount); - sp_desktop_message_stack(desktop)->flash(Inkscape::NORMAL_MESSAGE, msg); + desktop->getMessageStack()->flash(Inkscape::NORMAL_MESSAGE, msg); } } } @@ -558,7 +558,7 @@ std::vector<TracingEngineResult> PotraceTracingEngine::traceQuant(GdkPixbuf * th } //## Now we have a traceable graymap - long nodeCount; + long nodeCount = 0L; std::string d = grayMapToPath(gm, &nodeCount); if ( !d.empty() ) { @@ -573,7 +573,7 @@ std::vector<TracingEngineResult> PotraceTracingEngine::traceQuant(GdkPixbuf * th SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (desktop) { ustring msg = ustring::compose(_("Trace: %1. %2 nodes"), colorIndex, nodeCount); - sp_desktop_message_stack(desktop)->flash(Inkscape::NORMAL_MESSAGE, msg); + desktop->getMessageStack()->flash(Inkscape::NORMAL_MESSAGE, msg); } } }// for colorIndex diff --git a/src/trace/trace.cpp b/src/trace/trace.cpp index cb83541e3..cc3d000a3 100644 --- a/src/trace/trace.cpp +++ b/src/trace/trace.cpp @@ -16,7 +16,7 @@ #include "inkscape.h" #include "desktop.h" -#include "desktop-handles.h" + #include "document.h" #include "document-undo.h" #include "message-stack.h" @@ -51,9 +51,9 @@ SPImage *Tracer::getSelectedSPImage() return NULL; } - Inkscape::MessageStack *msgStack = sp_desktop_message_stack(desktop); + Inkscape::MessageStack *msgStack = desktop->getMessageStack(); - Inkscape::Selection *sel = sp_desktop_selection(desktop); + Inkscape::Selection *sel = desktop->getSelection(); if (!sel) { char *msg = _("Select an <b>image</b> to trace"); @@ -217,9 +217,9 @@ Glib::RefPtr<Gdk::Pixbuf> Tracer::sioxProcessImage(SPImage *img, Glib::RefPtr<Gd return Glib::RefPtr<Gdk::Pixbuf>(NULL); } - Inkscape::MessageStack *msgStack = sp_desktop_message_stack(desktop); + Inkscape::MessageStack *msgStack = desktop->getMessageStack(); - Inkscape::Selection *sel = sp_desktop_selection(desktop); + Inkscape::Selection *sel = desktop->getSelection(); if (!sel) { char *msg = _("Select an <b>image</b> to trace"); @@ -397,9 +397,9 @@ void Tracer::traceThread() return; } - Inkscape::MessageStack *msgStack = sp_desktop_message_stack(desktop); + Inkscape::MessageStack *msgStack = desktop->getMessageStack(); - Inkscape::Selection *selection = sp_desktop_selection (desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (!SP_ACTIVE_DOCUMENT) { diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index e5c605889..674254686 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -4,10 +4,11 @@ set(ui_SRC control-manager.cpp dialog-events.cpp draw-anchor.cpp - interface.cpp - object-edit.cpp + interface.cpp + object-edit.cpp previewholder.cpp shape-editor.cpp + tool-factory.cpp tools-switch.cpp uxmanager.cpp diff --git a/src/ui/Makefile_insert b/src/ui/Makefile_insert index 7aeb4a83d..f94cba4e9 100644 --- a/src/ui/Makefile_insert +++ b/src/ui/Makefile_insert @@ -21,6 +21,7 @@ ink_common_sources += \ ui/previewholder.h \ ui/shape-editor.cpp \ ui/shape-editor.h \ + ui/tool-factory.cpp \ ui/tool-factory.h \ ui/tools-switch.cpp \ ui/tools-switch.h \ diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp index 153ed9830..f1d0ff576 100644 --- a/src/ui/clipboard.cpp +++ b/src/ui/clipboard.cpp @@ -32,12 +32,12 @@ #include <glibmm/ustring.h> #include <glibmm/i18n.h> #include <glib/gstdio.h> // for g_file_set_contents etc., used in _onGet and paste -#include "gc-core.h" +#include "inkgc/gc-core.h" #include "xml/repr.h" #include "inkscape.h" #include "io/stringstream.h" #include "desktop.h" -#include "desktop-handles.h" + #include "desktop-style.h" // for sp_desktop_set_style, used in _pasteStyle #include "document.h" #include "document-private.h" @@ -107,7 +107,7 @@ class ClipboardManagerImpl : public ClipboardManager { public: virtual void copy(SPDesktop *desktop); virtual void copyPathParameter(Inkscape::LivePathEffect::PathParam *); - virtual void copySymbol(Inkscape::XML::Node* symbol, gchar const* style); + virtual void copySymbol(Inkscape::XML::Node* symbol, gchar const* style, bool user_symbol); virtual bool paste(SPDesktop *desktop, bool in_place); virtual bool pasteStyle(SPDesktop *desktop); virtual bool pasteSize(SPDesktop *desktop, bool separately, bool apply_x, bool apply_y); @@ -201,7 +201,7 @@ void ClipboardManagerImpl::copy(SPDesktop *desktop) if ( desktop == NULL ) { return; } - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); // Special case for when the gradient dragger is active - copies gradient color if (desktop->event_context->get_drag()) { @@ -303,7 +303,7 @@ void ClipboardManagerImpl::copyPathParameter(Inkscape::LivePathEffect::PathParam * Copy a symbol from the symbol dialog. * @param symbol The Inkscape::XML::Node for the symbol. */ -void ClipboardManagerImpl::copySymbol(Inkscape::XML::Node* symbol, gchar const* style) +void ClipboardManagerImpl::copySymbol(Inkscape::XML::Node* symbol, gchar const* style, bool user_symbol) { //std::cout << "ClipboardManagerImpl::copySymbol" << std::endl; if ( symbol == NULL ) { @@ -326,17 +326,28 @@ void ClipboardManagerImpl::copySymbol(Inkscape::XML::Node* symbol, gchar const* Glib::ustring id("#"); id += symbol->attribute("id"); + gdouble scale_units = 1; // scale from "px" to "document-units" + Inkscape::XML::Node *nv_repr = SP_ACTIVE_DESKTOP->getNamedView()->getRepr(); + if (nv_repr->attribute("inkscape:document-units")) + scale_units = Inkscape::Util::Quantity::convert(1, "px", nv_repr->attribute("inkscape:document-units")); + SPObject *cmobj = _clipboardSPDoc->getObjectByRepr(repr); + if (cmobj && !user_symbol) { // convert only stock symbols + if (!Geom::are_near(scale_units, 1.0, Geom::EPSILON)) { + dynamic_cast<SPGroup *>(cmobj)->scaleChildItemsRec(Geom::Scale(scale_units), + Geom::Point(0, SP_ACTIVE_DESKTOP->getDocument()->getHeight().value("px")), + false); + } + } + Inkscape::XML::Node *use = _doc->createElement("svg:use"); use->setAttribute("xlink:href", id.c_str() ); // Set a default style in <use> rather than <symbol> so it can be changed. use->setAttribute("style", style ); - - Inkscape::XML::Node *nv_repr = sp_desktop_namedview(inkscape_active_desktop())->getRepr(); - gdouble scale_units = Inkscape::Util::Quantity::convert(1, nv_repr->attribute("inkscape:document-units"), "px"); - gchar *transform_str = sp_svg_transform_write(Geom::Scale(scale_units, scale_units)); - use->setAttribute("transform", transform_str); - g_free(transform_str); - + if (!Geom::are_near(scale_units, 1.0, Geom::EPSILON)) { + gchar *transform_str = sp_svg_transform_write(Geom::Scale(1.0/scale_units)); + use->setAttribute("transform", transform_str); + g_free(transform_str); + } _root->appendChild(use); // This min and max sets offsets, we don't have any so set to zero. @@ -435,7 +446,7 @@ bool ClipboardManagerImpl::pasteStyle(SPDesktop *desktop) } // check whether something is selected - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (selection->isEmpty()) { _userWarn(desktop, _("Select <b>object(s)</b> to paste style to.")); return false; @@ -488,7 +499,7 @@ bool ClipboardManagerImpl::pasteSize(SPDesktop *desktop, bool separately, bool a if ( desktop == NULL ) { return false; } - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (selection->isEmpty()) { _userWarn(desktop, _("Select <b>object(s)</b> to paste size to.")); return false; @@ -551,7 +562,7 @@ bool ClipboardManagerImpl::pastePathEffect(SPDesktop *desktop) return false; } - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (selection && selection->isEmpty()) { _userWarn(desktop, _("Select <b>object(s)</b> to paste live path effect to.")); return false; @@ -674,10 +685,18 @@ void ClipboardManagerImpl::_copySelection(Inkscape::Selection *selection) sp_repr_css_set(obj_copy, css, "style"); sp_repr_css_attr_unref(css); + Geom::Affine transform=item->i2doc_affine(); + // write the complete accumulated transform passed to us // (we're dealing with unattached representations, so we write to their attributes // instead of using sp_item_set_transform) - gchar *transform_str = sp_svg_transform_write(item->i2doc_affine()); + SPUse *use=dynamic_cast<SPUse *>(item); + if( use && selection->includes(use->get_original()) ){//we are copying something whose parent is also copied (!) + transform = ((SPItem*)(use->get_original()->parent))->i2doc_affine().inverse() * transform; + } + gchar *transform_str = sp_svg_transform_write(transform ); + + obj_copy->setAttribute("transform", transform_str); g_free(transform_str); } @@ -925,15 +944,18 @@ bool ClipboardManagerImpl::_pasteImage(SPDocument *doc) } Inkscape::Extension::Extension *png = *i; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - Glib::ustring attr = prefs->getString("/dialogs/import/link"); + Glib::ustring attr_saved = prefs->getString("/dialogs/import/link"); + bool ask_saved = prefs->getBool("/dialogs/import/ask"); prefs->setString("/dialogs/import/link", "embed"); + prefs->setBool("/dialogs/import/ask", false); png->set_gui(false); gchar *filename = g_build_filename( g_get_tmp_dir(), "inkscape-clipboard-import", NULL ); img->save(filename, "png"); file_import(doc, filename, png); g_free(filename); - prefs->setString("/dialogs/import/link", attr); + prefs->setString("/dialogs/import/link", attr_saved); + prefs->setBool("/dialogs/import/ask", ask_saved); png->set_gui(true); return true; diff --git a/src/ui/clipboard.h b/src/ui/clipboard.h index b565740c3..9f3b6cbdb 100644 --- a/src/ui/clipboard.h +++ b/src/ui/clipboard.h @@ -44,7 +44,7 @@ class ClipboardManager { public: virtual void copy(SPDesktop *desktop) = 0; virtual void copyPathParameter(Inkscape::LivePathEffect::PathParam *) = 0; - virtual void copySymbol(Inkscape::XML::Node* symbol, gchar const* style) = 0; + virtual void copySymbol(Inkscape::XML::Node* symbol, gchar const* style, bool user_symbol = true) = 0; virtual bool paste(SPDesktop *desktop, bool in_place = false) = 0; virtual bool pasteStyle(SPDesktop *desktop) = 0; virtual bool pasteSize(SPDesktop *desktop, bool separately, bool apply_x, bool apply_y) = 0; diff --git a/src/ui/dialog-events.cpp b/src/ui/dialog-events.cpp index 6bd93bbc3..5bc8088a1 100644 --- a/src/ui/dialog-events.cpp +++ b/src/ui/dialog-events.cpp @@ -6,7 +6,7 @@ * bulia byak <bulia@dr.com> * Johan Engelen <j.b.c.engelen@ewi.utwente.nl> * - * Copyright (C) 2003-2007 Authors + * Copyright (C) 2003-2014 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -25,7 +25,7 @@ #include "macros.h" #include <gtk/gtk.h> #include "desktop.h" -#include "inkscape-private.h" +#include "inkscape.h" #include "preferences.h" #include "ui/tools/tool-base.h" @@ -183,12 +183,11 @@ void sp_transientize(GtkWidget *dialog) void on_transientize (SPDesktop *desktop, win_data *wd ) { - sp_transientize_callback (0, desktop, wd); + sp_transientize_callback (desktop, wd); } void -sp_transientize_callback ( InkscapeApplication * /*inkscape*/, - SPDesktop *desktop, win_data *wd ) +sp_transientize_callback ( SPDesktop *desktop, win_data *wd ) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gint transient_policy = prefs->getIntLimited( "/options/transientpolicy/value", 1, 0, 2); diff --git a/src/ui/dialog-events.h b/src/ui/dialog-events.h index b33eb3f38..b4a5d7c35 100644 --- a/src/ui/dialog-events.h +++ b/src/ui/dialog-events.h @@ -4,7 +4,7 @@ /* Authors: * bulia byak <bulia@dr.com> * - * Copyright (C) 2003 authors + * Copyright (C) 2003-2014 authors * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -28,8 +28,6 @@ class Entry; } class SPDesktop; - -struct InkscapeApplication; typedef struct { GtkWidget *win; @@ -53,14 +51,14 @@ void sp_transientize ( GtkWidget *win ); void on_transientize ( SPDesktop *desktop, win_data *wd ); -void sp_transientize_callback ( InkscapeApplication *inkscape, - SPDesktop *desktop, +void sp_transientize_callback ( SPDesktop *desktop, win_data *wd ); void on_dialog_hide (GtkWidget *w); void on_dialog_unhide (GtkWidget *w); -gboolean sp_dialog_hide (GObject *object, gpointer data); -gboolean sp_dialog_unhide (GObject *object, gpointer data); + +//gboolean sp_dialog_hide (GObject *object, gpointer data); +//gboolean sp_dialog_unhide (GObject *object, gpointer data); #endif diff --git a/src/ui/dialog/aboutbox.cpp b/src/ui/dialog/aboutbox.cpp index 50b35ca2f..81f48e6ef 100644 --- a/src/ui/dialog/aboutbox.cpp +++ b/src/ui/dialog/aboutbox.cpp @@ -470,6 +470,7 @@ void AboutBox::initStrings() { "Arman Aksoy <armish@linux-sevenler.de>, 2003.\n" "Arpad Biro <biro_arpad@yahoo.com>, 2004, 2005.\n" "Benedikt Roth <Benedikt.Roth@gmx.net>, 2000.\n" +"Benjamin Weis <benjamin.weis@gmx.com>, 2014.\n" "Benno Schulenberg <benno@vertaalt.nl>, 2008.\n" "Boštjan Špetič <igzebedze@cyberpipe.org>, 2004, 2005.\n" "Brisa Francesco <fbrisa@yahoo.it>, 2000.\n" @@ -492,7 +493,7 @@ void AboutBox::initStrings() { "Elias Norberg <elno0959 at student.su.se>, 2009.\n" "Equipe de Tradução Inkscape Brasil <www.inkscapebrasil.org>, 2007.\n" "Fatih Demir <kabalak@gtranslator.org>, 2000.\n" -"Firas Hanife <FirasHanife@gmail.com>, 2014.\n" +"Firas Hanife <FirasHanife@gmail.com>, 2014-2015.\n" "Foppe Benedictus <foppe.benedictus@gmail.com>, 2007-2009.\n" "Francesc Dorca <f.dorca@filnet.es>, 2003. Traducció sodipodi.\n" "Francisco Javier F. Serrador <serrador@arrakis.es>, 2003.\n" @@ -500,6 +501,7 @@ void AboutBox::initStrings() { "Frederic Rodrigo <f.rodrigo free.fr>, 2004-2005.\n" "Ge'ez Frontier Foundation <locales@geez.org>, 2002.\n" "George Boukeas <boukeas@gmail.com>, 2011.\n" +"Heiko Wöhrle <mail@heikowoehrle.de>, 2014.\n" "Hleb Valoshka <375gnu@gmail.com>, 2008-2009.\n" "Hizkuntza Politikarako Sailburuordetza <hizkpol@ej-gv.es>, 2005.\n" "Ilia Penev <lichopicho@gmail.com>, 2006.\n" @@ -564,7 +566,7 @@ void AboutBox::initStrings() { "Stefan Graubner <pflaumenmus92@gmx.net>, 2005.\n" "Supranee Thirawatthanasuk <supranee@opentle.org>, 2006.\n" "Takeshi Aihana <aihana@muc.biglobe.ne.jp>, 2000, 2001.\n" -"Tim Sheridan <tim.sheridan@gmail.com>, 2007-2011.\n" +"Tim Sheridan <tghs@tghs.net>, 2007-2014.\n" "Theppitak Karoonboonyanan <thep@linux.thai.net>, 2006.\n" "Thiago Pimentel <thiago.merces@gmail.com>, 2006.\n" "Toshifumi Sato <sato@centrosystem.com>, 2005.\n" diff --git a/src/ui/dialog/align-and-distribute.cpp b/src/ui/dialog/align-and-distribute.cpp index 431da7ad1..65bc94011 100644 --- a/src/ui/dialog/align-and-distribute.cpp +++ b/src/ui/dialog/align-and-distribute.cpp @@ -24,7 +24,7 @@ #include "align-and-distribute.h" #include <2geom/transforms.h> #include "ui/widget/spinbutton.h" -#include "desktop-handles.h" + #include "unclump.h" #include "document.h" #include "enums.h" @@ -91,7 +91,7 @@ Action::Action(const Glib::ustring &id, void ActionAlign::do_action(SPDesktop *desktop, int index) { - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (!selection) return; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -123,10 +123,10 @@ void ActionAlign::do_action(SPDesktop *desktop, int index) focus = selection->smallestItem(horiz); break; case PAGE: - b = sp_desktop_document(desktop)->preferredBounds(); + b = desktop->getDocument()->preferredBounds(); break; case DRAWING: - b = sp_desktop_document(desktop)->getRoot()->desktopPreferredBounds(); + b = desktop->getDocument()->getRoot()->desktopPreferredBounds(); break; case SELECTION: b = selection->preferredBounds(); @@ -152,7 +152,7 @@ void ActionAlign::do_action(SPDesktop *desktop, int index) for (std::list<SPItem *>::iterator it(selected.begin()); it != selected.end(); ++it) { - sp_desktop_document (desktop)->ensureUpToDate(); + desktop->getDocument()->ensureUpToDate(); if (!sel_as_group) b = (*it)->desktopPreferredBounds(); if (b && (!focus || (*it) != focus)) { @@ -167,7 +167,7 @@ void ActionAlign::do_action(SPDesktop *desktop, int index) } if (changed) { - DocumentUndo::done( sp_desktop_document(desktop) , SP_VERB_DIALOG_ALIGN_DISTRIBUTE, + DocumentUndo::done( desktop->getDocument() , SP_VERB_DIALOG_ALIGN_DISTRIBUTE, _("Align")); } } @@ -247,7 +247,7 @@ private : SPDesktop *desktop = _dialog.getDesktop(); if (!desktop) return; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (!selection) return; using Inkscape::Util::GSListConstIterator; @@ -337,7 +337,7 @@ private : prefs->setInt("/options/clonecompensation/value", saved_compensation); if (changed) { - DocumentUndo::done( sp_desktop_document(desktop), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, + DocumentUndo::done( desktop->getDocument(), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, _("Distribute")); } } @@ -458,13 +458,12 @@ private : // xGap and yGap are the minimum space required between bounding rectangles. double const xGap = removeOverlapXGap.get_value(); double const yGap = removeOverlapYGap.get_value(); - removeoverlap(sp_desktop_selection(_dialog.getDesktop())->itemList(), - xGap, yGap); + removeoverlap(_dialog.getDesktop()->getSelection()->itemList(), xGap, yGap); // restore compensation setting prefs->setInt("/options/clonecompensation/value", saved_compensation); - DocumentUndo::done(sp_desktop_document(_dialog.getDesktop()), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, + DocumentUndo::done(_dialog.getDesktop()->getDocument(), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, _("Remove overlaps")); } }; @@ -490,12 +489,12 @@ private : int saved_compensation = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); - graphlayout(sp_desktop_selection(_dialog.getDesktop())->itemList()); + graphlayout(_dialog.getDesktop()->getSelection()->itemList()); // restore compensation setting prefs->setInt("/options/clonecompensation/value", saved_compensation); - DocumentUndo::done(sp_desktop_document(_dialog.getDesktop()), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, + DocumentUndo::done(_dialog.getDesktop()->getDocument(), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, _("Arrange connector network")); } }; @@ -547,7 +546,7 @@ private : SPDesktop *desktop = _dialog.getDesktop(); if (!desktop) return; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (!selection) return; using Inkscape::Util::GSListConstIterator; @@ -588,7 +587,7 @@ private : // restore compensation setting prefs->setInt("/options/clonecompensation/value", saved_compensation); - DocumentUndo::done(sp_desktop_document(_dialog.getDesktop()), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, + DocumentUndo::done(_dialog.getDesktop()->getDocument(), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, _("Exchange Positions")); } }; @@ -617,12 +616,12 @@ private : int saved_compensation = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); - unclump ((GSList *) sp_desktop_selection(_dialog.getDesktop())->itemList()); + unclump ((GSList *) _dialog.getDesktop()->getSelection()->itemList()); // restore compensation setting prefs->setInt("/options/clonecompensation/value", saved_compensation); - DocumentUndo::done(sp_desktop_document(_dialog.getDesktop()), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, + DocumentUndo::done(_dialog.getDesktop()->getDocument(), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, _("Unclump")); } }; @@ -644,7 +643,7 @@ private : SPDesktop *desktop = _dialog.getDesktop(); if (!desktop) return; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (!selection) return; using Inkscape::Util::GSListConstIterator; @@ -677,7 +676,7 @@ private : it != selected.end(); ++it) { - sp_desktop_document (desktop)->ensureUpToDate(); + desktop->getDocument()->ensureUpToDate(); Geom::OptRect item_box = !prefs_bbox ? (*it)->desktopVisualBounds() : (*it)->desktopGeometricBounds(); if (item_box) { // find new center, staying within bbox @@ -694,7 +693,7 @@ private : // restore compensation setting prefs->setInt("/options/clonecompensation/value", saved_compensation); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, _("Randomize positions")); } }; @@ -743,7 +742,7 @@ private : SPDesktop *desktop = _dialog.getDesktop(); if (!desktop) return; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (!selection) return; using Inkscape::Util::GSListConstIterator; @@ -797,7 +796,7 @@ private : } if (changed) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, _("Distribute text baselines")); } @@ -820,7 +819,7 @@ private : } if (changed) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, _("Align text baselines")); } } @@ -829,14 +828,14 @@ private : -static void on_tool_changed(InkscapeApplication */*inkscape*/, Inkscape::UI::Tools::ToolBase */*context*/, AlignAndDistribute *daad) +static void on_tool_changed(AlignAndDistribute *daad) { SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (desktop && desktop->getEventContext()) daad->setMode(tools_active(desktop) == TOOLS_NODES); } -static void on_selection_changed(InkscapeApplication */*inkscape*/, Inkscape::Selection */*selection*/, AlignAndDistribute *daad) +static void on_selection_changed(AlignAndDistribute *daad) { daad->randomize_bbox = Geom::OptRect(); } @@ -1044,10 +1043,10 @@ AlignAndDistribute::AlignAndDistribute() contents->pack_start(_nodesFrame, true, true); //Connect to the global tool change signal - g_signal_connect (G_OBJECT (INKSCAPE), "set_eventcontext", G_CALLBACK (on_tool_changed), this); + _toolChangeConn = INKSCAPE.signal_eventcontext_set.connect(sigc::hide<0>(sigc::bind(sigc::ptr_fun(&on_tool_changed), this))); // Connect to the global selection change, to invalidate cached randomize_bbox - g_signal_connect (G_OBJECT (INKSCAPE), "change_selection", G_CALLBACK (on_selection_changed), this); + _selChangeConn = INKSCAPE.signal_selection_changed.connect(sigc::hide<0>(sigc::bind(sigc::ptr_fun(&on_selection_changed), this))); randomize_bbox = Geom::OptRect(); _desktopChangeConn = _deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &AlignAndDistribute::setDesktop) ); @@ -1055,18 +1054,18 @@ AlignAndDistribute::AlignAndDistribute() show_all_children(); - on_tool_changed (NULL, NULL, this); // set current mode + on_tool_changed (this); // set current mode } AlignAndDistribute::~AlignAndDistribute() { - sp_signal_disconnect_by_data (G_OBJECT (INKSCAPE), this); - for (std::list<Action *>::iterator it = _actionList.begin(); it != _actionList.end(); ++it) { delete *it; } + _toolChangeConn.disconnect(); + _selChangeConn.disconnect(); _desktopChangeConn.disconnect(); _deskTrack.disconnect(); } @@ -1075,7 +1074,7 @@ void AlignAndDistribute::setTargetDesktop(SPDesktop *desktop) { if (_desktop != desktop) { _desktop = desktop; - on_tool_changed (NULL, NULL, this); + on_tool_changed (this); } } diff --git a/src/ui/dialog/align-and-distribute.h b/src/ui/dialog/align-and-distribute.h index dfd84535b..eecc30ff8 100644 --- a/src/ui/dialog/align-and-distribute.h +++ b/src/ui/dialog/align-and-distribute.h @@ -127,7 +127,8 @@ protected: SPDesktop *_desktop; DesktopTracker _deskTrack; sigc::connection _desktopChangeConn; - + sigc::connection _toolChangeConn; + sigc::connection _selChangeConn; private: AlignAndDistribute(AlignAndDistribute const &d); AlignAndDistribute& operator=(AlignAndDistribute const &d); diff --git a/src/ui/dialog/clonetiler.cpp b/src/ui/dialog/clonetiler.cpp index 7a776a9b8..bd3ad0254 100644 --- a/src/ui/dialog/clonetiler.cpp +++ b/src/ui/dialog/clonetiler.cpp @@ -27,7 +27,7 @@ #include <gtkmm/adjustment.h> #include "desktop.h" -#include "desktop-handles.h" + #include "display/cairo-utils.h" #include "display/drawing.h" #include "display/drawing-context.h" @@ -76,15 +76,12 @@ static gdouble trace_zoom; static SPDocument *trace_doc = NULL; -CloneTiler::CloneTiler (void) : +CloneTiler::CloneTiler () : UI::Widget::Panel ("", "/dialogs/clonetiler/", SP_VERB_DIALOG_CLONETILER), dlg(NULL), desktop(NULL), deskTrack(), - table_row_labels(NULL), - selectChangedConn(), - subselChangedConn(), - selectModifiedConn() + table_row_labels(NULL) { Gtk::Box *contents = _getContents(); contents->set_spacing(0); @@ -1096,7 +1093,7 @@ CloneTiler::CloneTiler (void) : // unitmenu unit_menu = new Inkscape::UI::Widget::UnitMenu(); unit_menu->setUnitType(Inkscape::Util::UNIT_TYPE_LINEAR); - unit_menu->setUnit(sp_desktop_namedview(SP_ACTIVE_DESKTOP)->display_units->abbr); + unit_menu->setUnit(SP_ACTIVE_DESKTOP->getNamedView()->display_units->abbr); unitChangedConn = unit_menu->signal_changed().connect(sigc::mem_fun(*this, &CloneTiler::clonetiler_unit_changed)); { @@ -1273,12 +1270,13 @@ CloneTiler::CloneTiler (void) : // connect to global selection changed signal (so we can change desktops) and // external_change (so we're not fooled by undo) - g_signal_connect (G_OBJECT (INKSCAPE), "change_selection", G_CALLBACK (clonetiler_change_selection), dlg); - g_signal_connect (G_OBJECT (INKSCAPE), "external_change", G_CALLBACK (clonetiler_external_change), dlg); - g_signal_connect(G_OBJECT(dlg), "destroy", G_CALLBACK(clonetiler_disconnect_gsignal), G_OBJECT (INKSCAPE)); + selectChangedConn = INKSCAPE.signal_selection_changed.connect(sigc::bind(sigc::ptr_fun(&CloneTiler::clonetiler_change_selection), dlg)); + externChangedConn = INKSCAPE.signal_external_change.connect (sigc::bind(sigc::ptr_fun(&CloneTiler::clonetiler_external_change), dlg)); + + g_signal_connect(G_OBJECT(dlg), "destroy", G_CALLBACK(clonetiler_disconnect_gsignal), this); // update now - clonetiler_change_selection (NULL, sp_desktop_selection(SP_ACTIVE_DESKTOP), dlg); + clonetiler_change_selection (SP_ACTIVE_DESKTOP->getSelection(), dlg); } { @@ -1350,7 +1348,7 @@ void CloneTiler::on_picker_color_changed(guint rgba) is_updating = false; } -void CloneTiler::clonetiler_change_selection(InkscapeApplication * /*inkscape*/, Inkscape::Selection *selection, GtkWidget *dlg) +void CloneTiler::clonetiler_change_selection(Inkscape::Selection *selection, GtkWidget *dlg) { GtkWidget *buttons = GTK_WIDGET(g_object_get_data (G_OBJECT(dlg), "buttons_on_tiles")); GtkWidget *status = GTK_WIDGET(g_object_get_data (G_OBJECT(dlg), "status")); @@ -1379,16 +1377,18 @@ void CloneTiler::clonetiler_change_selection(InkscapeApplication * /*inkscape*/, } } -void CloneTiler::clonetiler_external_change(InkscapeApplication * /*inkscape*/, GtkWidget *dlg) +void CloneTiler::clonetiler_external_change(GtkWidget *dlg) { - clonetiler_change_selection (NULL, sp_desktop_selection(SP_ACTIVE_DESKTOP), dlg); + clonetiler_change_selection (SP_ACTIVE_DESKTOP->getSelection(), dlg); } -void CloneTiler::clonetiler_disconnect_gsignal(GObject *widget, gpointer source) +void CloneTiler::clonetiler_disconnect_gsignal(GObject *, gpointer source) { - if (source && G_IS_OBJECT(source)) { - sp_signal_disconnect_by_data (source, widget); - } + g_return_if_fail(source != NULL); + + CloneTiler* dlg = reinterpret_cast<CloneTiler*>(source); + dlg->selectChangedConn.disconnect(); + dlg->externChangedConn.disconnect(); } Geom::Affine CloneTiler::clonetiler_get_transform( @@ -2093,11 +2093,11 @@ void CloneTiler::clonetiler_unclump(GtkWidget */*widget*/, void *) return; } - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); // check if something is selected if (selection->isEmpty() || g_slist_length((GSList *) selection->itemList()) > 1) { - sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select <b>one object</b> whose tiled clones to unclump.")); + desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>one object</b> whose tiled clones to unclump.")); return; } @@ -2112,13 +2112,13 @@ void CloneTiler::clonetiler_unclump(GtkWidget */*widget*/, void *) } } - sp_desktop_document(desktop)->ensureUpToDate(); + desktop->getDocument()->ensureUpToDate(); unclump (to_unclump); g_slist_free (to_unclump); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_DIALOG_CLONETILER, + DocumentUndo::done(desktop->getDocument(), SP_VERB_DIALOG_CLONETILER, _("Unclump tiled clones")); } @@ -2144,11 +2144,11 @@ void CloneTiler::clonetiler_remove(GtkWidget */*widget*/, GtkWidget *dlg, bool d return; } - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); // check if something is selected if (selection->isEmpty() || g_slist_length((GSList *) selection->itemList()) > 1) { - sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select <b>one object</b> whose tiled clones to remove.")); + desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>one object</b> whose tiled clones to remove.")); return; } @@ -2169,10 +2169,10 @@ void CloneTiler::clonetiler_remove(GtkWidget */*widget*/, GtkWidget *dlg, bool d } g_slist_free (to_delete); - clonetiler_change_selection (NULL, selection, dlg); + clonetiler_change_selection (selection, dlg); if (do_undo) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_DIALOG_CLONETILER, + DocumentUndo::done(desktop->getDocument(), SP_VERB_DIALOG_CLONETILER, _("Delete tiled clones")); } } @@ -2216,17 +2216,17 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) return; } Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); // check if something is selected if (selection->isEmpty()) { - sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select an <b>object</b> to clone.")); + desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select an <b>object</b> to clone.")); return; } // Check if more than one object is selected. if (g_slist_length((GSList *) selection->itemList()) > 1) { - sp_desktop_message_stack(desktop)->flash(Inkscape::ERROR_MESSAGE, _("If you want to clone several objects, <b>group</b> them and <b>clone the group</b>.")); + desktop->getMessageStack()->flash(Inkscape::ERROR_MESSAGE, _("If you want to clone several objects, <b>group</b> them and <b>clone the group</b>.")); return; } @@ -2251,7 +2251,7 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) clonetiler_remove (NULL, dlg, false); - double scale_units = Inkscape::Util::Quantity::convert(1, "px", &sp_desktop_document(desktop)->getSVGUnit()); + double scale_units = Inkscape::Util::Quantity::convert(1, "px", &desktop->getDocument()->getSVGUnit()); double shiftx_per_i = 0.01 * prefs->getDoubleLimited(prefs_path + "shiftx_per_i", 0, -10000, 10000); double shifty_per_i = 0.01 * prefs->getDoubleLimited(prefs_path + "shifty_per_i", 0, -10000, 10000); @@ -2337,7 +2337,7 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) SPItem *item = dynamic_cast<SPItem *>(obj); if (dotrace) { - clonetiler_trace_setup (sp_desktop_document(desktop), 1.0, item); + clonetiler_trace_setup (desktop->getDocument(), 1.0, item); } Geom::Point center; @@ -2409,7 +2409,7 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) // Note: We create a clone at 0,0 too, right over the original, in case our clones are colored // Get transform from symmetry, shift, scale, rotation - Geom::Affine t = clonetiler_get_transform (type, i, j, center[Geom::X], center[Geom::Y], w, h, + Geom::Affine orig_t = clonetiler_get_transform (type, i, j, center[Geom::X], center[Geom::Y], w, h, shiftx_per_i, shifty_per_i, shiftx_per_j, shifty_per_j, shiftx_rand, shifty_rand, @@ -2428,7 +2428,8 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) rotate_rand, rotate_alternatei, rotate_alternatej, rotate_cumulatei, rotate_cumulatej ); - + Geom::Affine parent_transform = (((SPItem*)item->parent)->i2doc_affine())*(item->document->getRoot()->c2p.inverse()); + Geom::Affine t = parent_transform*orig_t*parent_transform.inverse(); cur = center * t - center; if (fillrect) { if ((cur[Geom::X] > fillwidth) || (cur[Geom::Y] > fillheight)) { // off limits @@ -2562,7 +2563,9 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) } } if (pick_to_size) { - t = Geom::Translate(-center[Geom::X], -center[Geom::Y]) * Geom::Scale (val, val) * Geom::Translate(center[Geom::X], center[Geom::Y]) * t; + t = parent_transform * Geom::Translate(-center[Geom::X], -center[Geom::Y]) + * Geom::Scale (val, val) * Geom::Translate(center[Geom::X], center[Geom::Y]) + * parent_transform.inverse() * t; } if (pick_to_opacity) { opacity *= val; @@ -2590,7 +2593,7 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) Geom::Point new_center; bool center_set = false; if (obj_repr->attribute("inkscape:transform-center-x") || obj_repr->attribute("inkscape:transform-center-y")) { - new_center = scale_units*desktop->dt2doc(item->getCenter()) * t; + new_center = scale_units*desktop->dt2doc(item->getCenter()) * orig_t; center_set = true; } @@ -2611,21 +2614,21 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) parent->getRepr()->appendChild(clone); if (blur > 0.0) { - SPObject *clone_object = sp_desktop_document(desktop)->getObjectByRepr(clone); + SPObject *clone_object = desktop->getDocument()->getObjectByRepr(clone); double perimeter = perimeter_original * t.descrim(); double radius = blur * perimeter; // this is necessary for all newly added clones to have correct bboxes, // otherwise filters won't work: - sp_desktop_document(desktop)->ensureUpToDate(); + desktop->getDocument()->ensureUpToDate(); // it's hard to figure out exact width/height of the tile without having an object // that we can take bbox of; however here we only need a lower bound so that blur // margins are not too small, and the perimeter should work - SPFilter *constructed = new_filter_gaussian_blur(sp_desktop_document(desktop), radius, t.descrim(), t.expansionX(), t.expansionY(), perimeter, perimeter); + SPFilter *constructed = new_filter_gaussian_blur(desktop->getDocument(), radius, t.descrim(), t.expansionX(), t.expansionY(), perimeter, perimeter); sp_style_set_property_url (clone_object, "filter", constructed, false); } if (center_set) { - SPObject *clone_object = sp_desktop_document(desktop)->getObjectByRepr(clone); + SPObject *clone_object = desktop->getDocument()->getObjectByRepr(clone); SPItem *item = dynamic_cast<SPItem *>(clone_object); if (clone_object && item) { clone_object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); @@ -2643,11 +2646,11 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) clonetiler_trace_finish (); } - clonetiler_change_selection (NULL, selection, dlg); + clonetiler_change_selection (selection, dlg); desktop->clearWaitingCursor(); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_DIALOG_CLONETILER, + DocumentUndo::done(desktop->getDocument(), SP_VERB_DIALOG_CLONETILER, _("Create tiled clones")); } diff --git a/src/ui/dialog/clonetiler.h b/src/ui/dialog/clonetiler.h index 70da86338..e5f5638b2 100644 --- a/src/ui/dialog/clonetiler.h +++ b/src/ui/dialog/clonetiler.h @@ -57,8 +57,8 @@ protected: static void clonetiler_keep_bbox_toggled(GtkToggleButton *tb, gpointer /*data*/); static void clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg); static void clonetiler_unclump(GtkWidget */*widget*/, void *); - static void clonetiler_change_selection(InkscapeApplication * /*inkscape*/, Inkscape::Selection *selection, GtkWidget *dlg); - static void clonetiler_external_change(InkscapeApplication * /*inkscape*/, GtkWidget *dlg); + static void clonetiler_change_selection(Inkscape::Selection *selection, GtkWidget *dlg); + static void clonetiler_external_change(GtkWidget *dlg); static void clonetiler_disconnect_gsignal(GObject *widget, gpointer source); static void clonetiler_reset(GtkWidget */*widget*/, GtkWidget *dlg); static guint clonetiler_number_of_clones(SPObject *obj); @@ -129,6 +129,7 @@ private: sigc::connection desktopChangeConn; sigc::connection selectChangedConn; + sigc::connection externChangedConn; sigc::connection subselChangedConn; sigc::connection selectModifiedConn; sigc::connection color_changed_connection; diff --git a/src/ui/dialog/color-item.cpp b/src/ui/dialog/color-item.cpp index bab7e18e1..a49a47d5c 100644 --- a/src/ui/dialog/color-item.cpp +++ b/src/ui/dialog/color-item.cpp @@ -29,7 +29,7 @@ #include "color-item.h" #include "desktop.h" -#include "desktop-handles.h" + #include "desktop-style.h" #include "display/cairo-utils.h" #include "document.h" @@ -476,7 +476,7 @@ void ColorItem::_updatePreviews() { SPDesktop *desktop = SP_ACTIVE_DESKTOP; if ( desktop ) { - SPDocument* document = sp_desktop_document( desktop ); + SPDocument* document = desktop->getDocument(); Inkscape::XML::Node *rroot = document->getReprRoot(); if ( rroot ) { @@ -706,7 +706,7 @@ void ColorItem::buttonClicked(bool secondary) sp_desktop_set_style(desktop, css); sp_repr_css_attr_unref(css); - DocumentUndo::done( sp_desktop_document(desktop), SP_VERB_DIALOG_SWATCHES, descr.c_str() ); + DocumentUndo::done( desktop->getDocument(), SP_VERB_DIALOG_SWATCHES, descr.c_str() ); } } diff --git a/src/ui/dialog/desktop-tracker.cpp b/src/ui/dialog/desktop-tracker.cpp index 3ed998252..0659de67b 100644 --- a/src/ui/dialog/desktop-tracker.cpp +++ b/src/ui/dialog/desktop-tracker.cpp @@ -22,7 +22,6 @@ DesktopTracker::DesktopTracker() : desktop(0), widget(0), hierID(0), - inkID(0), trackActive(false), desktopChangedSig() { @@ -41,7 +40,10 @@ void DesktopTracker::connect(GtkWidget *widget) // Use C/gobject callbacks to avoid gtkmm rewrap-during-destruct issues: hierID = g_signal_connect( G_OBJECT(widget), "hierarchy-changed", G_CALLBACK(hierarchyChangeCB), this ); - inkID = g_signal_connect( G_OBJECT(INKSCAPE), "activate_desktop", G_CALLBACK(activateDesktopCB), this ); + inkID = INKSCAPE.signal_activate_desktop.connect( + sigc::bind( + sigc::ptr_fun(&DesktopTracker::activateDesktopCB), this) + ); GtkWidget *wdgt = gtk_widget_get_ancestor(widget, SP_TYPE_DESKTOP_WIDGET); if (wdgt && !base) { @@ -60,11 +62,8 @@ void DesktopTracker::disconnect() } hierID = 0; } - if (inkID) { - if (INKSCAPE) { - g_signal_handler_disconnect(G_OBJECT(INKSCAPE), inkID); - } - inkID = 0; + if (inkID.connected()) { + inkID.disconnect(); } } @@ -94,12 +93,12 @@ sigc::connection DesktopTracker::connectDesktopChanged( const sigc::slot<void, S return desktopChangedSig.connect(slot); } -gboolean DesktopTracker::activateDesktopCB(InkscapeApplication */*inkscape*/, SPDesktop *desktop, DesktopTracker *self ) +void DesktopTracker::activateDesktopCB(SPDesktop *desktop, DesktopTracker *self ) { if (self && self->trackActive) { self->setDesktop(desktop); } - return FALSE; + //return FALSE; } bool DesktopTracker::hierarchyChangeCB(GtkWidget * /*widget*/, GtkWidget* /*prev*/, DesktopTracker *self) diff --git a/src/ui/dialog/desktop-tracker.h b/src/ui/dialog/desktop-tracker.h index 7b944ddfa..8cb205a35 100644 --- a/src/ui/dialog/desktop-tracker.h +++ b/src/ui/dialog/desktop-tracker.h @@ -36,7 +36,7 @@ public: sigc::connection connectDesktopChanged( const sigc::slot<void, SPDesktop*> & slot ); private: - static gboolean activateDesktopCB(InkscapeApplication *inkscape, SPDesktop *desktop, DesktopTracker *self ); + static void activateDesktopCB(SPDesktop *desktop, DesktopTracker *self ); static bool hierarchyChangeCB(GtkWidget *widget, GtkWidget* prev, DesktopTracker *self); void handleHierarchyChange(); @@ -46,7 +46,7 @@ private: SPDesktop *desktop; GtkWidget *widget; gulong hierID; - gulong inkID; + sigc::connection inkID; bool trackActive; sigc::signal<void, SPDesktop*> desktopChangedSig; }; diff --git a/src/ui/dialog/dialog.cpp b/src/ui/dialog/dialog.cpp index 213965a18..27d88bae7 100644 --- a/src/ui/dialog/dialog.cpp +++ b/src/ui/dialog/dialog.cpp @@ -25,7 +25,7 @@ #include "inkscape.h" #include "ui/tools/tool-base.h" #include "desktop.h" -#include "desktop-handles.h" + #include "shortcuts.h" #include "preferences.h" #include "ui/interface.h" @@ -41,12 +41,6 @@ namespace Inkscape { namespace UI { namespace Dialog { -void sp_retransientize(InkscapeApplication */*inkscape*/, SPDesktop *desktop, gpointer dlgPtr) -{ - Dialog *dlg = static_cast<Dialog *>(dlgPtr); - dlg->onDesktopActivated (desktop); -} - gboolean sp_retransientize_again(gpointer dlgPtr) { Dialog *dlg = static_cast<Dialog *>(dlgPtr); @@ -54,30 +48,6 @@ gboolean sp_retransientize_again(gpointer dlgPtr) return FALSE; // so that it is only called once } -void sp_dialog_shutdown(GObject * /*object*/, gpointer dlgPtr) -{ - Dialog *dlg = static_cast<Dialog *>(dlgPtr); - dlg->onShutdown(); -} - - -static void hideCallback(GObject * /*object*/, gpointer dlgPtr) -{ - g_return_if_fail( dlgPtr != NULL ); - - Dialog *dlg = static_cast<Dialog *>(dlgPtr); - dlg->onHideF12(); -} - -static void unhideCallback(GObject * /*object*/, gpointer dlgPtr) -{ - g_return_if_fail( dlgPtr != NULL ); - - Dialog *dlg = static_cast<Dialog *>(dlgPtr); - dlg->onShowF12(); -} - - //===================================================================== Dialog::Dialog(Behavior::BehaviorFactory behavior_factory, const char *prefs_path, int verb_num, @@ -103,10 +73,10 @@ Dialog::Dialog(Behavior::BehaviorFactory behavior_factory, const char *prefs_pat _behavior = behavior_factory(*this); _desktop = SP_ACTIVE_DESKTOP; - g_signal_connect(G_OBJECT(INKSCAPE), "activate_desktop", G_CALLBACK(sp_retransientize), (void *)this); - g_signal_connect(G_OBJECT(INKSCAPE), "dialogs_hide", G_CALLBACK(hideCallback), (void *)this); - g_signal_connect(G_OBJECT(INKSCAPE), "dialogs_unhide", G_CALLBACK(unhideCallback), (void *)this); - g_signal_connect(G_OBJECT(INKSCAPE), "shut_down", G_CALLBACK(sp_dialog_shutdown), (void *)this); + INKSCAPE.signal_activate_desktop.connect(sigc::mem_fun(*this, &Dialog::onDesktopActivated)); + INKSCAPE.signal_dialogs_hide.connect(sigc::mem_fun(*this, &Dialog::onHideF12)); + INKSCAPE.signal_dialogs_unhide.connect(sigc::mem_fun(*this, &Dialog::onShowF12)); + INKSCAPE.signal_shut_down.connect(sigc::mem_fun(*this, &Dialog::onShutdown)); Glib::wrap(gobj())->signal_event().connect(sigc::mem_fun(*this, &Dialog::_onEvent)); Glib::wrap(gobj())->signal_key_press_event().connect(sigc::mem_fun(*this, &Dialog::_onKeyPress)); @@ -340,7 +310,7 @@ void Dialog::_defocus() Inkscape::Selection* Dialog::_getSelection() { - return sp_desktop_selection(SP_ACTIVE_DESKTOP); + return SP_ACTIVE_DESKTOP->getSelection(); } } // namespace Dialog diff --git a/src/ui/dialog/dialog.h b/src/ui/dialog/dialog.h index ccff43a56..9c7efd47b 100644 --- a/src/ui/dialog/dialog.h +++ b/src/ui/dialog/dialog.h @@ -30,7 +30,6 @@ namespace Dialog { enum BehaviorType { FLOATING, DOCK }; -void sp_retransientize(InkscapeApplication *inkscape, SPDesktop *desktop, gpointer dlgPtr); gboolean sp_retransientize_again(gpointer dlgPtr); void sp_dialog_shutdown(GObject *object, gpointer dlgPtr); diff --git a/src/ui/dialog/document-metadata.cpp b/src/ui/dialog/document-metadata.cpp index 77ea175d9..da1facc08 100644 --- a/src/ui/dialog/document-metadata.cpp +++ b/src/ui/dialog/document-metadata.cpp @@ -20,7 +20,7 @@ #include "document-metadata.h" #include "desktop.h" -#include "desktop-handles.h" + #include "inkscape.h" #include "rdf.h" #include "sp-namedview.h" @@ -100,7 +100,7 @@ DocumentMetadata::init() { update(); - Inkscape::XML::Node *repr = sp_desktop_namedview(getDesktop())->getRepr(); + Inkscape::XML::Node *repr = getDesktop()->getNamedView()->getRepr(); repr->addListener (&_repr_events, this); show_all_children(); @@ -108,7 +108,7 @@ DocumentMetadata::init() DocumentMetadata::~DocumentMetadata() { - Inkscape::XML::Node *repr = sp_desktop_namedview(getDesktop())->getRepr(); + Inkscape::XML::Node *repr = getDesktop()->getNamedView()->getRepr(); repr->removeListenerByData (this); for (RDElist::iterator it = _rdflist.begin(); it != _rdflist.end(); ++it) @@ -217,23 +217,23 @@ void DocumentMetadata::update() void DocumentMetadata::_handleDocumentReplaced(SPDesktop* desktop, SPDocument *) { - Inkscape::XML::Node *repr = sp_desktop_namedview(desktop)->getRepr(); + Inkscape::XML::Node *repr = desktop->getNamedView()->getRepr(); repr->addListener (&_repr_events, this); update(); } void -DocumentMetadata::_handleActivateDesktop(InkscapeApplication *, SPDesktop *desktop) +DocumentMetadata::_handleActivateDesktop(SPDesktop *desktop) { - Inkscape::XML::Node *repr = sp_desktop_namedview(desktop)->getRepr(); + Inkscape::XML::Node *repr = desktop->getNamedView()->getRepr(); repr->addListener(&_repr_events, this); update(); } void -DocumentMetadata::_handleDeactivateDesktop(InkscapeApplication *, SPDesktop *desktop) +DocumentMetadata::_handleDeactivateDesktop(SPDesktop *desktop) { - Inkscape::XML::Node *repr = sp_desktop_namedview(desktop)->getRepr(); + Inkscape::XML::Node *repr = desktop->getNamedView()->getRepr(); repr->removeListenerByData(this); } diff --git a/src/ui/dialog/document-metadata.h b/src/ui/dialog/document-metadata.h index 77084bc3d..cde5d92fd 100644 --- a/src/ui/dialog/document-metadata.h +++ b/src/ui/dialog/document-metadata.h @@ -28,6 +28,7 @@ # include <gtkmm/table.h> #endif +#include "inkscape.h" #include "ui/widget/licensor.h" #include "ui/widget/registry.h" @@ -56,8 +57,8 @@ protected: void init(); void _handleDocumentReplaced(SPDesktop* desktop, SPDocument *document); - void _handleActivateDesktop(InkscapeApplication *application, SPDesktop *desktop); - void _handleDeactivateDesktop(InkscapeApplication *application, SPDesktop *desktop); + void _handleActivateDesktop(SPDesktop *desktop); + void _handleDeactivateDesktop(SPDesktop *desktop); Gtk::Notebook _notebook; diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index f7701655c..c381ed755 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -26,7 +26,7 @@ #include "document-properties.h" #include "display/canvas-grid.h" #include "document.h" -#include "desktop-handles.h" + #include "desktop.h" #include "inkscape.h" #include "io/sys.h" @@ -87,6 +87,13 @@ static Inkscape::XML::NodeEventVector const _repr_events = { NULL // order_changed }; +static void docprops_style_button(Gtk::Button& btn, char const* iconName) +{ + GtkWidget *child = sp_icon_new(Inkscape::ICON_SIZE_SMALL_TOOLBAR, iconName); + gtk_widget_show( child ); + btn.add(*Gtk::manage(Glib::wrap(child))); + btn.set_relief(Gtk::RELIEF_NONE); +} DocumentProperties& DocumentProperties::getInstance() { @@ -186,9 +193,9 @@ void DocumentProperties::init() { update(); - Inkscape::XML::Node *repr = sp_desktop_namedview(getDesktop())->getRepr(); + Inkscape::XML::Node *repr = getDesktop()->getNamedView()->getRepr(); repr->addListener (&_repr_events, this); - Inkscape::XML::Node *root = sp_desktop_document(getDesktop())->getRoot()->getRepr(); + Inkscape::XML::Node *root = getDesktop()->getDocument()->getRoot()->getRepr(); root->addListener (&_repr_events, this); show_all_children(); @@ -197,9 +204,9 @@ void DocumentProperties::init() DocumentProperties::~DocumentProperties() { - Inkscape::XML::Node *repr = sp_desktop_namedview(getDesktop())->getRepr(); + Inkscape::XML::Node *repr = getDesktop()->getNamedView()->getRepr(); repr->removeListenerByData (this); - Inkscape::XML::Node *root = sp_desktop_document(getDesktop())->getRoot()->getRepr(); + Inkscape::XML::Node *root = getDesktop()->getDocument()->getRoot()->getRepr(); root->removeListenerByData (this); for (RDElist::iterator it = _rdflist.begin(); it != _rdflist.end(); ++it) @@ -615,22 +622,10 @@ void DocumentProperties::build_cms() label_avail->set_markup (_("<b>Available Color Profiles:</b>")); _link_btn.set_tooltip_text(_("Link Profile")); -#if WITH_GTKMM_3_10 - _link_btn.set_image_from_icon_name(INKSCAPE_ICON("list-add"), Gtk::ICON_SIZE_SMALL_TOOLBAR); -#else - Gtk::Image *image_link = Gtk::manage(new Gtk::Image()); - image_link->set_from_icon_name(INKSCAPE_ICON("list-add"), Gtk::ICON_SIZE_SMALL_TOOLBAR); - _link_btn.set_image(*image_link); -#endif + docprops_style_button(_link_btn, INKSCAPE_ICON("list-add")); _unlink_btn.set_tooltip_text(_("Unlink Profile")); -#if WITH_GTKMM_3_10 - _unlink_btn.set_image_from_icon_name(INKSCAPE_ICON("list-remove"), Gtk::ICON_SIZE_SMALL_TOOLBAR); -#else - Gtk::Image *image_unlink = Gtk::manage(new Gtk::Image()); - image_unlink->set_from_icon_name(INKSCAPE_ICON("list-remove"), Gtk::ICON_SIZE_SMALL_TOOLBAR); - _unlink_btn.set_image(*image_unlink); -#endif + docprops_style_button(_unlink_btn, INKSCAPE_ICON("list-remove")); _page_cms->set_spacing(4); gint row = 0; @@ -752,22 +747,10 @@ void DocumentProperties::build_scripting() label_external->set_markup (_("<b>External script files:</b>")); _external_add_btn.set_tooltip_text(_("Add the current file name or browse for a file")); -#if WITH_GTKMM_3_10 - _external_add_btn.set_image_from_icon_name(INKSCAPE_ICON("list-add"), Gtk::ICON_SIZE_SMALL_TOOLBAR); -#else - Gtk::Image *image_ext_add = Gtk::manage(new Gtk::Image()); - image_ext_add->set_from_icon_name(INKSCAPE_ICON("list-add"), Gtk::ICON_SIZE_SMALL_TOOLBAR); - _external_add_btn.set_image(*image_ext_add); -#endif + docprops_style_button(_external_add_btn, INKSCAPE_ICON("list-add")); _external_remove_btn.set_tooltip_text(_("Remove")); -#if WITH_GTKMM_3_10 - _external_remove_btn.set_image_from_icon_name(INKSCAPE_ICON("list-remove"), Gtk::ICON_SIZE_SMALL_TOOLBAR); -#else - Gtk::Image *image_ext_rm = Gtk::manage(new Gtk::Image()); - image_ext_rm->set_from_icon_name(INKSCAPE_ICON("list-remove"), Gtk::ICON_SIZE_SMALL_TOOLBAR); - _external_remove_btn.set_image(*image_ext_rm); -#endif + docprops_style_button(_external_remove_btn, INKSCAPE_ICON("list-remove")); _page_external_scripts->set_spacing(4); gint row = 0; @@ -841,22 +824,10 @@ void DocumentProperties::build_scripting() label_embedded->set_markup (_("<b>Embedded script files:</b>")); _embed_new_btn.set_tooltip_text(_("New")); -#if WITH_GTKMM_3_10 - _embed_new_btn.set_image_from_icon_name(INKSCAPE_ICON("list-add"), Gtk::ICON_SIZE_SMALL_TOOLBAR); -#else - Gtk::Image *image_embed_new = Gtk::manage(new Gtk::Image()); - image_embed_new->set_from_icon_name(INKSCAPE_ICON("list-add"), Gtk::ICON_SIZE_SMALL_TOOLBAR); - _embed_new_btn.set_image(*image_embed_new); -#endif + docprops_style_button(_embed_new_btn, INKSCAPE_ICON("list-add")); _embed_remove_btn.set_tooltip_text(_("Remove")); -#if WITH_GTKMM_3_10 - _embed_remove_btn.set_image_from_icon_name(INKSCAPE_ICON("list-remove"), Gtk::ICON_SIZE_SMALL_TOOLBAR); -#else - Gtk::Image *image_embed_rm = Gtk::manage(new Gtk::Image()); - image_embed_rm->set_from_icon_name(INKSCAPE_ICON("list-remove"), Gtk::ICON_SIZE_SMALL_TOOLBAR); - _embed_remove_btn.set_image(*image_embed_rm); -#endif + docprops_style_button(_embed_remove_btn, INKSCAPE_ICON("list-remove")); #if !WITH_GTKMM_3_0 // TODO: This has been removed from Gtkmm 3.0. Check that @@ -1384,7 +1355,7 @@ void DocumentProperties::populate_script_lists(){ void DocumentProperties::update_gridspage() { SPDesktop *dt = getDesktop(); - SPNamedView *nv = sp_desktop_namedview(dt); + SPNamedView *nv = dt->getNamedView(); //remove all tabs while (_grids_notebook.get_n_pages() != 0) { @@ -1428,7 +1399,7 @@ void DocumentProperties::build_gridspage() /// Dissenting view: you want snapping without grid. SPDesktop *dt = getDesktop(); - SPNamedView *nv = sp_desktop_namedview(dt); + SPNamedView *nv = dt->getNamedView(); (void)nv; _grids_label_crea.set_markup(_("<b>Creation</b>")); @@ -1464,7 +1435,7 @@ void DocumentProperties::update() if (_wr.isUpdating()) return; SPDesktop *dt = getDesktop(); - SPNamedView *nv = sp_desktop_namedview(dt); + SPNamedView *nv = dt->getNamedView(); _wr.setUpdating (true); set_sensitive (true); @@ -1484,24 +1455,25 @@ void DocumentProperties::update() _rum_deflt.setUnit (nv->display_units->abbr); } - double doc_w = sp_desktop_document(dt)->getRoot()->width.value; - Glib::ustring doc_w_unit = unit_table.getUnit(sp_desktop_document(dt)->getRoot()->width.unit)->abbr; + double doc_w = dt->getDocument()->getRoot()->width.value; + Glib::ustring doc_w_unit = unit_table.getUnit(dt->getDocument()->getRoot()->width.unit)->abbr; if (doc_w_unit == "") { doc_w_unit = "px"; - } else if (doc_w_unit == "%" && sp_desktop_document(dt)->getRoot()->viewBox_set) { + } else if (doc_w_unit == "%" && dt->getDocument()->getRoot()->viewBox_set) { doc_w_unit = "px"; - doc_w = sp_desktop_document(dt)->getRoot()->viewBox.width(); + doc_w = dt->getDocument()->getRoot()->viewBox.width(); } - double doc_h = sp_desktop_document(dt)->getRoot()->height.value; - Glib::ustring doc_h_unit = unit_table.getUnit(sp_desktop_document(dt)->getRoot()->height.unit)->abbr; + double doc_h = dt->getDocument()->getRoot()->height.value; + Glib::ustring doc_h_unit = unit_table.getUnit(dt->getDocument()->getRoot()->height.unit)->abbr; if (doc_h_unit == "") { doc_h_unit = "px"; - } else if (doc_h_unit == "%" && sp_desktop_document(dt)->getRoot()->viewBox_set) { + } else if (doc_h_unit == "%" && dt->getDocument()->getRoot()->viewBox_set) { doc_h_unit = "px"; - doc_h = sp_desktop_document(dt)->getRoot()->viewBox.height(); + doc_h = dt->getDocument()->getRoot()->viewBox.height(); } _page_sizer.setDim(Inkscape::Util::Quantity(doc_w, doc_w_unit), Inkscape::Util::Quantity(doc_h, doc_h_unit)); _page_sizer.updateFitMarginsUI(nv->getRepr()); + _page_sizer.updateScaleUI(); //-----------------------------------------------------------guide page @@ -1592,27 +1564,27 @@ void DocumentProperties::save_default_metadata() void DocumentProperties::_handleDocumentReplaced(SPDesktop* desktop, SPDocument *document) { - Inkscape::XML::Node *repr = sp_desktop_namedview(desktop)->getRepr(); + Inkscape::XML::Node *repr = desktop->getNamedView()->getRepr(); repr->addListener(&_repr_events, this); Inkscape::XML::Node *root = document->getRoot()->getRepr(); root->addListener(&_repr_events, this); update(); } -void DocumentProperties::_handleActivateDesktop(InkscapeApplication *, SPDesktop *desktop) +void DocumentProperties::_handleActivateDesktop(SPDesktop *desktop) { - Inkscape::XML::Node *repr = sp_desktop_namedview(desktop)->getRepr(); + Inkscape::XML::Node *repr = desktop->getNamedView()->getRepr(); repr->addListener(&_repr_events, this); - Inkscape::XML::Node *root = sp_desktop_document(desktop)->getRoot()->getRepr(); + Inkscape::XML::Node *root = desktop->getDocument()->getRoot()->getRepr(); root->addListener(&_repr_events, this); update(); } -void DocumentProperties::_handleDeactivateDesktop(InkscapeApplication *, SPDesktop *desktop) +void DocumentProperties::_handleDeactivateDesktop(SPDesktop *desktop) { - Inkscape::XML::Node *repr = sp_desktop_namedview(desktop)->getRepr(); + Inkscape::XML::Node *repr = desktop->getNamedView()->getRepr(); repr->removeListenerByData(this); - Inkscape::XML::Node *root = sp_desktop_document(desktop)->getRoot()->getRepr(); + Inkscape::XML::Node *root = desktop->getDocument()->getRoot()->getRepr(); root->removeListenerByData(this); } @@ -1647,8 +1619,8 @@ static void on_repr_attr_changed(Inkscape::XML::Node *, gchar const *, gchar con void DocumentProperties::onNewGrid() { SPDesktop *dt = getDesktop(); - Inkscape::XML::Node *repr = sp_desktop_namedview(dt)->getRepr(); - SPDocument *doc = sp_desktop_document(dt); + Inkscape::XML::Node *repr = dt->getNamedView()->getRepr(); + SPDocument *doc = dt->getDocument(); Glib::ustring typestring = _grids_combo_gridtype.get_active_text(); CanvasGrid::writeNewGridToRepr(repr, doc, CanvasGrid::getGridTypeFromName(typestring.c_str())); @@ -1665,7 +1637,7 @@ void DocumentProperties::onRemoveGrid() return; SPDesktop *dt = getDesktop(); - SPNamedView *nv = sp_desktop_namedview(dt); + SPNamedView *nv = dt->getNamedView(); Inkscape::CanvasGrid * found_grid = NULL; int i = 0; for (GSList const * l = nv->grids; l != NULL; l = l->next, i++) { // not a very nice fix, but works. @@ -1679,11 +1651,13 @@ void DocumentProperties::onRemoveGrid() // delete the grid that corresponds with the selected tab // when the grid is deleted from SVG, the SPNamedview handler automatically deletes the object, so found_grid becomes an invalid pointer! found_grid->repr->parent()->removeChild(found_grid->repr); - DocumentUndo::done(sp_desktop_document(dt), SP_VERB_DIALOG_NAMEDVIEW, _("Remove grid")); + DocumentUndo::done(dt->getDocument(), SP_VERB_DIALOG_NAMEDVIEW, _("Remove grid")); } } /** Callback for document unit change. */ +/* This should not effect anything in the SVG tree (other than "inkscape:document-units"). + This should only effect values displayed in the GUI. */ void DocumentProperties::onDocUnitChange() { SPDocument *doc = SP_ACTIVE_DOCUMENT; @@ -1697,7 +1671,7 @@ void DocumentProperties::onDocUnitChange() } - Inkscape::XML::Node *repr = sp_desktop_namedview(getDesktop())->getRepr(); + Inkscape::XML::Node *repr = getDesktop()->getNamedView()->getRepr(); Inkscape::Util::Unit const *old_doc_unit = unit_table.getUnit("px"); if(repr->attribute("inkscape:document-units")) { old_doc_unit = unit_table.getUnit(repr->attribute("inkscape:document-units")); @@ -1709,6 +1683,8 @@ void DocumentProperties::onDocUnitChange() os << doc_unit->abbr; repr->setAttribute("inkscape:document-units", os.str().c_str()); + _page_sizer.updateScaleUI(); + // Disable changing of SVG Units. The intent here is to change the units in the UI, not the units in SVG. // This code should be moved (and fixed) once we have an "SVG Units" setting that sets what units are used in SVG data. #if 0 diff --git a/src/ui/dialog/document-properties.h b/src/ui/dialog/document-properties.h index ee7e88b18..b1f90b4b7 100644 --- a/src/ui/dialog/document-properties.h +++ b/src/ui/dialog/document-properties.h @@ -94,8 +94,8 @@ protected: void save_default_metadata(); void _handleDocumentReplaced(SPDesktop* desktop, SPDocument *document); - void _handleActivateDesktop(InkscapeApplication *application, SPDesktop *desktop); - void _handleDeactivateDesktop(InkscapeApplication *application, SPDesktop *desktop); + void _handleActivateDesktop(SPDesktop *desktop); + void _handleDeactivateDesktop(SPDesktop *desktop); Inkscape::XML::SignalObserver _emb_profiles_observer, _scripts_observer; Gtk::Notebook _notebook; diff --git a/src/ui/dialog/export.cpp b/src/ui/dialog/export.cpp index 37022a186..6d90c792e 100644 --- a/src/ui/dialog/export.cpp +++ b/src/ui/dialog/export.cpp @@ -51,10 +51,10 @@ #include "ui/widget/unit-menu.h" #include "util/units.h" #include "helper/window.h" -#include "inkscape-private.h" +#include "inkscape.h" #include "document.h" #include "document-undo.h" -#include "desktop-handles.h" + #include "sp-item.h" #include "selection.h" #include "file.h" @@ -101,7 +101,6 @@ #define EXPORT_COORD_PRECISION 3 -#include "../../desktop-handles.h" #include "../../document.h" #include "../../document-undo.h" #include "verbs.h" @@ -206,7 +205,7 @@ Export::Export (void) : SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (desktop) { - unit_selector.setUnit(sp_desktop_namedview(desktop)->display_units->abbr); + unit_selector.setUnit(desktop->getNamedView()->display_units->abbr); } unitChangedConn = unit_selector.signal_changed().connect(sigc::mem_fun(*this, &Export::onUnitChanged)); unitbox.pack_end(unit_selector, false, false, 0); @@ -588,7 +587,7 @@ Glib::ustring Export::create_filepath_from_id (Glib::ustring id, const Glib::ust } if (directory.empty()) { - directory = homedir_path(NULL); + directory = INKSCAPE.homedir_path(NULL); } Glib::ustring filename = Glib::build_filename(directory, id+".png"); @@ -606,7 +605,7 @@ void Export::onBatchClicked () void Export::updateCheckbuttons () { - gint num = g_slist_length((GSList *) sp_desktop_selection(SP_ACTIVE_DESKTOP)->itemList()); + gint num = g_slist_length((GSList *) SP_ACTIVE_DESKTOP->getSelection()->itemList()); if (num >= 2) { batch_export.set_sensitive(true); batch_export.set_label(g_strdup_printf (ngettext("B_atch export %d selected object","B_atch export %d selected objects",num), num)); @@ -622,7 +621,7 @@ inline void Export::findDefaultSelection() { selection_type key = SELECTION_NUMBER_OF; - if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) { + if ((SP_ACTIVE_DESKTOP->getSelection())->isEmpty() == false) { key = SELECTION_SELECTION; } @@ -660,15 +659,15 @@ inline void Export::findDefaultSelection() */ void Export::onSelectionChanged() { - Inkscape::Selection *selection = sp_desktop_selection (SP_ACTIVE_DESKTOP); + Inkscape::Selection *selection = SP_ACTIVE_DESKTOP->getSelection(); if ((current_key == SELECTION_DRAWING || current_key == SELECTION_PAGE) && - (sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false && + (SP_ACTIVE_DESKTOP->getSelection())->isEmpty() == false && was_empty) { current_key = SELECTION_SELECTION; selectiontype_buttons[current_key]->set_active(true); } - was_empty = (sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty(); + was_empty = (SP_ACTIVE_DESKTOP->getSelection())->isEmpty(); if ( selection && SELECTION_CUSTOM != current_key) { @@ -685,7 +684,7 @@ void Export::onSelectionModified ( guint /*flags*/ ) case SELECTION_DRAWING: if ( SP_ACTIVE_DESKTOP ) { SPDocument *doc; - doc = sp_desktop_document (SP_ACTIVE_DESKTOP); + doc = SP_ACTIVE_DESKTOP->getDocument(); Geom::OptRect bbox = doc->getRoot()->desktopVisualBounds(); if (bbox) { setArea ( bbox->left(), @@ -696,7 +695,7 @@ void Export::onSelectionModified ( guint /*flags*/ ) } break; case SELECTION_SELECTION: - Sel = sp_desktop_selection(SP_ACTIVE_DESKTOP); + Sel = SP_ACTIVE_DESKTOP->getSelection(); if (Sel->isEmpty() == false) { Geom::OptRect bbox = Sel->visualBounds(); if (bbox) @@ -736,16 +735,16 @@ void Export::onAreaToggled () SPDocument *doc; Geom::OptRect bbox; bbox = Geom::Rect(Geom::Point(0.0, 0.0),Geom::Point(0.0, 0.0)); - doc = sp_desktop_document (SP_ACTIVE_DESKTOP); + doc = SP_ACTIVE_DESKTOP->getDocument(); /* Notice how the switch is used to 'fall through' here to get various backups. If you modify this without noticing you'll probabaly screw something up. */ switch (key) { case SELECTION_SELECTION: - if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) + if ((SP_ACTIVE_DESKTOP->getSelection())->isEmpty() == false) { - bbox = sp_desktop_selection (SP_ACTIVE_DESKTOP)->visualBounds(); + bbox = SP_ACTIVE_DESKTOP->getSelection()->visualBounds(); /* Only if there is a selection that we can set do we break, otherwise we fall through to the drawing */ @@ -810,15 +809,15 @@ void Export::onAreaToggled () break; } case SELECTION_SELECTION: - if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) { + if ((SP_ACTIVE_DESKTOP->getSelection())->isEmpty() == false) { - sp_selection_get_export_hints (sp_desktop_selection(SP_ACTIVE_DESKTOP), filename, &xdpi, &ydpi); + sp_selection_get_export_hints (SP_ACTIVE_DESKTOP->getSelection(), filename, &xdpi, &ydpi); /* If we still don't have a filename -- let's build one that's nice */ if (filename.empty()) { const gchar * id = "object"; - const GSList * reprlst = sp_desktop_selection(SP_ACTIVE_DESKTOP)->reprList(); + const GSList * reprlst = SP_ACTIVE_DESKTOP->getSelection()->reprList(); for(; reprlst != NULL; reprlst = reprlst->next) { Inkscape::XML::Node * repr = (Inkscape::XML::Node *)reprlst->data; if (repr->attribute("id")) { @@ -1002,8 +1001,8 @@ void Export::onExport () SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (!desktop) return; - SPNamedView *nv = sp_desktop_namedview(desktop); - SPDocument *doc = sp_desktop_document (desktop); + SPNamedView *nv = desktop->getNamedView(); + SPDocument *doc = desktop->getDocument(); bool exportSuccessful = false; @@ -1011,7 +1010,7 @@ void Export::onExport () if (batch_export.get_active ()) { // Batch export of selected objects - gint num = g_slist_length(const_cast<GSList *>(sp_desktop_selection(desktop)->itemList())); + gint num = g_slist_length(const_cast<GSList *>(desktop->getSelection()->itemList())); gint n = 0; if (num < 1) { @@ -1025,7 +1024,7 @@ void Export::onExport () gint export_count = 0; - for (GSList *i = const_cast<GSList *>(sp_desktop_selection(desktop)->itemList()); i && !interrupted; i = i->next) { + for (GSList *i = const_cast<GSList *>(desktop->getSelection()->itemList()); i && !interrupted; i = i->next) { SPItem *item = reinterpret_cast<SPItem *>(i->data); prog_dlg->set_data("current", GINT_TO_POINTER(n)); @@ -1070,7 +1069,7 @@ void Export::onExport () nv->pagecolor, onProgressCallback, (void*)prog_dlg, TRUE, // overwrite without asking - hide ? const_cast<GSList *>(sp_desktop_selection(desktop)->itemList()) : NULL + hide ? const_cast<GSList *>(desktop->getSelection()->itemList()) : NULL )) { gchar * error = g_strdup_printf(_("Could not export to filename %s.\n"), safeFile); @@ -1154,12 +1153,12 @@ void Export::onExport () prog_dlg->set_data("total", GINT_TO_POINTER(0)); /* Do export */ - ExportResult status = sp_export_png_file(sp_desktop_document(desktop), path.c_str(), + ExportResult status = sp_export_png_file(desktop->getDocument(), path.c_str(), Geom::Rect(Geom::Point(x0, y0), Geom::Point(x1, y1)), width, height, xdpi, ydpi, nv->pagecolor, onProgressCallback, (void*)prog_dlg, FALSE, - hide ? const_cast<GSList *>(sp_desktop_selection(desktop)->itemList()) : NULL + hide ? const_cast<GSList *>(desktop->getSelection()->itemList()) : NULL ); if (status == EXPORT_ERROR) { gchar * safeFile = Inkscape::IO::sanitizeString(path.c_str()); @@ -1231,7 +1230,7 @@ void Export::onExport () bool saved = DocumentUndo::getUndoSensitive(doc); DocumentUndo::setUndoSensitive(doc, false); - reprlst = sp_desktop_selection(desktop)->reprList(); + reprlst = desktop->getSelection()->reprList(); for(; reprlst != NULL; reprlst = reprlst->next) { Inkscape::XML::Node * repr = static_cast<Inkscape::XML::Node *>(reprlst->data); @@ -1463,8 +1462,8 @@ void Export::detectSize() { i++) { switch (this_test[i]) { case SELECTION_SELECTION: - if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) { - Geom::OptRect bbox = (sp_desktop_selection (SP_ACTIVE_DESKTOP))->bounds(SPItem::VISUAL_BBOX); + if ((SP_ACTIVE_DESKTOP->getSelection())->isEmpty() == false) { + Geom::OptRect bbox = (SP_ACTIVE_DESKTOP->getSelection())->bounds(SPItem::VISUAL_BBOX); if ( bbox && bbox_equal(*bbox,current_bbox)) { key = SELECTION_SELECTION; @@ -1472,7 +1471,7 @@ void Export::detectSize() { } break; case SELECTION_DRAWING: { - SPDocument *doc = sp_desktop_document (SP_ACTIVE_DESKTOP); + SPDocument *doc = SP_ACTIVE_DESKTOP->getDocument(); Geom::OptRect bbox = doc->getRoot()->desktopVisualBounds(); @@ -1485,7 +1484,7 @@ void Export::detectSize() { case SELECTION_PAGE: { SPDocument *doc; - doc = sp_desktop_document (SP_ACTIVE_DESKTOP); + doc = SP_ACTIVE_DESKTOP->getDocument(); Geom::Point x(0.0, 0.0); Geom::Point y(doc->getWidth().value("px"), diff --git a/src/ui/dialog/filedialog.cpp b/src/ui/dialog/filedialog.cpp index 00ed09551..4e4b0278a 100644 --- a/src/ui/dialog/filedialog.cpp +++ b/src/ui/dialog/filedialog.cpp @@ -19,7 +19,7 @@ #include "filedialogimpl-gtkmm.h" #include "filedialog.h" -#include "gc-core.h" +#include "inkgc/gc-core.h" #include "ui/dialog-events.h" #include "extension/output.h" #include "preferences.h" diff --git a/src/ui/dialog/filedialogimpl-gtkmm.cpp b/src/ui/dialog/filedialogimpl-gtkmm.cpp index 5d330f7f0..17cf835cd 100644 --- a/src/ui/dialog/filedialogimpl-gtkmm.cpp +++ b/src/ui/dialog/filedialogimpl-gtkmm.cpp @@ -577,8 +577,9 @@ bool SVGPreview::set(Glib::ustring &fileName, int dialogType) SVGPreview::SVGPreview() { - if (!INKSCAPE) - inkscape_application_init("", false); + // \FIXME Why?!!?? + if (!Inkscape::Application::exists()) + Inkscape::Application::create("", false); document = NULL; viewerGtk = NULL; set_size_request(150, 150); @@ -1083,7 +1084,7 @@ FileSaveDialogImplGtk::FileSaveDialogImplGtk(Gtk::Window &parentWindow, const Gl } // allow easy access to the user's own templates folder - gchar *templates = profile_path("templates"); + gchar *templates = Inkscape::Application::profile_path("templates"); if (Inkscape::IO::file_test(templates, G_FILE_TEST_EXISTS) && Inkscape::IO::file_test(templates, G_FILE_TEST_IS_DIR) && g_path_is_absolute(templates)) { add_shortcut_folder(templates); diff --git a/src/ui/dialog/filedialogimpl-win32.cpp b/src/ui/dialog/filedialogimpl-win32.cpp index ee6a0ef3a..cafc3be4f 100644 --- a/src/ui/dialog/filedialogimpl-win32.cpp +++ b/src/ui/dialog/filedialogimpl-win32.cpp @@ -44,6 +44,7 @@ #include "filedialog.h" #include "sp-root.h" +#include "preferences.h" #include <zlib.h> #include <cairomm/win32_surface.h> @@ -272,6 +273,9 @@ void FileOpenDialogImplWin32::createFilterMenu() } if (dialogType != EXE_TYPES) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + _show_preview = prefs->getBool("/dialogs/open/enable_preview", true); + // Compose the filter string Inkscape::Extension::DB::InputList extension_list; Inkscape::Extension::db.get_input_list(extension_list); @@ -842,6 +846,10 @@ LRESULT CALLBACK FileOpenDialogImplWin32::preview_wnd_proc(HWND hwnd, UINT uMsg, void FileOpenDialogImplWin32::enable_preview(bool enable) { + if (_show_preview != enable) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setBool("/dialogs/open/enable_preview", enable); + } _show_preview = enable; // Relayout the dialog @@ -1949,7 +1957,7 @@ UINT_PTR CALLBACK FileSaveDialogImplWin32::GetSaveFileName_hookproc( pImpl = reinterpret_cast<FileSaveDialogImplWin32*>(ofn->lCustData); // Create the Title label and edit control - pImpl->_title_label = CreateWindowEx(0, "STATIC", "Title:", + pImpl->_title_label = CreateWindowEx(0, "STATIC", _("Title:"), WS_VISIBLE|WS_CHILD, CW_USEDEFAULT, CW_USEDEFAULT, rCB1.left-rST.left, rST.bottom-rST.top, hParentWnd, NULL, hInstance, NULL); diff --git a/src/ui/dialog/filedialogimpl-win32.h b/src/ui/dialog/filedialogimpl-win32.h index f77249abd..8c3b6bad6 100644 --- a/src/ui/dialog/filedialogimpl-win32.h +++ b/src/ui/dialog/filedialogimpl-win32.h @@ -24,7 +24,7 @@ #include "filedialogimpl-gtkmm.h" -#include "gc-core.h" +#include "inkgc/gc-core.h" // define WINVER high enough so we get the correct OPENFILENAMEW size #ifndef WINVER #define WINVER 0x0500 diff --git a/src/ui/dialog/fill-and-stroke.cpp b/src/ui/dialog/fill-and-stroke.cpp index c55d55cda..8141f7696 100644 --- a/src/ui/dialog/fill-and-stroke.cpp +++ b/src/ui/dialog/fill-and-stroke.cpp @@ -16,7 +16,7 @@ */ #include "ui/widget/notebook-page.h" -#include "desktop-handles.h" + #include "desktop-style.h" #include "document.h" #include "fill-and-stroke.h" diff --git a/src/ui/dialog/fill-and-stroke.h b/src/ui/dialog/fill-and-stroke.h index 35c98ef9c..f2a6bf39d 100644 --- a/src/ui/dialog/fill-and-stroke.h +++ b/src/ui/dialog/fill-and-stroke.h @@ -41,8 +41,7 @@ public: virtual void setDesktop(SPDesktop *desktop); - void selectionChanged(InkscapeApplication *inkscape, - Inkscape::Selection *selection); + //void selectionChanged(Inkscape::Selection *selection); void showPageFill(); void showPageStrokePaint(); diff --git a/src/ui/dialog/filter-effects-dialog.cpp b/src/ui/dialog/filter-effects-dialog.cpp index bd44846a3..3da0e0043 100644 --- a/src/ui/dialog/filter-effects-dialog.cpp +++ b/src/ui/dialog/filter-effects-dialog.cpp @@ -33,7 +33,7 @@ #include <glibmm/stringutils.h> #include "desktop.h" -#include "desktop-handles.h" + #include "dir-util.h" #include "document.h" #include "document-undo.h" @@ -688,7 +688,7 @@ public: private: void select_svg_element(){ - Inkscape::Selection* sel = sp_desktop_selection(_desktop); + Inkscape::Selection* sel = _desktop->getSelection(); if (sel->isEmpty()) return; Inkscape::XML::Node* node = (Inkscape::XML::Node*) g_slist_nth_data((GSList *)sel->reprList(), 0); if (!node || !node->matchAttributeName("id")) return; @@ -1416,7 +1416,7 @@ void FilterEffectsDialog::FilterModifier::setTargetDesktop(SPDesktop *desktop) _selectModifiedConn = desktop->selection->connectModified(sigc::hide<0>(sigc::mem_fun(*this, &FilterModifier::on_modified_selection))); } _doc_replaced = desktop->connectDocumentReplaced( sigc::mem_fun(*this, &FilterModifier::on_document_replaced)); - _resource_changed = sp_desktop_document(desktop)->connectResourcesChanged("filter",sigc::mem_fun(*this, &FilterModifier::update_filters)); + _resource_changed = desktop->getDocument()->connectResourcesChanged("filter",sigc::mem_fun(*this, &FilterModifier::update_filters)); _dialog.setDesktop(desktop); update_filters(); @@ -1441,7 +1441,7 @@ void FilterEffectsDialog::FilterModifier::on_document_replaced(SPDesktop * /*des // When the selection changes, show the active filter(s) in the dialog void FilterEffectsDialog::FilterModifier::on_change_selection() { - Inkscape::Selection *selection = sp_desktop_selection (SP_ACTIVE_DESKTOP); + Inkscape::Selection *selection = SP_ACTIVE_DESKTOP->getSelection(); update_selection(selection); } @@ -1537,9 +1537,9 @@ void FilterEffectsDialog::FilterModifier::on_selection_toggled(const Glib::ustri if(iter) { SPDesktop *desktop = _dialog.getDesktop(); - SPDocument *doc = sp_desktop_document(desktop); + SPDocument *doc = desktop->getDocument(); SPFilter* filter = (*iter)[_columns.filter]; - Inkscape::Selection *sel = sp_desktop_selection(desktop); + Inkscape::Selection *sel = desktop->getSelection(); /* If this filter is the only one used in the selection, unset it */ if((*iter)[_columns.sel] == 1) @@ -1571,7 +1571,7 @@ void FilterEffectsDialog::FilterModifier::on_selection_toggled(const Glib::ustri void FilterEffectsDialog::FilterModifier::update_filters() { SPDesktop* desktop = _dialog.getDesktop(); - SPDocument* document = sp_desktop_document(desktop); + SPDocument* document = desktop->getDocument(); const GSList* filters = document->getResourceList("filter"); _model->clear(); @@ -1627,7 +1627,7 @@ void FilterEffectsDialog::FilterModifier::filter_list_button_release(GdkEventBut void FilterEffectsDialog::FilterModifier::add_filter() { - SPDocument* doc = sp_desktop_document(_dialog.getDesktop()); + SPDocument* doc = _dialog.getDesktop()->getDocument(); SPFilter* filter = new_filter(doc); const int count = _model->children().size(); @@ -1937,7 +1937,7 @@ void FilterEffectsDialog::PrimitiveList::remove_selected() //XML Tree being used directly here while it shouldn't be. sp_repr_unparent(prim->getRepr()); - DocumentUndo::done(sp_desktop_document(_dialog.getDesktop()), SP_VERB_DIALOG_FILTER_EFFECTS, + DocumentUndo::done(_dialog.getDesktop()->getDocument(), SP_VERB_DIALOG_FILTER_EFFECTS, _("Remove filter primitive")); update(); diff --git a/src/ui/dialog/find.cpp b/src/ui/dialog/find.cpp index 1a7832688..951cb01ea 100644 --- a/src/ui/dialog/find.cpp +++ b/src/ui/dialog/find.cpp @@ -29,7 +29,7 @@ #include "document.h" #include "document-undo.h" #include "selection.h" -#include "desktop-handles.h" + #include "ui/dialog-events.h" #include "verbs.h" @@ -37,6 +37,7 @@ #include "preferences.h" #include "sp-text.h" #include "sp-flowtext.h" +#include "sp-flowdiv.h" #include "text-editing.h" #include "sp-tspan.h" #include "sp-tref.h" @@ -238,7 +239,7 @@ Find::Find() show_all_children(); - Inkscape::Selection *selection = sp_desktop_selection (SP_ACTIVE_DESKTOP); + Inkscape::Selection *selection = SP_ACTIVE_DESKTOP->getSelection(); SPItem *item = selection->singleItem(); if (item) { if (dynamic_cast<SPText *>(item) || dynamic_cast<SPFlowtext *>(item)) { @@ -693,7 +694,10 @@ bool Find::item_type_match (SPItem *item) } else if (dynamic_cast<SPPath *>(item) || dynamic_cast<SPLine *>(item) || dynamic_cast<SPPolyLine *>(item)) { return (all || check_paths.get_active()); - } else if (dynamic_cast<SPText *>(item) || dynamic_cast<SPTSpan *>(item) || dynamic_cast<SPTRef *>(item) || dynamic_cast<SPString *>(item)) { + } else if (dynamic_cast<SPText *>(item) || dynamic_cast<SPTSpan *>(item) || + dynamic_cast<SPTRef *>(item) || dynamic_cast<SPString *>(item) || + dynamic_cast<SPFlowtext *>(item) || dynamic_cast<SPFlowdiv *>(item) || + dynamic_cast<SPFlowtspan *>(item) || dynamic_cast<SPFlowpara *>(item)) { return (all || check_texts.get_active()); } else if (dynamic_cast<SPGroup *>(item) && !desktop->isLayer(item) ) { // never select layers! @@ -824,7 +828,7 @@ void Find::onAction() if (check_scope_layer.get_active()) { l = all_items (desktop->currentLayer(), l, hidden, locked); } else { - l = all_items(sp_desktop_document(desktop)->getRoot(), l, hidden, locked); + l = all_items(desktop->getDocument()->getRoot(), l, hidden, locked); } } guint all = g_slist_length (l); @@ -850,7 +854,7 @@ void Find::onAction() button_replace.set_sensitive(attributenameyok); } - Inkscape::Selection *selection = sp_desktop_selection (desktop); + Inkscape::Selection *selection = desktop->getSelection(); selection->clear(); selection->setList(n); SPObject *obj = reinterpret_cast<SPObject *>(n->data); @@ -859,13 +863,13 @@ void Find::onAction() scroll_to_show_item(desktop, item); if (_action_replace) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, _("Replace text or property")); + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("Replace text or property")); } } else { status.set_text(_("Nothing found")); if (!check_scope_selection.get_active()) { - Inkscape::Selection *selection = sp_desktop_selection (desktop); + Inkscape::Selection *selection = desktop->getSelection(); selection->clear(); } desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("No objects found")); diff --git a/src/ui/dialog/font-substitution.cpp b/src/ui/dialog/font-substitution.cpp index db7bdf222..ae03bdf0e 100644 --- a/src/ui/dialog/font-substitution.cpp +++ b/src/ui/dialog/font-substitution.cpp @@ -28,7 +28,7 @@ #include "selection.h" #include "ui/dialog-events.h" -#include "desktop-handles.h" + #include "selection-chemistry.h" #include "preferences.h" @@ -134,7 +134,7 @@ FontSubstitution::show(Glib::ustring out, GSList *l) if (cbSelect->get_active()) { SPDesktop *desktop = SP_ACTIVE_DESKTOP; - Inkscape::Selection *selection = sp_desktop_selection (desktop); + Inkscape::Selection *selection = desktop->getSelection(); selection->clear(); selection->setList(l); } diff --git a/src/ui/dialog/glyphs.cpp b/src/ui/dialog/glyphs.cpp index 9bad90e7c..2b9053da9 100644 --- a/src/ui/dialog/glyphs.cpp +++ b/src/ui/dialog/glyphs.cpp @@ -709,13 +709,12 @@ void GlyphsPanel::readSelection( bool updateStyle, bool /*updateContent*/ ) calcCanInsert(); if (targetDesktop && updateStyle) { - //SPStyle *query = sp_style_new(SP_ACTIVE_DOCUMENT); + //SPStyle query(SP_ACTIVE_DOCUMENT); - //int result_family = sp_desktop_query_style(targetDesktop, query, QUERY_STYLE_PROPERTY_FONTFAMILY); - //int result_style = sp_desktop_query_style(targetDesktop, query, QUERY_STYLE_PROPERTY_FONTSTYLE); - //int result_numbers = sp_desktop_query_style(targetDesktop, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + //int result_family = sp_desktop_query_style(targetDesktop, &query, QUERY_STYLE_PROPERTY_FONTFAMILY); + //int result_style = sp_desktop_query_style(targetDesktop, &query, QUERY_STYLE_PROPERTY_FONTSTYLE); + //int result_numbers = sp_desktop_query_style(targetDesktop, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); - //sp_style_unref(query); } } diff --git a/src/ui/dialog/grid-arrange-tab.cpp b/src/ui/dialog/grid-arrange-tab.cpp index 1417b39fa..d3ccb9bde 100644 --- a/src/ui/dialog/grid-arrange-tab.cpp +++ b/src/ui/dialog/grid-arrange-tab.cpp @@ -31,7 +31,7 @@ #include "verbs.h" #include "preferences.h" #include "inkscape.h" -#include "desktop-handles.h" + #include "selection.h" #include "document.h" #include "document-undo.h" @@ -165,9 +165,9 @@ void GridArrangeTab::arrange() grid_top = 99999; SPDesktop *desktop = Parent->getDesktop(); - sp_desktop_document(desktop)->ensureUpToDate(); + desktop->getDocument()->ensureUpToDate(); - Inkscape::Selection *selection = sp_desktop_selection (desktop); + Inkscape::Selection *selection = desktop->getSelection(); const GSList *items = selection ? selection->itemList() : 0; cnt=0; for (; items != NULL; items = items->next) { @@ -347,7 +347,7 @@ g_print("\n row = %f col = %f selection x= %f selection y = %f", total_row_h g_slist_free (current_row); } - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_SELECTION_ARRANGE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_SELECTION_ARRANGE, _("Arrange in a grid")); } @@ -567,17 +567,6 @@ void GridArrangeTab::updateSelection() } - -/*########################## -## Experimental -##########################*/ - -static void updateSelectionCallback(InkscapeApplication */*inkscape*/, Inkscape::Selection */*selection*/, GridArrangeTab *dlg) -{ - dlg->updateSelection(); -} - - //######################################################################### //## C O N S T R U C T O R / D E S T R U C T O R //######################################################################### @@ -605,7 +594,7 @@ GridArrangeTab::GridArrangeTab(ArrangeDialog *parent) { // Selection Change signal - g_signal_connect ( G_OBJECT (INKSCAPE), "change_selection", G_CALLBACK (updateSelectionCallback), this); + INKSCAPE.signal_selection_changed.connect(sigc::hide<0>(sigc::mem_fun(*this, &GridArrangeTab::updateSelection))); } Gtk::Box *contents = this; diff --git a/src/ui/dialog/guides.cpp b/src/ui/dialog/guides.cpp index 221f9a1c0..af8e2cc31 100644 --- a/src/ui/dialog/guides.cpp +++ b/src/ui/dialog/guides.cpp @@ -24,7 +24,7 @@ #include "document-undo.h" #include "sp-guide.h" #include "sp-namedview.h" -#include "desktop-handles.h" + #include "ui/tools/tool-base.h" #include "widgets/desktop-widget.h" #include <glibmm/i18n.h> diff --git a/src/ui/dialog/icon-preview.cpp b/src/ui/dialog/icon-preview.cpp index 468e85d36..b908a90cb 100644 --- a/src/ui/dialog/icon-preview.cpp +++ b/src/ui/dialog/icon-preview.cpp @@ -35,7 +35,7 @@ #include "ui/widget/frame.h" #include "desktop.h" -#include "desktop-handles.h" + #include "display/drawing.h" #include "document.h" #include "inkscape.h" @@ -362,7 +362,7 @@ void IconPreviewPanel::refreshPreview() target = (hold && !targetId.empty()) ? desktop->doc()->getObjectById( targetId.c_str() ) : 0; if ( !target ) { targetId.clear(); - Inkscape::Selection * sel = sp_desktop_selection(desktop); + Inkscape::Selection * sel = desktop->getSelection(); if ( sel ) { //g_message("found a selection to play with"); diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index 75cfe5bfe..3b0731953 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -32,7 +32,7 @@ #include "util/units.h" #include <iostream> #include "enums.h" -#include "desktop-handles.h" + #include "extension/internal/gdkpixbuf-input.h" #include "message-stack.h" #include "style.h" @@ -213,10 +213,10 @@ static void StyleFromSelectionToTool(Glib::ustring const &prefs_path, StyleSwatc if (desktop == NULL) return; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (selection->isEmpty()) { - sp_desktop_message_stack(desktop)->flash(Inkscape::ERROR_MESSAGE, + desktop->getMessageStack()->flash(Inkscape::ERROR_MESSAGE, _("<b>No objects selected</b> to take the style from.")); return; } @@ -225,7 +225,7 @@ static void StyleFromSelectionToTool(Glib::ustring const &prefs_path, StyleSwatc /* TODO: If each item in the selection has the same style then don't consider it an error. * Maybe we should try to handle multiple selections anyway, e.g. the intersection of the * style attributes for the selected items. */ - sp_desktop_message_stack(desktop)->flash(Inkscape::ERROR_MESSAGE, + desktop->getMessageStack()->flash(Inkscape::ERROR_MESSAGE, _("<b>More than one object selected.</b> Cannot take style from multiple objects.")); return; } @@ -279,10 +279,14 @@ void InkscapePreferences::AddNewObjectsStyle(DialogPage &p, Glib::ustring const p.add_line( true, "", *hb, "", ""); // style swatch - Gtk::Button* button = Gtk::manage( new Gtk::Button(_("Take from selection"),true)); + Gtk::Button* button = Gtk::manage( new Gtk::Button(_("Take from selection"), true)); StyleSwatch *swatch = 0; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + if (prefs->getInt(prefs_path + "/usecurrent")) { + button->set_sensitive(false); + } + SPCSSAttr *css = prefs->getStyle(prefs_path + "/style"); swatch = new StyleSwatch(css, _("This tool's style of new objects")); hb->add(*swatch); @@ -461,7 +465,7 @@ void InkscapePreferences::initPageTools() _page_text.add_line( false, _("Text size unit type:"), _font_unit_type, "", _("Set the type of unit used in the text toolbar and text dialogs"), false); _font_output_px.init ( _("Always output text size in pixels (px)"), "/options/font/textOutputPx", true); - _page_text.add_line( false, "", _font_output_px, "", _("Always convert the text size units above into pixels (px) before saving to file")); +// _page_text.add_line( false, "", _font_output_px, "", _("Always convert the text size units above into pixels (px) before saving to file")); this->AddNewObjectsStyle(_page_text, "/tools/text"); @@ -525,14 +529,14 @@ void InkscapePreferences::initPageUI() _("English/Canada (en_CA)"), _("English/Great Britain (en_GB)"), _("Pig Latin (en_US@piglatin)"), _("Esperanto (eo)"), _("Estonian (et)"), _("Farsi (fa)"), _("Finnish (fi)"), _("French (fr)"), _("Irish (ga)"), _("Galician (gl)"), _("Hebrew (he)"), _("Hungarian (hu)"), - _("Indonesian (id)"), _("Italian (it)"), _("Japanese (ja)"), _("Khmer (km)"), _("Kinyarwanda (rw)"), _("Korean (ko)"), _("Lithuanian (lt)"), _("Latvian (lv)"), _("Macedonian (mk)"), + _("Indonesian (id)"), _("Icelandic (is)"), _("Italian (it)"), _("Japanese (ja)"), _("Khmer (km)"), _("Kinyarwanda (rw)"), _("Korean (ko)"), _("Lithuanian (lt)"), _("Latvian (lv)"), _("Macedonian (mk)"), _("Mongolian (mn)"), _("Nepali (ne)"), _("Norwegian Bokmål (nb)"), _("Norwegian Nynorsk (nn)"), _("Panjabi (pa)"), _("Polish (pl)"), _("Portuguese (pt)"), _("Portuguese/Brazil (pt_BR)"), _("Romanian (ro)"), _("Russian (ru)"), _("Serbian (sr)"), _("Serbian in Latin script (sr@latin)"), _("Slovak (sk)"), _("Slovenian (sl)"), _("Spanish (es)"), _("Spanish/Mexico (es_MX)"), _("Swedish (sv)"),_("Telugu (te)"), _("Thai (th)"), _("Turkish (tr)"), _("Ukrainian (uk)"), _("Vietnamese (vi)")}; Glib::ustring langValues[] = {"", "sq", "am", "ar", "hy", "az", "eu", "be", "bg", "bn", "bn_BD", "br", "ca", "ca@valencia", "zh_CN", "zh_TW", "hr", "cs", "da", "nl", "dz", "de", "el", "en", "en_AU", "en_CA", "en_GB", "en_US@piglatin", "eo", "et", "fa", "fi", "fr", "ga", - "gl", "he", "hu", "id", "it", "ja", "km", "rw", "ko", "lt", "lv", "mk", "mn", "ne", "nb", "nn", "pa", + "gl", "he", "hu", "id", "is", "it", "ja", "km", "rw", "ko", "lt", "lv", "mk", "mn", "ne", "nb", "nn", "pa", "pl", "pt", "pt_BR", "ro", "ru", "sr", "sr@latin", "sk", "sl", "es", "es_MX", "sv", "te", "th", "tr", "uk", "vi" }; { @@ -1487,7 +1491,7 @@ void InkscapePreferences::initKeyboardShortcuts(Gtk::TreeModel::iterator iter_ui _kb_filelist.init( "/options/kbshortcuts/shortcutfile", &fileLabels[0], &fileNames[0], fileLabels.size(), fileNames[0]); - Glib::ustring tooltip(_("Select a file of predefined shortcuts to use. Any customized shortcuts you create will be added seperately to ")); + Glib::ustring tooltip(_("Select a file of predefined shortcuts to use. Any customized shortcuts you create will be added separately to ")); tooltip += Glib::ustring(IO::Resource::get_path(IO::Resource::USER, IO::Resource::KEYS, "default.xml")); _page_keyshortcuts.add_line( false, _("Shortcut file:"), _kb_filelist, "", tooltip.c_str(), false); @@ -1742,6 +1746,10 @@ void InkscapePreferences::onKBListKeyboardShortcuts() // Find this group in the tree Glib::ustring group = verb->get_group() ? _(verb->get_group()) : _("Misc"); + Glib::ustring verb_id = verb->get_id(); + if (verb_id .compare(0,26,"org.inkscape.effect.filter") == 0) { + group = _("Filters"); + } Gtk::TreeStore::iterator iter_group; bool found = false; while (path) { @@ -1913,7 +1921,7 @@ void InkscapePreferences::initPageSystem() _page_system.add_group_header( _("System info")); - _sys_user_config.set_text((char const *)profile_path("")); + _sys_user_config.set_text((char const *)Inkscape::Application::profile_path("")); _sys_user_config.set_editable(false); _page_system.add_line(true, _("User config: "), _sys_user_config, "", _("Location of users configuration"), true); diff --git a/src/ui/dialog/layer-properties.cpp b/src/ui/dialog/layer-properties.cpp index d5540b88a..1b8fbb3f7 100644 --- a/src/ui/dialog/layer-properties.cpp +++ b/src/ui/dialog/layer-properties.cpp @@ -23,7 +23,7 @@ #include "document-undo.h" #include "layer-manager.h" #include "message-stack.h" -#include "desktop-handles.h" + #include "sp-object.h" #include "sp-item.h" #include "verbs.h" @@ -132,7 +132,7 @@ LayerPropertiesDialog::_apply() g_assert(_strategy != NULL); _strategy->perform(*this); - DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_NONE, + DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_NONE, _("Add layer")); _close(); @@ -364,7 +364,7 @@ void LayerPropertiesDialog::Rename::perform(LayerPropertiesDialog &dialog) { (gchar *)name.c_str(), FALSE ); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_NONE, + DocumentUndo::done(desktop->getDocument(), SP_VERB_NONE, _("Rename layer")); // TRANSLATORS: This means "The layer has been renamed" desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Renamed layer")); @@ -399,7 +399,7 @@ void LayerPropertiesDialog::Create::perform(LayerPropertiesDialog &dialog) { if (!name.empty()) { desktop->layer_manager->renameLayer( new_layer, (gchar *)name.c_str(), TRUE ); } - sp_desktop_selection(desktop)->clear(); + desktop->getSelection()->clear(); desktop->setCurrentLayer(new_layer); desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("New layer created.")); } diff --git a/src/ui/dialog/livepatheffect-editor.cpp b/src/ui/dialog/livepatheffect-editor.cpp index eb3857ee7..422ec10ae 100644 --- a/src/ui/dialog/livepatheffect-editor.cpp +++ b/src/ui/dialog/livepatheffect-editor.cpp @@ -23,10 +23,11 @@ #include <vector> #include "desktop.h" -#include "desktop-handles.h" + #include "document.h" #include "document-undo.h" #include "gtkmm/widget.h" +#include "helper/action.h" #include "inkscape.h" #include "live_effects/effect.h" #include "live_effects/lpeobject.h" @@ -44,6 +45,7 @@ #include "ui/icon-names.h" #include "ui/widget/imagetoggler.h" #include "verbs.h" +#include "widgets/icon.h" #include "xml/node.h" #include "livepatheffect-add.h" @@ -68,6 +70,14 @@ static void lpeeditor_selection_modified (Inkscape::Selection * selection, guint lpeeditor->onSelectionChanged(selection); } +static void lpe_style_button(Gtk::Button& btn, char const* iconName) +{ + GtkWidget *child = sp_icon_new(Inkscape::ICON_SIZE_SMALL_TOOLBAR, iconName); + gtk_widget_show( child ); + btn.add(*Gtk::manage(Glib::wrap(child))); + btn.set_relief(Gtk::RELIEF_NONE); +} + /* * LivePathEffectEditor @@ -107,43 +117,19 @@ LivePathEffectEditor::LivePathEffectEditor() effectcontrol_frame.add(effectcontrol_vbox); button_add.set_tooltip_text(_("Add path effect")); -#if WITH_GTKMM_3_10 - button_add.set_image_from_icon_name(INKSCAPE_ICON("list-add"), Gtk::ICON_SIZE_SMALL_TOOLBAR); -#else - Gtk::Image *image_add = Gtk::manage(new Gtk::Image()); - image_add->set_from_icon_name(INKSCAPE_ICON("list-add"), Gtk::ICON_SIZE_SMALL_TOOLBAR); - button_add.set_image(*image_add); -#endif + lpe_style_button(button_add, INKSCAPE_ICON("list-add")); button_add.set_relief(Gtk::RELIEF_NONE); button_remove.set_tooltip_text(_("Delete current path effect")); -#if WITH_GTKMM_3_10 - button_remove.set_image_from_icon_name(INKSCAPE_ICON("list-remove"), Gtk::ICON_SIZE_SMALL_TOOLBAR); -#else - Gtk::Image *image_remove = Gtk::manage(new Gtk::Image()); - image_remove->set_from_icon_name(INKSCAPE_ICON("list-remove"), Gtk::ICON_SIZE_SMALL_TOOLBAR); - button_remove.set_image(*image_remove); -#endif + lpe_style_button(button_remove, INKSCAPE_ICON("list-remove")); button_remove.set_relief(Gtk::RELIEF_NONE); button_up.set_tooltip_text(_("Raise the current path effect")); -#if WITH_GTKMM_3_10 - button_up.set_image_from_icon_name(INKSCAPE_ICON("go-up"), Gtk::ICON_SIZE_SMALL_TOOLBAR); -#else - Gtk::Image *image_up = Gtk::manage(new Gtk::Image()); - image_up->set_from_icon_name(INKSCAPE_ICON("go-up"), Gtk::ICON_SIZE_SMALL_TOOLBAR); - button_up.set_image(*image_up); -#endif + lpe_style_button(button_up, INKSCAPE_ICON("go-up")); button_up.set_relief(Gtk::RELIEF_NONE); button_down.set_tooltip_text(_("Lower the current path effect")); -#if WITH_GTKMM_3_10 - button_down.set_image_from_icon_name(INKSCAPE_ICON("go-down"), Gtk::ICON_SIZE_SMALL_TOOLBAR); -#else - Gtk::Image *image_down = Gtk::manage(new Gtk::Image()); - image_down->set_from_icon_name(INKSCAPE_ICON("go-down"), Gtk::ICON_SIZE_SMALL_TOOLBAR); - button_down.set_image(*image_down); -#endif + lpe_style_button(button_down, INKSCAPE_ICON("go-down")); button_down.set_relief(Gtk::RELIEF_NONE); // Add toolbar items to toolbar @@ -398,7 +384,7 @@ LivePathEffectEditor::setDesktop(SPDesktop *desktop) lpe_list_locked = false; current_desktop = desktop; if (desktop) { - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); selection_changed_connection = selection->connectChanged( sigc::bind (sigc::ptr_fun(&lpeeditor_selection_changed), this ) ); selection_modified_connection = selection->connectModified( @@ -475,9 +461,13 @@ LivePathEffectEditor::onAdd() // run sp_selection_clone_original_path_lpe sp_selection_clone_original_path_lpe(current_desktop); + SPItem *new_item = sel->singleItem(); - new_item->getRepr()->setAttribute("id", id); - new_item->getRepr()->setAttribute("transform", transform); + // Check that the cloning was successful. We don't want to change the ID of the original referenced path! + if (new_item && (new_item != orig)) { + new_item->getRepr()->setAttribute("id", id); + new_item->getRepr()->setAttribute("transform", transform); + } g_free(id); g_free(transform); @@ -506,7 +496,7 @@ LivePathEffectEditor::onRemove() if ( lpeitem ) { lpeitem->removeCurrentPathEffect(false); - DocumentUndo::done( sp_desktop_document(current_desktop), SP_VERB_DIALOG_LIVE_PATH_EFFECT, + DocumentUndo::done( current_desktop->getDocument(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Remove path effect") ); effect_list_reload(lpeitem); @@ -524,7 +514,7 @@ void LivePathEffectEditor::onUp() if ( lpeitem ) { lpeitem->upCurrentPathEffect(); - DocumentUndo::done( sp_desktop_document(current_desktop), SP_VERB_DIALOG_LIVE_PATH_EFFECT, + DocumentUndo::done( current_desktop->getDocument(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Move path effect up") ); effect_list_reload(lpeitem); @@ -541,7 +531,7 @@ void LivePathEffectEditor::onDown() if ( lpeitem ) { lpeitem->downCurrentPathEffect(); - DocumentUndo::done( sp_desktop_document(current_desktop), SP_VERB_DIALOG_LIVE_PATH_EFFECT, + DocumentUndo::done( current_desktop->getDocument(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Move path effect down") ); effect_list_reload(lpeitem); @@ -580,7 +570,7 @@ void LivePathEffectEditor::on_visibility_toggled( Glib::ustring const& str ) /* FIXME: this explicit writing to SVG is wrong. The lpe_item should have a method to disable/enable an effect within its stack. * So one can call: lpe_item->setActive(lpeobjref->lpeobject); */ lpeobjref->lpeobject->get_lpe()->getRepr()->setAttribute("is_visible", newValue ? "true" : "false"); - DocumentUndo::done( sp_desktop_document(current_desktop), SP_VERB_DIALOG_LIVE_PATH_EFFECT, + DocumentUndo::done( current_desktop->getDocument(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, newValue ? _("Activate path effect") : _("Deactivate path effect")); } } diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp index 55a19fc51..7e5c17133 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp @@ -23,7 +23,7 @@ #include "document-undo.h" #include "layer-manager.h" #include "message-stack.h" -#include "desktop-handles.h" + #include "sp-object.h" #include "sp-item.h" #include "verbs.h" @@ -129,7 +129,7 @@ void FilletChamferPropertiesDialog::showDialog( const gchar *unit, bool use_distance, bool aprox_radius, - Glib::ustring const * documentUnit) + Glib::ustring documentUnit) { FilletChamferPropertiesDialog *dialog = new FilletChamferPropertiesDialog(); @@ -172,7 +172,7 @@ void FilletChamferPropertiesDialog::_apply() } d_pos = _index + (d_pos / 100); } else { - d_pos = Inkscape::Util::Quantity::convert(d_pos, unit, *document_unit); + d_pos = Inkscape::Util::Quantity::convert(d_pos, unit, document_unit); d_pos = d_pos * -1; } _knotpoint->knot_set_offset(Geom::Point(d_pos, d_width)); @@ -207,12 +207,12 @@ void FilletChamferPropertiesDialog::_handleButtonEvent(GdkEventButton *event) void FilletChamferPropertiesDialog::_set_knot_point(Geom::Point knotpoint) { double position; - std::string distance_or_radius = std::string(_("Radius ")); + std::string distance_or_radius = std::string(_("Radius")); if(aprox){ - distance_or_radius = std::string(_("Radius approximated ")); + distance_or_radius = std::string(_("Radius approximated")); } if(use_distance){ - distance_or_radius = std::string(_("Knot distance ")); + distance_or_radius = std::string(_("Knot distance")); } if (knotpoint.x() > 0) { double intpart; @@ -222,12 +222,11 @@ void FilletChamferPropertiesDialog::_set_knot_point(Geom::Point knotpoint) _fillet_chamfer_position_label.set_label(_("Position (%):")); } else { _flexible = false; - std::string posConcat = distance_or_radius + - std::string(_("(")) + std::string(unit) + std::string(")"); + std::string posConcat = Glib::ustring::compose (_("%1 (%2):"), distance_or_radius, unit); _fillet_chamfer_position_label.set_label(_(posConcat.c_str())); position = knotpoint[Geom::X] * -1; - position = Inkscape::Util::Quantity::convert(position, *document_unit, unit); + position = Inkscape::Util::Quantity::convert(position, document_unit, unit); } _fillet_chamfer_position_numeric.set_value(position); if (knotpoint.y() == 1) { @@ -257,7 +256,7 @@ void FilletChamferPropertiesDialog::_set_unit(const gchar *abbr) unit = abbr; } -void FilletChamferPropertiesDialog::_set_document_unit(Glib::ustring const *abbr) +void FilletChamferPropertiesDialog::_set_document_unit(Glib::ustring abbr) { document_unit = abbr; } diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.h b/src/ui/dialog/lpe-fillet-chamfer-properties.h index 3807e98c8..870a1734f 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.h +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.h @@ -33,7 +33,7 @@ public: const gchar *unit, bool use_distance, bool aprox_radius, - Glib::ustring const * documentUnit); + Glib::ustring documentUnit); protected: @@ -69,14 +69,14 @@ protected: void _set_pt(const Inkscape::LivePathEffect:: FilletChamferPointArrayParamKnotHolderEntity *pt); void _set_unit(const gchar *abbr); - void _set_document_unit(Glib::ustring const * abbr); + void _set_document_unit(Glib::ustring abbr); void _set_use_distance(bool use_knot_distance); void _set_aprox(bool aprox_radius); void _apply(); void _close(); bool _flexible; const gchar *unit; - Glib::ustring const * document_unit; + Glib::ustring document_unit; bool use_distance; bool aprox; void _set_knot_point(Geom::Point knotpoint); diff --git a/src/ui/dialog/lpe-powerstroke-properties.cpp b/src/ui/dialog/lpe-powerstroke-properties.cpp index 55f938a48..a9e57970d 100644 --- a/src/ui/dialog/lpe-powerstroke-properties.cpp +++ b/src/ui/dialog/lpe-powerstroke-properties.cpp @@ -32,7 +32,7 @@ #include "document-undo.h" #include "layer-manager.h" #include "message-stack.h" -#include "desktop-handles.h" + #include "sp-object.h" #include "sp-item.h" #include "verbs.h" diff --git a/src/ui/dialog/memory.cpp b/src/ui/dialog/memory.cpp index 0008eb284..c0bc884fa 100644 --- a/src/ui/dialog/memory.cpp +++ b/src/ui/dialog/memory.cpp @@ -20,7 +20,7 @@ #include <gtkmm/liststore.h> #include <gtkmm/treeview.h> -#include "gc-core.h" +#include "inkgc/gc-core.h" #include "debug/heap.h" #include "verbs.h" diff --git a/src/ui/dialog/object-attributes.cpp b/src/ui/dialog/object-attributes.cpp index cfa5c6182..f43a15225 100644 --- a/src/ui/dialog/object-attributes.cpp +++ b/src/ui/dialog/object-attributes.cpp @@ -22,7 +22,7 @@ #include "ui/dialog/dialog-manager.h" #include "desktop.h" -#include "desktop-handles.h" + #include "macros.h" #include "sp-anchor.h" #include "sp-image.h" @@ -113,7 +113,7 @@ void ObjectAttributes::widget_setup (void) return; } - Inkscape::Selection *selection = sp_desktop_selection (SP_ACTIVE_DESKTOP); + Inkscape::Selection *selection = SP_ACTIVE_DESKTOP->getSelection(); SPItem *item = selection->singleItem(); if (!item) { diff --git a/src/ui/dialog/object-properties.cpp b/src/ui/dialog/object-properties.cpp index 28e9b360b..dfe211e94 100644 --- a/src/ui/dialog/object-properties.cpp +++ b/src/ui/dialog/object-properties.cpp @@ -28,7 +28,7 @@ #include "object-properties.h" #include "widgets/sp-attribute-widget.h" -#include "desktop-handles.h" + #include "document.h" #include "document-undo.h" #include "verbs.h" @@ -353,7 +353,7 @@ void ObjectProperties::update() return; } - Inkscape::Selection *selection = sp_desktop_selection(SP_ACTIVE_DESKTOP); + Inkscape::Selection *selection = SP_ACTIVE_DESKTOP->getSelection(); Gtk::Box *contents = _getContents(); if (!selection->singleItem()) { @@ -458,7 +458,7 @@ void ObjectProperties::_labelChanged() return; } - SPItem *item = sp_desktop_selection(SP_ACTIVE_DESKTOP)->singleItem(); + SPItem *item = SP_ACTIVE_DESKTOP->getSelection()->singleItem(); g_return_if_fail (item != NULL); _blocked = true; @@ -518,7 +518,7 @@ void ObjectProperties::_imageRenderingChanged() return; } - SPItem *item = sp_desktop_selection(SP_ACTIVE_DESKTOP)->singleItem(); + SPItem *item = SP_ACTIVE_DESKTOP->getSelection()->singleItem(); g_return_if_fail (item != NULL); _blocked = true; @@ -543,7 +543,7 @@ void ObjectProperties::_sensitivityToggled() return; } - SPItem *item = sp_desktop_selection(SP_ACTIVE_DESKTOP)->singleItem(); + SPItem *item = SP_ACTIVE_DESKTOP->getSelection()->singleItem(); g_return_if_fail(item != NULL); _blocked = true; @@ -559,7 +559,7 @@ void ObjectProperties::_hiddenToggled() return; } - SPItem *item = sp_desktop_selection(SP_ACTIVE_DESKTOP)->singleItem(); + SPItem *item = SP_ACTIVE_DESKTOP->getSelection()->singleItem(); g_return_if_fail(item != NULL); _blocked = true; diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index c95529a56..9db0285d7 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -231,15 +231,13 @@ public: /** * Stylizes a button using the given icon name and tooltip */ -void ObjectsPanel::_styleButton( Gtk::Button& btn, char const* iconName, char const* tooltip ) +void ObjectsPanel::_styleButton(Gtk::Button& btn, char const* iconName, char const* tooltip) { GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, iconName ); gtk_widget_show( child ); btn.add( *Gtk::manage(Glib::wrap(child)) ); btn.set_relief(Gtk::RELIEF_NONE); - btn.set_tooltip_text (tooltip); - } /** @@ -1799,29 +1797,14 @@ ObjectsPanel::ObjectsPanel() : //Add object/layer Gtk::Button* btn = Gtk::manage( new Gtk::Button() ); - btn->set_tooltip_text(_("Add layer...")); -#if GTK_CHECK_VERSION(3,10,0) - btn->set_image_from_icon_name(INKSCAPE_ICON("list-add"), Gtk::ICON_SIZE_SMALL_TOOLBAR); -#else - Gtk::Image *image_add = Gtk::manage(new Gtk::Image()); - image_add->set_from_icon_name(INKSCAPE_ICON("list-add"), Gtk::ICON_SIZE_SMALL_TOOLBAR); - btn->set_image(*image_add); -#endif + _styleButton(*btn, INKSCAPE_ICON("list-add"), _("Add layer...")); btn->set_relief(Gtk::RELIEF_NONE); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_NEW) ); _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); - //Remove object btn = Gtk::manage( new Gtk::Button() ); - btn->set_tooltip_text(_("Remove object")); -#if GTK_CHECK_VERSION(3,10,0) - btn->set_image_from_icon_name(INKSCAPE_ICON("list-remove"), Gtk::ICON_SIZE_SMALL_TOOLBAR); -#else - Gtk::Image *image_remove = Gtk::manage(new Gtk::Image()); - image_remove->set_from_icon_name(INKSCAPE_ICON("list-remove"), Gtk::ICON_SIZE_SMALL_TOOLBAR); - btn->set_image(*image_remove); -#endif + _styleButton(*btn, INKSCAPE_ICON("list-remove"), _("Remove object")); btn->set_relief(Gtk::RELIEF_NONE); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_DELETE) ); _watching.push_back( btn ); @@ -1829,14 +1812,7 @@ ObjectsPanel::ObjectsPanel() : //Move to bottom btn = Gtk::manage( new Gtk::Button() ); - btn->set_tooltip_text(_("Move To Bottom")); -#if GTK_CHECK_VERSION(3,10,0) - btn->set_image_from_icon_name(INKSCAPE_ICON("go-bottom"), Gtk::ICON_SIZE_SMALL_TOOLBAR); -#else - image_remove = Gtk::manage(new Gtk::Image()); - image_remove->set_from_icon_name(INKSCAPE_ICON("go-bottom"), Gtk::ICON_SIZE_SMALL_TOOLBAR); - btn->set_image(*image_remove); -#endif + _styleButton(*btn, INKSCAPE_ICON("go-bottom"), _("Move To Bottom")); btn->set_relief(Gtk::RELIEF_NONE); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_BOTTOM) ); _watchingNonBottom.push_back( btn ); @@ -1844,14 +1820,7 @@ ObjectsPanel::ObjectsPanel() : //Move down btn = Gtk::manage( new Gtk::Button() ); - btn->set_tooltip_text(_("Move Down")); -#if GTK_CHECK_VERSION(3,10,0) - btn->set_image_from_icon_name(INKSCAPE_ICON("go-down"), Gtk::ICON_SIZE_SMALL_TOOLBAR); -#else - image_remove = Gtk::manage(new Gtk::Image()); - image_remove->set_from_icon_name(INKSCAPE_ICON("go-down"), Gtk::ICON_SIZE_SMALL_TOOLBAR); - btn->set_image(*image_remove); -#endif + _styleButton(*btn, INKSCAPE_ICON("go-down"), _("Move Down")); btn->set_relief(Gtk::RELIEF_NONE); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_DOWN) ); _watchingNonBottom.push_back( btn ); @@ -1859,14 +1828,7 @@ ObjectsPanel::ObjectsPanel() : //Move up btn = Gtk::manage( new Gtk::Button() ); - btn->set_tooltip_text(_("Move Up")); -#if GTK_CHECK_VERSION(3,10,0) - btn->set_image_from_icon_name(INKSCAPE_ICON("go-up"), Gtk::ICON_SIZE_SMALL_TOOLBAR); -#else - image_remove = Gtk::manage(new Gtk::Image()); - image_remove->set_from_icon_name(INKSCAPE_ICON("go-up"), Gtk::ICON_SIZE_SMALL_TOOLBAR); - btn->set_image(*image_remove); -#endif + _styleButton(*btn, INKSCAPE_ICON("go-up"), _("Move Up")); btn->set_relief(Gtk::RELIEF_NONE); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_UP) ); _watchingNonTop.push_back( btn ); @@ -1874,14 +1836,7 @@ ObjectsPanel::ObjectsPanel() : //Move to top btn = Gtk::manage( new Gtk::Button() ); - btn->set_tooltip_text(_("Move To Top")); -#if GTK_CHECK_VERSION(3,10,0) - btn->set_image_from_icon_name(INKSCAPE_ICON("go-top"), Gtk::ICON_SIZE_SMALL_TOOLBAR); -#else - image_remove = Gtk::manage(new Gtk::Image()); - image_remove->set_from_icon_name(INKSCAPE_ICON("go-top"), Gtk::ICON_SIZE_SMALL_TOOLBAR); - btn->set_image(*image_remove); -#endif + _styleButton(*btn, INKSCAPE_ICON("go-top"), _("Move To Top")); btn->set_relief(Gtk::RELIEF_NONE); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_TOP) ); _watchingNonTop.push_back( btn ); @@ -1889,14 +1844,7 @@ ObjectsPanel::ObjectsPanel() : //Collapse all btn = Gtk::manage( new Gtk::Button() ); - btn->set_tooltip_text(_("Collapse All")); -#if GTK_CHECK_VERSION(3,10,0) - btn->set_image_from_icon_name(INKSCAPE_ICON("gtk-unindent-ltr"), Gtk::ICON_SIZE_SMALL_TOOLBAR); -#else - image_remove = Gtk::manage(new Gtk::Image()); - image_remove->set_from_icon_name(INKSCAPE_ICON("gtk-unindent-ltr"), Gtk::ICON_SIZE_SMALL_TOOLBAR); - btn->set_image(*image_remove); -#endif + _styleButton(*btn, INKSCAPE_ICON("format-indent-less"), _("Collapse All")); btn->set_relief(Gtk::RELIEF_NONE); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_COLLAPSE_ALL) ); _watchingNonBottom.push_back( btn ); diff --git a/src/ui/dialog/ocaldialogs.cpp b/src/ui/dialog/ocaldialogs.cpp index c4dd9df98..a1c7d41bd 100644 --- a/src/ui/dialog/ocaldialogs.cpp +++ b/src/ui/dialog/ocaldialogs.cpp @@ -26,7 +26,7 @@ #include "path-prefix.h" #include "filedialogimpl-gtkmm.h" #include "ui/interface.h" -#include "gc-core.h" +#include "inkgc/gc-core.h" #include "ui/dialog-events.h" #include "io/sys.h" #include "preferences.h" diff --git a/src/ui/dialog/panel-dialog.h b/src/ui/dialog/panel-dialog.h index b4a355083..39110f47a 100644 --- a/src/ui/dialog/panel-dialog.h +++ b/src/ui/dialog/panel-dialog.h @@ -49,19 +49,10 @@ public: virtual UI::Widget::Panel &getPanel() { return _panel; } protected: - static void handle_deactivate_desktop(InkscapeApplication *application, SPDesktop *desktop, void *data) { - g_return_if_fail(data != NULL); - static_cast<PanelDialogBase *>(data)->_propagateDesktopDeactivated(application, desktop); - } - - static void _handle_activate_desktop(InkscapeApplication *application, SPDesktop *desktop, void *data) { - g_return_if_fail(data != NULL); - static_cast<PanelDialogBase *>(data)->_propagateDesktopActivated(application, desktop); - } inline virtual void _propagateDocumentReplaced(SPDesktop* desktop, SPDocument *document); - inline virtual void _propagateDesktopActivated(InkscapeApplication *, SPDesktop *); - inline virtual void _propagateDesktopDeactivated(InkscapeApplication *, SPDesktop *); + inline virtual void _propagateDesktopActivated(SPDesktop *); + inline virtual void _propagateDesktopDeactivated(SPDesktop *); UI::Widget::Panel &_panel; sigc::connection _document_replaced_connection; @@ -134,17 +125,17 @@ void PanelDialogBase::_propagateDocumentReplaced(SPDesktop *desktop, SPDocument _panel.signalDocumentReplaced().emit(desktop, document); } -void PanelDialogBase::_propagateDesktopActivated(InkscapeApplication *application, SPDesktop *desktop) +void PanelDialogBase::_propagateDesktopActivated(SPDesktop *desktop) { _document_replaced_connection = desktop->connectDocumentReplaced(sigc::mem_fun(*this, &PanelDialogBase::_propagateDocumentReplaced)); - _panel.signalActivateDesktop().emit(application, desktop); + _panel.signalActivateDesktop().emit(desktop); } -void PanelDialogBase::_propagateDesktopDeactivated(InkscapeApplication *application, SPDesktop *desktop) +void PanelDialogBase::_propagateDesktopDeactivated(SPDesktop *desktop) { _document_replaced_connection.disconnect(); - _panel.signalDeactiveDesktop().emit(application, desktop); + _panel.signalDeactiveDesktop().emit(desktop); } @@ -162,7 +153,7 @@ PanelDialog<B>::PanelDialog(Widget::Panel &panel, char const *prefs_path, int co SPDesktop *desktop = SP_ACTIVE_DESKTOP; - _propagateDesktopActivated(INKSCAPE, desktop); + _propagateDesktopActivated(desktop); _document_replaced_connection = desktop->connectDocumentReplaced(sigc::mem_fun(*this, &PanelDialog::_propagateDocumentReplaced)); @@ -211,7 +202,7 @@ PanelDialog<Behavior::FloatingBehavior>::PanelDialog(UI::Widget::Panel &panel, c SPDesktop *desktop = SP_ACTIVE_DESKTOP; - _propagateDesktopActivated(INKSCAPE, desktop); + _propagateDesktopActivated(desktop); _document_replaced_connection = desktop->connectDocumentReplaced(sigc::mem_fun(*this, &PanelDialog::_propagateDocumentReplaced)); @@ -247,8 +238,12 @@ PanelDialog<Behavior::FloatingBehavior> *PanelDialog<Behavior::FloatingBehavior> new PanelDialog<Behavior::FloatingBehavior>(panel, panel.getPrefsPath(), panel.getVerb(), panel.getApplyLabel()); - g_signal_connect(G_OBJECT(INKSCAPE), "activate_desktop", G_CALLBACK(_handle_activate_desktop), instance); - g_signal_connect(G_OBJECT(INKSCAPE), "deactivate_desktop", G_CALLBACK(handle_deactivate_desktop), instance); + INKSCAPE.signal_activate_desktop.connect( + sigc::mem_fun(*instance, &PanelDialog<Behavior::FloatingBehavior>::_propagateDesktopActivated) + ); + INKSCAPE.signal_deactivate_desktop.connect( + sigc::mem_fun(*instance, &PanelDialog<Behavior::FloatingBehavior>::_propagateDesktopDeactivated) + ); return instance; } diff --git a/src/ui/dialog/polar-arrange-tab.cpp b/src/ui/dialog/polar-arrange-tab.cpp index 80579c9d3..281958998 100644 --- a/src/ui/dialog/polar-arrange-tab.cpp +++ b/src/ui/dialog/polar-arrange-tab.cpp @@ -16,7 +16,7 @@ #include "verbs.h" #include "preferences.h" #include "inkscape.h" -#include "desktop-handles.h" + #include "selection.h" #include "document.h" #include "document-undo.h" @@ -38,12 +38,12 @@ PolarArrangeTab::PolarArrangeTab(ArrangeDialog *parent_) #else parametersTable(3, 3, false), #endif - centerY("", "Y coordinate of the center", UNIT_TYPE_LINEAR), - centerX("", "X coordinate of the center", centerY), - radiusY("", "Y coordinate of the radius", UNIT_TYPE_LINEAR), - radiusX("", "X coordinate of the radius", radiusY), - angleY("", "Starting angle", UNIT_TYPE_RADIAL), - angleX("", "End angle", angleY) + centerY("", C_("Polar arrange tab", "Y coordinate of the center"), UNIT_TYPE_LINEAR), + centerX("", C_("Polar arrange tab", "X coordinate of the center"), centerY), + radiusY("", C_("Polar arrange tab", "Y coordinate of the radius"), UNIT_TYPE_LINEAR), + radiusX("", C_("Polar arrange tab", "X coordinate of the radius"), radiusY), + angleY("", C_("Polar arrange tab", "Starting angle"), UNIT_TYPE_RADIAL), + angleX("", C_("Polar arrange tab", "End angle"), angleY) { anchorPointLabel.set_text(C_("Polar arrange tab", "Anchor point:")); anchorPointLabel.set_alignment(Gtk::ALIGN_START); @@ -80,7 +80,7 @@ PolarArrangeTab::PolarArrangeTab(ArrangeDialog *parent_) arrangeOnParametersRadio.signal_toggled().connect(sigc::mem_fun(*this, &PolarArrangeTab::on_arrange_radio_changed)); pack_start(arrangeOnParametersRadio, false, false); - centerLabel.set_text(_("Center X/Y:")); + centerLabel.set_text(C_("Polar arrange tab", "Center X/Y:")); #if WITH_GTKMM_3_0 parametersTable.attach(centerLabel, 0, 0, 1, 1); #else @@ -102,7 +102,7 @@ PolarArrangeTab::PolarArrangeTab(ArrangeDialog *parent_) parametersTable.attach(centerY, 2, 3, 0, 1, Gtk::FILL); #endif - radiusLabel.set_text(_("Radius X/Y:")); + radiusLabel.set_text(C_("Polar arrange tab", "Radius X/Y:")); #if WITH_GTKMM_3_0 parametersTable.attach(radiusLabel, 0, 1, 1, 1); #else @@ -296,7 +296,7 @@ static void moveToPoint(int anchor, SPItem *item, Geom::Point p) void PolarArrangeTab::arrange() { - Inkscape::Selection *selection = sp_desktop_selection(parent->getDesktop()); + Inkscape::Selection *selection = parent->getDesktop()->getSelection(); const GSList *items, *tmp; tmp = items = selection->itemList(); SPGenericEllipse *referenceEllipse = NULL; // Last ellipse in selection @@ -399,7 +399,7 @@ void PolarArrangeTab::arrange() tmp = tmp->next; } - DocumentUndo::done(sp_desktop_document(parent->getDesktop()), SP_VERB_SELECTION_ARRANGE, + DocumentUndo::done(parent->getDesktop()->getDocument(), SP_VERB_SELECTION_ARRANGE, _("Arrange on ellipse")); } diff --git a/src/ui/dialog/print.cpp b/src/ui/dialog/print.cpp index a015d28f9..ad979b570 100644 --- a/src/ui/dialog/print.cpp +++ b/src/ui/dialog/print.cpp @@ -126,30 +126,13 @@ static void draw_page( cairo_surface_t *surface = cairo_get_target(cr); cairo_matrix_t ctm; cairo_get_matrix(cr, &ctm); -#ifdef WIN32 - //Gtk+ does not take the non printable area into account - //http://bugzilla.gnome.org/show_bug.cgi?id=381371 - // - // This workaround translates the origin from the top left of the - // printable area to the top left of the page. - GtkPrintSettings *settings = gtk_print_operation_get_print_settings(operation); - const gchar *printerName = gtk_print_settings_get_printer(settings); - HDC hdc = CreateDC("WINSPOOL", printerName, NULL, NULL); - if (hdc) { - cairo_matrix_t mat; - int x_off = GetDeviceCaps (hdc, PHYSICALOFFSETX); - int y_off = GetDeviceCaps (hdc, PHYSICALOFFSETY); - cairo_matrix_init_translate(&mat, -x_off, -y_off); - cairo_matrix_multiply (&ctm, &ctm, &mat); - DeleteDC(hdc); - } -#endif + bool ret = ctx->setSurfaceTarget (surface, true, &ctm); if (ret) { ret = renderer.setupDocument (ctx, junk->_doc, TRUE, 0., NULL); if (ret) { renderer.renderItem(ctx, junk->_base); - ret = ctx->finish(); + ctx->finish(); } else { g_warning("%s", _("Could not set up Document")); diff --git a/src/ui/dialog/spellcheck.cpp b/src/ui/dialog/spellcheck.cpp index 9faa8a2cb..6da8acb20 100644 --- a/src/ui/dialog/spellcheck.cpp +++ b/src/ui/dialog/spellcheck.cpp @@ -22,7 +22,7 @@ #include "document.h" #include "selection.h" #include "desktop.h" -#include "desktop-handles.h" + #include "ui/tools-switch.h" #include "ui/tools/text-tool.h" #include "ui/interface.h" @@ -407,7 +407,7 @@ SpellCheck::init(SPDesktop *d) } #endif /* HAVE_ASPELL */ - _root = sp_desktop_document(desktop)->getRoot(); + _root = desktop->getDocument()->getRoot(); // empty the list of objects we've checked g_slist_free (_seen_objects); @@ -612,7 +612,7 @@ SpellCheck::nextWord() area.expandBy(MAX(0.05 * mindim, 1)); // create canvas path rectangle, red stroke - SPCanvasItem *rect = sp_canvas_bpath_new(sp_desktop_sketch(desktop), NULL); + SPCanvasItem *rect = sp_canvas_bpath_new(desktop->getSketch(), NULL); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(rect), 0xff0000ff, 3.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(rect), 0, SP_WIND_RULE_NONZERO); SPCurve *curve = new SPCurve(); @@ -792,7 +792,7 @@ void SpellCheck::onAccept () // find the end of the word anew _end_w = _begin_w; _end_w.nextEndOfWord(); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("Fix spelling")); } } diff --git a/src/ui/dialog/svg-fonts-dialog.cpp b/src/ui/dialog/svg-fonts-dialog.cpp index 56ecfdecc..bc228633d 100644 --- a/src/ui/dialog/svg-fonts-dialog.cpp +++ b/src/ui/dialog/svg-fonts-dialog.cpp @@ -29,7 +29,8 @@ #include "xml/node.h" #include "xml/repr.h" #include "sp-font-face.h" -#include "desktop-handles.h" +#include "desktop.h" + #include "display/nr-svgfonts.h" #include "verbs.h" #include "sp-glyph.h" @@ -181,7 +182,7 @@ void SvgFontsDialog::on_kerning_value_changed(){ return; } - SPDocument* document = sp_desktop_document(this->getDesktop()); + SPDocument* document = this->getDesktop()->getDocument(); //TODO: I am unsure whether this is the correct way of calling SPDocumentUndo::maybe_done Glib::ustring undokey = "svgfonts:hkern:k:"; @@ -264,7 +265,7 @@ void SvgFontsDialog::update_sensitiveness(){ void SvgFontsDialog::update_fonts() { SPDesktop* desktop = this->getDesktop(); - SPDocument* document = sp_desktop_document(desktop); + SPDocument* document = desktop->getDocument(); const GSList* fonts = document->getResourceList("font"); _model->clear(); @@ -481,7 +482,7 @@ void SvgFontsDialog::update_glyphs(){ void SvgFontsDialog::add_glyph(){ const int count = _GlyphsListStore->children().size(); - SPDocument* doc = sp_desktop_document(this->getDesktop()); + SPDocument* doc = this->getDesktop()->getDocument(); /* SPGlyph* glyph =*/ new_glyph(doc, get_selected_spfont(), count+1); DocumentUndo::done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Add glyph")); @@ -514,9 +515,9 @@ void SvgFontsDialog::set_glyph_description_from_selected_path(){ return; } - Inkscape::MessageStack *msgStack = sp_desktop_message_stack(desktop); - SPDocument* doc = sp_desktop_document(desktop); - Inkscape::Selection* sel = sp_desktop_selection(desktop); + Inkscape::MessageStack *msgStack = desktop->getMessageStack(); + SPDocument* doc = desktop->getDocument(); + Inkscape::Selection* sel = desktop->getSelection(); if (sel->isEmpty()){ char *msg = _("Select a <b>path</b> to define the curves of a glyph"); msgStack->flash(Inkscape::ERROR_MESSAGE, msg); @@ -556,9 +557,9 @@ void SvgFontsDialog::missing_glyph_description_from_selected_path(){ return; } - Inkscape::MessageStack *msgStack = sp_desktop_message_stack(desktop); - SPDocument* doc = sp_desktop_document(desktop); - Inkscape::Selection* sel = sp_desktop_selection(desktop); + Inkscape::MessageStack *msgStack = desktop->getMessageStack(); + SPDocument* doc = desktop->getDocument(); + Inkscape::Selection* sel = desktop->getSelection(); if (sel->isEmpty()){ char *msg = _("Select a <b>path</b> to define the curves of a glyph"); msgStack->flash(Inkscape::ERROR_MESSAGE, msg); @@ -597,7 +598,7 @@ void SvgFontsDialog::reset_missing_glyph_description(){ return; } - SPDocument* doc = sp_desktop_document(desktop); + SPDocument* doc = desktop->getDocument(); SPObject* obj; for (obj = get_selected_spfont()->children; obj; obj=obj->next){ if (SP_IS_MISSING_GLYPH(obj)){ @@ -618,7 +619,7 @@ void SvgFontsDialog::glyph_name_edit(const Glib::ustring&, const Glib::ustring& //XML Tree being directly used here while it shouldn't be. glyph->getRepr()->setAttribute("glyph-name", str.c_str()); - SPDocument* doc = sp_desktop_document(this->getDesktop()); + SPDocument* doc = this->getDesktop()->getDocument(); DocumentUndo::done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Edit glyph name")); update_glyphs(); @@ -632,7 +633,7 @@ void SvgFontsDialog::glyph_unicode_edit(const Glib::ustring&, const Glib::ustrin //XML Tree being directly used here while it shouldn't be. glyph->getRepr()->setAttribute("unicode", str.c_str()); - SPDocument* doc = sp_desktop_document(this->getDesktop()); + SPDocument* doc = this->getDesktop()->getDocument(); DocumentUndo::done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Set glyph unicode")); update_glyphs(); @@ -644,7 +645,7 @@ void SvgFontsDialog::remove_selected_font(){ //XML Tree being directly used here while it shouldn't be. sp_repr_unparent(font->getRepr()); - SPDocument* doc = sp_desktop_document(this->getDesktop()); + SPDocument* doc = this->getDesktop()->getDocument(); DocumentUndo::done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Remove font")); update_fonts(); @@ -661,7 +662,7 @@ void SvgFontsDialog::remove_selected_glyph(){ //XML Tree being directly used here while it shouldn't be. sp_repr_unparent(glyph->getRepr()); - SPDocument* doc = sp_desktop_document(this->getDesktop()); + SPDocument* doc = this->getDesktop()->getDocument(); DocumentUndo::done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Remove glyph")); update_glyphs(); @@ -678,7 +679,7 @@ void SvgFontsDialog::remove_selected_kerning_pair(){ //XML Tree being directly used here while it shouldn't be. sp_repr_unparent(pair->getRepr()); - SPDocument* doc = sp_desktop_document(this->getDesktop()); + SPDocument* doc = this->getDesktop()->getDocument(); DocumentUndo::done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Remove kerning pair")); update_glyphs(); @@ -749,7 +750,7 @@ void SvgFontsDialog::add_kerning_pair(){ if (this->kerning_pair) return; //We already have this kerning pair - SPDocument* document = sp_desktop_document(this->getDesktop()); + SPDocument* document = this->getDesktop()->getDocument(); Inkscape::XML::Document *xml_doc = document->getReprDoc(); // create a new hkern node @@ -863,7 +864,7 @@ void set_font_family(SPFont* font, char* str){ } void SvgFontsDialog::add_font(){ - SPDocument* doc = sp_desktop_document(this->getDesktop()); + SPDocument* doc = this->getDesktop()->getDocument(); SPFont* font = new_font(doc); const int count = _model->children().size(); @@ -937,7 +938,7 @@ SvgFontsDialog::SvgFontsDialog() _FontsList.signal_button_release_event().connect_notify(sigc::mem_fun(*this, &SvgFontsDialog::fonts_list_button_release)); create_fonts_popup_menu(_FontsList, sigc::mem_fun(*this, &SvgFontsDialog::remove_selected_font)); - _defs_observer.set(sp_desktop_document(this->getDesktop())->getDefs()); + _defs_observer.set(this->getDesktop()->getDocument()->getDefs()); _defs_observer.signal_changed().connect(sigc::mem_fun(*this, &SvgFontsDialog::update_fonts)); _getContents()->show_all(); diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index a3cfeeba8..8759039c3 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -28,7 +28,7 @@ #include "color-item.h" #include "desktop.h" -#include "desktop-handles.h" + #include "desktop-style.h" #include "document.h" #include "document-private.h" @@ -122,15 +122,15 @@ static void editGradientImpl( SPDesktop* desktop, SPGradient* gr ) if ( gr ) { bool shown = false; if ( desktop && desktop->doc() ) { - Inkscape::Selection *selection = sp_desktop_selection( desktop ); + Inkscape::Selection *selection = desktop->getSelection(); GSList const *items = selection->itemList(); if (items) { - SPStyle *query = sp_style_new( desktop->doc() ); - int result = objects_query_fillstroke(const_cast<GSList *>(items), query, true); + SPStyle query( desktop->doc() ); + int result = objects_query_fillstroke(const_cast<GSList *>(items), &query, true); if ( (result == QUERY_STYLE_MULTIPLE_SAME) || (result == QUERY_STYLE_SINGLE) ) { // could be pertinent - if (query->fill.isPaintserver()) { - SPPaintServer* server = query->getFillPaintServer(); + if (query.fill.isPaintserver()) { + SPPaintServer* server = query.getFillPaintServer(); if ( SP_IS_GRADIENT(server) ) { SPGradient* grad = SP_GRADIENT(server); if ( grad->isSwatch() && grad->getId() == gr->getId()) { @@ -140,7 +140,6 @@ static void editGradientImpl( SPDesktop* desktop, SPGradient* gr ) } } } - sp_style_unref(query); } } @@ -527,7 +526,7 @@ static void loadEmUp() beenHere = true; std::list<gchar *> sources; - sources.push_back( profile_path("palettes") ); + sources.push_back( Inkscape::Application::profile_path("palettes") ); sources.push_back( g_strdup(INKSCAPE_PALETTESDIR) ); sources.push_back( g_strdup(CREATE_PALETTESDIR) ); @@ -1061,15 +1060,15 @@ void SwatchesPanel::_updateFromSelection() Glib::ustring fillId; Glib::ustring strokeId; - SPStyle *tmpStyle = sp_style_new( sp_desktop_document(_currentDesktop) ); - int result = sp_desktop_query_style( _currentDesktop, tmpStyle, QUERY_STYLE_PROPERTY_FILL ); + SPStyle tmpStyle(_currentDesktop->getDocument()); + int result = sp_desktop_query_style( _currentDesktop, &tmpStyle, QUERY_STYLE_PROPERTY_FILL ); switch (result) { case QUERY_STYLE_SINGLE: case QUERY_STYLE_MULTIPLE_AVERAGED: case QUERY_STYLE_MULTIPLE_SAME: { - if (tmpStyle->fill.set && tmpStyle->fill.isPaintserver()) { - SPPaintServer* server = tmpStyle->getFillPaintServer(); + if (tmpStyle.fill.set && tmpStyle.fill.isPaintserver()) { + SPPaintServer* server = tmpStyle.getFillPaintServer(); if ( SP_IS_GRADIENT(server) ) { SPGradient* target = 0; SPGradient* grad = SP_GRADIENT(server); @@ -1095,14 +1094,14 @@ void SwatchesPanel::_updateFromSelection() } } - result = sp_desktop_query_style( _currentDesktop, tmpStyle, QUERY_STYLE_PROPERTY_STROKE ); + result = sp_desktop_query_style( _currentDesktop, &tmpStyle, QUERY_STYLE_PROPERTY_STROKE ); switch (result) { case QUERY_STYLE_SINGLE: case QUERY_STYLE_MULTIPLE_AVERAGED: case QUERY_STYLE_MULTIPLE_SAME: { - if (tmpStyle->stroke.set && tmpStyle->stroke.isPaintserver()) { - SPPaintServer* server = tmpStyle->getStrokePaintServer(); + if (tmpStyle.stroke.set && tmpStyle.stroke.isPaintserver()) { + SPPaintServer* server = tmpStyle.getStrokePaintServer(); if ( SP_IS_GRADIENT(server) ) { SPGradient* target = 0; SPGradient* grad = SP_GRADIENT(server); @@ -1126,7 +1125,6 @@ void SwatchesPanel::_updateFromSelection() break; } } - sp_style_unref(tmpStyle); for ( boost::ptr_vector<ColorItem>::iterator it = docPalette->_colors.begin(); it != docPalette->_colors.end(); ++it ) { ColorItem* item = &*it; diff --git a/src/ui/dialog/symbols.cpp b/src/ui/dialog/symbols.cpp index a17a03861..eeb4d6cbe 100644 --- a/src/ui/dialog/symbols.cpp +++ b/src/ui/dialog/symbols.cpp @@ -52,7 +52,7 @@ #include "selection.h" #include "desktop.h" -#include "desktop-handles.h" + #include "document.h" #include "inkscape.h" #include "sp-root.h" @@ -287,8 +287,8 @@ SymbolsDialog::SymbolsDialog( gchar const* prefsPath ) : ++row; /**********************************************************/ - currentDesktop = inkscape_active_desktop(); - currentDocument = sp_desktop_document(currentDesktop); + currentDesktop = SP_ACTIVE_DESKTOP; + currentDocument = currentDesktop->getDocument(); previewDocument = symbols_preview_doc(); /* Template to render symbols in */ previewDocument->ensureUpToDate(); /* Necessary? */ @@ -498,7 +498,7 @@ void SymbolsDialog::iconChanged() { } ClipboardManager *cm = ClipboardManager::get(); - cm->copySymbol(symbol->getRepr(), style); + cm->copySymbol(symbol->getRepr(), style, symbolDocument == currentDocument); } } @@ -585,13 +585,15 @@ void SymbolsDialog::get_symbols() { std::list<Glib::ustring> directories; +// \TODO optimize this + if( Inkscape::IO::file_test( INKSCAPE_SYMBOLSDIR, G_FILE_TEST_EXISTS ) && Inkscape::IO::file_test( INKSCAPE_SYMBOLSDIR, G_FILE_TEST_IS_DIR ) ) { directories.push_back( INKSCAPE_SYMBOLSDIR ); } - if( Inkscape::IO::file_test( profile_path("symbols"), G_FILE_TEST_EXISTS ) && - Inkscape::IO::file_test( profile_path("symbols"), G_FILE_TEST_IS_DIR ) ) { - directories.push_back( profile_path("symbols") ); + if( Inkscape::IO::file_test( Inkscape::Application::profile_path("symbols"), G_FILE_TEST_EXISTS ) && + Inkscape::IO::file_test( Inkscape::Application::profile_path("symbols"), G_FILE_TEST_IS_DIR ) ) { + directories.push_back( Inkscape::Application::profile_path("symbols") ); } std::list<Glib::ustring>::iterator it; diff --git a/src/ui/dialog/tags.cpp b/src/ui/dialog/tags.cpp index 8a104d137..7d3edaffb 100644 --- a/src/ui/dialog/tags.cpp +++ b/src/ui/dialog/tags.cpp @@ -145,31 +145,12 @@ public: int _actionCode; }; -void TagsPanel::_styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* tooltip ) +void TagsPanel::_styleButton(Gtk::Button& btn, char const* iconName, char const* tooltip) { - bool set = false; - - if ( iconName ) { - GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, iconName ); - gtk_widget_show( child ); - btn.add( *manage(Glib::wrap(child)) ); - btn.set_relief(Gtk::RELIEF_NONE); - set = true; - } - - if ( desktop ) { - Verb *verb = Verb::get( code ); - if ( verb ) { - SPAction *action = verb->get_action(desktop); - if ( !set && action && action->image ) { - GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, action->image ); - gtk_widget_show( child ); - btn.add( *manage(Glib::wrap(child)) ); - set = true; - } - } - } - + GtkWidget *child = sp_icon_new(Inkscape::ICON_SIZE_SMALL_TOOLBAR, iconName); + gtk_widget_show(child); + btn.add(*manage(Glib::wrap(child))); + btn.set_relief(Gtk::RELIEF_NONE); btn.set_tooltip_text (tooltip); } @@ -1013,7 +994,7 @@ TagsPanel::TagsPanel() : SPDesktop* targetDesktop = getDesktop(); Gtk::Button* btn = manage( new Gtk::Button() ); - _styleButton( *btn, targetDesktop, SP_VERB_TAG_NEW, GTK_STOCK_ADD, _("Add a new selection set") ); + _styleButton(*btn, "list-add", _("Add a new selection set") ); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &TagsPanel::_takeAction), (int)BUTTON_NEW) ); _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); @@ -1022,7 +1003,7 @@ TagsPanel::TagsPanel() : // _buttonsRow.add( *btn ); btn = manage( new Gtk::Button() ); - _styleButton( *btn, targetDesktop, SP_VERB_LAYER_DELETE, GTK_STOCK_REMOVE, _("Remove Item/Set") ); + _styleButton( *btn, "list-remove", _("Remove Item/Set") ); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &TagsPanel::_takeAction), (int)BUTTON_DELETE) ); _watching.push_back( btn ); _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); diff --git a/src/ui/dialog/tags.h b/src/ui/dialog/tags.h index d35dfba01..3576bd111 100644 --- a/src/ui/dialog/tags.h +++ b/src/ui/dialog/tags.h @@ -62,7 +62,7 @@ private: TagsPanel(TagsPanel const &); // no copy TagsPanel &operator=(TagsPanel const &); // no assign - void _styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* tooltip ); + void _styleButton( Gtk::Button& btn, char const* iconName, char const* tooltip ); void _fireAction( unsigned int code ); Gtk::MenuItem& _addPopupItem( SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback, int id ); diff --git a/src/ui/dialog/template-load-tab.cpp b/src/ui/dialog/template-load-tab.cpp index 13cb01eef..fca1f7b30 100644 --- a/src/ui/dialog/template-load-tab.cpp +++ b/src/ui/dialog/template-load-tab.cpp @@ -194,7 +194,7 @@ void TemplateLoadTab::_refreshTemplatesList() void TemplateLoadTab::_loadTemplates() { // user's local dir - _getTemplatesFromDir(profile_path("templates") + _loading_path); + _getTemplatesFromDir(Inkscape::Application::profile_path("templates") + _loading_path); // system templates dir _getTemplatesFromDir(INKSCAPE_TEMPLATESDIR + _loading_path); diff --git a/src/ui/dialog/template-widget.cpp b/src/ui/dialog/template-widget.cpp index f79d166f2..eff75b311 100644 --- a/src/ui/dialog/template-widget.cpp +++ b/src/ui/dialog/template-widget.cpp @@ -20,7 +20,7 @@ #include "template-load-tab.h" #include "desktop.h" -#include "desktop-handles.h" + #include "document.h" #include "document-undo.h" #include "file.h" @@ -68,8 +68,8 @@ void TemplateWidget::create() SPDesktop *desktop = SP_ACTIVE_DESKTOP; SPDesktop *desc = sp_file_new_default(); _current_template.tpl_effect->effect(desc); - DocumentUndo::clearUndo(sp_desktop_document(desc)); - sp_desktop_document(desc)->setModifiedSinceSave(false); + DocumentUndo::clearUndo(desc->getDocument()); + desc->getDocument()->setModifiedSinceSave(false); // Apply cx,cy etc. from document sp_namedview_window_from_document( desc ); diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp index 0f4a6f7f1..a8be8b543 100644 --- a/src/ui/dialog/text-edit.cpp +++ b/src/ui/dialog/text-edit.cpp @@ -41,7 +41,7 @@ extern "C" { #include "document.h" #include "desktop.h" #include "desktop-style.h" -#include "desktop-handles.h" + #include "document-undo.h" #include "selection.h" #include "style.h" @@ -325,18 +325,18 @@ void TextEdit::onReadSelection ( gboolean dostyle, gboolean /*docontent*/ ) if (dostyle) { // create temporary style - SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); + SPStyle query(SP_ACTIVE_DOCUMENT); // query style from desktop into it. This returns a result flag and fills query with the style of subselection, if any, or selection - //int result_fontspec = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION); - int result_family = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY); - int result_style = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTSTYLE); - int result_numbers = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + //int result_fontspec = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION); + int result_family = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTFAMILY); + int result_style = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTSTYLE); + int result_numbers = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); // If querying returned nothing, read the style from the text tool prefs (default style for new texts) // (Ok to not get a font specification - must just rely on the family and style in that case) if (result_family == QUERY_STYLE_NOTHING || result_style == QUERY_STYLE_NOTHING || result_numbers == QUERY_STYLE_NOTHING) { - sp_style_read_from_prefs(query, "/tools/text"); + query.readFromPrefs("/tools/text"); } // FIXME: process result_family/style == QUERY_STYLE_MULTIPLE_DIFFERENT by showing "Many" in the lists @@ -344,47 +344,46 @@ void TextEdit::onReadSelection ( gboolean dostyle, gboolean /*docontent*/ ) Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); // This is normally done for us by text-toolbar but only when we are in text editing context - fontlister->update_font_list(sp_desktop_document(this->desktop)); + fontlister->update_font_list(this->desktop->getDocument()); fontlister->selection_update(); Glib::ustring fontspec = fontlister->get_fontspec(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT); - double size = sp_style_css_size_px_to_units(query->font_size.computed, unit); + double size = sp_style_css_size_px_to_units(query.font_size.computed, unit); sp_font_selector_set_fontspec(fsel, fontspec, size ); setPreviewText (fontspec, phrase); - if (query->text_anchor.computed == SP_CSS_TEXT_ANCHOR_START) { - if (query->text_align.computed == SP_CSS_TEXT_ALIGN_JUSTIFY) { + if (query.text_anchor.computed == SP_CSS_TEXT_ANCHOR_START) { + if (query.text_align.computed == SP_CSS_TEXT_ALIGN_JUSTIFY) { align_justify.set_active(); } else { align_left.set_active(); } - } else if (query->text_anchor.computed == SP_CSS_TEXT_ANCHOR_MIDDLE) { + } else if (query.text_anchor.computed == SP_CSS_TEXT_ANCHOR_MIDDLE) { align_center.set_active(); } else { align_right.set_active(); } - if (query->writing_mode.computed == SP_CSS_WRITING_MODE_LR_TB) { + if (query.writing_mode.computed == SP_CSS_WRITING_MODE_LR_TB) { text_horizontal.set_active(); } else { text_vertical.set_active(); } double height; - if (query->line_height.normal) height = Inkscape::Text::Layout::LINE_HEIGHT_NORMAL; - else if (query->line_height.unit == SP_CSS_UNIT_PERCENT) - height = query->line_height.value; - else height = query->line_height.computed; + if (query.line_height.normal) height = Inkscape::Text::Layout::LINE_HEIGHT_NORMAL; + else if (query.line_height.unit == SP_CSS_UNIT_PERCENT) + height = query.line_height.value; + else height = query.line_height.computed; gchar *sstr = g_strdup_printf ("%d%%", (int) floor(height * 100 + 0.5)); gtk_entry_set_text ((GtkEntry *) gtk_bin_get_child ((GtkBin *) spacing_combo), sstr); g_free(sstr); - sp_style_unref(query); } blocked = false; } @@ -419,7 +418,7 @@ SPItem *TextEdit::getSelectedTextItem (void) if (!SP_ACTIVE_DESKTOP) return NULL; - for (const GSList *item = sp_desktop_selection(SP_ACTIVE_DESKTOP)->itemList(); + for (const GSList *item = SP_ACTIVE_DESKTOP->getSelection()->itemList(); item != NULL; item = item->next) { @@ -438,7 +437,7 @@ unsigned TextEdit::getSelectedTextCount (void) unsigned int items = 0; - for (const GSList *item = sp_desktop_selection(SP_ACTIVE_DESKTOP)->itemList(); + for (const GSList *item = SP_ACTIVE_DESKTOP->getSelection()->itemList(); item != NULL; item = item->next) { @@ -543,7 +542,7 @@ void TextEdit::onApply() SPDesktop *desktop = SP_ACTIVE_DESKTOP; unsigned items = 0; - const GSList *item_list = sp_desktop_selection(desktop)->itemList(); + const GSList *item_list = desktop->getSelection()->itemList(); SPCSSAttr *css = fillTextStyle (); sp_desktop_set_style(desktop, css, true); @@ -569,7 +568,7 @@ void TextEdit::onApply() } else if (items == 1) { // exactly one text object; now set its text, too - SPItem *item = sp_desktop_selection(SP_ACTIVE_DESKTOP)->singleItem(); + SPItem *item = SP_ACTIVE_DESKTOP->getSelection()->singleItem(); if (SP_IS_TEXT (item) || SP_IS_FLOWTEXT(item)) { updateObjectText (item); } @@ -583,7 +582,7 @@ void TextEdit::onApply() } // complete the transaction - DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_CONTEXT_TEXT, + DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_CONTEXT_TEXT, _("Set text style")); apply_button.set_sensitive ( false ); @@ -658,7 +657,7 @@ void TextEdit::onStartOffsetChange(GtkTextBuffer * /*text_buffer*/, TextEdit *se const gchar *sstr = gtk_combo_box_text_get_active_text(reinterpret_cast<GtkComboBoxText *>(self->startOffset)); tp->setAttribute("startOffset", sstr); - DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "startOffset", SP_VERB_CONTEXT_TEXT, _("Set text style")); + DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "startOffset", SP_VERB_CONTEXT_TEXT, _("Set text style")); } } diff --git a/src/ui/dialog/transformation.cpp b/src/ui/dialog/transformation.cpp index 6dbcf4a05..233d99750 100644 --- a/src/ui/dialog/transformation.cpp +++ b/src/ui/dialog/transformation.cpp @@ -25,7 +25,8 @@ #include "document.h" #include "document-undo.h" -#include "desktop-handles.h" +#include "desktop.h" + #include "transformation.h" #include "align-and-distribute.h" #include "inkscape.h" @@ -47,16 +48,13 @@ namespace Inkscape { namespace UI { namespace Dialog { -static void on_selection_changed(InkscapeApplication */*inkscape*/, Inkscape::Selection *selection, Transformation *daad) +static void on_selection_changed(Inkscape::Selection *selection, Transformation *daad) { int page = daad->getCurrentPage(); daad->updateSelection((Inkscape::UI::Dialog::Transformation::PageType)page, selection); } -static void on_selection_modified( InkscapeApplication */*inkscape*/, - Inkscape::Selection *selection, - guint /*flags*/, - Transformation *daad ) +static void on_selection_modified(Inkscape::Selection *selection, Transformation *daad) { int page = daad->getCurrentPage(); daad->updateSelection((Inkscape::UI::Dialog::Transformation::PageType)page, selection); @@ -159,8 +157,8 @@ Transformation::Transformation() } // Connect to the global selection changed & modified signals - g_signal_connect (G_OBJECT (INKSCAPE), "change_selection", G_CALLBACK (on_selection_changed), this); - g_signal_connect (G_OBJECT (INKSCAPE), "modify_selection", G_CALLBACK (on_selection_modified), this); + _selChangeConn = INKSCAPE.signal_selection_changed.connect(sigc::bind(sigc::ptr_fun(&on_selection_changed), this)); + _selModifyConn = INKSCAPE.signal_selection_modified.connect(sigc::hide<1>(sigc::bind(sigc::ptr_fun(&on_selection_modified), this))); _desktopChangeConn = _deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &Transformation::setDesktop) ); _deskTrack.connect(GTK_WIDGET(gobj())); @@ -170,7 +168,8 @@ Transformation::Transformation() Transformation::~Transformation() { - sp_signal_disconnect_by_data (G_OBJECT (INKSCAPE), this); + _selModifyConn.disconnect(); + _selChangeConn.disconnect(); _desktopChangeConn.disconnect(); _deskTrack.disconnect(); } @@ -207,7 +206,7 @@ void Transformation::layoutPageMove() // Setting default unit to document unit SPDesktop *dt = getDesktop(); - SPNamedView *nv = sp_desktop_namedview(dt); + SPNamedView *nv = dt->getNamedView(); if (nv->display_units) { _units_move.setUnit(nv->display_units->abbr); } @@ -580,7 +579,7 @@ void Transformation::onSwitchPage(Gtk::Widget * /*page*/, guint pagenum) void Transformation::onSwitchPage(GtkNotebookPage * /*page*/, guint pagenum) #endif { - updateSelection((PageType)pagenum, sp_desktop_selection(getDesktop())); + updateSelection((PageType)pagenum, getDesktop()->getSelection()); } @@ -803,7 +802,7 @@ void Transformation::applyPageMove(Inkscape::Selection *selection) } } - DocumentUndo::done( sp_desktop_document(selection->desktop()) , SP_VERB_DIALOG_TRANSFORM, + DocumentUndo::done( selection->desktop()->getDocument() , SP_VERB_DIALOG_TRANSFORM, _("Move")); } @@ -865,7 +864,7 @@ void Transformation::applyPageScale(Inkscape::Selection *selection) } } - DocumentUndo::done(sp_desktop_document(selection->desktop()), SP_VERB_DIALOG_TRANSFORM, + DocumentUndo::done(selection->desktop()->getDocument(), SP_VERB_DIALOG_TRANSFORM, _("Scale")); } @@ -890,7 +889,7 @@ void Transformation::applyPageRotate(Inkscape::Selection *selection) } } - DocumentUndo::done(sp_desktop_document(selection->desktop()), SP_VERB_DIALOG_TRANSFORM, + DocumentUndo::done(selection->desktop()->getDocument(), SP_VERB_DIALOG_TRANSFORM, _("Rotate")); } @@ -905,7 +904,7 @@ void Transformation::applyPageSkew(Inkscape::Selection *selection) double skewX = _scalar_skew_horizontal.getValue("%"); double skewY = _scalar_skew_vertical.getValue("%"); if (fabs(0.01*skewX*0.01*skewY - 1.0) < Geom::EPSILON) { - sp_desktop_message_stack(getDesktop())->flash(Inkscape::WARNING_MESSAGE, _("Transform matrix is singular, <b>not used</b>.")); + getDesktop()->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Transform matrix is singular, <b>not used</b>.")); return; } sp_item_skew_rel (item, 0.01*skewX, 0.01*skewY); @@ -916,7 +915,7 @@ void Transformation::applyPageSkew(Inkscape::Selection *selection) || (fabs(angleX - angleY - M_PI/2) < Geom::EPSILON) || (fabs((angleX - angleY)/3 + M_PI/2) < Geom::EPSILON) || (fabs((angleX - angleY)/3 - M_PI/2) < Geom::EPSILON)) { - sp_desktop_message_stack(getDesktop())->flash(Inkscape::WARNING_MESSAGE, _("Transform matrix is singular, <b>not used</b>.")); + getDesktop()->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Transform matrix is singular, <b>not used</b>.")); return; } double skewX = tan(-angleX); @@ -930,7 +929,7 @@ void Transformation::applyPageSkew(Inkscape::Selection *selection) double width = bbox->dimensions()[Geom::X]; double height = bbox->dimensions()[Geom::Y]; if (fabs(skewX*skewY - width*height) < Geom::EPSILON) { - sp_desktop_message_stack(getDesktop())->flash(Inkscape::WARNING_MESSAGE, _("Transform matrix is singular, <b>not used</b>.")); + getDesktop()->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Transform matrix is singular, <b>not used</b>.")); return; } sp_item_skew_rel (item, skewX/height, skewY/width); @@ -949,7 +948,7 @@ void Transformation::applyPageSkew(Inkscape::Selection *selection) double skewX = _scalar_skew_horizontal.getValue("%"); double skewY = _scalar_skew_vertical.getValue("%"); if (fabs(0.01*skewX*0.01*skewY - 1.0) < Geom::EPSILON) { - sp_desktop_message_stack(getDesktop())->flash(Inkscape::WARNING_MESSAGE, _("Transform matrix is singular, <b>not used</b>.")); + getDesktop()->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Transform matrix is singular, <b>not used</b>.")); return; } sp_selection_skew_relative(selection, *center, 0.01*skewX, 0.01*skewY); @@ -960,7 +959,7 @@ void Transformation::applyPageSkew(Inkscape::Selection *selection) || (fabs(angleX - angleY - M_PI/2) < Geom::EPSILON) || (fabs((angleX - angleY)/3 + M_PI/2) < Geom::EPSILON) || (fabs((angleX - angleY)/3 - M_PI/2) < Geom::EPSILON)) { - sp_desktop_message_stack(getDesktop())->flash(Inkscape::WARNING_MESSAGE, _("Transform matrix is singular, <b>not used</b>.")); + getDesktop()->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Transform matrix is singular, <b>not used</b>.")); return; } double skewX = tan(-angleX); @@ -970,7 +969,7 @@ void Transformation::applyPageSkew(Inkscape::Selection *selection) double skewX = _scalar_skew_horizontal.getValue("px"); double skewY = _scalar_skew_vertical.getValue("px"); if (fabs(skewX*skewY - width*height) < Geom::EPSILON) { - sp_desktop_message_stack(getDesktop())->flash(Inkscape::WARNING_MESSAGE, _("Transform matrix is singular, <b>not used</b>.")); + getDesktop()->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Transform matrix is singular, <b>not used</b>.")); return; } sp_selection_skew_relative(selection, *center, skewX/height, skewY/width); @@ -978,7 +977,7 @@ void Transformation::applyPageSkew(Inkscape::Selection *selection) } } - DocumentUndo::done(sp_desktop_document(selection->desktop()), SP_VERB_DIALOG_TRANSFORM, + DocumentUndo::done(selection->desktop()->getDocument(), SP_VERB_DIALOG_TRANSFORM, _("Skew")); } @@ -994,7 +993,7 @@ void Transformation::applyPageTransform(Inkscape::Selection *selection) Geom::Affine displayed(a, b, c, d, e, f); if (displayed.isSingular()) { - sp_desktop_message_stack(getDesktop())->flash(Inkscape::WARNING_MESSAGE, _("Transform matrix is singular, <b>not used</b>.")); + getDesktop()->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Transform matrix is singular, <b>not used</b>.")); return; } @@ -1008,7 +1007,7 @@ void Transformation::applyPageTransform(Inkscape::Selection *selection) sp_selection_apply_affine(selection, displayed); // post-multiply each object's transform } - DocumentUndo::done(sp_desktop_document(selection->desktop()), SP_VERB_DIALOG_TRANSFORM, + DocumentUndo::done(selection->desktop()->getDocument(), SP_VERB_DIALOG_TRANSFORM, _("Edit transformation matrix")); } diff --git a/src/ui/dialog/transformation.h b/src/ui/dialog/transformation.h index 1d24a0c94..89aa95d90 100644 --- a/src/ui/dialog/transformation.h +++ b/src/ui/dialog/transformation.h @@ -232,6 +232,9 @@ private: Gtk::Button *applyButton; Gtk::Button *resetButton; Gtk::Button *cancelButton; + + sigc::connection _selChangeConn; + sigc::connection _selModifyConn; }; diff --git a/src/ui/dialog/undo-history.cpp b/src/ui/dialog/undo-history.cpp index 53691cd37..a50a169eb 100644 --- a/src/ui/dialog/undo-history.cpp +++ b/src/ui/dialog/undo-history.cpp @@ -24,7 +24,7 @@ #include "document-undo.h" #include "inkscape.h" #include "verbs.h" -#include "desktop-handles.h" + #include "util/signal-blocker.h" #include "desktop.h" diff --git a/src/ui/dialog/xml-tree.cpp b/src/ui/dialog/xml-tree.cpp index 7ab6c78ba..99a4acc69 100644 --- a/src/ui/dialog/xml-tree.cpp +++ b/src/ui/dialog/xml-tree.cpp @@ -23,7 +23,7 @@ #include <gtkmm/stock.h> #include "desktop.h" -#include "desktop-handles.h" + #include "ui/dialog-events.h" #include "document.h" #include "document-undo.h" @@ -71,10 +71,10 @@ XmlTree::XmlTree (void) : xml_text_new_button ( _("New text node")), xml_node_delete_button ( Q_("nodeAsInXMLdialogTooltip|Delete node")), xml_node_duplicate_button ( _("Duplicate node")), - unindent_node_button (Gtk::Stock::UNINDENT), - indent_node_button (Gtk::Stock::INDENT), - raise_node_button (Gtk::Stock::GO_UP), - lower_node_button (Gtk::Stock::GO_DOWN), + unindent_node_button(), + indent_node_button(), + raise_node_button(), + lower_node_button(), attr_toolbar(), xml_attribute_delete_button (_("Delete attribute")), text_container (), @@ -149,21 +149,29 @@ XmlTree::XmlTree (void) : tree_toolbar.add(separator2); + unindent_node_button.set_icon_widget(*Gtk::manage(Glib::wrap( + sp_icon_new (Inkscape::ICON_SIZE_LARGE_TOOLBAR, INKSCAPE_ICON("format-indent-less"))))); unindent_node_button.set_label(_("Unindent node")); unindent_node_button.set_tooltip_text(_("Unindent node")); unindent_node_button.set_sensitive(false); tree_toolbar.add(unindent_node_button); + indent_node_button.set_icon_widget(*Gtk::manage(Glib::wrap( + sp_icon_new (Inkscape::ICON_SIZE_LARGE_TOOLBAR, INKSCAPE_ICON("format-indent-more"))))); indent_node_button.set_label(_("Indent node")); indent_node_button.set_tooltip_text(_("Indent node")); indent_node_button.set_sensitive(false); tree_toolbar.add(indent_node_button); + raise_node_button.set_icon_widget(*Gtk::manage(Glib::wrap( + sp_icon_new (Inkscape::ICON_SIZE_LARGE_TOOLBAR, INKSCAPE_ICON("go-up"))))); raise_node_button.set_label(_("Raise node")); raise_node_button.set_tooltip_text(_("Raise node")); raise_node_button.set_sensitive(false); tree_toolbar.add(raise_node_button); + lower_node_button.set_icon_widget(*Gtk::manage(Glib::wrap( + sp_icon_new (Inkscape::ICON_SIZE_LARGE_TOOLBAR, INKSCAPE_ICON("go-down"))))); lower_node_button.set_label(_("Lower node")); lower_node_button.set_tooltip_text(_("Lower node")); lower_node_button.set_sensitive(false); @@ -360,10 +368,10 @@ void XmlTree::set_tree_desktop(SPDesktop *desktop) } current_desktop = desktop; if (desktop) { - sel_changed_connection = sp_desktop_selection(desktop)->connectChanged(sigc::hide(sigc::mem_fun(this, &XmlTree::on_desktop_selection_changed))); + sel_changed_connection = desktop->getSelection()->connectChanged(sigc::hide(sigc::mem_fun(this, &XmlTree::on_desktop_selection_changed))); document_replaced_connection = desktop->connectDocumentReplaced(sigc::mem_fun(this, &XmlTree::on_document_replaced)); - set_tree_document(sp_desktop_document(desktop)); + set_tree_document(desktop->getDocument()); } else { set_tree_document(NULL); } @@ -472,7 +480,7 @@ Inkscape::XML::Node *XmlTree::get_dt_select() if (!current_desktop) { return NULL; } - return sp_desktop_selection(current_desktop)->singleRepr(); + return current_desktop->getSelection()->singleRepr(); } @@ -483,7 +491,7 @@ void XmlTree::set_dt_select(Inkscape::XML::Node *repr) return; } - Inkscape::Selection *selection = sp_desktop_selection(current_desktop); + Inkscape::Selection *selection = current_desktop->getSelection(); SPObject *object; if (repr) { @@ -493,7 +501,7 @@ void XmlTree::set_dt_select(Inkscape::XML::Node *repr) repr = repr->parent(); } // end of while loop - object = sp_desktop_document(current_desktop)->getObjectByRepr(repr); + object = current_desktop->getDocument()->getObjectByRepr(repr); } else { object = NULL; } @@ -827,7 +835,7 @@ void XmlTree::on_document_replaced(SPDesktop *dt, SPDocument *doc) if (current_desktop) sel_changed_connection.disconnect(); - sel_changed_connection = sp_desktop_selection(dt)->connectChanged(sigc::hide(sigc::mem_fun(this, &XmlTree::on_desktop_selection_changed))); + sel_changed_connection = dt->getSelection()->connectChanged(sigc::hide(sigc::mem_fun(this, &XmlTree::on_desktop_selection_changed))); set_tree_document(doc); } diff --git a/src/ui/draw-anchor.cpp b/src/ui/draw-anchor.cpp index 84c919018..6b9a88ed7 100644 --- a/src/ui/draw-anchor.cpp +++ b/src/ui/draw-anchor.cpp @@ -15,7 +15,6 @@ #include "ui/draw-anchor.h" #include "desktop.h" -#include "desktop-handles.h" #include "ui/tools/tool-base.h" #include "ui/tools/lpe-tool.h" #include "display/sodipodi-ctrl.h" @@ -45,7 +44,7 @@ SPDrawAnchor *sp_draw_anchor_new(Inkscape::UI::Tools::FreehandBase *dc, SPCurve a->start = start; a->active = FALSE; a->dp = delta; - a->ctrl = ControlManager::getManager().createControl(sp_desktop_controls(&dc->getDesktop()), Inkscape::CTRL_TYPE_ANCHOR); + a->ctrl = ControlManager::getManager().createControl(dc->getDesktop().getControls(), Inkscape::CTRL_TYPE_ANCHOR); SP_CTRL(a->ctrl)->moveto(delta); diff --git a/src/ui/interface.cpp b/src/ui/interface.cpp index 7830a8de1..87438ac01 100644 --- a/src/ui/interface.cpp +++ b/src/ui/interface.cpp @@ -29,7 +29,7 @@ #include <gtkmm/imagemenuitem.h> #include <gtkmm/separatormenuitem.h> -#include "inkscape-private.h" +#include "inkscape.h" #include "extension/db.h" #include "extension/effect.h" #include "extension/input.h" @@ -38,7 +38,7 @@ #include "path-prefix.h" #include "shortcuts.h" #include "document.h" -#include "desktop-handles.h" + #include "ui/interface.h" #include "desktop.h" #include "selection.h" @@ -270,7 +270,7 @@ sp_create_window(SPViewWidget *vw, bool editable) // needed because the first ACTIVATE_DESKTOP was sent when there was no window yet if ( SP_IS_DESKTOP_WIDGET(vw) ) { - inkscape_reactivate_desktop(SP_DESKTOP_WIDGET(vw)->desktop); + INKSCAPE.reactivate_desktop(SP_DESKTOP_WIDGET(vw)->desktop); } } @@ -318,13 +318,13 @@ sp_ui_close_view(GtkWidget */*widget*/) // If closing the last document, open a new document so Inkscape doesn't quit. std::list<SPDesktop *> desktops; - inkscape_get_all_desktops(desktops); + INKSCAPE.get_all_desktops(desktops); if (desktops.size() == 1) { Glib::ustring templateUri = sp_file_default_template_uri(); SPDocument *doc = SPDocument::createNewDoc( templateUri.c_str() , TRUE, true ); // Set viewBox if it doesn't exist if (!doc->getRoot()->viewBox_set) { - doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDefaultUnit()), doc->getHeight().value(doc->getDefaultUnit()))); + doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDisplayUnit()), doc->getHeight().value(doc->getDisplayUnit()))); } dt->change_document(doc); sp_namedview_window_from_document(dt); @@ -921,7 +921,7 @@ static void sp_ui_build_dyn_menus(Inkscape::XML::Node *menus, GtkWidget *menu, I GtkWidget *sp_ui_main_menubar(Inkscape::UI::View::View *view) { GtkWidget *mbar = gtk_menu_bar_new(); - sp_ui_build_dyn_menus(inkscape_get_menus(INKSCAPE), mbar, view); + sp_ui_build_dyn_menus(INKSCAPE.get_menus(), mbar, view); return mbar; } @@ -1232,12 +1232,12 @@ sp_ui_drag_data_received(GtkWidget *widget, SPObject *new_obj = NULL; new_obj = desktop->currentLayer()->appendChildRepr(newgroup); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); selection->set(SP_ITEM(new_obj)); // move to mouse pointer { - sp_desktop_document(desktop)->ensureUpToDate(); + desktop->getDocument()->ensureUpToDate(); Geom::OptRect sel_bbox = selection->visualBounds(); if (sel_bbox) { Geom::Point m( desktop->point() - sel_bbox->midpoint() ); @@ -1815,7 +1815,7 @@ void ContextMenu::SelectSameStrokeColor(void) void ContextMenu::SelectSameStrokeStyle(void) { - sp_select_same_stroke_style(_desktop); + sp_select_same_fill_stroke_style(_desktop, false, false, true); } void ContextMenu::SelectSameObjectType(void) @@ -2117,13 +2117,13 @@ void ContextMenu::ImageEdit(void) void ContextMenu::ImageTraceBitmap(void) { - inkscape_dialogs_unhide(); + INKSCAPE.dialogs_unhide(); _desktop->_dlg_mgr->showDialog("Trace"); } void ContextMenu::ImageTracePixelArt(void) { - inkscape_dialogs_unhide(); + INKSCAPE.dialogs_unhide(); _desktop->_dlg_mgr->showDialog("PixelArt"); } diff --git a/src/ui/object-edit.cpp b/src/ui/object-edit.cpp index ca550502d..0a6c792dc 100644 --- a/src/ui/object-edit.cpp +++ b/src/ui/object-edit.cpp @@ -28,7 +28,7 @@ #include "preferences.h" #include "style.h" #include "desktop.h" -#include "desktop-handles.h" + #include "sp-namedview.h" #include "live_effects/effect.h" #include "sp-pattern.h" @@ -154,12 +154,9 @@ RectKnotHolderEntityRX::knot_set(Geom::Point const &p, Geom::Point const &/*orig if (state & GDK_CONTROL_MASK) { gdouble temp = MIN(rect->height.computed, rect->width.computed) / 2.0; - rect->rx.computed = rect->ry.computed = CLAMP(rect->x.computed + rect->width.computed - s[Geom::X], 0.0, temp); - rect->rx._set = rect->ry._set = true; - + rect->rx = rect->ry = CLAMP(rect->x.computed + rect->width.computed - s[Geom::X], 0.0, temp); } else { - rect->rx.computed = CLAMP(rect->x.computed + rect->width.computed - s[Geom::X], 0.0, rect->width.computed / 2.0); - rect->rx._set = true; + rect->rx = CLAMP(rect->x.computed + rect->width.computed - s[Geom::X], 0.0, rect->width.computed / 2.0); } update_knot(); @@ -207,20 +204,17 @@ RectKnotHolderEntityRY::knot_set(Geom::Point const &p, Geom::Point const &/*orig if (state & GDK_CONTROL_MASK) { // When holding control then rx will be kept equal to ry, // resulting in a perfect circle (and not an ellipse) gdouble temp = MIN(rect->height.computed, rect->width.computed) / 2.0; - rect->rx.computed = rect->ry.computed = CLAMP(s[Geom::Y] - rect->y.computed, 0.0, temp); - rect->ry._set = rect->rx._set = true; + rect->rx = rect->ry = CLAMP(s[Geom::Y] - rect->y.computed, 0.0, temp); } else { if (!rect->rx._set || rect->rx.computed == 0) { - rect->ry.computed = CLAMP(s[Geom::Y] - rect->y.computed, - 0.0, - MIN(rect->height.computed / 2.0, rect->width.computed / 2.0)); + rect->ry = CLAMP(s[Geom::Y] - rect->y.computed, + 0.0, + MIN(rect->height.computed / 2.0, rect->width.computed / 2.0)); } else { - rect->ry.computed = CLAMP(s[Geom::Y] - rect->y.computed, - 0.0, - rect->height.computed / 2.0); + rect->ry = CLAMP(s[Geom::Y] - rect->y.computed, + 0.0, + rect->height.computed / 2.0); } - - rect->ry._set = true; } update_knot(); @@ -250,12 +244,10 @@ static void sp_rect_clamp_radii(SPRect *rect) { // clamp rounding radii so that they do not exceed width/height if (2 * rect->rx.computed > rect->width.computed) { - rect->rx.computed = 0.5 * rect->width.computed; - rect->rx._set = true; + rect->rx = 0.5 * rect->width.computed; } if (2 * rect->ry.computed > rect->height.computed) { - rect->ry.computed = 0.5 * rect->height.computed; - rect->ry._set = true; + rect->ry = 0.5 * rect->height.computed; } } @@ -296,44 +288,45 @@ RectKnotHolderEntityWH::set_internal(Geom::Point const &p, Geom::Point const &or // closer to the diagonal and in same-sign quarters, change both using ratio s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(p_handle, Geom::Point(-ratio, -1)), state); minx = s[Geom::X] - origin[Geom::X]; - miny = s[Geom::Y] - origin[Geom::Y]; - rect->height.computed = MAX(h_orig + minx / ratio, 0); + // Dead assignment: Value stored to 'miny' is never read + //miny = s[Geom::Y] - origin[Geom::Y]; + rect->height = MAX(h_orig + minx / ratio, 0); } else { // closer to the horizontal, change only width, height is h_orig s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(p_handle, Geom::Point(-1, 0)), state); minx = s[Geom::X] - origin[Geom::X]; - miny = s[Geom::Y] - origin[Geom::Y]; - rect->height.computed = MAX(h_orig, 0); + // Dead assignment: Value stored to 'miny' is never read + //miny = s[Geom::Y] - origin[Geom::Y]; + rect->height = MAX(h_orig, 0); } - rect->width.computed = MAX(w_orig + minx, 0); + rect->width = MAX(w_orig + minx, 0); } else { // snap to vertical or diagonal if (miny != 0 && fabs(minx/miny) > 0.5 * ratio && (SGN(minx) == SGN(miny))) { // closer to the diagonal and in same-sign quarters, change both using ratio s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(p_handle, Geom::Point(-ratio, -1)), state); - minx = s[Geom::X] - origin[Geom::X]; + // Dead assignment: Value stored to 'minx' is never read + //minx = s[Geom::X] - origin[Geom::X]; miny = s[Geom::Y] - origin[Geom::Y]; - rect->width.computed = MAX(w_orig + miny * ratio, 0); + rect->width = MAX(w_orig + miny * ratio, 0); } else { // closer to the vertical, change only height, width is w_orig s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(p_handle, Geom::Point(0, -1)), state); - minx = s[Geom::X] - origin[Geom::X]; + // Dead assignment: Value stored to 'minx' is never read + //minx = s[Geom::X] - origin[Geom::X]; miny = s[Geom::Y] - origin[Geom::Y]; - rect->width.computed = MAX(w_orig, 0); + rect->width = MAX(w_orig, 0); } - rect->height.computed = MAX(h_orig + miny, 0); + rect->height = MAX(h_orig + miny, 0); } - rect->width._set = rect->height._set = true; - } else { // move freely s = snap_knot_position(p, state); - rect->width.computed = MAX(s[Geom::X] - rect->x.computed, 0); - rect->height.computed = MAX(s[Geom::Y] - rect->y.computed, 0); - rect->width._set = rect->height._set = true; + rect->width = MAX(s[Geom::X] - rect->x.computed, 0); + rect->height = MAX(s[Geom::Y] - rect->y.computed, 0); } sp_rect_clamp_radii(rect); @@ -388,53 +381,54 @@ RectKnotHolderEntityXY::knot_set(Geom::Point const &p, Geom::Point const &origin // closer to the diagonal and in same-sign quarters, change both using ratio s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(p_handle, Geom::Point(-ratio, -1)), state); minx = s[Geom::X] - origin[Geom::X]; - miny = s[Geom::Y] - origin[Geom::Y]; - rect->y.computed = MIN(origin[Geom::Y] + minx / ratio, opposite_y); - rect->height.computed = MAX(h_orig - minx / ratio, 0); + // Dead assignment: Value stored to 'miny' is never read + //miny = s[Geom::Y] - origin[Geom::Y]; + rect->y = MIN(origin[Geom::Y] + minx / ratio, opposite_y); + rect->height = MAX(h_orig - minx / ratio, 0); } else { // closer to the horizontal, change only width, height is h_orig s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(p_handle, Geom::Point(-1, 0)), state); minx = s[Geom::X] - origin[Geom::X]; - miny = s[Geom::Y] - origin[Geom::Y]; - rect->y.computed = MIN(origin[Geom::Y], opposite_y); - rect->height.computed = MAX(h_orig, 0); + // Dead assignment: Value stored to 'miny' is never read + //miny = s[Geom::Y] - origin[Geom::Y]; + rect->y = MIN(origin[Geom::Y], opposite_y); + rect->height = MAX(h_orig, 0); } - rect->x.computed = MIN(s[Geom::X], opposite_x); - rect->width.computed = MAX(w_orig - minx, 0); + rect->x = MIN(s[Geom::X], opposite_x); + rect->width = MAX(w_orig - minx, 0); } else { // snap to vertical or diagonal if (miny != 0 && fabs(minx/miny) > 0.5 *ratio && (SGN(minx) == SGN(miny))) { // closer to the diagonal and in same-sign quarters, change both using ratio s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(p_handle, Geom::Point(-ratio, -1)), state); - minx = s[Geom::X] - origin[Geom::X]; + // Dead assignment: Value stored to 'minx' is never read + //minx = s[Geom::X] - origin[Geom::X]; miny = s[Geom::Y] - origin[Geom::Y]; - rect->x.computed = MIN(origin[Geom::X] + miny * ratio, opposite_x); - rect->width.computed = MAX(w_orig - miny * ratio, 0); + rect->x = MIN(origin[Geom::X] + miny * ratio, opposite_x); + rect->width = MAX(w_orig - miny * ratio, 0); } else { // closer to the vertical, change only height, width is w_orig s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(p_handle, Geom::Point(0, -1)), state); - minx = s[Geom::X] - origin[Geom::X]; + // Dead assignment: Value stored to 'minx' is never read + //minx = s[Geom::X] - origin[Geom::X]; miny = s[Geom::Y] - origin[Geom::Y]; - rect->x.computed = MIN(origin[Geom::X], opposite_x); - rect->width.computed = MAX(w_orig, 0); + rect->x = MIN(origin[Geom::X], opposite_x); + rect->width = MAX(w_orig, 0); } - rect->y.computed = MIN(s[Geom::Y], opposite_y); - rect->height.computed = MAX(h_orig - miny, 0); + rect->y = MIN(s[Geom::Y], opposite_y); + rect->height = MAX(h_orig - miny, 0); } - rect->width._set = rect->height._set = rect->x._set = rect->y._set = true; - } else { // move freely s = snap_knot_position(p, state); minx = s[Geom::X] - origin[Geom::X]; miny = s[Geom::Y] - origin[Geom::Y]; - rect->x.computed = MIN(s[Geom::X], opposite_x); - rect->width.computed = MAX(w_orig - minx, 0); - rect->y.computed = MIN(s[Geom::Y], opposite_y); - rect->height.computed = MAX(h_orig - miny, 0); - rect->width._set = rect->height._set = rect->x._set = rect->y._set = true; + rect->x = MIN(s[Geom::X], opposite_x); + rect->y = MIN(s[Geom::Y], opposite_y); + rect->width = MAX(w_orig - minx, 0); + rect->height = MAX(h_orig - miny, 0); } sp_rect_clamp_radii(rect); @@ -909,10 +903,10 @@ ArcKnotHolderEntityRX::knot_set(Geom::Point const &p, Geom::Point const &/*origi Geom::Point const s = snap_knot_position(p, state); - ge->rx.computed = fabs( ge->cx.computed - s[Geom::X] ); + ge->rx = fabs( ge->cx.computed - s[Geom::X] ); if ( state & GDK_CONTROL_MASK ) { - ge->ry.computed = ge->rx.computed; + ge->ry = ge->rx.computed; } item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); @@ -934,7 +928,7 @@ ArcKnotHolderEntityRX::knot_click(unsigned int state) g_assert(ge != NULL); if (state & GDK_CONTROL_MASK) { - ge->ry.computed = ge->rx.computed; + ge->ry = ge->rx.computed; ge->updateRepr(); } } @@ -947,10 +941,10 @@ ArcKnotHolderEntityRY::knot_set(Geom::Point const &p, Geom::Point const &/*origi Geom::Point const s = snap_knot_position(p, state); - ge->ry.computed = fabs( ge->cy.computed - s[Geom::Y] ); + ge->ry = fabs( ge->cy.computed - s[Geom::Y] ); if ( state & GDK_CONTROL_MASK ) { - ge->rx.computed = ge->ry.computed; + ge->rx = ge->ry.computed; } item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); @@ -972,7 +966,7 @@ ArcKnotHolderEntityRY::knot_click(unsigned int state) g_assert(ge != NULL); if (state & GDK_CONTROL_MASK) { - ge->rx.computed = ge->ry.computed; + ge->rx = ge->ry.computed; ge->updateRepr(); } } diff --git a/src/ui/shape-editor.cpp b/src/ui/shape-editor.cpp index 0b9fc24c5..aec5cde27 100644 --- a/src/ui/shape-editor.cpp +++ b/src/ui/shape-editor.cpp @@ -14,7 +14,7 @@ #include <string.h> #include <glibmm/i18n.h> -#include "desktop-handles.h" +#include "desktop.h" #include "document.h" #include "gc-anchored.h" #include "knotholder.h" @@ -146,7 +146,7 @@ void ShapeEditor::set_item(SPItem *item, bool keep_knotholder) { void ShapeEditor::reset_item(bool keep_knotholder) { if (knotholder) { - SPObject *obj = sp_desktop_document(desktop)->getObjectByRepr(knotholder_listener_attached_for); /// note that it is not certain that this is an SPItem; it could be a LivePathEffectObject. + SPObject *obj = desktop->getDocument()->getObjectByRepr(knotholder_listener_attached_for); /// note that it is not certain that this is an SPItem; it could be a LivePathEffectObject. set_item(SP_ITEM(obj), keep_knotholder); } } diff --git a/src/ui/tool-factory.cpp b/src/ui/tool-factory.cpp new file mode 100644 index 000000000..700bd40ce --- /dev/null +++ b/src/ui/tool-factory.cpp @@ -0,0 +1,102 @@ +/* + * Factory for ToolBase tree + * + * Authors: + * Markus Engel + * + * Copyright (C) 2013 Authors + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "tool-factory.h" + +#include "ui/tools/arc-tool.h" +#include "ui/tools/box3d-tool.h" +#include "ui/tools/calligraphic-tool.h" +#include "ui/tools/connector-tool.h" +#include "ui/tools/dropper-tool.h" +#include "ui/tools/eraser-tool.h" +#include "ui/tools/flood-tool.h" +#include "ui/tools/gradient-tool.h" +#include "ui/tools/lpe-tool.h" +#include "ui/tools/measure-tool.h" +#include "ui/tools/mesh-tool.h" +#include "ui/tools/node-tool.h" +#include "ui/tools/pencil-tool.h" +#include "ui/tools/pen-tool.h" +#include "ui/tools/rect-tool.h" +#include "ui/tools/select-tool.h" +#include "ui/tools/spiral-tool.h" +#include "ui/tools/spray-tool.h" +#include "ui/tools/star-tool.h" +#include "ui/tools/text-tool.h" +#include "ui/tools/tool-base.h" +#include "ui/tools/tweak-tool.h" +#include "ui/tools/zoom-tool.h" + +using namespace Inkscape::UI::Tools; + +ToolBase *ToolFactory::createObject(std::string const& id) +{ + ToolBase *tool = NULL; + + if (id == "/tools/shapes/arc") + tool = new ArcTool; + else if (id == "/tools/shapes/3dbox") + tool = new Box3dTool; + else if (id == "/tools/calligraphic") + tool = new CalligraphicTool; + else if (id == "/tools/connector") + tool = new ConnectorTool; + else if (id == "/tools/dropper") + tool = new DropperTool; + else if (id == "/tools/eraser") + tool = new EraserTool; + else if (id == "/tools/paintbucket") + tool = new FloodTool; + else if (id == "/tools/gradient") + tool = new GradientTool; + else if (id == "/tools/lpetool") + tool = new LpeTool; + else if (id == "/tools/measure") + tool = new MeasureTool; + else if (id == "/tools/mesh") + tool = new MeshTool; + else if (id == "/tools/nodes") + tool = new NodeTool; + else if (id == "/tools/freehand/pencil") + tool = new PencilTool; + else if (id == "/tools/freehand/pen") + tool = new PenTool; + else if (id == "/tools/shapes/rect") + tool = new RectTool; + else if (id == "/tools/select") + tool = new SelectTool; + else if (id == "/tools/shapes/spiral") + tool = new SpiralTool; + else if (id == "/tools/spray") + tool = new SprayTool; + else if (id == "/tools/shapes/star") + tool = new StarTool; + else if (id == "/tools/text") + tool = new TextTool; + else if (id == "/tools/tweak") + tool = new TweakTool; + else if (id == "/tools/zoom") + tool = new ZoomTool; + else + fprintf(stderr, "WARNING: unknown tool: %s", id.c_str()); + + return tool; +} + +/* + 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/tool-factory.h b/src/ui/tool-factory.h index 726706732..3b041fec5 100644 --- a/src/ui/tool-factory.h +++ b/src/ui/tool-factory.h @@ -1,6 +1,6 @@ -/** @file +/* * Factory for ToolBase tree - *//* + * * Authors: * Markus Engel * @@ -11,7 +11,7 @@ #ifndef TOOL_FACTORY_SEEN #define TOOL_FACTORY_SEEN -#include "factory.h" +#include <string> namespace Inkscape { namespace UI { @@ -23,7 +23,9 @@ class ToolBase; } } -typedef Singleton< Factory<Inkscape::UI::Tools::ToolBase> > ToolFactory; +struct ToolFactory { + static Inkscape::UI::Tools::ToolBase *createObject(std::string const& id); +}; #endif diff --git a/src/ui/tool/control-point.cpp b/src/ui/tool/control-point.cpp index e98c7b2a2..bcf5c9fce 100644 --- a/src/ui/tool/control-point.cpp +++ b/src/ui/tool/control-point.cpp @@ -11,7 +11,7 @@ #include <gdkmm.h> #include <2geom/point.h> #include "desktop.h" -#include "desktop-handles.h" + #include "display/sp-canvas.h" #include "display/snap-indicator.h" #include "ui/tools/tool-base.h" @@ -74,7 +74,7 @@ ControlPoint::ControlPoint(SPDesktop *d, Geom::Point const &initial_pos, SPAncho _lurking(false) { _canvas_item = sp_canvas_item_new( - group ? group : sp_desktop_controls(_desktop), SP_TYPE_CTRL, + group ? group : _desktop->getControls(), SP_TYPE_CTRL, "anchor", (SPAnchorType) anchor, "size", (gdouble) pixbuf->get_width(), "shape", SP_CTRL_SHAPE_BITMAP, "pixbuf", pixbuf->gobj(), "filled", TRUE, "fill_color", _cset.normal.fill, @@ -93,7 +93,7 @@ ControlPoint::ControlPoint(SPDesktop *d, Geom::Point const &initial_pos, SPAncho _position(initial_pos), _lurking(false) { - _canvas_item = ControlManager::getManager().createControl(group ? group : sp_desktop_controls(_desktop), type); + _canvas_item = ControlManager::getManager().createControl(group ? group : _desktop->getControls(), type); g_object_set(_canvas_item, "anchor", anchor, "filled", TRUE, "fill_color", _cset.normal.fill, diff --git a/src/ui/tool/curve-drag-point.cpp b/src/ui/tool/curve-drag-point.cpp index 013553410..49c949107 100644 --- a/src/ui/tool/curve-drag-point.cpp +++ b/src/ui/tool/curve-drag-point.cpp @@ -94,8 +94,22 @@ void CurveDragPoint::dragged(Geom::Point &new_pos, GdkEventMotion *event) if(!_pm.isBSpline(false)){ first->front()->move(first->front()->position() + offset0); second->back()->move(second->back()->position() + offset1); - }else if(weight>=0.8 && held_shift(*event))second->back()->move(new_pos); - else if(weight<=0.2 && held_shift(*event))first->front()->move(new_pos); + }else if(weight>=0.8){ + if(held_shift(*event)){ + second->back()->move(new_pos); + } else { + second->move(second->position() + delta); + } + }else if(weight<=0.2){ + if(held_shift(*event)){ + first->back()->move(new_pos); + } else { + first->move(first->position() + delta); + } + }else{ + first->move(first->position() + delta); + second->move(second->position() + delta); + } _pm.update(); } diff --git a/src/ui/tool/multi-path-manipulator.cpp b/src/ui/tool/multi-path-manipulator.cpp index d7b35c974..f53cef5f4 100644 --- a/src/ui/tool/multi-path-manipulator.cpp +++ b/src/ui/tool/multi-path-manipulator.cpp @@ -14,7 +14,7 @@ #include "node.h" #include <glibmm/i18n.h> #include "desktop.h" -#include "desktop-handles.h" + #include "document.h" #include "document-undo.h" #include "live_effects/lpeobject.h" @@ -820,9 +820,9 @@ void MultiPathManipulator::_commit(CommitEvent cps) _selection.signal_update.emit(); invokeForAll(&PathManipulator::writeXML); if (key) { - DocumentUndo::maybeDone(sp_desktop_document(_desktop), key, SP_VERB_CONTEXT_NODE, reason); + DocumentUndo::maybeDone(_desktop->getDocument(), key, SP_VERB_CONTEXT_NODE, reason); } else { - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_NODE, reason); + DocumentUndo::done(_desktop->getDocument(), SP_VERB_CONTEXT_NODE, reason); } signal_coords_changed.emit(); } @@ -831,7 +831,7 @@ void MultiPathManipulator::_commit(CommitEvent cps) void MultiPathManipulator::_done(gchar const *reason, bool alert_LPE) { invokeForAll(&PathManipulator::update, alert_LPE); invokeForAll(&PathManipulator::writeXML); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_NODE, reason); + DocumentUndo::done(_desktop->getDocument(), SP_VERB_CONTEXT_NODE, reason); signal_coords_changed.emit(); } diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 8c22f7c6e..eeea47e4d 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -17,7 +17,7 @@ #include "display/sp-canvas.h" #include "display/sp-canvas-util.h" #include "desktop.h" -#include "desktop-handles.h" + #include "preferences.h" #include "snap.h" #include "snap-preferences.h" diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 8b99c33b8..c8b986824 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -23,7 +23,7 @@ #include <glibmm/i18n.h> #include "ui/tool/path-manipulator.h" #include "desktop.h" -#include "desktop-handles.h" + #include "display/sp-canvas.h" #include "display/sp-canvas-util.h" #include "display/curve.h" @@ -972,6 +972,10 @@ NodeList::iterator PathManipulator::subdivideSegment(NodeList::iterator first, d NodeList &list = NodeList::get(first); NodeList::iterator second = first.next(); if (!second) throw std::invalid_argument("Subdivide after last node in open path"); + if (first->type() == NODE_SYMMETRIC) + first->setType(NODE_SMOOTH, false); + if (second->type() == NODE_SYMMETRIC) + second->setType(NODE_SMOOTH, false); // We need to insert the segment after 'first'. We can't simply use 'second' // as the point of insertion, because when 'first' is the last node of closed path, @@ -1617,13 +1621,13 @@ void PathManipulator::_removeNodesFromSelection() void PathManipulator::_commit(Glib::ustring const &annotation) { writeXML(); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_NODE, annotation.data()); + DocumentUndo::done(_desktop->getDocument(), SP_VERB_CONTEXT_NODE, annotation.data()); } void PathManipulator::_commit(Glib::ustring const &annotation, gchar const *key) { writeXML(); - DocumentUndo::maybeDone(sp_desktop_document(_desktop), key, SP_VERB_CONTEXT_NODE, + DocumentUndo::maybeDone(_desktop->getDocument(), key, SP_VERB_CONTEXT_NODE, annotation.data()); } diff --git a/src/ui/tool/selector.cpp b/src/ui/tool/selector.cpp index bdeacadc9..e4e701785 100644 --- a/src/ui/tool/selector.cpp +++ b/src/ui/tool/selector.cpp @@ -11,7 +11,7 @@ #include "control-point.h" #include "desktop.h" -#include "desktop-handles.h" + #include "display/sodipodi-ctrlrect.h" #include "ui/tools/tool-base.h" #include "preferences.h" @@ -37,7 +37,7 @@ public: _cancel(false) { setVisible(false); - _rubber = static_cast<CtrlRect*>(sp_canvas_item_new(sp_desktop_controls(_desktop), + _rubber = static_cast<CtrlRect*>(sp_canvas_item_new(_desktop->getControls(), SP_TYPE_CTRLRECT, NULL)); sp_canvas_item_hide(_rubber); } @@ -100,7 +100,7 @@ private: Selector::Selector(SPDesktop *d) : Manipulator(d) - , _dragger(new SelectorPoint(d, sp_desktop_controls(d), this)) + , _dragger(new SelectorPoint(d, d->getControls(), this)) { _dragger->setVisible(false); } diff --git a/src/ui/tool/transform-handle-set.cpp b/src/ui/tool/transform-handle-set.cpp index 7d5c9bf0c..da2a54989 100644 --- a/src/ui/tool/transform-handle-set.cpp +++ b/src/ui/tool/transform-handle-set.cpp @@ -15,7 +15,7 @@ #include <glib/gi18n.h> #include <2geom/transforms.h> #include "desktop.h" -#include "desktop-handles.h" + #include "display/sodipodi-ctrlrect.h" #include "preferences.h" #include "snap.h" @@ -686,7 +686,7 @@ TransformHandleSet::TransformHandleSet(SPDesktop *d, SPCanvasGroup *th_group) , _in_transform(false) , _visible(true) { - _trans_outline = static_cast<CtrlRect*>(sp_canvas_item_new(sp_desktop_controls(_desktop), + _trans_outline = static_cast<CtrlRect*>(sp_canvas_item_new(_desktop->getControls(), SP_TYPE_CTRLRECT, NULL)); sp_canvas_item_hide(_trans_outline); _trans_outline->setDashed(true); diff --git a/src/ui/tools-switch.cpp b/src/ui/tools-switch.cpp index 47b9d2832..11313f550 100644 --- a/src/ui/tools-switch.cpp +++ b/src/ui/tools-switch.cpp @@ -16,9 +16,9 @@ #include <cstring> #include <string> -#include "inkscape-private.h" +#include "inkscape.h" #include "desktop.h" -#include "desktop-handles.h" + #include <glibmm/i18n.h> #include <xml/repr.h> @@ -159,7 +159,7 @@ tools_switch(SPDesktop *dt, int num) /* fixme: This is really ugly hack. We should bind and unbind class methods */ /* First 4 tools use guides, first is undefined but we don't care */ dt->activate_guides(num < 5); - inkscape_eventcontext_set(dt->getEventContext()); + INKSCAPE.eventcontext_set(dt->getEventContext()); } void tools_switch_by_item(SPDesktop *dt, SPItem *item, Geom::Point const p) diff --git a/src/ui/tools/arc-tool.cpp b/src/ui/tools/arc-tool.cpp index 9c3195a42..c6a9bb23a 100644 --- a/src/ui/tools/arc-tool.cpp +++ b/src/ui/tools/arc-tool.cpp @@ -29,7 +29,7 @@ #include "document-undo.h" #include "sp-namedview.h" #include "selection.h" -#include "desktop-handles.h" + #include "snap.h" #include "pixmaps/cursor-ellipse.xpm" #include "xml/repr.h" @@ -48,20 +48,10 @@ using Inkscape::DocumentUndo; -#include "ui/tool-factory.h" - namespace Inkscape { namespace UI { namespace Tools { -namespace { - ToolBase* createArcContext() { - return new ArcTool(); - } - - bool arcContextRegistered = ToolFactory::instance().registerObject("/tools/shapes/arc", createArcContext); -} - const std::string& ArcTool::getPrefsPath() { return ArcTool::prefsPath; } @@ -109,11 +99,11 @@ void ArcTool::selection_changed(Inkscape::Selection* selection) { void ArcTool::setup() { ToolBase::setup(); - Inkscape::Selection *selection = sp_desktop_selection(this->desktop); + Inkscape::Selection *selection = this->desktop->getSelection(); this->shape_editor = new ShapeEditor(this->desktop); - SPItem *item = sp_desktop_selection(this->desktop)->singleItem(); + SPItem *item = this->desktop->getSelection()->singleItem(); if (item) { this->shape_editor->set_item(item); } @@ -151,7 +141,7 @@ bool ArcTool::item_handler(SPItem* item, GdkEvent* event) { bool ArcTool::root_handler(GdkEvent* event) { static bool dragging; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); this->tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100); @@ -442,16 +432,16 @@ void ArcTool::finishItem() { desktop->canvas->endForcedFullRedraws(); - sp_desktop_selection(desktop)->set(this->arc); + desktop->getSelection()->set(this->arc); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_ARC, _("Create ellipse")); + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_ARC, _("Create ellipse")); this->arc = NULL; } } void ArcTool::cancel() { - sp_desktop_selection(desktop)->clear(); + desktop->getSelection()->clear(); sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), 0); if (this->arc != NULL) { @@ -466,7 +456,7 @@ void ArcTool::cancel() { desktop->canvas->endForcedFullRedraws(); - DocumentUndo::cancel(sp_desktop_document(desktop)); + DocumentUndo::cancel(desktop->getDocument()); } } diff --git a/src/ui/tools/box3d-tool.cpp b/src/ui/tools/box3d-tool.cpp index 0a20a0842..538e0c7e2 100644 --- a/src/ui/tools/box3d-tool.cpp +++ b/src/ui/tools/box3d-tool.cpp @@ -26,7 +26,7 @@ #include "sp-namedview.h" #include "selection.h" #include "selection-chemistry.h" -#include "desktop-handles.h" + #include "snap.h" #include "display/curve.h" #include "display/sp-canvas-item.h" @@ -52,20 +52,10 @@ using Inkscape::DocumentUndo; -#include "ui/tool-factory.h" - namespace Inkscape { namespace UI { namespace Tools { -namespace { - ToolBase* createBox3dTool() { - return new Box3dTool(); - } - - bool Box3dToolRegistered = ToolFactory::instance().registerObject("/tools/shapes/3dbox", createBox3dTool); -} - const std::string& Box3dTool::getPrefsPath() { return Box3dTool::prefsPath; } @@ -145,17 +135,17 @@ void Box3dTool::setup() { this->shape_editor = new ShapeEditor(this->desktop); - SPItem *item = sp_desktop_selection(this->desktop)->singleItem(); + SPItem *item = this->desktop->getSelection()->singleItem(); if (item) { this->shape_editor->set_item(item); } this->sel_changed_connection.disconnect(); - this->sel_changed_connection = sp_desktop_selection(this->desktop)->connectChanged( + this->sel_changed_connection = this->desktop->getSelection()->connectChanged( sigc::mem_fun(this, &Box3dTool::selection_changed) ); - this->_vpdrag = new Box3D::VPDrag(sp_desktop_document(this->desktop)); + this->_vpdrag = new Box3D::VPDrag(this->desktop->getDocument()); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -195,8 +185,8 @@ bool Box3dTool::item_handler(SPItem* item, GdkEvent* event) { bool Box3dTool::root_handler(GdkEvent* event) { static bool dragging; - SPDocument *document = sp_desktop_document (desktop); - Inkscape::Selection *selection = sp_desktop_selection (desktop); + SPDocument *document = desktop->getDocument(); + Inkscape::Selection *selection = desktop->getSelection(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); int const snaps = prefs->getInt("/options/rotationsnapsperpi/value", 12); @@ -466,7 +456,7 @@ bool Box3dTool::root_handler(GdkEvent* event) { break; case GDK_KEY_Escape: - sp_desktop_selection(desktop)->clear(); + desktop->getSelection()->clear(); //TODO: make dragging escapable by Esc break; @@ -589,7 +579,7 @@ void Box3dTool::finishItem() { this->extruded = false; if (this->box3d != NULL) { - SPDocument *doc = sp_desktop_document(this->desktop); + SPDocument *doc = this->desktop->getDocument(); if (!doc || !doc->getCurrentPersp3D()) { return; @@ -604,8 +594,8 @@ void Box3dTool::finishItem() { desktop->canvas->endForcedFullRedraws(); - sp_desktop_selection(desktop)->set(this->box3d); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_3DBOX, + desktop->getSelection()->set(this->box3d); + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_3DBOX, _("Create 3D box")); this->box3d = NULL; diff --git a/src/ui/tools/calligraphic-tool.cpp b/src/ui/tools/calligraphic-tool.cpp index d297fe5e1..15e6527a3 100644 --- a/src/ui/tools/calligraphic-tool.cpp +++ b/src/ui/tools/calligraphic-tool.cpp @@ -47,7 +47,7 @@ #include "selection.h" #include "desktop.h" #include "desktop-events.h" -#include "desktop-handles.h" + #include "desktop-style.h" #include "message-context.h" #include "preferences.h" @@ -82,22 +82,12 @@ using Inkscape::DocumentUndo; #define DYNA_MIN_WIDTH 1.0e-6 -#include "ui/tool-factory.h" - namespace Inkscape { namespace UI { namespace Tools { static void add_cap(SPCurve *curve, Geom::Point const &from, Geom::Point const &to, double rounding); -namespace { - ToolBase* createCalligraphicContext() { - return new CalligraphicTool(); - } - - bool calligraphicContextRegistered = ToolFactory::instance().registerObject("/tools/calligraphic", createCalligraphicContext); -} - const std::string& CalligraphicTool::getPrefsPath() { return CalligraphicTool::prefsPath; } @@ -141,7 +131,7 @@ void CalligraphicTool::setup() { this->cal1 = new SPCurve(); this->cal2 = new SPCurve(); - this->currentshape = sp_canvas_item_new(sp_desktop_sketch(this->desktop), SP_TYPE_CANVAS_BPATH, NULL); + this->currentshape = sp_canvas_item_new(this->desktop->getSketch(), SP_TYPE_CANVAS_BPATH, NULL); sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(this->currentshape), DDC_RED_RGBA, SP_WIND_RULE_EVENODD); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(this->currentshape), 0x00000000, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); @@ -155,7 +145,7 @@ void CalligraphicTool::setup() { SPCurve *c = new SPCurve(path); - this->hatch_area = sp_canvas_bpath_new(sp_desktop_controls(this->desktop), c); + this->hatch_area = sp_canvas_bpath_new(this->desktop->getControls(), c); c->unref(); @@ -373,7 +363,7 @@ void CalligraphicTool::brush() { double R, G, B, A; Geom::IntRect area = Geom::IntRect::from_xywh(brush_w.floor(), Geom::IntPoint(1, 1)); cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1); - sp_canvas_arena_render_surface(SP_CANVAS_ARENA(sp_desktop_drawing(SP_EVENT_CONTEXT(this)->desktop)), s, area); + sp_canvas_arena_render_surface(SP_CANVAS_ARENA(this->desktop->getDrawing()), s, area); ink_cairo_surface_average_color_premul(s, R, G, B, A); cairo_surface_destroy(s); double max = MAX (MAX (R, G), B); @@ -506,7 +496,7 @@ bool CalligraphicTool::root_handler(GdkEvent* event) { if (event->motion.state & GDK_CONTROL_MASK) { // hatching - sense the item - SPItem *selected = sp_desktop_selection(desktop)->singleItem(); + SPItem *selected = desktop->getSelection()->singleItem(); if (selected && (SP_IS_SHAPE(selected) || SP_IS_TEXT(selected))) { // One item selected, and it's a path; // let's try to track it as a guide @@ -940,14 +930,14 @@ void CalligraphicTool::set_to_accumulated(bool unionize, bool subtract) { g_free(str); if (unionize) { - sp_desktop_selection(desktop)->add(this->repr); - sp_selected_path_union_skip_undo(sp_desktop_selection(desktop), desktop); + desktop->getSelection()->add(this->repr); + sp_selected_path_union_skip_undo(desktop->getSelection(), desktop); } else if (subtract) { - sp_desktop_selection(desktop)->add(this->repr); - sp_selected_path_diff_skip_undo(sp_desktop_selection(desktop), desktop); + desktop->getSelection()->add(this->repr); + sp_selected_path_diff_skip_undo(desktop->getSelection(), desktop); } else { if (this->keep_selected) { - sp_desktop_selection(desktop)->set(this->repr); + desktop->getSelection()->set(this->repr); } } @@ -973,7 +963,7 @@ void CalligraphicTool::set_to_accumulated(bool unionize, bool subtract) { this->repr = NULL; } - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_CALLIGRAPHIC, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_CALLIGRAPHIC, _("Draw calligraphic stroke")); } @@ -1142,7 +1132,7 @@ void CalligraphicTool::fit_and_split(bool release) { if (!release) { g_assert(!this->currentcurve->is_empty()); - SPCanvasItem *cbp = sp_canvas_item_new(sp_desktop_sketch(desktop), + SPCanvasItem *cbp = sp_canvas_item_new(desktop->getSketch(), SP_TYPE_CANVAS_BPATH, NULL); SPCurve *curve = this->currentcurve->copy(); diff --git a/src/ui/tools/connector-tool.cpp b/src/ui/tools/connector-tool.cpp index 7b5c84c16..d76b0d142 100644 --- a/src/ui/tools/connector-tool.cpp +++ b/src/ui/tools/connector-tool.cpp @@ -79,7 +79,7 @@ #include "svg/svg.h" #include "desktop.h" #include "desktop-style.h" -#include "desktop-handles.h" + #include "document.h" #include "document-undo.h" #include "message-context.h" @@ -109,8 +109,6 @@ using Inkscape::DocumentUndo; -#include "ui/tool-factory.h" - namespace Inkscape { namespace UI { namespace Tools { @@ -147,14 +145,6 @@ static Inkscape::XML::NodeEventVector layer_repr_events = { NULL /* order_changed */ }; -namespace { - ToolBase* createConnectorContext() { - return new ConnectorTool(); - } - - bool connectorContextRegistered = ToolFactory::instance().registerObject("/tools/connector", createConnectorContext); -} - const std::string& ConnectorTool::getPrefsPath() { return ConnectorTool::prefsPath; } @@ -223,7 +213,7 @@ ConnectorTool::~ConnectorTool() { void ConnectorTool::setup() { ToolBase::setup(); - this->selection = sp_desktop_selection(this->desktop); + this->selection = this->desktop->getSelection(); this->sel_changed_connection.disconnect(); this->sel_changed_connection = this->selection->connectChanged( @@ -231,7 +221,7 @@ void ConnectorTool::setup() { ); /* Create red bpath */ - this->red_bpath = sp_canvas_bpath_new(sp_desktop_sketch(this->desktop), NULL); + this->red_bpath = sp_canvas_bpath_new(this->desktop->getSketch(), NULL); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(this->red_bpath), this->red_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(this->red_bpath), 0x00000000, @@ -659,7 +649,7 @@ bool ConnectorTool::_handleButtonRelease(GdkEventButton const &revent) { bool ret = false; if ( revent.button == 1 && !this->space_panning ) { - SPDocument *doc = sp_desktop_document(desktop); + SPDocument *doc = desktop->getDocument(); SnapManager &m = desktop->namedview->snap_manager; Geom::Point const event_w(revent.x, revent.y); @@ -729,7 +719,7 @@ bool ConnectorTool::_handleKeyPress(guint const keyval) { break; case GDK_KEY_Escape: if (this->state == SP_CONNECTOR_CONTEXT_REROUTING) { - SPDocument *doc = sp_desktop_document(desktop); + SPDocument *doc = desktop->getDocument(); this->_reroutingFinish(NULL); @@ -754,7 +744,7 @@ bool ConnectorTool::_handleKeyPress(guint const keyval) { } void ConnectorTool::_reroutingFinish(Geom::Point *const p) { - SPDocument *doc = sp_desktop_document(desktop); + SPDocument *doc = desktop->getDocument(); // Clear the temporary path: this->red_curve->reset(); @@ -812,7 +802,7 @@ void ConnectorTool::_setSubsequentPoint(Geom::Point const p) { Avoid::Point dst(d[Geom::X], d[Geom::Y]); if (!this->newConnRef) { - Avoid::Router *router = sp_desktop_document(desktop)->router; + Avoid::Router *router = desktop->getDocument()->router; this->newConnRef = new Avoid::ConnRef(router); this->newConnRef->setEndpoint(Avoid::VertID::src, src); if (this->isOrthogonal) @@ -876,7 +866,7 @@ void ConnectorTool::_flushWhite(SPCurve *gc) { /* Now we have to go back to item coordinates at last */ c->transform(this->desktop->dt2doc()); - SPDocument *doc = sp_desktop_document(desktop); + SPDocument *doc = desktop->getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); if ( c && !c->is_empty() ) { @@ -1304,14 +1294,14 @@ bool cc_item_is_connector(SPItem *item) void cc_selection_set_avoid(bool const set_avoid) { - SPDesktop *desktop = inkscape_active_desktop(); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (desktop == NULL) { return; } - SPDocument *document = sp_desktop_document(desktop); + SPDocument *document = desktop->getDocument(); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); GSList *l = const_cast<GSList *>(selection->itemList()); diff --git a/src/ui/tools/dropper-tool.cpp b/src/ui/tools/dropper-tool.cpp index 6c55f7484..bda9d8e8a 100644 --- a/src/ui/tools/dropper-tool.cpp +++ b/src/ui/tools/dropper-tool.cpp @@ -34,7 +34,7 @@ #include "sp-namedview.h" #include "sp-cursor.h" #include "desktop.h" -#include "desktop-handles.h" + #include "selection.h" #include "document.h" #include "document-undo.h" @@ -52,20 +52,10 @@ using Inkscape::DocumentUndo; static GdkCursor *cursor_dropper_fill = NULL; static GdkCursor *cursor_dropper_stroke = NULL; -#include "ui/tool-factory.h" - namespace Inkscape { namespace UI { namespace Tools { -namespace { - ToolBase* createDropperContext() { - return new DropperTool(); - } - - bool dropperContextRegistered = ToolFactory::instance().registerObject("/tools/dropper", createDropperContext); -} - const std::string& DropperTool::getPrefsPath() { return DropperTool::prefsPath; } @@ -73,7 +63,7 @@ const std::string& DropperTool::getPrefsPath() { const std::string DropperTool::prefsPath = "/tools/dropper"; DropperTool::DropperTool() - : ToolBase(cursor_dropper_f_xpm, 7, 7) + : ToolBase(cursor_dropper_f_xpm, 5, 5) , R(0) , G(0) , B(0) @@ -83,8 +73,8 @@ DropperTool::DropperTool() , area(NULL) , centre(0, 0) { - cursor_dropper_fill = sp_cursor_new_from_xpm(cursor_dropper_f_xpm , 7, 7); - cursor_dropper_stroke = sp_cursor_new_from_xpm(cursor_dropper_s_xpm , 7, 7); + cursor_dropper_fill = sp_cursor_new_from_xpm(cursor_dropper_f_xpm , 5, 5); + cursor_dropper_stroke = sp_cursor_new_from_xpm(cursor_dropper_s_xpm , 5, 5); } DropperTool::~DropperTool() { @@ -99,7 +89,7 @@ void DropperTool::setup() { SPCurve *c = new SPCurve(path); - this->area = sp_canvas_bpath_new(sp_desktop_controls(this->desktop), c); + this->area = sp_canvas_bpath_new(this->desktop->getControls(), c); c->unref(); @@ -200,7 +190,7 @@ bool DropperTool::root_handler(GdkEvent* event) { // If one time pick with stroke set the pixmap if (prefs->getBool("/tools/dropper/onetimepick", false) && prefs->getInt("/dialogs/fillstroke/page", 0) == 1) { //TODO Only set when not set already - GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(sp_desktop_canvas(desktop))); + GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(desktop->getCanvas())); gdk_window_set_cursor(window, cursor_dropper_stroke); } @@ -230,7 +220,7 @@ bool DropperTool::root_handler(GdkEvent* event) { if (!r.hasZeroArea()) { Geom::IntRect area = r.roundOutwards(); cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, area.width(), area.height()); - sp_canvas_arena_render_surface(SP_CANVAS_ARENA(sp_desktop_drawing(desktop)), s, area); + sp_canvas_arena_render_surface(SP_CANVAS_ARENA(desktop->getDrawing()), s, area); ink_cairo_surface_average_color_premul(s, R, G, B, A); cairo_surface_destroy(s); } @@ -238,14 +228,14 @@ bool DropperTool::root_handler(GdkEvent* event) { // pick single pixel Geom::IntRect area = Geom::IntRect::from_xywh(floor(event->button.x), floor(event->button.y), 1, 1); cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1); - sp_canvas_arena_render_surface(SP_CANVAS_ARENA(sp_desktop_drawing(desktop)), s, area); + sp_canvas_arena_render_surface(SP_CANVAS_ARENA(desktop->getDrawing()), s, area); ink_cairo_surface_average_color_premul(s, R, G, B, A); cairo_surface_destroy(s); } if (pick == SP_DROPPER_PICK_VISIBLE) { // compose with page color - guint32 bg = sp_desktop_namedview(desktop)->pagecolor; + guint32 bg = desktop->getNamedView()->pagecolor; R = R + (SP_RGBA32_R_F(bg)) * (1 - A); G = G + (SP_RGBA32_G_F(bg)) * (1 - A); B = B + (SP_RGBA32_B_F(bg)) * (1 - A); @@ -324,12 +314,12 @@ bool DropperTool::root_handler(GdkEvent* event) { // REJON: set aux. toolbar input to hex color! if (event->button.state & GDK_SHIFT_MASK) { - GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(sp_desktop_canvas(desktop))); + GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(desktop->getCanvas())); gdk_window_set_cursor(window, cursor_dropper_stroke); } - if (!(sp_desktop_selection(desktop)->isEmpty())) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_DROPPER, + if (!(desktop->getSelection()->isEmpty())) { + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_DROPPER, _("Set picked color")); } @@ -359,11 +349,11 @@ bool DropperTool::root_handler(GdkEvent* event) { break; case GDK_KEY_Escape: - sp_desktop_selection(desktop)->clear(); + desktop->getSelection()->clear(); case GDK_KEY_Shift_L: case GDK_KEY_Shift_R: if (!desktop->isWaitingCursor() && !prefs->getBool("/tools/dropper/onetimepick", false)) { - GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(sp_desktop_canvas(desktop))); + GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(desktop->getCanvas())); gdk_window_set_cursor(window, cursor_dropper_stroke); } @@ -378,7 +368,7 @@ bool DropperTool::root_handler(GdkEvent* event) { case GDK_KEY_Shift_L: case GDK_KEY_Shift_R: if (!desktop->isWaitingCursor() && !prefs->getBool("/tools/dropper/onetimepick", false)) { - GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(sp_desktop_canvas(desktop))); + GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(desktop->getCanvas())); gdk_window_set_cursor(window, cursor_dropper_fill); } break; diff --git a/src/ui/tools/eraser-tool.cpp b/src/ui/tools/eraser-tool.cpp index bf4015b4c..af0cbcb78 100644 --- a/src/ui/tools/eraser-tool.cpp +++ b/src/ui/tools/eraser-tool.cpp @@ -44,7 +44,7 @@ #include "selection.h" #include "desktop.h" #include "desktop-events.h" -#include "desktop-handles.h" + #include "desktop-style.h" #include "message-context.h" #include "preferences.h" @@ -84,20 +84,10 @@ using Inkscape::DocumentUndo; #define DRAG_DEFAULT 1.0 #define DRAG_MAX 1.0 -#include "ui/tool-factory.h" - namespace Inkscape { namespace UI { namespace Tools { -namespace { - ToolBase* createEraserContext() { - return new EraserTool(); - } - - bool eraserContextRegistered = ToolFactory::instance().registerObject("/tools/eraser", createEraserContext); -} - const std::string& EraserTool::getPrefsPath() { return EraserTool::prefsPath; } @@ -121,7 +111,7 @@ void EraserTool::setup() { this->cal1 = new SPCurve(); this->cal2 = new SPCurve(); - this->currentshape = sp_canvas_item_new(sp_desktop_sketch(desktop), SP_TYPE_CANVAS_BPATH, NULL); + this->currentshape = sp_canvas_item_new(desktop->getSketch(), SP_TYPE_CANVAS_BPATH, NULL); sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(this->currentshape), ERC_RED_RGBA, SP_WIND_RULE_EVENODD); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(this->currentshape), 0x00000000, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); @@ -666,7 +656,7 @@ void EraserTool::set_to_accumulated() { if ( this->repr ) { bool wasSelection = false; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gint eraserMode = prefs->getBool("/tools/eraser/mode") ? 1 : 0; @@ -680,10 +670,10 @@ void EraserTool::set_to_accumulated() { if (selection->isEmpty()) { if ( eraserMode ) { - toWorkOn = sp_desktop_document(desktop)->getItemsPartiallyInBox(desktop->dkey, bounds); + toWorkOn = desktop->getDocument()->getItemsPartiallyInBox(desktop->dkey, bounds); } else { Inkscape::Rubberband *r = Inkscape::Rubberband::get(desktop); - toWorkOn = sp_desktop_document(desktop)->getItemsAtPoints(desktop->dkey, r->getPoints()); + toWorkOn = desktop->getDocument()->getItemsAtPoints(desktop->dkey, r->getPoints()); } toWorkOn = g_slist_remove( toWorkOn, acid ); @@ -767,9 +757,9 @@ void EraserTool::set_to_accumulated() { if ( workDone ) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_ERASER, _("Draw eraser stroke")); + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_ERASER, _("Draw eraser stroke")); } else { - DocumentUndo::cancel(sp_desktop_document(desktop)); + DocumentUndo::cancel(desktop->getDocument()); } } @@ -949,7 +939,7 @@ void EraserTool::fit_and_split(bool release) { gint eraserMode = prefs->getBool("/tools/eraser/mode") ? 1 : 0; g_assert(!this->currentcurve->is_empty()); - SPCanvasItem *cbp = sp_canvas_item_new(sp_desktop_sketch(desktop), SP_TYPE_CANVAS_BPATH, NULL); + SPCanvasItem *cbp = sp_canvas_item_new(desktop->getSketch(), SP_TYPE_CANVAS_BPATH, NULL); SPCurve *curve = this->currentcurve->copy(); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH (cbp), curve); curve->unref(); diff --git a/src/ui/tools/flood-tool.cpp b/src/ui/tools/flood-tool.cpp index 5745fc9cc..bb8782dfa 100644 --- a/src/ui/tools/flood-tool.cpp +++ b/src/ui/tools/flood-tool.cpp @@ -31,7 +31,7 @@ #include "color.h" #include "context-fns.h" #include "desktop.h" -#include "desktop-handles.h" + #include "desktop-style.h" #include "display/cairo-utils.h" #include "display/drawing-context.h" @@ -74,20 +74,10 @@ using Inkscape::Display::ExtractARGB32; using Inkscape::Display::ExtractRGB32; using Inkscape::Display::AssembleARGB32; -#include "ui/tool-factory.h" - namespace Inkscape { namespace UI { namespace Tools { -namespace { - ToolBase* createPaintbucketContext() { - return new FloodTool(); - } - - bool paintbucketContextRegistered = ToolFactory::instance().registerObject("/tools/paintbucket", createPaintbucketContext); -} - const std::string& FloodTool::getPrefsPath() { return FloodTool::prefsPath; } @@ -128,13 +118,13 @@ void FloodTool::setup() { this->shape_editor = new ShapeEditor(this->desktop); - SPItem *item = sp_desktop_selection(this->desktop)->singleItem(); + SPItem *item = this->desktop->getSelection()->singleItem(); if (item) { this->shape_editor->set_item(item); } this->sel_changed_connection.disconnect(); - this->sel_changed_connection = sp_desktop_selection(this->desktop)->connectChanged( + this->sel_changed_connection = this->desktop->getSelection()->connectChanged( sigc::mem_fun(this, &FloodTool::selection_changed) ); @@ -360,7 +350,7 @@ inline static bool check_if_pixel_is_paintable(guchar *px, unsigned char *trace_ * @param union_with_selection If true, merge the final SVG path with the current selection. */ static void do_trace(bitmap_coords_info bci, guchar *trace_px, SPDesktop *desktop, Geom::Affine transform, unsigned int min_x, unsigned int max_x, unsigned int min_y, unsigned int max_y, bool union_with_selection) { - SPDocument *document = sp_desktop_document(desktop); + SPDocument *document = desktop->getDocument(); unsigned char *trace_t; @@ -467,7 +457,7 @@ static void do_trace(bitmap_coords_info bci, guchar *trace_px, SPDesktop *deskto g_free(affinestr); } - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); pathRepr->setPosition(-1); @@ -476,7 +466,7 @@ static void do_trace(bitmap_coords_info bci, guchar *trace_px, SPDesktop *deskto ngettext("Area filled, path with <b>%d</b> node created and unioned with selection.","Area filled, path with <b>%d</b> nodes created and unioned with selection.", SP_PATH(reprobj)->nodesInPath()), SP_PATH(reprobj)->nodesInPath() ); selection->add(reprobj); - sp_selected_path_union_skip_undo(sp_desktop_selection(desktop), desktop); + sp_selected_path_union_skip_undo(desktop->getSelection(), desktop); } else { desktop->messageStack()->flashF( Inkscape::WARNING_MESSAGE, ngettext("Area filled, path with <b>%d</b> node created.","Area filled, path with <b>%d</b> nodes created.", @@ -621,7 +611,7 @@ static ScanlineCheckResult perform_bitmap_scanline_check(std::deque<Geom::Point> bool currently_painting_top = false; bool currently_painting_bottom = false; - unsigned int top_ty = bci.y - 1; + unsigned int top_ty = (bci.y > 0) ? bci.y - 1 : 0; unsigned int bottom_ty = bci.y + 1; bool can_paint_top = (top_ty > 0); @@ -740,7 +730,7 @@ static bool sort_fill_queue_horizontal(Geom::Point a, Geom::Point b) { */ static void sp_flood_do_flood_fill(ToolBase *event_context, GdkEvent *event, bool union_with_selection, bool is_point_fill, bool is_touch_fill) { SPDesktop *desktop = event_context->desktop; - SPDocument *document = sp_desktop_document(desktop); + SPDocument *document = desktop->getDocument(); document->ensureUpToDate(); @@ -792,7 +782,7 @@ static void sp_flood_do_flood_fill(ToolBase *event_context, GdkEvent *event, boo Inkscape::DrawingContext dc(s, Geom::Point(0,0)); // cairo_translate not necessary here - surface origin is at 0,0 - SPNamedView *nv = sp_desktop_namedview(desktop); + SPNamedView *nv = desktop->getNamedView(); bgcolor = nv->pagecolor; // bgcolor is 0xrrggbbaa, we need 0xaarrggbb dtc = (bgcolor >> 8) | (bgcolor << 24); @@ -1096,9 +1086,9 @@ bool FloodTool::item_handler(SPItem* item, GdkEvent* event) { // Set style desktop->applyCurrentOrToolStyle(item, "/tools/paintbucket", false); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_PAINTBUCKET, _("Set style on object")); - - ret = TRUE; + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_PAINTBUCKET, _("Set style on object")); + // Dead assignment: Value stored to 'ret' is never read + //ret = TRUE; } break; @@ -1229,9 +1219,9 @@ void FloodTool::finishItem() { desktop->canvas->endForcedFullRedraws(); - sp_desktop_selection(desktop)->set(this->item); + desktop->getSelection()->set(this->item); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_PAINTBUCKET, _("Fill bounded area")); + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_PAINTBUCKET, _("Fill bounded area")); this->item = NULL; } diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 2ef06df61..22948c7bc 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -28,7 +28,7 @@ #include <glibmm/i18n.h> #include "display/curve.h" #include "desktop.h" -#include "desktop-handles.h" + #include "desktop-style.h" #include "document.h" #include "ui/draw-anchor.h" @@ -118,7 +118,7 @@ FreehandBase::~FreehandBase() { void FreehandBase::setup() { ToolBase::setup(); - this->selection = sp_desktop_selection(desktop); + this->selection = desktop->getSelection(); // Connect signals to track selection changes this->sel_changed_connection = this->selection->connectChanged( @@ -129,14 +129,14 @@ void FreehandBase::setup() { ); // Create red bpath - this->red_bpath = sp_canvas_bpath_new(sp_desktop_sketch(this->desktop), NULL); + this->red_bpath = sp_canvas_bpath_new(this->desktop->getSketch(), NULL); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(this->red_bpath), this->red_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); // Create red curve this->red_curve = new SPCurve(); // Create blue bpath - this->blue_bpath = sp_canvas_bpath_new(sp_desktop_sketch(this->desktop), NULL); + this->blue_bpath = sp_canvas_bpath_new(this->desktop->getSketch(), NULL); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(this->blue_bpath), this->blue_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); // Create blue curve @@ -248,11 +248,9 @@ static void spdc_apply_powerstroke_shape(const std::vector<Geom::Point> & points char const *style_str = NULL; style_str = repr->attribute("style"); if (style_str) { - SPStyle *style = sp_style_new(SP_ACTIVE_DOCUMENT); - sp_style_merge_from_style_string(style, style_str); - stroke_width = style->stroke_width.computed; - style->stroke_width.computed = 0; - sp_style_unref(style); + SPStyle style(SP_ACTIVE_DOCUMENT); + style.mergeString(style_str); + stroke_width = style.stroke_width.computed; } std::ostringstream s; @@ -557,7 +555,7 @@ void spdc_endpoint_snap_free(ToolBase const * const ec, Geom::Point& p, boost::o { SPDesktop *dt = ec->desktop; SnapManager &m = dt->namedview->snap_manager; - Inkscape::Selection *selection = sp_desktop_selection (dt); + Inkscape::Selection *selection = dt->getSelection(); // selection->singleItem() is the item that is currently being drawn. This item will not be snapped to (to avoid self-snapping) // TODO: Allow snapping to the stationary parts of the item, and only ignore the last segment @@ -723,7 +721,7 @@ static void spdc_flush_white(FreehandBase *dc, SPCurve *gc) : dc->desktop->dt2doc() ); SPDesktop *desktop = dc->desktop; - SPDocument *doc = sp_desktop_document(desktop); + SPDocument *doc = desktop->getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); if ( c && !c->is_empty() ) { @@ -774,7 +772,7 @@ static void spdc_flush_white(FreehandBase *dc, SPCurve *gc) // results in the tool losing all of the selected path's curve except that last subpath. To // fix this, we force the selection_modified callback now, to make sure the tool's curve is // in sync immediately. - spdc_selection_modified(sp_desktop_selection(desktop), 0, dc); + spdc_selection_modified(desktop->getSelection(), 0, dc); } c->unref(); @@ -880,14 +878,11 @@ void spdc_create_single_dot(ToolBase *ec, Geom::Point const &pt, char const *too // find out stroke width (TODO: is there an easier way??) double stroke_width = 3.0; - gchar const *style_str = NULL; - style_str = repr->attribute("style"); + gchar const *style_str = repr->attribute("style"); if (style_str) { - SPStyle *style = sp_style_new(SP_ACTIVE_DOCUMENT); - sp_style_merge_from_style_string(style, style_str); - stroke_width = style->stroke_width.computed; - style->stroke_width.computed = 0; - sp_style_unref(style); + SPStyle style(SP_ACTIVE_DOCUMENT); + style.mergeString(style_str); + stroke_width = style.stroke_width.computed; } // unset stroke and set fill color to former stroke color @@ -921,10 +916,10 @@ void spdc_create_single_dot(ToolBase *ec, Geom::Point const &pt, char const *too sp_repr_set_svg_double (repr, "sodipodi:ry", rad * stroke_width); item->updateRepr(); - sp_desktop_selection(desktop)->set(item); + desktop->getSelection()->set(item); desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Creating single dot")); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_NONE, _("Create single dot")); + DocumentUndo::done(desktop->getDocument(), SP_VERB_NONE, _("Create single dot")); } } diff --git a/src/ui/tools/gradient-tool.cpp b/src/ui/tools/gradient-tool.cpp index 9c853917e..5be84eb76 100644 --- a/src/ui/tools/gradient-tool.cpp +++ b/src/ui/tools/gradient-tool.cpp @@ -23,7 +23,7 @@ #include "document.h" #include "selection.h" #include "desktop.h" -#include "desktop-handles.h" + #include "message-context.h" #include "message-stack.h" #include "pixmaps/cursor-gradient.xpm" @@ -51,22 +51,12 @@ using Inkscape::DocumentUndo; -#include "ui/tool-factory.h" - namespace Inkscape { namespace UI { namespace Tools { static void sp_gradient_drag(GradientTool &rc, Geom::Point const pt, guint state, guint32 etime); -namespace { - ToolBase* createGradientContext() { - return new GradientTool(); - } - - bool gradientContextRegistered = ToolFactory::instance().registerObject("/tools/gradient", createGradientContext); -} - const std::string& GradientTool::getPrefsPath() { return GradientTool::prefsPath; } @@ -112,7 +102,7 @@ void GradientTool::selection_changed(Inkscape::Selection*) { GradientTool *rc = (GradientTool *) this; GrDrag *drag = rc->_grdrag; - Inkscape::Selection *selection = sp_desktop_selection(SP_EVENT_CONTEXT(rc)->desktop); + Inkscape::Selection *selection = this->desktop->getSelection(); if (selection == NULL) { return; } @@ -167,7 +157,7 @@ void GradientTool::setup() { } this->enableGrDrag(); - Inkscape::Selection *selection = sp_desktop_selection(this->desktop); + Inkscape::Selection *selection = this->desktop->getSelection(); this->selcon = new sigc::connection(selection->connectChanged( sigc::mem_fun(this, &GradientTool::selection_changed) @@ -464,7 +454,7 @@ sp_gradient_context_add_stop_near_point (GradientTool *rc, SPItem *item, Geom:: SPStop *newstop = ec->get_drag()->addStopNearPoint (item, mouse_p, tolerance/desktop->current_zoom()); - DocumentUndo::done(sp_desktop_document (desktop), SP_VERB_CONTEXT_GRADIENT, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_GRADIENT, _("Add gradient stop")); ec->get_drag()->updateDraggers(); @@ -475,7 +465,7 @@ sp_gradient_context_add_stop_near_point (GradientTool *rc, SPItem *item, Geom:: bool GradientTool::root_handler(GdkEvent* event) { static bool dragging; - Inkscape::Selection *selection = sp_desktop_selection (desktop); + Inkscape::Selection *selection = desktop->getSelection(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); this->tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100); @@ -509,13 +499,13 @@ bool GradientTool::root_handler(GdkEvent* event) { SPGradientType new_type = (SPGradientType) prefs->getInt("/tools/gradient/newgradient", SP_GRADIENT_TYPE_LINEAR); Inkscape::PaintTarget fsmode = (prefs->getInt("/tools/gradient/newfillorstroke", 1) != 0) ? Inkscape::FOR_FILL : Inkscape::FOR_STROKE; - SPGradient *vector = sp_gradient_vector_for_object(sp_desktop_document(desktop), desktop, item, fsmode); + SPGradient *vector = sp_gradient_vector_for_object(desktop->getDocument(), desktop, item, fsmode); SPGradient *priv = sp_item_set_gradient(item, vector, new_type, fsmode); sp_gradient_reset_to_userspace(priv, item); } - DocumentUndo::done(sp_desktop_document (desktop), SP_VERB_CONTEXT_GRADIENT, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_GRADIENT, _("Create default gradient")); } ret = TRUE; @@ -892,8 +882,8 @@ bool GradientTool::root_handler(GdkEvent* event) { static void sp_gradient_drag(GradientTool &rc, Geom::Point const pt, guint /*state*/, guint32 etime) { SPDesktop *desktop = SP_EVENT_CONTEXT(&rc)->desktop; - Inkscape::Selection *selection = sp_desktop_selection(desktop); - SPDocument *document = sp_desktop_document(desktop); + Inkscape::Selection *selection = desktop->getSelection(); + SPDocument *document = desktop->getDocument(); ToolBase *ec = SP_EVENT_CONTEXT(&rc); if (!selection->isEmpty()) { @@ -957,7 +947,7 @@ static void sp_gradient_drag(GradientTool &rc, Geom::Point const pt, guint /*sta "<b>Gradient</b> for %d objects; with <b>Ctrl</b> to snap angle", n_objects), n_objects); } else { - sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select <b>objects</b> on which to create gradient.")); + desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>objects</b> on which to create gradient.")); } } diff --git a/src/ui/tools/lpe-tool.cpp b/src/ui/tools/lpe-tool.cpp index 1fd1ebf8c..c0517578d 100644 --- a/src/ui/tools/lpe-tool.cpp +++ b/src/ui/tools/lpe-tool.cpp @@ -30,7 +30,7 @@ #include "preferences.h" #include "ui/shape-editor.h" #include "selection.h" -#include "desktop-handles.h" + #include "document.h" #include "display/curve.h" #include "display/canvas-bpath.h" @@ -58,23 +58,12 @@ SubtoolEntry lpesubtools[] = { {Inkscape::LivePathEffect::MIRROR_SYMMETRY, "draw-geometry-mirror"} }; - -#include "ui/tool-factory.h" - namespace Inkscape { namespace UI { namespace Tools { void sp_lpetool_context_selection_changed(Inkscape::Selection *selection, gpointer data); -namespace { - ToolBase* createLPEToolContext() { - return new LpeTool(); - } - - bool lpetoolContextRegistered = ToolFactory::instance().registerObject("/tools/lpetool", createLPEToolContext); -} - const std::string& LpeTool::getPrefsPath() { return LpeTool::prefsPath; } @@ -110,7 +99,7 @@ LpeTool::~LpeTool() { void LpeTool::setup() { PenTool::setup(); - Inkscape::Selection *selection = sp_desktop_selection (this->desktop); + Inkscape::Selection *selection = this->desktop->getSelection(); SPItem *item = selection->singleItem(); this->sel_changed_connection.disconnect(); @@ -164,7 +153,7 @@ bool LpeTool::item_handler(SPItem* item, GdkEvent* event) { case GDK_BUTTON_PRESS: { // select the clicked item but do nothing else - Inkscape::Selection * const selection = sp_desktop_selection(this->desktop); + Inkscape::Selection * const selection = this->desktop->getSelection(); selection->clear(); selection->add(item); ret = TRUE; @@ -186,7 +175,7 @@ bool LpeTool::item_handler(SPItem* item, GdkEvent* event) { } bool LpeTool::root_handler(GdkEvent* event) { - Inkscape::Selection *selection = sp_desktop_selection (desktop); + Inkscape::Selection *selection = desktop->getSelection(); bool ret = false; @@ -305,12 +294,12 @@ int lpetool_item_has_construction(LpeTool */*lc*/, SPItem *item) bool lpetool_try_construction(LpeTool *lc, Inkscape::LivePathEffect::EffectType const type) { - Inkscape::Selection *selection = sp_desktop_selection(lc->desktop); + Inkscape::Selection *selection = lc->desktop->getSelection(); SPItem *item = selection->singleItem(); // TODO: should we check whether type represents a valid geometric construction? if (item && SP_IS_LPE_ITEM(item) && Inkscape::LivePathEffect::Effect::acceptsNumClicks(type) == 0) { - Inkscape::LivePathEffect::Effect::createAndApply(type, sp_desktop_document(lc->desktop), item); + Inkscape::LivePathEffect::Effect::createAndApply(type, lc->desktop->getDocument(), item); return true; } return false; @@ -360,7 +349,7 @@ lpetool_context_reset_limiting_bbox(LpeTool *lc) if (!prefs->getBool("/tools/lpetool/show_bbox", true)) return; - SPDocument *document = sp_desktop_document(lc->desktop); + SPDocument *document = lc->desktop->getDocument(); Geom::Point A, B; lpetool_get_limiting_bbox_corners(document, A, B); @@ -371,7 +360,7 @@ lpetool_context_reset_limiting_bbox(LpeTool *lc) Geom::Rect rect(A, B); SPCurve *curve = SPCurve::new_from_rect(rect); - lc->canvas_bbox = sp_canvas_bpath_new (sp_desktop_controls(lc->desktop), curve); + lc->canvas_bbox = sp_canvas_bpath_new (lc->desktop->getControls(), curve); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(lc->canvas_bbox), 0x0000ffff, 0.8, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT, 5, 5); } @@ -396,7 +385,7 @@ void lpetool_create_measuring_items(LpeTool *lc, Inkscape::Selection *selection) { if (!selection) { - selection = sp_desktop_selection(lc->desktop); + selection = lc->desktop->getSelection(); } Inkscape::Preferences *prefs = Inkscape::Preferences::get(); bool show = prefs->getBool("/tools/lpetool/show_measuring_info", true); @@ -404,7 +393,7 @@ lpetool_create_measuring_items(LpeTool *lc, Inkscape::Selection *selection) SPPath *path; SPCurve *curve; SPCanvasText *canvas_text; - SPCanvasGroup *tmpgrp = sp_desktop_tempgroup(lc->desktop); + SPCanvasGroup *tmpgrp = lc->desktop->getTempGroup(); gchar *arc_length; double lengthval; diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index 6b5cbeccd..0875c29e0 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -29,7 +29,7 @@ #include "pixmaps/cursor-measure.xpm" #include "preferences.h" #include "inkscape.h" -#include "desktop-handles.h" + #include "ui/tools/measure-tool.h" #include "ui/tools/freehand-base.h" #include "display/canvas-text.h" @@ -49,22 +49,12 @@ using Inkscape::ControlManager; using Inkscape::CTLINE_SECONDARY; using Inkscape::Util::unit_table; -#include "ui/tool-factory.h" - namespace Inkscape { namespace UI { namespace Tools { std::vector<Inkscape::Display::TemporaryItem*> measure_tmp_items; -namespace { - ToolBase* createMeasureContext() { - return new MeasureTool(); - } - - bool measureContextRegistered = ToolFactory::instance().registerObject("/tools/measure", createMeasureContext); -} - const std::string& MeasureTool::getPrefsPath() { return MeasureTool::prefsPath; } @@ -228,7 +218,7 @@ void createAngleDisplayCurve(SPDesktop *desktop, Geom::Point const ¢er, Geom yc + ay + (k2 * ax)); Geom::Point p3(xc + bx + (k2 * by), yc + by - (k2 * bx)); - SPCtrlCurve *curve = ControlManager::getManager().createControlCurve(sp_desktop_tempgroup(desktop), p1, p2, p3, p4, CTLINE_SECONDARY); + SPCtrlCurve *curve = ControlManager::getManager().createControlCurve(desktop->getTempGroup(), p1, p2, p3, p4, CTLINE_SECONDARY); measure_tmp_items.push_back(desktop->add_temporary_canvasitem(SP_CANVAS_ITEM(curve), 0, true)); } @@ -291,7 +281,7 @@ static void calculate_intersections(SPDesktop * /*desktop*/, SPItem* item, Geom: //TODO: consider only visible intersections Geom::Point intersection = lineseg[0].pointAt((*m).ta); double eps = 0.0001; - SPDocument* doc = sp_desktop_document(desktop); + SPDocument* doc = desktop->getDocument(); if (((*m).ta > eps && item == doc->getItemAtPoint(desktop->dkey, lineseg[0].pointAt((*m).ta - eps), false, NULL)) || ((*m).ta + eps < 1 && @@ -441,7 +431,7 @@ bool MeasureTool::root_handler(GdkEvent* event) { // TODO switch to a different variable name. The single letter 'l' is easy to misread. //select elements crossed by line segment: - GSList *items = sp_desktop_document(desktop)->getItemsAtPoints(desktop->dkey, points); + GSList *items = desktop->getDocument()->getItemsAtPoints(desktop->dkey, points); std::vector<double> intersection_times; for (GSList *l = items; l != NULL; l = l->next) { SPItem *item = static_cast<SPItem*>(l->data); @@ -525,7 +515,7 @@ bool MeasureTool::root_handler(GdkEvent* event) { // TODO cleanup memory, Glib::ustring, etc.: gchar *measure_str = g_strdup_printf("%.2f %s", place.lengthVal, unit_name.c_str()); - SPCanvasText *canvas_tooltip = sp_canvastext_new(sp_desktop_tempgroup(desktop), + SPCanvasText *canvas_tooltip = sp_canvastext_new(desktop->getTempGroup(), desktop, place.end, measure_str); @@ -548,7 +538,7 @@ bool MeasureTool::root_handler(GdkEvent* event) { // TODO cleanup memory, Glib::ustring, etc.: gchar *angle_str = g_strdup_printf("%.2f °", angle * 180/M_PI); - SPCanvasText *canvas_tooltip = sp_canvastext_new(sp_desktop_tempgroup(desktop), + SPCanvasText *canvas_tooltip = sp_canvastext_new(desktop->getTempGroup(), desktop, angleDisplayPt, angle_str); @@ -569,7 +559,7 @@ bool MeasureTool::root_handler(GdkEvent* event) { // TODO cleanup memory, Glib::ustring, etc.: gchar *totallength_str = g_strdup_printf("%.2f %s", totallengthval, unit_name.c_str()); - SPCanvasText *canvas_tooltip = sp_canvastext_new(sp_desktop_tempgroup(desktop), + SPCanvasText *canvas_tooltip = sp_canvastext_new(desktop->getTempGroup(), desktop, end_point + desktop->w2d(Geom::Point(3*fontsize, -fontsize)), totallength_str); @@ -590,7 +580,7 @@ bool MeasureTool::root_handler(GdkEvent* event) { // TODO cleanup memory, Glib::ustring, etc.: gchar *total_str = g_strdup_printf("%.2f %s", totallengthval, unit_name.c_str()); - SPCanvasText *canvas_tooltip = sp_canvastext_new(sp_desktop_tempgroup(desktop), + SPCanvasText *canvas_tooltip = sp_canvastext_new(desktop->getTempGroup(), desktop, desktop->doc2dt((intersections[0] + intersections[intersections.size()-1])/2) + normal * 60, total_str); @@ -609,7 +599,7 @@ bool MeasureTool::root_handler(GdkEvent* event) { for (size_t idx = 0; idx < intersections.size(); ++idx) { // Display the intersection indicator (i.e. the cross) - SPCanvasItem * canvasitem = sp_canvas_item_new(sp_desktop_tempgroup(desktop), + SPCanvasItem * canvasitem = sp_canvas_item_new(desktop->getTempGroup(), SP_TYPE_CTRL, "anchor", SP_ANCHOR_CENTER, "size", 8.0, @@ -627,7 +617,7 @@ bool MeasureTool::root_handler(GdkEvent* event) { // draw main control line { - SPCtrlLine *control_line = ControlManager::getManager().createControlLine(sp_desktop_tempgroup(desktop), + SPCtrlLine *control_line = ControlManager::getManager().createControlLine(desktop->getTempGroup(), start_point, end_point); measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0)); @@ -642,7 +632,7 @@ bool MeasureTool::root_handler(GdkEvent* event) { * Geom::Affine(Geom::Translate(start_point))); } - SPCtrlLine *control_line = ControlManager::getManager().createControlLine(sp_desktop_tempgroup(desktop), + SPCtrlLine *control_line = ControlManager::getManager().createControlLine(desktop->getTempGroup(), start_point, anchorEnd, CTLINE_SECONDARY); @@ -655,17 +645,17 @@ bool MeasureTool::root_handler(GdkEvent* event) { if (intersections.size() > 2) { ControlManager &mgr = ControlManager::getManager(); SPCtrlLine *control_line = 0; - control_line = mgr.createControlLine(sp_desktop_tempgroup(desktop), + control_line = mgr.createControlLine(desktop->getTempGroup(), desktop->doc2dt(intersections[0]) + normal * 60, desktop->doc2dt(intersections[intersections.size() - 1]) + normal * 60); measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0)); - control_line = mgr.createControlLine(sp_desktop_tempgroup(desktop), + control_line = mgr.createControlLine(desktop->getTempGroup(), desktop->doc2dt(intersections[0]), desktop->doc2dt(intersections[0]) + normal * 65); measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0)); - control_line = mgr.createControlLine(sp_desktop_tempgroup(desktop), + control_line = mgr.createControlLine(desktop->getTempGroup(), desktop->doc2dt(intersections[intersections.size() - 1]), desktop->doc2dt(intersections[intersections.size() - 1]) + normal * 65); measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0)); @@ -677,7 +667,7 @@ bool MeasureTool::root_handler(GdkEvent* event) { LabelPlacement &place = *it; ControlManager &mgr = ControlManager::getManager(); - SPCtrlLine *control_line = mgr.createControlLine(sp_desktop_tempgroup(desktop), + SPCtrlLine *control_line = mgr.createControlLine(desktop->getTempGroup(), place.start, place.end, CTLINE_SECONDARY); @@ -689,7 +679,7 @@ bool MeasureTool::root_handler(GdkEvent* event) { Geom::Point measure_text_pos = (intersections[idx - 1] + intersections[idx]) / 2; ControlManager &mgr = ControlManager::getManager(); - SPCtrlLine *control_line = mgr.createControlLine(sp_desktop_tempgroup(desktop), + SPCtrlLine *control_line = mgr.createControlLine(desktop->getTempGroup(), desktop->doc2dt(measure_text_pos), desktop->doc2dt(measure_text_pos) - (normal * DIMENSION_OFFSET), CTLINE_SECONDARY); @@ -699,7 +689,7 @@ bool MeasureTool::root_handler(GdkEvent* event) { // Initial point { - SPCanvasItem * canvasitem = sp_canvas_item_new(sp_desktop_tempgroup(desktop), + SPCanvasItem * canvasitem = sp_canvas_item_new(desktop->getTempGroup(), SP_TYPE_CTRL, "anchor", SP_ANCHOR_CENTER, "size", 8.0, diff --git a/src/ui/tools/mesh-tool.cpp b/src/ui/tools/mesh-tool.cpp index 8a1fb7c72..67ed7aef1 100644 --- a/src/ui/tools/mesh-tool.cpp +++ b/src/ui/tools/mesh-tool.cpp @@ -27,7 +27,7 @@ // General #include "desktop.h" -#include "desktop-handles.h" + #include "document.h" #include "document-undo.h" #include "macros.h" @@ -48,27 +48,17 @@ // Mesh specific #include "ui/tools/mesh-tool.h" -#include "sp-mesh-gradient.h" +#include "sp-mesh.h" #include "display/sp-ctrlcurve.h" using Inkscape::DocumentUndo; -#include "ui/tool-factory.h" - namespace Inkscape { namespace UI { namespace Tools { static void sp_mesh_drag(MeshTool &rc, Geom::Point const pt, guint state, guint32 etime); -namespace { - ToolBase* createMeshContext() { - return new MeshTool(); - } - - bool meshContextRegistered = ToolFactory::instance().registerObject("/tools/mesh", createMeshContext); -} - const std::string& MeshTool::getPrefsPath() { return MeshTool::prefsPath; } @@ -107,7 +97,7 @@ const gchar *ms_handle_descr [] = { void MeshTool::selection_changed(Inkscape::Selection* /*sel*/) { GrDrag *drag = this->_grdrag; - Inkscape::Selection *selection = sp_desktop_selection(this->desktop); + Inkscape::Selection *selection = this->desktop->getSelection(); if (selection == NULL) { return; @@ -172,9 +162,9 @@ void MeshTool::selection_changed(Inkscape::Selection* /*sel*/) { // if (style && (style->fill.isPaintserver())) { // SPPaintServer *server = item->style->getFillPaintServer(); - // if ( SP_IS_MESHGRADIENT(server) ) { + // if ( SP_IS_MESH(server) ) { - // SPMeshGradient *mg = SP_MESHGRADIENT(server); + // SPMesh *mg = SP_MESH(server); // guint rows = 0;//mg->array.patches.size(); // for ( guint i = 0; i < rows; ++i ) { @@ -234,7 +224,7 @@ void MeshTool::setup() { } this->enableGrDrag(); - Inkscape::Selection *selection = sp_desktop_selection(this->desktop); + Inkscape::Selection *selection = this->desktop->getSelection(); this->selcon = new sigc::connection(selection->connectChanged( sigc::mem_fun(this, &MeshTool::selection_changed) @@ -317,7 +307,7 @@ static void sp_mesh_context_split_near_point(MeshTool *rc, SPItem *item, Geom:: ec->get_drag()->addStopNearPoint (item, mouse_p, tolerance/desktop->current_zoom()); - DocumentUndo::done(sp_desktop_document (desktop), SP_VERB_CONTEXT_MESH, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MESH, _("Split mesh row/column")); ec->get_drag()->updateDraggers(); @@ -337,8 +327,8 @@ sp_mesh_context_corner_operation (MeshTool *rc, MeshCornerOperation operation ) SPDocument *doc = NULL; GrDrag *drag = rc->_grdrag; - std::map<SPMeshGradient*, std::vector<guint> > points; - std::map<SPMeshGradient*, SPItem*> items; + std::map<SPMesh*, std::vector<guint> > points; + std::map<SPMesh*, SPItem*> items; // Get list of selected draggers for each mesh. // For all selected draggers @@ -352,7 +342,7 @@ sp_mesh_context_corner_operation (MeshTool *rc, MeshCornerOperation operation ) if( d->point_type != POINT_MG_CORNER ) continue; // Find the gradient - SPMeshGradient *gradient = SP_MESHGRADIENT( getGradient (d->item, d->fill_or_stroke) ); + SPMesh *gradient = SP_MESH( getGradient (d->item, d->fill_or_stroke) ); // Collect points together for same gradient points[gradient].push_back( d->point_i ); @@ -361,8 +351,8 @@ sp_mesh_context_corner_operation (MeshTool *rc, MeshCornerOperation operation ) } // Loop over meshes. - for( std::map<SPMeshGradient*, std::vector<guint> >::const_iterator iter = points.begin(); iter != points.end(); ++iter) { - SPMeshGradient *mg = SP_MESHGRADIENT( iter->first ); + for( std::map<SPMesh*, std::vector<guint> >::const_iterator iter = points.begin(); iter != points.end(); ++iter) { + SPMesh *mg = SP_MESH( iter->first ); if( iter->second.size() > 0 ) { guint noperation = 0; switch (operation) { @@ -440,7 +430,7 @@ Handles all keyboard and mouse input for meshs. bool MeshTool::root_handler(GdkEvent* event) { static bool dragging; - Inkscape::Selection *selection = sp_desktop_selection (desktop); + Inkscape::Selection *selection = desktop->getSelection(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); this->tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100); @@ -488,13 +478,13 @@ bool MeshTool::root_handler(GdkEvent* event) { #ifdef DEBUG_MESH std::cout << "sp_mesh_context_root_handler: creating new mesh on: " << (fsmode == Inkscape::FOR_FILL ? "Fill" : "Stroke") << std::endl; #endif - SPGradient *vector = sp_gradient_vector_for_object(sp_desktop_document(desktop), desktop, item, fsmode); + SPGradient *vector = sp_gradient_vector_for_object(desktop->getDocument(), desktop, item, fsmode); SPGradient *priv = sp_item_set_gradient(item, vector, new_type, fsmode); sp_gradient_reset_to_userspace(priv, item); } - DocumentUndo::done(sp_desktop_document (desktop), SP_VERB_CONTEXT_MESH, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MESH, _("Create default mesh")); } @@ -933,8 +923,8 @@ bool MeshTool::root_handler(GdkEvent* event) { static void sp_mesh_drag(MeshTool &rc, Geom::Point const /*pt*/, guint /*state*/, guint32 /*etime*/) { SPDesktop *desktop = SP_EVENT_CONTEXT(&rc)->desktop; - Inkscape::Selection *selection = sp_desktop_selection(desktop); - SPDocument *document = sp_desktop_document(desktop); + Inkscape::Selection *selection = desktop->getSelection(); + SPDocument *document = desktop->getDocument(); ToolBase *ec = SP_EVENT_CONTEXT(&rc); if (!selection->isEmpty()) { @@ -994,7 +984,7 @@ static void sp_mesh_drag(MeshTool &rc, Geom::Point const /*pt*/, guint /*state*/ "<b>Gradient</b> for %d objects; with <b>Ctrl</b> to snap angle", n_objects), n_objects); } else { - sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select <b>objects</b> on which to create gradient.")); + desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>objects</b> on which to create gradient.")); } } diff --git a/src/ui/tools/node-tool.cpp b/src/ui/tools/node-tool.cpp index 838c2a884..f8045a029 100644 --- a/src/ui/tools/node-tool.cpp +++ b/src/ui/tools/node-tool.cpp @@ -13,7 +13,7 @@ #include "ui/tool/curve-drag-point.h" #include <glib/gi18n.h> #include "desktop.h" -#include "desktop-handles.h" + #include "display/sp-canvas-group.h" #include "display/canvas-bpath.h" #include "display/curve.h" @@ -107,20 +107,10 @@ using Inkscape::ControlManager; -#include "ui/tool-factory.h" - namespace Inkscape { namespace UI { namespace Tools { -namespace { - ToolBase* createNodesContext() { - return new NodeTool(); - } - - bool nodesContextRegistered = ToolFactory::instance().registerObject("/tools/nodes", createNodesContext); -} - const std::string& NodeTool::getPrefsPath() { return NodeTool::prefsPath; } @@ -155,7 +145,7 @@ NodeTool::NodeTool() SPCanvasGroup *create_control_group(SPDesktop *d) { return reinterpret_cast<SPCanvasGroup*>(sp_canvas_item_new( - sp_desktop_controls(d), SP_TYPE_CANVAS_GROUP, NULL)); + d->getControls(), SP_TYPE_CANVAS_GROUP, NULL)); } void destroy_group(SPCanvasGroup *g) @@ -215,7 +205,7 @@ void NodeTool::setup() { data.node_data.node_group = create_control_group(this->desktop); data.node_data.handle_group = create_control_group(this->desktop); - Inkscape::Selection *selection = sp_desktop_selection (this->desktop); + Inkscape::Selection *selection = this->desktop->getSelection(); this->_selection_changed_connection.disconnect(); this->_selection_changed_connection = @@ -295,7 +285,7 @@ void NodeTool::setup() { // show helper paths of the applied LPE, if any void NodeTool::update_helperpath () { - Inkscape::Selection *selection = sp_desktop_selection (this->desktop); + Inkscape::Selection *selection = this->desktop->getSelection(); if (this->helperpath_tmpitem) { this->desktop->remove_temporary_canvasitem(this->helperpath_tmpitem); @@ -324,7 +314,7 @@ void NodeTool::update_helperpath () { cc->reset(); } if (!c->is_empty()) { - SPCanvasItem *helperpath = sp_canvas_bpath_new(sp_desktop_tempgroup(this->desktop), c); + SPCanvasItem *helperpath = sp_canvas_bpath_new(this->desktop->getTempGroup(), c); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(helperpath), 0x0000ff9A, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(helperpath), 0, SP_WIND_RULE_NONZERO); sp_canvas_item_affine_absolute(helperpath, selection->singleItem()->i2dt_affine()); @@ -527,7 +517,7 @@ bool NodeTool::root_handler(GdkEvent* event) { } c->transform(over_item->i2dt_affine()); - SPCanvasItem *flash = sp_canvas_bpath_new(sp_desktop_tempgroup(desktop), c); + SPCanvasItem *flash = sp_canvas_bpath_new(desktop->getTempGroup(), c); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(flash), //prefs->getInt("/tools/nodes/highlight_color", 0xff0000ff), 1.0, @@ -668,7 +658,7 @@ void NodeTool::select_area(Geom::Rect const &sel, GdkEventButton *event) { if (this->_multipath->empty()) { // if multipath is empty, select rubberbanded items rather than nodes Inkscape::Selection *selection = this->desktop->selection; - GSList *items = sp_desktop_document(this->desktop)->getItemsInBox(this->desktop->dkey, sel); + GSList *items = this->desktop->getDocument()->getItemsInBox(this->desktop->dkey, sel); selection->setList(items); g_slist_free(items); } else { diff --git a/src/ui/tools/node-tool.h b/src/ui/tools/node-tool.h index ab72f3632..20375e869 100644 --- a/src/ui/tools/node-tool.h +++ b/src/ui/tools/node-tool.h @@ -33,6 +33,8 @@ namespace Inkscape { } } +struct SPCanvasGroup; + #define INK_NODE_TOOL(obj) (dynamic_cast<Inkscape::UI::Tools::NodeTool*>((Inkscape::UI::Tools::ToolBase*)obj)) #define INK_IS_NODE_TOOL(obj) (dynamic_cast<const Inkscape::UI::Tools::NodeTool*>((const Inkscape::UI::Tools::ToolBase*)obj)) diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index fbcdf6142..d28b7c27a 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -20,10 +20,13 @@ #include <cstring> #include <string> +#include "shortcuts.h" +#include "verbs.h" + #include "ui/tools/pen-tool.h" #include "sp-namedview.h" #include "desktop.h" -#include "desktop-handles.h" + #include "selection.h" #include "selection-chemistry.h" #include "ui/draw-anchor.h" @@ -70,8 +73,6 @@ #include "live_effects/lpe-bspline.h" #include <2geom/nearest-point.h> -#include "ui/tool-factory.h" - #include "live_effects/effect.h" @@ -85,13 +86,6 @@ static Geom::Point pen_drag_origin_w(0, 0); static bool pen_within_tolerance = false; static int pen_last_paraxial_dir = 0; // last used direction in horizontal/vertical mode; 0 = horizontal, 1 = vertical const double handleCubicGap = 0.01; -namespace { - ToolBase* createPenContext() { - return new PenTool(); - } - - bool penContextRegistered = ToolFactory::instance().registerObject("/tools/freehand/pen", createPenContext); -} const std::string& PenTool::getPrefsPath() { return PenTool::prefsPath; @@ -192,14 +186,14 @@ void PenTool::setup() { ControlManager &mgr = ControlManager::getManager(); // Pen indicators - this->c0 = mgr.createControl(sp_desktop_controls(this->desktop), Inkscape::CTRL_TYPE_ADJ_HANDLE); + this->c0 = mgr.createControl(this->desktop->getControls(), Inkscape::CTRL_TYPE_ADJ_HANDLE); mgr.track(this->c0); - this->c1 = mgr.createControl(sp_desktop_controls(this->desktop), Inkscape::CTRL_TYPE_ADJ_HANDLE); + this->c1 = mgr.createControl(this->desktop->getControls(), Inkscape::CTRL_TYPE_ADJ_HANDLE); mgr.track(this->c1); - this->cl0 = mgr.createControlLine(sp_desktop_controls(this->desktop)); - this->cl1 = mgr.createControlLine(sp_desktop_controls(this->desktop)); + this->cl0 = mgr.createControlLine(this->desktop->getControls()); + this->cl1 = mgr.createControlLine(this->desktop->getControls()); sp_canvas_item_hide(this->c0); sp_canvas_item_hide(this->c1); @@ -468,7 +462,7 @@ bool PenTool::_handleButtonPress(GdkEventButton const &bevent) { // This is the first click of a new curve; deselect item so that // this curve is not combined with it (unless it is drawn from its // anchor, which is handled by the sibling branch above) - Inkscape::Selection * const selection = sp_desktop_selection(desktop); + Inkscape::Selection * const selection = desktop->getSelection(); if (!(bevent.state & GDK_SHIFT_MASK) || this->hasWaitingLPE()) { // if we have a waiting LPE, we need a fresh path to be created // so don't append to an existing one @@ -614,7 +608,12 @@ bool PenTool::_handleMotionNotify(GdkEventMotion const &mevent) { ret = true; break; case PenTool::STOP: - // This is perfectly valid + if (!this->sp_event_context_knot_mouseover()) { + SnapManager &m = desktop->namedview->snap_manager; + m.setup(desktop); + m.preSnap(Inkscape::SnapCandidatePoint(p, Inkscape::SNAPSOURCE_NODE_HANDLE)); + m.unSetup(); + } break; default: break; @@ -685,8 +684,7 @@ bool PenTool::_handleMotionNotify(GdkEventMotion const &mevent) { ret = true; break; case PenTool::STOP: - // This is perfectly valid - break; + // Don't break; fall through to default to do preSnapping default: if (!this->sp_event_context_knot_mouseover()) { SnapManager &m = desktop->namedview->snap_manager; @@ -846,7 +844,7 @@ bool PenTool::_handleButtonRelease(GdkEventButton const &revent) { if (this->expecting_clicks_for_LPE == 0 && this->hasWaitingLPE()) { this->setPolylineMode(); - Inkscape::Selection *selection = sp_desktop_selection(this->desktop); + Inkscape::Selection *selection = this->desktop->getSelection(); if (this->waiting_LPE) { // we have an already created LPE waiting for a path @@ -881,7 +879,7 @@ void PenTool::_redrawAll() { this->green_bpaths = g_slist_remove(this->green_bpaths, this->green_bpaths->data); } // one canvas bpath for all of green_curve - SPCanvasItem *cshape = sp_canvas_bpath_new(sp_desktop_sketch(this->desktop), this->green_curve); + SPCanvasItem *cshape = sp_canvas_bpath_new(this->desktop->getSketch(), this->green_curve); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(cshape), this->green_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(cshape), 0, SP_WIND_RULE_NONZERO); @@ -1064,6 +1062,23 @@ bool PenTool::_handleKeyPress(GdkEvent *event) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gdouble const nudge = prefs->getDoubleLimited("/options/nudgedistance/value", 2, 0, 1000, "px"); // in px + // Check for undo if we have started drawing a path. + if (this->npoints > 0) { + unsigned int shortcut = Inkscape::UI::Tools::get_group0_keyval (&event->key) | + ( event->key.state & GDK_SHIFT_MASK ? + SP_SHORTCUT_SHIFT_MASK : 0 ) | + ( event->key.state & GDK_CONTROL_MASK ? + SP_SHORTCUT_CONTROL_MASK : 0 ) | + ( event->key.state & GDK_MOD1_MASK ? + SP_SHORTCUT_ALT_MASK : 0 ); + Inkscape::Verb* verb = sp_shortcut_get_verb(shortcut); + if (verb) { + unsigned int vcode = verb->get_code(); + if (vcode == SP_VERB_EDIT_UNDO) + return _undoLastPoint(); + } + } + switch (get_group0_keyval (&event->key)) { case GDK_KEY_Left: // move last point left case GDK_KEY_KP_Left: @@ -1218,14 +1233,6 @@ bool PenTool::_handleKeyPress(GdkEvent *event) { ret = true; } break; - case GDK_KEY_z: - case GDK_KEY_Z: - if (MOD__CTRL_ONLY(event) && this->npoints != 0) { - // if drawing, cancel, otherwise pass it up for undo - this->_cancel (); - ret = true; - } - break; case GDK_KEY_g: case GDK_KEY_G: if (MOD__SHIFT_ONLY(event)) { @@ -1236,83 +1243,7 @@ bool PenTool::_handleKeyPress(GdkEvent *event) { case GDK_KEY_BackSpace: case GDK_KEY_Delete: case GDK_KEY_KP_Delete: - if ( this->green_curve->is_empty() || (this->green_curve->last_segment() == NULL) ) { - if (!this->red_curve->is_empty()) { - this->_cancel (); - ret = true; - } else { - // do nothing; this event should be handled upstream - } - } else { - // Reset red curve - this->red_curve->reset(); - // Destroy topmost green bpath - if (this->green_bpaths) { - if (this->green_bpaths->data) { - sp_canvas_item_destroy(SP_CANVAS_ITEM(this->green_bpaths->data)); - } - this->green_bpaths = g_slist_remove(this->green_bpaths, this->green_bpaths->data); - } - // Get last segment - if ( this->green_curve->is_empty() ) { - g_warning("pen_handle_key_press, case GDK_KP_Delete: Green curve is empty"); - break; - } - // The code below assumes that this->green_curve has only ONE path ! - Geom::Curve const * crv = this->green_curve->last_segment(); - this->p[0] = crv->initialPoint(); - if ( Geom::CubicBezier const * cubic = dynamic_cast<Geom::CubicBezier const *>(crv)) { - this->p[1] = (*cubic)[1]; - - } else { - this->p[1] = this->p[0]; - } - - // asign the value in a third of the distance of the last segment. - if (this->bspline){ - this->p[1] = this->p[0] + (1./3)*(this->p[3] - this->p[0]); - } - - Geom::Point const pt( (this->npoints < 4) ? crv->finalPoint() : this->p[3] ); - - this->npoints = 2; - // delete the last segment of the green curve - if (this->green_curve->get_segment_count() == 1) { - this->npoints = 5; - if (this->green_bpaths) { - if (this->green_bpaths->data) { - sp_canvas_item_destroy(SP_CANVAS_ITEM(this->green_bpaths->data)); - } - this->green_bpaths = g_slist_remove(this->green_bpaths, this->green_bpaths->data); - } - this->green_curve->reset(); - } else { - this->green_curve->backspace(); - } - - // assign the value of this->p[1] to the oposite of the green line last segment - if (this->spiro){ - Geom::CubicBezier const *cubic = dynamic_cast<Geom::CubicBezier const *>(this->green_curve->last_segment()); - if ( cubic ) { - this->p[1] = (*cubic)[3] + (*cubic)[3] - (*cubic)[2]; - SP_CTRL(this->c1)->moveto(this->p[0]); - } else { - this->p[1] = this->p[0]; - } - } - - sp_canvas_item_hide(this->c0); - sp_canvas_item_hide(this->c1); - sp_canvas_item_hide(this->cl0); - sp_canvas_item_hide(this->cl1); - this->state = PenTool::POINT; - this->_setSubsequentPoint(pt, true); - pen_last_paraxial_dir = !pen_last_paraxial_dir; - - //redraw - this->_bspline_spiro_build(); - ret = true; - } + ret = _undoLastPoint(); break; default: break; @@ -1415,7 +1346,7 @@ void PenTool::_bspline_spiro_color() this->green_bpaths = g_slist_remove(this->green_bpaths, this->green_bpaths->data); } // one canvas bpath for all of green_curve - SPCanvasItem *cshape = sp_canvas_bpath_new(sp_desktop_sketch(this->desktop), this->green_curve); + SPCanvasItem *cshape = sp_canvas_bpath_new(this->desktop->getSketch(), this->green_curve); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(cshape), this->green_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(cshape), 0, SP_WIND_RULE_NONZERO); this->green_bpaths = g_slist_prepend(this->green_bpaths, cshape); @@ -2161,7 +2092,7 @@ void PenTool::_finishSegment(Geom::Point const p, guint const state) { SPCurve *curve = this->red_curve->copy(); /// \todo fixme: - SPCanvasItem *cshape = sp_canvas_bpath_new(sp_desktop_sketch(this->desktop), curve); + SPCanvasItem *cshape = sp_canvas_bpath_new(this->desktop->getSketch(), curve); curve->unref(); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(cshape), this->green_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); @@ -2175,6 +2106,92 @@ void PenTool::_finishSegment(Geom::Point const p, guint const state) { } } +// Partial fix for https://bugs.launchpad.net/inkscape/+bug/171990 +// TODO: implement the redo feature +bool PenTool::_undoLastPoint() { + bool ret = false; + + if ( this->green_curve->is_empty() || (this->green_curve->last_segment() == NULL) ) { + if (!this->red_curve->is_empty()) { + this->_cancel (); + ret = true; + } else { + // do nothing; this event should be handled upstream + } + } else { + // Reset red curve + this->red_curve->reset(); + // Destroy topmost green bpath + if (this->green_bpaths) { + if (this->green_bpaths->data) { + sp_canvas_item_destroy(SP_CANVAS_ITEM(this->green_bpaths->data)); + } + this->green_bpaths = g_slist_remove(this->green_bpaths, this->green_bpaths->data); + } + // Get last segment + if ( this->green_curve->is_empty() ) { + g_warning("pen_handle_key_press, case GDK_KP_Delete: Green curve is empty"); + return false; + } + // The code below assumes that this->green_curve has only ONE path ! + Geom::Curve const * crv = this->green_curve->last_segment(); + this->p[0] = crv->initialPoint(); + if ( Geom::CubicBezier const * cubic = dynamic_cast<Geom::CubicBezier const *>(crv)) { + this->p[1] = (*cubic)[1]; + + } else { + this->p[1] = this->p[0]; + } + + // asign the value in a third of the distance of the last segment. + if (this->bspline){ + this->p[1] = this->p[0] + (1./3)*(this->p[3] - this->p[0]); + } + + Geom::Point const pt( (this->npoints < 4) ? crv->finalPoint() : this->p[3] ); + + this->npoints = 2; + // delete the last segment of the green curve + if (this->green_curve->get_segment_count() == 1) { + this->npoints = 5; + if (this->green_bpaths) { + if (this->green_bpaths->data) { + sp_canvas_item_destroy(SP_CANVAS_ITEM(this->green_bpaths->data)); + } + this->green_bpaths = g_slist_remove(this->green_bpaths, this->green_bpaths->data); + } + this->green_curve->reset(); + } else { + this->green_curve->backspace(); + } + + // assign the value of this->p[1] to the oposite of the green line last segment + if (this->spiro){ + Geom::CubicBezier const *cubic = dynamic_cast<Geom::CubicBezier const *>(this->green_curve->last_segment()); + if ( cubic ) { + this->p[1] = (*cubic)[3] + (*cubic)[3] - (*cubic)[2]; + SP_CTRL(this->c1)->moveto(this->p[0]); + } else { + this->p[1] = this->p[0]; + } + } + + sp_canvas_item_hide(this->c0); + sp_canvas_item_hide(this->c1); + sp_canvas_item_hide(this->cl0); + sp_canvas_item_hide(this->cl1); + this->state = PenTool::POINT; + this->_setSubsequentPoint(pt, true); + pen_last_paraxial_dir = !pen_last_paraxial_dir; + + //redraw + this->_bspline_spiro_build(); + ret = true; + } + + return ret; +} + void PenTool::_finish(gboolean const closed) { if (this->expecting_clicks_for_LPE > 1) { // don't let the path be finished before we have collected the required number of mouse clicks @@ -2277,7 +2294,7 @@ void PenTool::_setToNearestHorizVert(Geom::Point &pt, guint const state, bool sn // Snap along the constraint line; if we didn't snap then still the constraint will be applied SnapManager &m = this->desktop->namedview->snap_manager; - Inkscape::Selection *selection = sp_desktop_selection (this->desktop); + Inkscape::Selection *selection = this->desktop->getSelection(); // selection->singleItem() is the item that is currently being drawn. This item will not be snapped to (to avoid self-snapping) // TODO: Allow snapping to the stationary parts of the item, and only ignore the last segment diff --git a/src/ui/tools/pen-tool.h b/src/ui/tools/pen-tool.h index 98fd0a43e..2208005c5 100644 --- a/src/ui/tools/pen-tool.h +++ b/src/ui/tools/pen-tool.h @@ -121,6 +121,7 @@ private: void _setSubsequentPoint(Geom::Point const p, bool statusbar, guint status = 0); void _setCtrl(Geom::Point const p, guint state); void _finishSegment(Geom::Point p, guint state); + bool _undoLastPoint(); void _finish(gboolean closed); diff --git a/src/ui/tools/pencil-tool.cpp b/src/ui/tools/pencil-tool.cpp index 3ea2ae843..db24c7432 100644 --- a/src/ui/tools/pencil-tool.cpp +++ b/src/ui/tools/pencil-tool.cpp @@ -20,7 +20,7 @@ #include "ui/tools/pencil-tool.h" #include "desktop.h" -#include "desktop-handles.h" + #include "selection.h" #include "selection-chemistry.h" #include "ui/draw-anchor.h" @@ -43,7 +43,6 @@ #include "display/sp-canvas.h" #include "display/curve.h" #include "livarot/Path.h" -#include "ui/tool-factory.h" #include "ui/tool/event-utils.h" namespace Inkscape { @@ -55,14 +54,6 @@ static bool pencil_within_tolerance = false; static bool in_svg_plane(Geom::Point const &p) { return Geom::LInfty(p) < 1e18; } -namespace { - ToolBase* createPencilContext() { - return new PencilTool(); - } - - bool pencilContextRegistered = ToolFactory::instance().registerObject("/tools/freehand/pencil", createPencilContext); -} - const std::string& PencilTool::getPrefsPath() { return PencilTool::prefsPath; } @@ -153,7 +144,7 @@ bool PencilTool::_handleButtonPress(GdkEventButton const &bevent) { bool ret = false; if ( bevent.button == 1 && !this->space_panning) { - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (Inkscape::have_viable_layer(desktop, this->message_context) == false) { return true; @@ -853,7 +844,7 @@ void PencilTool::_fitAndSplit() { SPCurve *curve = this->red_curve->copy(); /// \todo fixme: - SPCanvasItem *cshape = sp_canvas_bpath_new(sp_desktop_sketch(this->desktop), curve); + SPCanvasItem *cshape = sp_canvas_bpath_new(this->desktop->getSketch(), curve); curve->unref(); this->highlight_color = SP_ITEM(this->desktop->currentLayer())->highlight_color(); diff --git a/src/ui/tools/rect-tool.cpp b/src/ui/tools/rect-tool.cpp index 67df0d9a5..62a9006ea 100644 --- a/src/ui/tools/rect-tool.cpp +++ b/src/ui/tools/rect-tool.cpp @@ -28,7 +28,7 @@ #include "sp-namedview.h" #include "selection.h" #include "selection-chemistry.h" -#include "desktop-handles.h" + #include "snap.h" #include "desktop.h" #include "desktop-style.h" @@ -46,20 +46,10 @@ using Inkscape::DocumentUndo; -#include "ui/tool-factory.h" - namespace Inkscape { namespace UI { namespace Tools { -namespace { - ToolBase* createRectContext() { - return new RectTool(); - } - - bool rectContextRegistered = ToolFactory::instance().registerObject("/tools/shapes/rect", createRectContext); -} - const std::string& RectTool::getPrefsPath() { return RectTool::prefsPath; } @@ -111,13 +101,13 @@ void RectTool::setup() { this->shape_editor = new ShapeEditor(this->desktop); - SPItem *item = sp_desktop_selection(this->desktop)->singleItem(); + SPItem *item = this->desktop->getSelection()->singleItem(); if (item) { this->shape_editor->set_item(item); } this->sel_changed_connection.disconnect(); - this->sel_changed_connection = sp_desktop_selection(this->desktop)->connectChanged( + this->sel_changed_connection = this->desktop->getSelection()->connectChanged( sigc::mem_fun(this, &RectTool::selection_changed) ); @@ -170,7 +160,7 @@ bool RectTool::root_handler(GdkEvent* event) { static bool dragging; SPDesktop *desktop = this->desktop; - Inkscape::Selection *selection = sp_desktop_selection (desktop); + Inkscape::Selection *selection = desktop->getSelection(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -476,16 +466,16 @@ void RectTool::finishItem() { this->desktop->canvas->endForcedFullRedraws(); - sp_desktop_selection(this->desktop)->set(this->rect); + this->desktop->getSelection()->set(this->rect); - DocumentUndo::done(sp_desktop_document(this->desktop), SP_VERB_CONTEXT_RECT, _("Create rectangle")); + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_RECT, _("Create rectangle")); this->rect = NULL; } } void RectTool::cancel(){ - sp_desktop_selection(this->desktop)->clear(); + this->desktop->getSelection()->clear(); sp_canvas_item_ungrab(SP_CANVAS_ITEM(this->desktop->acetate), 0); if (this->rect != NULL) { @@ -500,7 +490,7 @@ void RectTool::cancel(){ this->desktop->canvas->endForcedFullRedraws(); - DocumentUndo::cancel(sp_desktop_document(this->desktop)); + DocumentUndo::cancel(this->desktop->getDocument()); } } diff --git a/src/ui/tools/select-tool.cpp b/src/ui/tools/select-tool.cpp index a8267ea1d..40b994968 100644 --- a/src/ui/tools/select-tool.cpp +++ b/src/ui/tools/select-tool.cpp @@ -38,7 +38,7 @@ #include "extension/dbus/document-interface.h" #endif #include "desktop.h" -#include "desktop-handles.h" + #include "sp-root.h" #include "preferences.h" #include "ui/tools-switch.h" @@ -49,7 +49,6 @@ #include "display/sp-canvas.h" #include "display/sp-canvas-item.h" #include "display/drawing-item.h" -#include "ui/tool-factory.h" using Inkscape::DocumentUndo; @@ -65,14 +64,6 @@ static GdkCursor *CursorSelectDragging = NULL; static gint rb_escaped = 0; // if non-zero, rubberband was canceled by esc, so the next button release should not deselect static gint drag_escaped = 0; // if non-zero, drag was canceled by esc -namespace { - ToolBase* createSelectContext() { - return new SelectTool(); - } - - bool selectContextRegistered = ToolFactory::instance().registerObject("/tools/select", createSelectContext); -} - const std::string& SelectTool::getPrefsPath() { return SelectTool::prefsPath; } @@ -208,7 +199,7 @@ bool SelectTool::sp_select_context_abort() { if (this->item) { // only undo if the item is still valid if (this->item->document) { - DocumentUndo::undo(sp_desktop_document(desktop)); + DocumentUndo::undo(desktop->getDocument()); } sp_object_unref( this->item, NULL); @@ -216,7 +207,7 @@ bool SelectTool::sp_select_context_abort() { // NOTE: This is a workaround to a bug. // When the ctrl key is held, sc->item is not defined // so in this case (only), we skip the object doc check - DocumentUndo::undo(sp_desktop_document(desktop)); + DocumentUndo::undo(desktop->getDocument()); } this->item = NULL; @@ -272,7 +263,7 @@ sp_select_context_up_one_layer(SPDesktop *desktop) { desktop->setCurrentLayer(parent); if (current_group && (SPGroup::LAYER != current_group->layerMode())) { - sp_desktop_selection(desktop)->set(current_layer); + desktop->getSelection()->set(current_layer); } } } @@ -308,7 +299,7 @@ bool SelectTool::item_handler(SPItem* item, GdkEvent* event) { // if shift or ctrl was pressed, do not move objects; // pass the event to root handler which will perform rubberband, shift-click, ctrl-click, ctrl-drag } else { - GdkWindow* window = gtk_widget_get_window (GTK_WIDGET (sp_desktop_canvas(desktop))); + GdkWindow* window = gtk_widget_get_window (GTK_WIDGET (desktop->getCanvas())); this->dragging = TRUE; this->moved = FALSE; @@ -353,7 +344,7 @@ bool SelectTool::item_handler(SPItem* item, GdkEvent* event) { case GDK_ENTER_NOTIFY: { if (!desktop->isWaitingCursor() && !this->dragging) { - GdkWindow* window = gtk_widget_get_window (GTK_WIDGET (sp_desktop_canvas(desktop))); + GdkWindow* window = gtk_widget_get_window (GTK_WIDGET (desktop->getCanvas())); gdk_window_set_cursor(window, CursorSelectMouseover); } @@ -361,7 +352,7 @@ bool SelectTool::item_handler(SPItem* item, GdkEvent* event) { } case GDK_LEAVE_NOTIFY: if (!desktop->isWaitingCursor() && !this->dragging) { - GdkWindow* window = gtk_widget_get_window (GTK_WIDGET (sp_desktop_canvas(desktop))); + GdkWindow* window = gtk_widget_get_window (GTK_WIDGET (desktop->getCanvas())); gdk_window_set_cursor(window, this->cursor); } @@ -469,7 +460,7 @@ bool SelectTool::root_handler(GdkEvent* event) { SPItem *item_at_point = NULL, *group_at_point = NULL, *item_in_group = NULL; gint ret = FALSE; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); // make sure we still have valid objects to move around @@ -485,7 +476,7 @@ bool SelectTool::root_handler(GdkEvent* event) { if (dynamic_cast<SPGroup *>(clicked_item) && !dynamic_cast<SPBox3D *>(clicked_item)) { // enter group if it's not a 3D box desktop->setCurrentLayer(clicked_item); - sp_desktop_selection(desktop)->clear(); + desktop->getSelection()->clear(); this->dragging = false; sp_event_context_discard_delayed_snap_event(this); @@ -573,7 +564,7 @@ bool SelectTool::root_handler(GdkEvent* event) { // but not with shift) we want to drag rather than rubberband this->dragging = TRUE; - GdkWindow* window = gtk_widget_get_window (GTK_WIDGET (sp_desktop_canvas(desktop))); + GdkWindow* window = gtk_widget_get_window (GTK_WIDGET (desktop->getCanvas())); gdk_window_set_cursor(window, CursorSelectDragging); @@ -702,7 +693,7 @@ bool SelectTool::root_handler(GdkEvent* event) { } this->dragging = FALSE; - window = gtk_widget_get_window (GTK_WIDGET (sp_desktop_canvas(desktop))); + window = gtk_widget_get_window (GTK_WIDGET (desktop->getCanvas())); gdk_window_set_cursor(window, CursorSelectMouseover); sp_event_context_discard_delayed_snap_event(this); @@ -722,9 +713,9 @@ bool SelectTool::root_handler(GdkEvent* event) { if (r->getMode() == RUBBERBAND_MODE_RECT) { Geom::OptRect const b = r->getRectangle(); - items = sp_desktop_document(desktop)->getItemsInBox(desktop->dkey, *b); + items = desktop->getDocument()->getItemsInBox(desktop->dkey, *b); } else if (r->getMode() == RUBBERBAND_MODE_TOUCHPATH) { - items = sp_desktop_document(desktop)->getItemsAtPoints(desktop->dkey, r->getPoints()); + items = desktop->getDocument()->getItemsAtPoints(desktop->dkey, r->getPoints()); } _seltrans->resetState(); @@ -953,7 +944,7 @@ bool SelectTool::root_handler(GdkEvent* event) { // if Alt and nonempty selection, show moving cursor ("move selected"): if (alt && !selection->isEmpty() && !desktop->isWaitingCursor()) { - GdkWindow* window = gtk_widget_get_window (GTK_WIDGET (sp_desktop_canvas(desktop))); + GdkWindow* window = gtk_widget_get_window (GTK_WIDGET (desktop->getCanvas())); gdk_window_set_cursor(window, CursorSelectDragging); } @@ -974,15 +965,15 @@ bool SelectTool::root_handler(GdkEvent* event) { if (MOD__ALT(event)) { // alt if (MOD__SHIFT(event)) { - sp_selection_move_screen(sp_desktop_selection(desktop), mul*-10, 0); // shift + sp_selection_move_screen(desktop->getSelection(), mul*-10, 0); // shift } else { - sp_selection_move_screen(sp_desktop_selection(desktop), mul*-1, 0); // no shift + sp_selection_move_screen(desktop->getSelection(), mul*-1, 0); // no shift } } else { // no alt if (MOD__SHIFT(event)) { - sp_selection_move(sp_desktop_selection(desktop), mul*-10*nudge, 0); // shift + sp_selection_move(desktop->getSelection(), mul*-10*nudge, 0); // shift } else { - sp_selection_move(sp_desktop_selection(desktop), mul*-nudge, 0); // no shift + sp_selection_move(desktop->getSelection(), mul*-nudge, 0); // no shift } } @@ -997,15 +988,15 @@ bool SelectTool::root_handler(GdkEvent* event) { if (MOD__ALT(event)) { // alt if (MOD__SHIFT(event)) { - sp_selection_move_screen(sp_desktop_selection(desktop), 0, mul*10); // shift + sp_selection_move_screen(desktop->getSelection(), 0, mul*10); // shift } else { - sp_selection_move_screen(sp_desktop_selection(desktop), 0, mul*1); // no shift + sp_selection_move_screen(desktop->getSelection(), 0, mul*1); // no shift } } else { // no alt if (MOD__SHIFT(event)) { - sp_selection_move(sp_desktop_selection(desktop), 0, mul*10*nudge); // shift + sp_selection_move(desktop->getSelection(), 0, mul*10*nudge); // shift } else { - sp_selection_move(sp_desktop_selection(desktop), 0, mul*nudge); // no shift + sp_selection_move(desktop->getSelection(), 0, mul*nudge); // no shift } } @@ -1020,15 +1011,15 @@ bool SelectTool::root_handler(GdkEvent* event) { if (MOD__ALT(event)) { // alt if (MOD__SHIFT(event)) { - sp_selection_move_screen(sp_desktop_selection(desktop), mul*10, 0); // shift + sp_selection_move_screen(desktop->getSelection(), mul*10, 0); // shift } else { - sp_selection_move_screen(sp_desktop_selection(desktop), mul*1, 0); // no shift + sp_selection_move_screen(desktop->getSelection(), mul*1, 0); // no shift } } else { // no alt if (MOD__SHIFT(event)) { - sp_selection_move(sp_desktop_selection(desktop), mul*10*nudge, 0); // shift + sp_selection_move(desktop->getSelection(), mul*10*nudge, 0); // shift } else { - sp_selection_move(sp_desktop_selection(desktop), mul*nudge, 0); // no shift + sp_selection_move(desktop->getSelection(), mul*nudge, 0); // no shift } } @@ -1043,15 +1034,15 @@ bool SelectTool::root_handler(GdkEvent* event) { if (MOD__ALT(event)) { // alt if (MOD__SHIFT(event)) { - sp_selection_move_screen(sp_desktop_selection(desktop), 0, mul*-10); // shift + sp_selection_move_screen(desktop->getSelection(), 0, mul*-10); // shift } else { - sp_selection_move_screen(sp_desktop_selection(desktop), 0, mul*-1); // no shift + sp_selection_move_screen(desktop->getSelection(), 0, mul*-1); // no shift } } else { // no alt if (MOD__SHIFT(event)) { - sp_selection_move(sp_desktop_selection(desktop), 0, mul*-10*nudge); // shift + sp_selection_move(desktop->getSelection(), 0, mul*-10*nudge); // shift } else { - sp_selection_move(sp_desktop_selection(desktop), 0, mul*-nudge); // no shift + sp_selection_move(desktop->getSelection(), 0, mul*-nudge); // no shift } } @@ -1155,7 +1146,7 @@ bool SelectTool::root_handler(GdkEvent* event) { SPGroup *clickedGroup = dynamic_cast<SPGroup *>(clicked_item); if ( (clickedGroup && (clickedGroup->layerMode() != SPGroup::LAYER)) || dynamic_cast<SPBox3D *>(clicked_item)) { // enter group or a 3D box desktop->setCurrentLayer(clicked_item); - sp_desktop_selection(desktop)->clear(); + desktop->getSelection()->clear(); } else { this->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Selected object is not a group. Cannot enter.")); } @@ -1226,7 +1217,7 @@ bool SelectTool::root_handler(GdkEvent* event) { // set cursor to default. if (!desktop->isWaitingCursor()) { // Do we need to reset the cursor here on key release ? - //GdkWindow* window = gtk_widget_get_window (GTK_WIDGET (sp_desktop_canvas(desktop))); + //GdkWindow* window = gtk_widget_get_window (GTK_WIDGET (desktop->getCanvas())); //gdk_window_set_cursor(window, event_context->cursor); } break; diff --git a/src/ui/tools/spiral-tool.cpp b/src/ui/tools/spiral-tool.cpp index 31c4e8829..833fef18d 100644 --- a/src/ui/tools/spiral-tool.cpp +++ b/src/ui/tools/spiral-tool.cpp @@ -27,7 +27,7 @@ #include "document-undo.h" #include "sp-namedview.h" #include "selection.h" -#include "desktop-handles.h" + #include "snap.h" #include "desktop.h" #include "desktop-style.h" @@ -45,20 +45,10 @@ using Inkscape::DocumentUndo; -#include "ui/tool-factory.h" - namespace Inkscape { namespace UI { namespace Tools { -namespace { - ToolBase* createSpiralContext() { - return new SpiralTool(); - } - - bool spiralContextRegistered = ToolFactory::instance().registerObject("/tools/shapes/spiral", createSpiralContext); -} - const std::string& SpiralTool::getPrefsPath() { return SpiralTool::prefsPath; } @@ -117,12 +107,12 @@ void SpiralTool::setup() { this->shape_editor = new ShapeEditor(this->desktop); - SPItem *item = sp_desktop_selection(this->desktop)->singleItem(); + SPItem *item = this->desktop->getSelection()->singleItem(); if (item) { this->shape_editor->set_item(item); } - Inkscape::Selection *selection = sp_desktop_selection(this->desktop); + Inkscape::Selection *selection = this->desktop->getSelection(); this->sel_changed_connection.disconnect(); this->sel_changed_connection = selection->connectChanged(sigc::mem_fun(this, &SpiralTool::selection_changed)); @@ -154,7 +144,7 @@ bool SpiralTool::root_handler(GdkEvent* event) { static gboolean dragging; SPDesktop *desktop = this->desktop; - Inkscape::Selection *selection = sp_desktop_selection (desktop); + Inkscape::Selection *selection = desktop->getSelection(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); this->tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100); @@ -417,15 +407,15 @@ void SpiralTool::finishItem() { this->desktop->canvas->endForcedFullRedraws(); - sp_desktop_selection(this->desktop)->set(this->spiral); - DocumentUndo::done(sp_desktop_document(this->desktop), SP_VERB_CONTEXT_SPIRAL, _("Create spiral")); + this->desktop->getSelection()->set(this->spiral); + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_SPIRAL, _("Create spiral")); this->spiral = NULL; } } void SpiralTool::cancel() { - sp_desktop_selection(this->desktop)->clear(); + this->desktop->getSelection()->clear(); sp_canvas_item_ungrab(SP_CANVAS_ITEM(this->desktop->acetate), 0); if (this->spiral != NULL) { @@ -440,7 +430,7 @@ void SpiralTool::cancel() { this->desktop->canvas->endForcedFullRedraws(); - DocumentUndo::cancel(sp_desktop_document(this->desktop)); + DocumentUndo::cancel(this->desktop->getDocument()); } } diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index cdc608558..ec7d10e13 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -33,7 +33,7 @@ #include "selection.h" #include "desktop.h" #include "desktop-events.h" -#include "desktop-handles.h" + #include "message-context.h" #include "pixmaps/cursor-spray.xpm" #include <boost/optional.hpp> @@ -84,20 +84,10 @@ using namespace std; // Please enable again when working on 1.0 #define ENABLE_SPRAY_MODE_SINGLE_PATH -#include "ui/tool-factory.h" - namespace Inkscape { namespace UI { namespace Tools { -namespace { - ToolBase* createSprayContext() { - return new SprayTool(); - } - - bool sprayContextRegistered = ToolFactory::instance().registerObject("/tools/spray", createSprayContext); -} - const std::string& SprayTool::getPrefsPath() { return SprayTool::prefsPath; } @@ -222,7 +212,7 @@ void SprayTool::setup() { SPCurve *c = new SPCurve(path); - this->dilate_area = sp_canvas_bpath_new(sp_desktop_controls(this->desktop), c); + this->dilate_area = sp_canvas_bpath_new(this->desktop->getControls(), c); c->unref(); sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(this->dilate_area), 0x00000000,(SPWindRule)0); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(this->dilate_area), 0xff9900ff, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); @@ -449,39 +439,41 @@ static bool sp_spray_recursive(SPDesktop *desktop, } i++; } - SPDocument *doc = parent_item->document; - Inkscape::XML::Document* xml_doc = doc->getReprDoc(); - Inkscape::XML::Node *old_repr = parent_item->getRepr(); - Inkscape::XML::Node *parent = old_repr->parent(); - - Geom::OptRect a = parent_item->documentVisualBounds(); - if (a) { - if (_fid <= population) { // Rules the population of objects sprayed - // Duplicates the parent item - Inkscape::XML::Node *copy = old_repr->duplicate(xml_doc); - parent->appendChild(copy); - SPObject *new_obj = doc->getObjectByRepr(copy); - item_copied = dynamic_cast<SPItem *>(new_obj); - - // Move around the cursor - Geom::Point move = (Geom::Point(cos(tilt)*cos(dp)*dr/(1-ratio)+sin(tilt)*sin(dp)*dr/(1+ratio), -sin(tilt)*cos(dp)*dr/(1-ratio)+cos(tilt)*sin(dp)*dr/(1+ratio)))+(p-a->midpoint()); - - Geom::Point center = parent_item->getCenter(); - sp_spray_scale_rel(center, desktop, item_copied, Geom::Scale(_scale, _scale)); - sp_spray_scale_rel(center, desktop, item_copied, Geom::Scale(scale, scale)); - sp_spray_rotate_rel(center, desktop, item_copied, Geom::Rotate(angle)); - sp_item_move_rel(item_copied, Geom::Translate(move[Geom::X], -move[Geom::Y])); - - // Union and duplication - selection->clear(); - selection->add(item_copied); - if (unionResult) { // No need to add the very first item (initialized with NULL). - selection->add(unionResult); + if (parent_item) { + SPDocument *doc = parent_item->document; + Inkscape::XML::Document* xml_doc = doc->getReprDoc(); + Inkscape::XML::Node *old_repr = parent_item->getRepr(); + Inkscape::XML::Node *parent = old_repr->parent(); + + Geom::OptRect a = parent_item->documentVisualBounds(); + if (a) { + if (_fid <= population) { // Rules the population of objects sprayed + // Duplicates the parent item + Inkscape::XML::Node *copy = old_repr->duplicate(xml_doc); + parent->appendChild(copy); + SPObject *new_obj = doc->getObjectByRepr(copy); + item_copied = dynamic_cast<SPItem *>(new_obj); + + // Move around the cursor + Geom::Point move = (Geom::Point(cos(tilt)*cos(dp)*dr/(1-ratio)+sin(tilt)*sin(dp)*dr/(1+ratio), -sin(tilt)*cos(dp)*dr/(1-ratio)+cos(tilt)*sin(dp)*dr/(1+ratio)))+(p-a->midpoint()); + + Geom::Point center = parent_item->getCenter(); + sp_spray_scale_rel(center, desktop, item_copied, Geom::Scale(_scale, _scale)); + sp_spray_scale_rel(center, desktop, item_copied, Geom::Scale(scale, scale)); + sp_spray_rotate_rel(center, desktop, item_copied, Geom::Rotate(angle)); + sp_item_move_rel(item_copied, Geom::Translate(move[Geom::X], -move[Geom::Y])); + + // Union and duplication + selection->clear(); + selection->add(item_copied); + if (unionResult) { // No need to add the very first item (initialized with NULL). + selection->add(unionResult); + } + sp_selected_path_union_skip_undo(selection, selection->desktop()); + selection->add(parent_item); + Inkscape::GC::release(copy); + did = true; } - sp_selected_path_union_skip_undo(selection, selection->desktop()); - selection->add(parent_item); - Inkscape::GC::release(copy); - did = true; } } #endif @@ -527,7 +519,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point p, Geom::Point vector, bool reverse) { SPDesktop *desktop = tc->desktop; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (selection->isEmpty()) { return false; @@ -735,15 +727,15 @@ bool SprayTool::root_handler(GdkEvent* event) { this->has_dilated = false; switch (this->mode) { case SPRAY_MODE_COPY: - DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(this)->desktop), + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_SPRAY, _("Spray with copies")); break; case SPRAY_MODE_CLONE: - DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(this)->desktop), + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_SPRAY, _("Spray with clones")); break; case SPRAY_MODE_SINGLE_PATH: - DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(this)->desktop), + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_SPRAY, _("Spray in single path")); break; } diff --git a/src/ui/tools/star-tool.cpp b/src/ui/tools/star-tool.cpp index b5544d263..9190ae57b 100644 --- a/src/ui/tools/star-tool.cpp +++ b/src/ui/tools/star-tool.cpp @@ -30,7 +30,7 @@ #include "document-undo.h" #include "sp-namedview.h" #include "selection.h" -#include "desktop-handles.h" + #include "snap.h" #include "desktop.h" #include "desktop-style.h" @@ -49,20 +49,10 @@ using Inkscape::DocumentUndo; -#include "ui/tool-factory.h" - namespace Inkscape { namespace UI { namespace Tools { -namespace { - ToolBase* createStarContext() { - return new StarTool(); - } - - bool starContextRegistered = ToolFactory::instance().registerObject("/tools/shapes/star", createStarContext); -} - const std::string& StarTool::getPrefsPath() { return StarTool::prefsPath; } @@ -127,12 +117,12 @@ void StarTool::setup() { this->shape_editor = new ShapeEditor(this->desktop); - SPItem *item = sp_desktop_selection(this->desktop)->singleItem(); + SPItem *item = this->desktop->getSelection()->singleItem(); if (item) { this->shape_editor->set_item(item); } - Inkscape::Selection *selection = sp_desktop_selection(this->desktop); + Inkscape::Selection *selection = this->desktop->getSelection(); this->sel_changed_connection.disconnect(); @@ -168,7 +158,7 @@ bool StarTool::root_handler(GdkEvent* event) { static bool dragging; SPDesktop *desktop = this->desktop; - Inkscape::Selection *selection = sp_desktop_selection (desktop); + Inkscape::Selection *selection = desktop->getSelection(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); this->tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100); @@ -441,8 +431,8 @@ void StarTool::finishItem() { desktop->canvas->endForcedFullRedraws(); - sp_desktop_selection(desktop)->set(this->star); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_STAR, + desktop->getSelection()->set(this->star); + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_STAR, _("Create star")); this->star = NULL; @@ -450,7 +440,7 @@ void StarTool::finishItem() { } void StarTool::cancel() { - sp_desktop_selection(desktop)->clear(); + desktop->getSelection()->clear(); sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), 0); if (this->star != NULL) { @@ -465,7 +455,7 @@ void StarTool::cancel() { desktop->canvas->endForcedFullRedraws(); - DocumentUndo::cancel(sp_desktop_document(desktop)); + DocumentUndo::cancel(desktop->getDocument()); } } diff --git a/src/ui/tools/text-tool.cpp b/src/ui/tools/text-tool.cpp index 578add843..a2c0c81ae 100644 --- a/src/ui/tools/text-tool.cpp +++ b/src/ui/tools/text-tool.cpp @@ -26,7 +26,7 @@ #include <sstream> #include "context-fns.h" -#include "desktop-handles.h" + #include "desktop-style.h" #include "desktop.h" #include "document.h" @@ -52,7 +52,6 @@ #include "xml/node-event-vector.h" #include "xml/repr.h" #include <gtk/gtk.h> -#include "ui/tool-factory.h" using Inkscape::ControlManager; using Inkscape::DocumentUndo; @@ -71,14 +70,6 @@ static gint sptc_focus_in(GtkWidget *widget, GdkEventFocus *event, TextTool *tc) static gint sptc_focus_out(GtkWidget *widget, GdkEventFocus *event, TextTool *tc); static void sptc_commit(GtkIMContext *imc, gchar *string, TextTool *tc); -namespace { - ToolBase* createTextContext() { - return new TextTool(); - } - - bool textContextRegistered = ToolFactory::instance().registerObject("/tools/text", createTextContext); -} - const std::string& TextTool::getPrefsPath() { return TextTool::prefsPath; } @@ -131,17 +122,17 @@ void TextTool::setup() { timeout /= 2; } - this->cursor = ControlManager::getManager().createControlLine(sp_desktop_controls(desktop), Geom::Point(100, 0), Geom::Point(100, 100)); + this->cursor = ControlManager::getManager().createControlLine(desktop->getControls(), Geom::Point(100, 0), Geom::Point(100, 100)); this->cursor->setRgba32(0x000000ff); sp_canvas_item_hide(this->cursor); - this->indicator = sp_canvas_item_new(sp_desktop_controls(desktop), SP_TYPE_CTRLRECT, NULL); + this->indicator = sp_canvas_item_new(desktop->getControls(), SP_TYPE_CTRLRECT, NULL); SP_CTRLRECT(this->indicator)->setRectangle(Geom::Rect(Geom::Point(0, 0), Geom::Point(100, 100))); SP_CTRLRECT(this->indicator)->setColor(0x0000ff7f, false, 0); SP_CTRLRECT(this->indicator)->setShadow(1, 0xffffff7f); sp_canvas_item_hide(this->indicator); - this->frame = sp_canvas_item_new(sp_desktop_controls(desktop), SP_TYPE_CTRLRECT, NULL); + this->frame = sp_canvas_item_new(desktop->getControls(), SP_TYPE_CTRLRECT, NULL); SP_CTRLRECT(this->frame)->setRectangle(Geom::Rect(Geom::Point(0, 0), Geom::Point(100, 100))); SP_CTRLRECT(this->frame)->setColor(0x0000ff7f, false, 0); sp_canvas_item_hide(this->frame); @@ -150,7 +141,7 @@ void TextTool::setup() { this->imc = gtk_im_multicontext_new(); if (this->imc) { - GtkWidget *canvas = GTK_WIDGET(sp_desktop_canvas(desktop)); + GtkWidget *canvas = GTK_WIDGET(desktop->getCanvas()); /* im preedit handling is very broken in inkscape for * multi-byte characters. See bug 1086769. @@ -175,15 +166,15 @@ void TextTool::setup() { this->shape_editor = new ShapeEditor(this->desktop); - SPItem *item = sp_desktop_selection(this->desktop)->singleItem(); + SPItem *item = this->desktop->getSelection()->singleItem(); if (item && SP_IS_FLOWTEXT(item) && SP_FLOWTEXT(item)->has_internal_frame()) { this->shape_editor->set_item(item); } - this->sel_changed_connection = sp_desktop_selection(desktop)->connectChangedFirst( + this->sel_changed_connection = desktop->getSelection()->connectChangedFirst( sigc::mem_fun(*this, &TextTool::_selectionChanged) ); - this->sel_modified_connection = sp_desktop_selection(desktop)->connectModifiedFirst( + this->sel_modified_connection = desktop->getSelection()->connectModifiedFirst( sigc::mem_fun(*this, &TextTool::_selectionModified) ); this->style_set_connection = desktop->connectSetStyle( @@ -193,7 +184,7 @@ void TextTool::setup() { sigc::mem_fun(*this, &TextTool::_styleQueried) ); - _selectionChanged(sp_desktop_selection(desktop)); + _selectionChanged(desktop->getSelection()); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if (prefs->getBool("/tools/text/selcue")) { @@ -206,7 +197,7 @@ void TextTool::setup() { void TextTool::finish() { if (this->desktop) { - sp_signal_disconnect_by_data(sp_desktop_canvas(this->desktop), this); + sp_signal_disconnect_by_data(this->desktop->getCanvas(), this); } this->enableGrDrag(false); @@ -268,7 +259,7 @@ bool TextTool::item_handler(SPItem* item, GdkEvent* event) { // find out clicked item, disregarding groups item_ungrouped = desktop->getItemAtPoint(Geom::Point(event->button.x, event->button.y), TRUE); if (SP_IS_TEXT(item_ungrouped) || SP_IS_FLOWTEXT(item_ungrouped)) { - sp_desktop_selection(desktop)->set(item_ungrouped); + desktop->getSelection()->set(item_ungrouped); if (this->text) { // find out click point in document coordinates Geom::Point p = desktop->w2d(Geom::Point(event->button.x, event->button.y)); @@ -425,13 +416,13 @@ static void sp_text_context_setup_text(TextTool *tc) SPItem *text_item = SP_ITEM(ec->desktop->currentLayer()->appendChildRepr(rtext)); /* fixme: Is selection::changed really immediate? */ /* yes, it's immediate .. why does it matter? */ - sp_desktop_selection(ec->desktop)->set(text_item); + ec->desktop->getSelection()->set(text_item); Inkscape::GC::release(rtext); text_item->transform = SP_ITEM(ec->desktop->currentLayer())->i2doc_affine().inverse(); text_item->updateRepr(); text_item->doWriteTransform(text_item->getRepr(), text_item->transform, NULL, true); - DocumentUndo::done(sp_desktop_document(ec->desktop), SP_VERB_CONTEXT_TEXT, + DocumentUndo::done(ec->desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("Create text")); } @@ -471,7 +462,7 @@ static void insert_uni_char(TextTool *const tc) tc->text_sel_start = tc->text_sel_end = sp_te_replace(tc->text, tc->text_sel_start, tc->text_sel_end, u); sp_text_context_update_cursor(tc); sp_text_context_update_text_selection(tc); - DocumentUndo::done(sp_desktop_document(tc->desktop), SP_VERB_DIALOG_TRANSFORM, + DocumentUndo::done(tc->desktop->getDocument(), SP_VERB_DIALOG_TRANSFORM, _("Insert Unicode character")); } } @@ -627,7 +618,7 @@ bool TextTool::root_handler(GdkEvent* event) { if (this->creating && this->within_tolerance) { /* Button 1, set X & Y & new item */ - sp_desktop_selection(desktop)->clear(); + desktop->getSelection()->clear(); this->pdoc = desktop->dt2doc(p1); this->show = TRUE; this->phase = 1; @@ -660,9 +651,9 @@ bool TextTool::root_handler(GdkEvent* event) { SPItem *ft = create_flowtext_with_internal_frame (desktop, this->p0, p1); /* Set style */ sp_desktop_apply_style_tool(desktop, ft->getRepr(), "/tools/text", true); - sp_desktop_selection(desktop)->set(ft); + desktop->getSelection()->set(ft); desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Flowed text is created.")); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, _("Create flowed text")); + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("Create flowed text")); } else { desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("The frame is <b>too small</b> for the current font size. Flowed text not created.")); } @@ -801,7 +792,7 @@ bool TextTool::root_handler(GdkEvent* event) { sp_text_context_update_cursor(this); sp_text_context_update_text_selection(this); desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("No-break space")); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, _("Insert no-break space")); + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("Insert no-break space")); return TRUE; } break; @@ -837,7 +828,7 @@ bool TextTool::root_handler(GdkEvent* event) { sp_repr_css_set_property(css, "font-weight", "normal"); sp_te_apply_style(this->text, this->text_sel_start, this->text_sel_end, css); sp_repr_css_attr_unref(css); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, _("Make bold")); + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("Make bold")); sp_text_context_update_cursor(this); sp_text_context_update_text_selection(this); return TRUE; @@ -854,7 +845,7 @@ bool TextTool::root_handler(GdkEvent* event) { sp_repr_css_set_property(css, "font-style", "italic"); sp_te_apply_style(this->text, this->text_sel_start, this->text_sel_end, css); sp_repr_css_attr_unref(css); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, _("Make italic")); + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("Make italic")); sp_text_context_update_cursor(this); sp_text_context_update_text_selection(this); return TRUE; @@ -892,7 +883,7 @@ bool TextTool::root_handler(GdkEvent* event) { sp_text_context_update_cursor(this); sp_text_context_update_text_selection(this); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, _("New line")); + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("New line")); return TRUE; } case GDK_KEY_BackSpace: @@ -933,7 +924,7 @@ bool TextTool::root_handler(GdkEvent* event) { sp_text_context_update_cursor(this); sp_text_context_update_text_selection(this); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, _("Backspace")); + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("Backspace")); } return TRUE; case GDK_KEY_Delete: @@ -971,7 +962,7 @@ bool TextTool::root_handler(GdkEvent* event) { sp_text_context_update_cursor(this); sp_text_context_update_text_selection(this); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, _("Delete")); + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("Delete")); } return TRUE; case GDK_KEY_Left: @@ -987,7 +978,7 @@ bool TextTool::root_handler(GdkEvent* event) { sp_te_adjust_kerning_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, Geom::Point(mul*-1, 0)); sp_text_context_update_cursor(this); sp_text_context_update_text_selection(this); - DocumentUndo::maybeDone(sp_desktop_document(desktop), "kern:left", SP_VERB_CONTEXT_TEXT, _("Kern to the left")); + DocumentUndo::maybeDone(desktop->getDocument(), "kern:left", SP_VERB_CONTEXT_TEXT, _("Kern to the left")); } else { if (MOD__CTRL(event)) this->text_sel_end.cursorLeftWithControl(); @@ -1011,7 +1002,7 @@ bool TextTool::root_handler(GdkEvent* event) { sp_te_adjust_kerning_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, Geom::Point(mul*1, 0)); sp_text_context_update_cursor(this); sp_text_context_update_text_selection(this); - DocumentUndo::maybeDone(sp_desktop_document(desktop), "kern:right", SP_VERB_CONTEXT_TEXT, _("Kern to the right")); + DocumentUndo::maybeDone(desktop->getDocument(), "kern:right", SP_VERB_CONTEXT_TEXT, _("Kern to the right")); } else { if (MOD__CTRL(event)) this->text_sel_end.cursorRightWithControl(); @@ -1035,7 +1026,7 @@ bool TextTool::root_handler(GdkEvent* event) { sp_te_adjust_kerning_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, Geom::Point(0, mul*-1)); sp_text_context_update_cursor(this); sp_text_context_update_text_selection(this); - DocumentUndo::maybeDone(sp_desktop_document(desktop), "kern:up", SP_VERB_CONTEXT_TEXT, _("Kern up")); + DocumentUndo::maybeDone(desktop->getDocument(), "kern:up", SP_VERB_CONTEXT_TEXT, _("Kern up")); } else { if (MOD__CTRL(event)) this->text_sel_end.cursorUpWithControl(); @@ -1059,7 +1050,7 @@ bool TextTool::root_handler(GdkEvent* event) { sp_te_adjust_kerning_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, Geom::Point(0, mul*1)); sp_text_context_update_cursor(this); sp_text_context_update_text_selection(this); - DocumentUndo::maybeDone(sp_desktop_document(desktop), "kern:down", SP_VERB_CONTEXT_TEXT, _("Kern down")); + DocumentUndo::maybeDone(desktop->getDocument(), "kern:down", SP_VERB_CONTEXT_TEXT, _("Kern down")); } else { if (MOD__CTRL(event)) this->text_sel_end.cursorDownWithControl(); @@ -1117,7 +1108,7 @@ bool TextTool::root_handler(GdkEvent* event) { } Inkscape::Rubberband::get(desktop)->stop(); } else { - sp_desktop_selection(desktop)->clear(); + desktop->getSelection()->clear(); } this->nascent_object = FALSE; return TRUE; @@ -1134,7 +1125,7 @@ bool TextTool::root_handler(GdkEvent* event) { } else { sp_te_adjust_rotation(this->text, this->text_sel_start, this->text_sel_end, desktop, -90); } - DocumentUndo::maybeDone(sp_desktop_document(desktop), "textrot:ccw", SP_VERB_CONTEXT_TEXT, _("Rotate counterclockwise")); + DocumentUndo::maybeDone(desktop->getDocument(), "textrot:ccw", SP_VERB_CONTEXT_TEXT, _("Rotate counterclockwise")); sp_text_context_update_cursor(this); sp_text_context_update_text_selection(this); return TRUE; @@ -1154,7 +1145,7 @@ bool TextTool::root_handler(GdkEvent* event) { } else { sp_te_adjust_rotation(this->text, this->text_sel_start, this->text_sel_end, desktop, 90); } - DocumentUndo::maybeDone(sp_desktop_document(desktop), "textrot:cw", SP_VERB_CONTEXT_TEXT, _("Rotate clockwise")); + DocumentUndo::maybeDone(desktop->getDocument(), "textrot:cw", SP_VERB_CONTEXT_TEXT, _("Rotate clockwise")); sp_text_context_update_cursor(this); sp_text_context_update_text_selection(this); return TRUE; @@ -1170,13 +1161,13 @@ bool TextTool::root_handler(GdkEvent* event) { sp_te_adjust_linespacing_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, -10); else sp_te_adjust_linespacing_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, -1); - DocumentUndo::maybeDone(sp_desktop_document(desktop), "linespacing:dec", SP_VERB_CONTEXT_TEXT, _("Contract line spacing")); + DocumentUndo::maybeDone(desktop->getDocument(), "linespacing:dec", SP_VERB_CONTEXT_TEXT, _("Contract line spacing")); } else { if (MOD__SHIFT(event)) sp_te_adjust_tspan_letterspacing_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, -10); else sp_te_adjust_tspan_letterspacing_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, -1); - DocumentUndo::maybeDone(sp_desktop_document(desktop), "letterspacing:dec", SP_VERB_CONTEXT_TEXT, _("Contract letter spacing")); + DocumentUndo::maybeDone(desktop->getDocument(), "letterspacing:dec", SP_VERB_CONTEXT_TEXT, _("Contract letter spacing")); } sp_text_context_update_cursor(this); sp_text_context_update_text_selection(this); @@ -1193,13 +1184,13 @@ bool TextTool::root_handler(GdkEvent* event) { sp_te_adjust_linespacing_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, 10); else sp_te_adjust_linespacing_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, 1); - DocumentUndo::maybeDone(sp_desktop_document(desktop), "linespacing:inc", SP_VERB_CONTEXT_TEXT, _("Expand line spacing")); + DocumentUndo::maybeDone(desktop->getDocument(), "linespacing:inc", SP_VERB_CONTEXT_TEXT, _("Expand line spacing")); } else { if (MOD__SHIFT(event)) sp_te_adjust_tspan_letterspacing_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, 10); else sp_te_adjust_tspan_letterspacing_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, 1); - DocumentUndo::maybeDone(sp_desktop_document(desktop), "letterspacing:inc", SP_VERB_CONTEXT_TEXT, _("Expand letter spacing"));\ + DocumentUndo::maybeDone(desktop->getDocument(), "letterspacing:inc", SP_VERB_CONTEXT_TEXT, _("Expand letter spacing"));\ } sp_text_context_update_cursor(this); sp_text_context_update_text_selection(this); @@ -1328,7 +1319,7 @@ bool sp_text_paste_inline(ToolBase *ec) tc->text_sel_start = tc->text_sel_end = sp_te_insert_line(tc->text, tc->text_sel_start); begin = end + 1; } - DocumentUndo::done(sp_desktop_document(ec->desktop), SP_VERB_CONTEXT_TEXT, + DocumentUndo::done(ec->desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("Paste text")); return true; @@ -1451,7 +1442,7 @@ bool TextTool::_styleSet(SPCSSAttr const *css) return false; // will get picked up by the parent and applied to the whole text object sp_te_apply_style(this->text, this->text_sel_start, this->text_sel_end, css); - DocumentUndo::done(sp_desktop_document(this->desktop), SP_VERB_CONTEXT_TEXT, + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("Set text style")); sp_text_context_update_cursor(this); sp_text_context_update_text_selection(this); @@ -1614,7 +1605,7 @@ static void sp_text_context_update_text_selection(TextTool *tc) quads = sp_te_create_selection_quads(tc->text, tc->text_sel_start, tc->text_sel_end, (tc->text)->i2dt_affine()); for (unsigned i = 0 ; i < quads.size() ; i += 4) { SPCanvasItem *quad_canvasitem; - quad_canvasitem = sp_canvas_item_new(sp_desktop_controls(tc->desktop), SP_TYPE_CTRLQUADR, NULL); + quad_canvasitem = sp_canvas_item_new(tc->desktop->getControls(), SP_TYPE_CTRLQUADR, NULL); // FIXME: make the color settable in prefs // for now, use semitrasparent blue, as cairo cannot do inversion :( sp_ctrlquadr_set_rgba32(SP_CTRLQUADR(quad_canvasitem), 0x00777777); @@ -1661,7 +1652,7 @@ static void sp_text_context_forget_text(TextTool *tc) // the XML editor if ( text_repr && text_repr->parent() ) { sp_repr_unparent(text_repr); - SPDocumentUndo::done(sp_desktop_document(tc->desktop), SP_VERB_CONTEXT_TEXT, + SPDocumentUndo::done(tc->desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("Remove empty text")); } } diff --git a/src/ui/tools/tool-base.cpp b/src/ui/tools/tool-base.cpp index 37ca5eeea..a07f2fb86 100644 --- a/src/ui/tools/tool-base.cpp +++ b/src/ui/tools/tool-base.cpp @@ -39,7 +39,7 @@ #include "xml/node-event-vector.h" #include "sp-cursor.h" #include "desktop.h" -#include "desktop-handles.h" + #include "desktop-events.h" #include "desktop-style.h" #include "sp-namedview.h" @@ -149,7 +149,7 @@ ToolBase::~ToolBase() { */ void ToolBase::sp_event_context_set_cursor(GdkCursorType cursor_type) { - GtkWidget *w = GTK_WIDGET(sp_desktop_canvas(this->desktop)); + GtkWidget *w = GTK_WIDGET(this->desktop->getCanvas()); GdkDisplay *display = gdk_display_get_default(); GdkCursor *cursor = gdk_cursor_new_for_display(display, cursor_type); @@ -169,7 +169,7 @@ void ToolBase::sp_event_context_set_cursor(GdkCursorType cursor_type) { * Recreates and draws cursor on desktop related to ToolBase. */ void ToolBase::sp_event_context_update_cursor() { - GtkWidget *w = GTK_WIDGET(sp_desktop_canvas(this->desktop)); + GtkWidget *w = GTK_WIDGET(this->desktop->getCanvas()); if (gtk_widget_get_window (w)) { GtkStyle *style = gtk_widget_get_style(w); @@ -530,7 +530,7 @@ bool ToolBase::root_handler(GdkEvent* event) { if (panning_cursor == 1) { panning_cursor = 0; - GtkWidget *w = GTK_WIDGET(sp_desktop_canvas(this->desktop)); + GtkWidget *w = GTK_WIDGET(this->desktop->getCanvas()); gdk_window_set_cursor(gtk_widget_get_window (w), this->cursor); } @@ -641,7 +641,7 @@ bool ToolBase::root_handler(GdkEvent* event) { case GDK_KEY_KP_4: if (MOD__CTRL_ONLY(event)) { int i = (int) floor(key_scroll * accelerate_scroll(event, - acceleration, sp_desktop_canvas(desktop))); + acceleration, desktop->getCanvas())); gobble_key_events(get_group0_keyval(&event->key), GDK_CONTROL_MASK); this->desktop->scroll_world(i, 0); @@ -654,7 +654,7 @@ bool ToolBase::root_handler(GdkEvent* event) { case GDK_KEY_KP_8: if (MOD__CTRL_ONLY(event)) { int i = (int) floor(key_scroll * accelerate_scroll(event, - acceleration, sp_desktop_canvas(desktop))); + acceleration, desktop->getCanvas())); gobble_key_events(get_group0_keyval(&event->key), GDK_CONTROL_MASK); this->desktop->scroll_world(0, i); @@ -667,7 +667,7 @@ bool ToolBase::root_handler(GdkEvent* event) { case GDK_KEY_KP_6: if (MOD__CTRL_ONLY(event)) { int i = (int) floor(key_scroll * accelerate_scroll(event, - acceleration, sp_desktop_canvas(desktop))); + acceleration, desktop->getCanvas())); gobble_key_events(get_group0_keyval(&event->key), GDK_CONTROL_MASK); this->desktop->scroll_world(-i, 0); @@ -680,7 +680,7 @@ bool ToolBase::root_handler(GdkEvent* event) { case GDK_KEY_KP_2: if (MOD__CTRL_ONLY(event)) { int i = (int) floor(key_scroll * accelerate_scroll(event, - acceleration, sp_desktop_canvas(desktop))); + acceleration, desktop->getCanvas())); gobble_key_events(get_group0_keyval(&event->key), GDK_CONTROL_MASK); this->desktop->scroll_world(0, -i); @@ -740,7 +740,7 @@ bool ToolBase::root_handler(GdkEvent* event) { if (panning_cursor == 1) { panning_cursor = 0; - GtkWidget *w = GTK_WIDGET(sp_desktop_canvas(this->desktop)); + GtkWidget *w = GTK_WIDGET(this->desktop->getCanvas()); gdk_window_set_cursor(gtk_widget_get_window (w), this->cursor); } @@ -1083,7 +1083,7 @@ void sp_event_root_menu_popup(SPDesktop *desktop, SPItem *item, GdkEvent *event) /* fixme: This is not what I want but works for now (Lauris) */ if (event->type == GDK_KEY_PRESS) { - item = sp_desktop_selection(desktop)->singleItem(); + item = desktop->getSelection()->singleItem(); } ContextMenu* CM = new ContextMenu(desktop, item); diff --git a/src/ui/tools/tweak-tool.cpp b/src/ui/tools/tweak-tool.cpp index f56975de2..80b52fba6 100644 --- a/src/ui/tools/tweak-tool.cpp +++ b/src/ui/tools/tweak-tool.cpp @@ -28,7 +28,7 @@ #include "selection.h" #include "desktop.h" #include "desktop-events.h" -#include "desktop-handles.h" + #include "desktop-style.h" #include "message-context.h" #include "pixmaps/cursor-tweak-move.xpm" @@ -91,20 +91,10 @@ using Inkscape::DocumentUndo; #define DYNA_MIN_WIDTH 1.0e-6 -#include "ui/tool-factory.h" - namespace Inkscape { namespace UI { namespace Tools { -namespace { - ToolBase* createTweakContext() { - return new TweakTool(); - } - - bool tweakContextRegistered = ToolFactory::instance().registerObject("/tools/tweak", createTweakContext); -} - const std::string& TweakTool::getPrefsPath() { return TweakTool::prefsPath; } @@ -274,7 +264,7 @@ void TweakTool::setup() { SPCurve *c = new SPCurve(path); - this->dilate_area = sp_canvas_bpath_new(sp_desktop_controls(this->desktop), c); + this->dilate_area = sp_canvas_bpath_new(this->desktop->getControls(), c); c->unref(); sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(this->dilate_area), 0x00000000,(SPWindRule)0); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(this->dilate_area), 0xff9900ff, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); @@ -1032,7 +1022,7 @@ sp_tweak_color_recursive (guint mode, SPItem *item, SPItem *item_at_point, static bool sp_tweak_dilate (TweakTool *tc, Geom::Point event_p, Geom::Point p, Geom::Point vector, bool reverse) { - Inkscape::Selection *selection = sp_desktop_selection(SP_EVENT_CONTEXT(tc)->desktop); + Inkscape::Selection *selection = tc->desktop->getSelection(); SPDesktop *desktop = SP_EVENT_CONTEXT(tc)->desktop; if (selection->isEmpty()) { @@ -1235,55 +1225,55 @@ bool TweakTool::root_handler(GdkEvent* event) { this->has_dilated = false; switch (this->mode) { case TWEAK_MODE_MOVE: - DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(this)->desktop), + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_TWEAK, _("Move tweak")); break; case TWEAK_MODE_MOVE_IN_OUT: - DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(this)->desktop), + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_TWEAK, _("Move in/out tweak")); break; case TWEAK_MODE_MOVE_JITTER: - DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(this)->desktop), + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_TWEAK, _("Move jitter tweak")); break; case TWEAK_MODE_SCALE: - DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(this)->desktop), + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_TWEAK, _("Scale tweak")); break; case TWEAK_MODE_ROTATE: - DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(this)->desktop), + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_TWEAK, _("Rotate tweak")); break; case TWEAK_MODE_MORELESS: - DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(this)->desktop), + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_TWEAK, _("Duplicate/delete tweak")); break; case TWEAK_MODE_PUSH: - DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(this)->desktop), + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_TWEAK, _("Push path tweak")); break; case TWEAK_MODE_SHRINK_GROW: - DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(this)->desktop), + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_TWEAK, _("Shrink/grow path tweak")); break; case TWEAK_MODE_ATTRACT_REPEL: - DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(this)->desktop), + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_TWEAK, _("Attract/repel path tweak")); break; case TWEAK_MODE_ROUGHEN: - DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(this)->desktop), + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_TWEAK, _("Roughen path tweak")); break; case TWEAK_MODE_COLORPAINT: - DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(this)->desktop), + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_TWEAK, _("Color paint tweak")); break; case TWEAK_MODE_COLORJITTER: - DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(this)->desktop), + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_TWEAK, _("Color jitter tweak")); break; case TWEAK_MODE_BLUR: - DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(this)->desktop), + DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_TWEAK, _("Blur tweak")); break; } diff --git a/src/ui/tools/zoom-tool.cpp b/src/ui/tools/zoom-tool.cpp index b3fb78c8f..6a4d4dbbd 100644 --- a/src/ui/tools/zoom-tool.cpp +++ b/src/ui/tools/zoom-tool.cpp @@ -25,20 +25,11 @@ #include "selection-chemistry.h" #include "ui/tools/zoom-tool.h" -#include "ui/tool-factory.h" namespace Inkscape { namespace UI { namespace Tools { -namespace { - ToolBase* createZoomContext() { - return new ZoomTool(); - } - - bool zoomContextRegistered = ToolFactory::instance().registerObject("/tools/zoom", createZoomContext); -} - const std::string& ZoomTool::getPrefsPath() { return ZoomTool::prefsPath; } diff --git a/src/ui/view/view.cpp b/src/ui/view/view.cpp index 72548e213..47e2a1e0d 100644 --- a/src/ui/view/view.cpp +++ b/src/ui/view/view.cpp @@ -20,7 +20,7 @@ #include "message-stack.h" #include "message-context.h" #include "verbs.h" -#include "inkscape-private.h" +#include "inkscape.h" namespace Inkscape { namespace UI { @@ -85,7 +85,7 @@ void View::_close() { if (_doc) { _document_uri_set_connection.disconnect(); _document_resized_connection.disconnect(); - if (inkscape_remove_document(_doc)) { + if (INKSCAPE.remove_document(_doc)) { // this was the last view of this document, so delete it delete _doc; } @@ -111,13 +111,13 @@ void View::setDocument(SPDocument *doc) { if (_doc) { _document_uri_set_connection.disconnect(); _document_resized_connection.disconnect(); - if (inkscape_remove_document(_doc)) { + if (INKSCAPE.remove_document(_doc)) { // this was the last view of this document, so delete it delete _doc; } } - inkscape_add_document(doc); + INKSCAPE.add_document(doc); _doc = doc; _document_uri_set_connection = diff --git a/src/ui/view/view.h b/src/ui/view/view.h index 48f4d2549..21a5d0dfc 100644 --- a/src/ui/view/view.h +++ b/src/ui/view/view.h @@ -15,7 +15,7 @@ #include <stddef.h> #include <sigc++/connection.h> #include "message.h" -#include "gc-managed.h" +#include "inkgc/gc-managed.h" #include "gc-finalized.h" #include "gc-anchored.h" #include <2geom/forward.h> diff --git a/src/ui/widget/addtoicon.cpp b/src/ui/widget/addtoicon.cpp index 0798d1c98..f15d7abf7 100644 --- a/src/ui/widget/addtoicon.cpp +++ b/src/ui/widget/addtoicon.cpp @@ -23,6 +23,7 @@ #include "widgets/icon.h" #include "widgets/toolbox.h" #include "ui/icon-names.h" +#include "preferences.h" #include "layertypeicon.h" #include "addtoicon.h" @@ -39,6 +40,7 @@ AddToIcon::AddToIcon() : { property_mode() = Gtk::CELL_RENDERER_MODE_ACTIVATABLE; phys = sp_icon_get_phys_size((int)Inkscape::ICON_SIZE_BUTTON); + // Glib::RefPtr<Gtk::IconTheme> icon_theme = Gtk::IconTheme::get_default(); // // if (!icon_theme->has_icon(_pixAddName)) { @@ -50,7 +52,8 @@ AddToIcon::AddToIcon() : // // _property_pixbuf_add = Gtk::Widget:: - property_stock_id() = GTK_STOCK_ADD; + //property_stock_id() = GTK_STOCK_ADD; + set_pixbuf(); } @@ -118,7 +121,7 @@ void AddToIcon::render_vfunc( const Glib::RefPtr<Gdk::Drawable>& window, Gtk::CellRendererState flags ) #endif { - property_stock_id() = property_active().get_value() ? GTK_STOCK_ADD : GTK_STOCK_DELETE; + set_pixbuf(); #if WITH_GTKMM_3_0 Gtk::CellRendererPixbuf::render_vfunc( cr, widget, background_area, cell_area, flags ); @@ -137,6 +140,14 @@ bool AddToIcon::activate_vfunc(GdkEvent* /*event*/, return false; } +void AddToIcon::set_pixbuf() +{ + bool active = property_active().get_value(); + + GdkPixbuf *pixbuf = sp_pixbuf_new(Inkscape::ICON_SIZE_BUTTON, active ? INKSCAPE_ICON("list-add") : INKSCAPE_ICON("edit-delete")); + property_pixbuf() = Glib::wrap(pixbuf); +} + } // namespace Widget } // namespace UI @@ -152,5 +163,3 @@ bool AddToIcon::activate_vfunc(GdkEvent* /*event*/, End: */ // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : - - diff --git a/src/ui/widget/addtoicon.h b/src/ui/widget/addtoicon.h index 9c134d231..a8d900d1f 100644 --- a/src/ui/widget/addtoicon.h +++ b/src/ui/widget/addtoicon.h @@ -74,7 +74,7 @@ private: Glib::Property<bool> _property_active; // Glib::Property< Glib::RefPtr<Gdk::Pixbuf> > _property_pixbuf_add; - + void set_pixbuf(); }; diff --git a/src/ui/widget/color-picker.cpp b/src/ui/widget/color-picker.cpp index 6b5a351f6..d4c4d394e 100644 --- a/src/ui/widget/color-picker.cpp +++ b/src/ui/widget/color-picker.cpp @@ -12,7 +12,7 @@ #include "color-picker.h" #include "inkscape.h" -#include "desktop-handles.h" +#include "desktop.h" #include "document.h" #include "document-undo.h" #include "ui/dialog-events.h" @@ -128,7 +128,7 @@ void sp_color_picker_color_mod(SPColorSelector *csel, GObject *cp) (ptr->_preview).setRgba32 (rgba); if (ptr->_undo && SP_ACTIVE_DESKTOP) - DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_NONE, + DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_NONE, /* TODO: annotate */ "color-picker.cpp:130"); ptr->on_changed (rgba); diff --git a/src/ui/widget/dock.cpp b/src/ui/widget/dock.cpp index 52e9ea605..c5e14d4f0 100644 --- a/src/ui/widget/dock.cpp +++ b/src/ui/widget/dock.cpp @@ -119,8 +119,9 @@ Dock::Dock(Gtk::Orientation orientation) gdl_dock_bar_set_style(_gdl_dock_bar, gdl_dock_bar_style); - g_signal_connect(G_OBJECT(INKSCAPE), "dialogs_hide", G_CALLBACK(hideCallback), (void *)this); - g_signal_connect(G_OBJECT(INKSCAPE), "dialogs_unhide", G_CALLBACK(unhideCallback), (void *)this); + + INKSCAPE.signal_dialogs_hide.connect(sigc::mem_fun(*this, &Dock::hide)); + INKSCAPE.signal_dialogs_unhide.connect(sigc::mem_fun(*this, &Dock::show)); g_signal_connect(_paned->gobj(), "button-press-event", G_CALLBACK(_on_paned_button_event), (void *)this); g_signal_connect(_paned->gobj(), "button-release-event", G_CALLBACK(_on_paned_button_event), (void *)this); diff --git a/src/ui/widget/filter-effect-chooser.cpp b/src/ui/widget/filter-effect-chooser.cpp index 4754b9c23..242a99073 100644 --- a/src/ui/widget/filter-effect-chooser.cpp +++ b/src/ui/widget/filter-effect-chooser.cpp @@ -13,7 +13,7 @@ #include <glibmm/i18n.h> #include "desktop.h" -#include "desktop-handles.h" + #include "document.h" #include "inkscape.h" diff --git a/src/ui/widget/imageicon.cpp b/src/ui/widget/imageicon.cpp index 22abd04ba..df261b69a 100644 --- a/src/ui/widget/imageicon.cpp +++ b/src/ui/widget/imageicon.cpp @@ -88,8 +88,9 @@ ImageIcon::~ImageIcon() */ void ImageIcon::init() { - if (!INKSCAPE) - inkscape_application_init("",false); + // \FIXME Why? + if (!Inkscape::Application::exists()) + Inkscape::Application::create("", false); document = NULL; viewerGtkmm = NULL; //set_size_request(150,150); diff --git a/src/ui/widget/layer-selector.cpp b/src/ui/widget/layer-selector.cpp index 7b1a8dbfb..dc89d233f 100644 --- a/src/ui/widget/layer-selector.cpp +++ b/src/ui/widget/layer-selector.cpp @@ -21,7 +21,7 @@ #include <glibmm/i18n.h> #include "desktop.h" -#include "desktop-handles.h" + #include "document.h" #include "document-undo.h" #include "layer-manager.h" @@ -601,7 +601,7 @@ void LayerSelector::_prepareLabelRenderer( void LayerSelector::_lockLayer(bool lock) { if ( _layer && SP_IS_ITEM(_layer) ) { SP_ITEM(_layer)->setLocked(lock); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_NONE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_NONE, lock? _("Lock layer") : _("Unlock layer")); } } @@ -609,7 +609,7 @@ void LayerSelector::_lockLayer(bool lock) { void LayerSelector::_hideLayer(bool hide) { if ( _layer && SP_IS_ITEM(_layer) ) { SP_ITEM(_layer)->setHidden(hide); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_NONE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_NONE, hide? _("Hide layer") : _("Unhide layer")); } } diff --git a/src/ui/widget/licensor.cpp b/src/ui/widget/licensor.cpp index 7429bb07e..d21e848f2 100644 --- a/src/ui/widget/licensor.cpp +++ b/src/ui/widget/licensor.cpp @@ -69,7 +69,7 @@ void LicenseItem::on_toggled() SPDocument *doc = SP_ACTIVE_DOCUMENT; rdf_set_license (doc, _lic->details ? _lic : 0); if (doc->priv->sensitive) { - DocumentUndo::done(doc, SP_VERB_NONE, "Document license updated"); + DocumentUndo::done(doc, SP_VERB_NONE, _("Document license updated")); } _wr.setUpdating (false); static_cast<Gtk::Entry*>(_eep->_packable)->set_text (_lic->uri); diff --git a/src/ui/widget/object-composite-settings.cpp b/src/ui/widget/object-composite-settings.cpp index e4cd76345..00a74c4fe 100644 --- a/src/ui/widget/object-composite-settings.cpp +++ b/src/ui/widget/object-composite-settings.cpp @@ -17,7 +17,7 @@ #include <glibmm/i18n.h> #include "desktop.h" -#include "desktop-handles.h" + #include "desktop-style.h" #include "document.h" #include "document-undo.h" @@ -39,26 +39,6 @@ namespace Inkscape { namespace UI { namespace Widget { -/*void ObjectCompositeSettings::_on_desktop_activate( - InkscapeApplication *application, - SPDesktop *desktop, - ObjectCompositeSettings *w -) { - if (w->_subject) { - w->_subject->setDesktop(desktop); - } -} - -void ObjectCompositeSettings::_on_desktop_deactivate( - InkscapeApplication *application, - SPDesktop *desktop, - ObjectCompositeSettings *w -) { - if (w->_subject) { - w->_subject->setDesktop(NULL); - } -}*/ - ObjectCompositeSettings::ObjectCompositeSettings(unsigned int verb_code, char const *history_prefix, int flags) : _verb_code(verb_code), _blur_tag(Glib::ustring(history_prefix) + ":blur"), @@ -102,7 +82,6 @@ ObjectCompositeSettings::ObjectCompositeSettings(unsigned int verb_code, char co ObjectCompositeSettings::~ObjectCompositeSettings() { setSubject(NULL); - g_signal_handler_disconnect(G_OBJECT(INKSCAPE), _desktop_activated); } void ObjectCompositeSettings::setSubject(StyleSubject *subject) { @@ -125,14 +104,14 @@ ObjectCompositeSettings::_blendBlurValueChanged() if (!desktop) { return; } - SPDocument *document = sp_desktop_document (desktop); + SPDocument *document = desktop->getDocument(); if (_blocked) return; _blocked = true; // FIXME: fix for GTK breakage, see comment in SelectedStyle::on_opacity_changed; here it results in crash 1580903 - //sp_canvas_force_full_redraw_after_interruptions(sp_desktop_canvas(desktop), 0); + //sp_canvas_force_full_redraw_after_interruptions(desktop->getCanvas(), 0); Geom::OptRect bbox = _subject->getBounds(SPItem::GEOMETRIC_BBOX); double radius; @@ -180,7 +159,7 @@ ObjectCompositeSettings::_blendBlurValueChanged() _("Change blur")); // resume interruptibility - //sp_canvas_end_forced_full_redraws(sp_desktop_canvas(desktop)); + //sp_canvas_end_forced_full_redraws(desktop->getCanvas()); _blocked = false; } @@ -204,7 +183,7 @@ ObjectCompositeSettings::_opacityValueChanged() // FIXME: fix for GTK breakage, see comment in SelectedStyle::on_opacity_changed; here it results in crash 1580903 // UPDATE: crash fixed in GTK+ 2.10.7 (bug 374378), remove this as soon as it's reasonably common // (though this only fixes the crash, not the multiple change events) - //sp_canvas_force_full_redraw_after_interruptions(sp_desktop_canvas(desktop), 0); + //sp_canvas_force_full_redraw_after_interruptions(desktop->getCanvas(), 0); SPCSSAttr *css = sp_repr_css_attr_new (); @@ -216,11 +195,11 @@ ObjectCompositeSettings::_opacityValueChanged() sp_repr_css_attr_unref (css); - DocumentUndo::maybeDone(sp_desktop_document (desktop), _opacity_tag.c_str(), _verb_code, + DocumentUndo::maybeDone(desktop->getDocument(), _opacity_tag.c_str(), _verb_code, _("Change opacity")); // resume interruptibility - //sp_canvas_end_forced_full_redraws(sp_desktop_canvas(desktop)); + //sp_canvas_end_forced_full_redraws(desktop->getCanvas()); _blocked = false; } @@ -240,8 +219,8 @@ ObjectCompositeSettings::_subjectChanged() { return; _blocked = true; - SPStyle *query = sp_style_new (sp_desktop_document(desktop)); - int result = _subject->queryStyle(query, QUERY_STYLE_PROPERTY_MASTEROPACITY); + SPStyle query(desktop->getDocument()); + int result = _subject->queryStyle(&query, QUERY_STYLE_PROPERTY_MASTEROPACITY); switch (result) { case QUERY_STYLE_NOTHING: @@ -252,19 +231,19 @@ ObjectCompositeSettings::_subjectChanged() { case QUERY_STYLE_MULTIPLE_AVERAGED: // TODO: treat this slightly differently case QUERY_STYLE_MULTIPLE_SAME: _opacity_vbox.set_sensitive(true); - _opacity_scale.get_adjustment()->set_value(100 * SP_SCALE24_TO_FLOAT(query->opacity.value)); + _opacity_scale.get_adjustment()->set_value(100 * SP_SCALE24_TO_FLOAT(query.opacity.value)); break; } //query now for current filter mode and average blurring of selection - const int blend_result = _subject->queryStyle(query, QUERY_STYLE_PROPERTY_BLEND); + const int blend_result = _subject->queryStyle(&query, QUERY_STYLE_PROPERTY_BLEND); switch(blend_result) { case QUERY_STYLE_NOTHING: _fe_cb.set_sensitive(false); break; case QUERY_STYLE_SINGLE: case QUERY_STYLE_MULTIPLE_SAME: - _fe_cb.set_blend_mode(query->filter_blend_mode.value); + _fe_cb.set_blend_mode(query.filter_blend_mode.value); _fe_cb.set_sensitive(true); break; case QUERY_STYLE_MULTIPLE_DIFFERENT: @@ -274,7 +253,7 @@ ObjectCompositeSettings::_subjectChanged() { } if(blend_result == QUERY_STYLE_SINGLE || blend_result == QUERY_STYLE_MULTIPLE_SAME) { - int blur_result = _subject->queryStyle(query, QUERY_STYLE_PROPERTY_BLUR); + int blur_result = _subject->queryStyle(&query, QUERY_STYLE_PROPERTY_BLUR); switch (blur_result) { case QUERY_STYLE_NOTHING: //no blurring _fe_cb.set_blur_sensitive(false); @@ -287,7 +266,7 @@ ObjectCompositeSettings::_subjectChanged() { double perimeter = bbox->dimensions()[Geom::X] + bbox->dimensions()[Geom::Y]; // fixme: this is only half the perimeter, is that correct? _fe_cb.set_blur_sensitive(true); //update blur widget value - float radius = query->filter_gaussianBlur_deviation.value; + float radius = query.filter_gaussianBlur_deviation.value; float percent = radius * 400 / perimeter; // so that for a square, 100% == half side _fe_cb.set_blur_value(percent); } @@ -295,8 +274,6 @@ ObjectCompositeSettings::_subjectChanged() { } } - sp_style_unref(query); - _blocked = false; } diff --git a/src/ui/widget/object-composite-settings.h b/src/ui/widget/object-composite-settings.h index e375bf24a..5a723a2fd 100644 --- a/src/ui/widget/object-composite-settings.h +++ b/src/ui/widget/object-composite-settings.h @@ -66,8 +66,8 @@ private: gulong _desktop_activated; sigc::connection _subject_changed; - static void _on_desktop_activate(InkscapeApplication *application, SPDesktop *desktop, ObjectCompositeSettings *w); - static void _on_desktop_deactivate(InkscapeApplication *application, SPDesktop *desktop, ObjectCompositeSettings *w); + static void _on_desktop_activate(SPDesktop *desktop, ObjectCompositeSettings *w); + static void _on_desktop_deactivate(SPDesktop *desktop, ObjectCompositeSettings *w); void _subjectChanged(); void _blendBlurValueChanged(); void _opacityValueChanged(); diff --git a/src/ui/widget/page-sizer.cpp b/src/ui/widget/page-sizer.cpp index b775b3c49..8e647ebb4 100644 --- a/src/ui/widget/page-sizer.cpp +++ b/src/ui/widget/page-sizer.cpp @@ -26,13 +26,14 @@ #include <cmath> #include <string> #include <string.h> +#include <sstream> #include <vector> #include <glibmm/i18n.h> #include <2geom/transforms.h> -#include "desktop-handles.h" + #include "document.h" #include "desktop.h" #include "helper/action.h" @@ -240,6 +241,8 @@ PageSizer::PageSizer(Registry & _wr) _marginRight( _("Ri_ght:"), _("Right margin"), "fit-margin-right", _wr), _marginBottom( _("Botto_m:"), _("Bottom margin"), "fit-margin-bottom", _wr), _lockMarginUpdate(false), + _scaleX(_("Scale _x:"), _("Scale X"), "scale-x", _wr), + _lockScaleUpdate(false), _widgetRegistry(&_wr) { // set precision of scalar entry boxes @@ -250,6 +253,8 @@ PageSizer::PageSizer(Registry & _wr) _marginLeft.setDigits(5); _marginRight.setDigits(5); _marginBottom.setDigits(5); + _scaleX.setDigits(5); + _scaleX.setRange( 0.00001, 100000 ); _wr.setUpdating (false); //# Set up the Paper Size combo box @@ -309,7 +314,7 @@ PageSizer::PageSizer(Registry & _wr) // Setting default custom unit to document unit SPDesktop *dt = SP_ACTIVE_DESKTOP; - SPNamedView *nv = sp_desktop_namedview(dt); + SPNamedView *nv = dt->getNamedView(); _wr.setUpdating (true); if (nv->page_size_units) { _dimensionUnits.setUnit(nv->page_size_units->abbr); @@ -318,6 +323,7 @@ PageSizer::PageSizer(Registry & _wr) } _wr.setUpdating (false); + //## Set up custom size frame _customFrame.set_label(_("Custom size")); pack_start (_customFrame, false, false, 0); @@ -419,6 +425,34 @@ PageSizer::PageSizer(Registry & _wr) _fitPageButton.set_label(_("_Resize page to drawing or selection")); _fitPageButton.set_tooltip_text(_("Resize the page to fit the current selection, or the entire drawing if there is no selection")); + _scaleFrame.set_label(_("Scale")); + pack_start (_scaleFrame, false, false, 0); + _scaleFrame.add(_scaleTable); + + _scaleTable.set_border_width(4); + +#if WITH_GTKMM_3_0 + _scaleTable.set_row_spacing(4); + _scaleTable.set_column_spacing(4); + + _dimensionWidth.set_hexpand(); + _dimensionWidth.set_vexpand(); + _scaleTable.attach(_scaleX, 0, 0, 1, 1); + + _dimensionUnits.set_hexpand(); + _dimensionUnits.set_vexpand(); + _scaleTable.attach(_scaleLabel, 1, 0, 1, 1); +#else + _scaleTable.resize(2, 1); + _scaleTable.set_row_spacings(4); + _scaleTable.set_col_spacings(4); + _scaleTable.attach(_scaleX, 0,1, 0,1); + _scaleTable.attach(_scaleLabel, 1,2, 0,1); +#endif + + _wr.setUpdating (true); + updateScaleUI(); + _wr.setUpdating (false); } @@ -444,7 +478,7 @@ PageSizer::init () _changedh_connection = _dimensionHeight.signal_value_changed().connect (sigc::mem_fun (*this, &PageSizer::on_value_changed)); _changedu_connection = _dimensionUnits.getUnitMenu()->signal_changed().connect (sigc::mem_fun (*this, &PageSizer::on_units_changed)); _fitPageButton.signal_clicked().connect(sigc::mem_fun(*this, &PageSizer::fire_fit_canvas_to_selection_or_drawing)); - + _changeds_connection = _scaleX.signal_value_changed().connect (sigc::mem_fun (*this, &PageSizer::on_scale_changed)); show_all_children(); } @@ -459,7 +493,7 @@ PageSizer::init () * \param changeList whether to modify the paper size list */ void -PageSizer::setDim (Inkscape::Util::Quantity w, Inkscape::Util::Quantity h, bool changeList) +PageSizer::setDim (Inkscape::Util::Quantity w, Inkscape::Util::Quantity h, bool changeList, bool changeSize) { static bool _called = false; if (_called) { @@ -477,14 +511,15 @@ PageSizer::setDim (Inkscape::Util::Quantity w, Inkscape::Util::Quantity h, bool _unit = w.unit->abbr; if (SP_ACTIVE_DESKTOP && !_widgetRegistry->isUpdating()) { - SPDocument *doc = sp_desktop_document(SP_ACTIVE_DESKTOP); + SPDocument *doc = SP_ACTIVE_DESKTOP->getDocument(); Inkscape::Util::Quantity const old_height = doc->getHeight(); - doc->setWidth (w); - doc->setHeight (h); + doc->setWidthAndHeight (w, h, changeSize); // The origin for the user is in the lower left corner; this point should remain stationary when // changing the page size. The SVG's origin however is in the upper left corner, so we must compensate for this - Geom::Translate const vert_offset(Geom::Point(0, (old_height.value("px") - h.value("px")))); - doc->getRoot()->translateChildItems(vert_offset); + if (changeSize) { + Geom::Translate const vert_offset(Geom::Point(0, (old_height.value("px") - h.value("px")))); + doc->getRoot()->translateChildItems(vert_offset); + } DocumentUndo::done(doc, SP_VERB_NONE, _("Set page size")); } @@ -511,6 +546,7 @@ PageSizer::setDim (Inkscape::Util::Quantity w, Inkscape::Util::Quantity h, bool _dimensionHeight.setUnit(h.unit->abbr); _dimensionHeight.setValue (h.quantity); + _paper_size_list_connection.unblock(); _landscape_connection.unblock(); _portrait_connection.unblock(); @@ -606,7 +642,7 @@ PageSizer::fire_fit_canvas_to_selection_or_drawing() SPNamedView *nv; Inkscape::XML::Node *nv_repr; - if ((doc = sp_desktop_document(SP_ACTIVE_DESKTOP)) + if ((doc = SP_ACTIVE_DESKTOP->getDocument()) && (nv = sp_document_namedview(doc, 0)) && (nv_repr = nv->getRepr())) { _lockMarginUpdate = true; @@ -700,6 +736,60 @@ PageSizer::on_landscape() } } + +/** + * Update scale widgets + */ +void +PageSizer::updateScaleUI() +{ + + if (_lockScaleUpdate) { + return; + } + + static bool _called = false; + if (_called) { + return; + } + + _called = true; + + _changeds_connection.block(); + + SPDesktop *dt = SP_ACTIVE_DESKTOP; + if (dt) { + SPDocument *doc = dt->getDocument(); + Geom::Scale scale = doc->getDocumentScale(); + + SPNamedView *nv = dt->getNamedView(); + + std::stringstream ss; + ss << _("User units per ") << nv->display_units->abbr << "." ; + _scaleLabel.set_text( ss.str() ); + + double scaleX_inv = + Inkscape::Util::Quantity::convert( scale[Geom::X], "px", nv->display_units ); + if( scaleX_inv > 0 ) { + _scaleX.setValue(1.0/scaleX_inv); + } else { + // Should never happen + std::cerr << "PageSizer::updateScaleUI(): Invalid scale value: " << scaleX_inv << std::endl; + _scaleX.setValue(1.0); + } + + } else { + // Should never happen + std::cerr << "PageSizer::updateScaleUI(): No active desktop." << std::endl; + _scaleLabel.set_text( "Unknown scale" ); + } + + _changeds_connection.unblock(); + + _called = false; +} + + /** * Callback for the dimension widgets */ @@ -717,7 +807,34 @@ PageSizer::on_units_changed() if (_widgetRegistry->isUpdating()) return; _unit = _dimensionUnits.getUnit()->abbr; setDim (Inkscape::Util::Quantity(_dimensionWidth.getValue(""), _dimensionUnits.getUnit()), - Inkscape::Util::Quantity(_dimensionHeight.getValue(""), _dimensionUnits.getUnit())); + Inkscape::Util::Quantity(_dimensionHeight.getValue(""), _dimensionUnits.getUnit()), + true, false); +} + +/** + * Callback for scale widgets + */ +void +PageSizer::on_scale_changed() +{ + if (_widgetRegistry->isUpdating()) return; + + double value = _scaleX.getValue(); + if( value > 0 ) { + + SPDesktop *dt = SP_ACTIVE_DESKTOP; + if (dt) { + SPDocument *doc = dt->getDocument(); + SPNamedView *nv = dt->getNamedView(); + + double scaleX_inv = Inkscape::Util::Quantity(1.0/value, nv->display_units ).value("px"); + + _lockScaleUpdate = true; + doc->setDocumentScale( 1.0/scaleX_inv ); + _lockScaleUpdate = false; + DocumentUndo::done(doc, SP_VERB_NONE, _("Set page scale")); + } + } } } // namespace Widget diff --git a/src/ui/widget/page-sizer.h b/src/ui/widget/page-sizer.h index f4bcae4b6..f9a72d9f3 100644 --- a/src/ui/widget/page-sizer.h +++ b/src/ui/widget/page-sizer.h @@ -161,7 +161,7 @@ public: * Set the page size to the given dimensions. If 'changeList' is * true, then reset the paper size list to the closest match */ - void setDim (Inkscape::Util::Quantity w, Inkscape::Util::Quantity h, bool changeList=true); + void setDim (Inkscape::Util::Quantity w, Inkscape::Util::Quantity h, bool changeList=true, bool changeSize=true); /** * Updates the scalar widgets for the fit margins. (Just changes the value @@ -169,6 +169,11 @@ public: */ void updateFitMarginsUI(Inkscape::XML::Node *nv_repr); + /** + * Updates the scale widgets. (Just changes the values of the ui widgets.) + */ + void updateScaleUI(); + protected: /** @@ -250,12 +255,26 @@ protected: Gtk::Button _fitPageButton; bool _lockMarginUpdate; + // Document scale + Gtk::Frame _scaleFrame; +#if WITH_GTKMM_3_0 + Gtk::Grid _scaleTable; +#else + Gtk::Table _scaleTable; +#endif + + Gtk::Label _scaleLabel; + RegisteredScalar _scaleX; + bool _lockScaleUpdate; + //callback void on_value_changed(); void on_units_changed(); + void on_scale_changed(); sigc::connection _changedw_connection; sigc::connection _changedh_connection; sigc::connection _changedu_connection; + sigc::connection _changeds_connection; Registry *_widgetRegistry; diff --git a/src/ui/widget/panel.cpp b/src/ui/widget/panel.cpp index 0abd81b16..0cff25d88 100644 --- a/src/ui/widget/panel.cpp +++ b/src/ui/widget/panel.cpp @@ -33,7 +33,8 @@ #include "panel.h" #include "icon-size.h" #include "preferences.h" -#include "desktop-handles.h" +#include "desktop.h" + #include "inkscape.h" #include "widgets/eek-preview.h" #include "ui/previewfillable.h" @@ -293,7 +294,7 @@ void Panel::_init() signalResponse().connect(sigc::mem_fun(*this, &Panel::_handleResponse)); - signalActivateDesktop().connect(sigc::hide<0>(sigc::mem_fun(*this, &Panel::setDesktop))); + signalActivateDesktop().connect(sigc::mem_fun(*this, &Panel::setDesktop)); show_all_children(); @@ -643,13 +644,13 @@ Panel::signalDocumentReplaced() return _signal_document_replaced; } -sigc::signal<void, InkscapeApplication *, SPDesktop *> & +sigc::signal<void, SPDesktop *> & Panel::signalActivateDesktop() { return _signal_activate_desktop; } -sigc::signal<void, InkscapeApplication *, SPDesktop *> & +sigc::signal<void, SPDesktop *> & Panel::signalDeactiveDesktop() { return _signal_deactive_desktop; @@ -667,7 +668,7 @@ void Panel::_handleResponse(int response_id) Inkscape::Selection *Panel::_getSelection() { - return sp_desktop_selection(_desktop); + return _desktop->getSelection(); } } // namespace Widget diff --git a/src/ui/widget/panel.h b/src/ui/widget/panel.h index 177314797..5680cac30 100644 --- a/src/ui/widget/panel.h +++ b/src/ui/widget/panel.h @@ -48,6 +48,7 @@ namespace Gtk { struct InkscapeApplication; namespace Inkscape { + class Selection; namespace UI { @@ -116,8 +117,8 @@ public: void setResponseSensitive(int response_id, bool setting); virtual sigc::signal<void, SPDesktop *, SPDocument *> &signalDocumentReplaced(); - virtual sigc::signal<void, InkscapeApplication *, SPDesktop *> &signalActivateDesktop(); - virtual sigc::signal<void, InkscapeApplication *, SPDesktop *> &signalDeactiveDesktop(); + virtual sigc::signal<void, SPDesktop *> &signalActivateDesktop(); + virtual sigc::signal<void, SPDesktop *> &signalDeactiveDesktop(); protected: /** @@ -147,8 +148,8 @@ protected: sigc::signal<void, int> _signal_response; sigc::signal<void> _signal_present; sigc::signal<void, SPDesktop *, SPDocument *> _signal_document_replaced; - sigc::signal<void, InkscapeApplication *, SPDesktop *> _signal_activate_desktop; - sigc::signal<void, InkscapeApplication *, SPDesktop *> _signal_deactive_desktop; + sigc::signal<void, SPDesktop *> _signal_activate_desktop; + sigc::signal<void, SPDesktop *> _signal_deactive_desktop; private: void _init(); diff --git a/src/ui/widget/preferences-widget.cpp b/src/ui/widget/preferences-widget.cpp index 7f3e6cd47..98028ed78 100644 --- a/src/ui/widget/preferences-widget.cpp +++ b/src/ui/widget/preferences-widget.cpp @@ -34,7 +34,7 @@ #include "desktop.h" #include "enums.h" #include "inkscape.h" -#include "desktop-handles.h" + #include "message-stack.h" #include "style.h" #include "selection.h" diff --git a/src/ui/widget/registered-widget.cpp b/src/ui/widget/registered-widget.cpp index e97285de4..298377af3 100644 --- a/src/ui/widget/registered-widget.cpp +++ b/src/ui/widget/registered-widget.cpp @@ -36,6 +36,11 @@ // for interruptability bug: #include "display/sp-canvas.h" +#include "desktop.h" + + +#include "sp-root.h" + namespace Inkscape { namespace UI { namespace Widget { @@ -203,7 +208,7 @@ RegisteredScalarUnit::~RegisteredScalarUnit() _value_changed_connection.disconnect(); } -RegisteredScalarUnit::RegisteredScalarUnit (const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, const RegisteredUnitMenu &rum, Registry& wr, Inkscape::XML::Node* repr_in, SPDocument *doc_in) +RegisteredScalarUnit::RegisteredScalarUnit (const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, const RegisteredUnitMenu &rum, Registry& wr, Inkscape::XML::Node* repr_in, SPDocument *doc_in, RSU_UserUnits user_units) : RegisteredWidget<ScalarUnit>(label, tip, UNIT_TYPE_LINEAR, "", "", rum.getUnitMenu()), _um(0) { @@ -215,6 +220,7 @@ RegisteredScalarUnit::RegisteredScalarUnit (const Glib::ustring& label, const Gl setUnit (rum.getUnitMenu()->getUnitAbbr()); setDigits (2); _um = rum.getUnitMenu(); + _user_units = user_units; _value_changed_connection = signal_value_changed().connect (sigc::mem_fun (*this, &RegisteredScalarUnit::on_value_changed)); } @@ -233,12 +239,31 @@ RegisteredScalarUnit::on_value_changed() _wr->setUpdating (true); Inkscape::SVGOStringStream os; - os << getValue(""); - if (_um) - os << _um->getUnitAbbr(); + if (_user_units != RSU_none) { + // Output length in 'user units', taking into account scale in 'x' or 'y'. + double scale = 1.0; + if (doc) { + SPRoot *root = doc->getRoot(); + if (root->viewBox_set) { + // check to see if scaling is uniform + if(Geom::are_near((root->viewBox.width() * root->height.computed) / (root->width.computed * root->viewBox.height()), 1.0, Geom::EPSILON)) { + scale = (root->viewBox.width() / root->width.computed + root->viewBox.height() / root->height.computed)/2.0; + } else if (_user_units == RSU_x) { + scale = root->viewBox.width() / root->width.computed; + } else { + scale = root->viewBox.height() / root->height.computed; + } + } + } + os << getValue("px") * scale; + } else { + // Output using unit identifiers. + os << getValue(""); + if (_um) + os << _um->getUnitAbbr(); + } write_to_xml(os.str().c_str()); - _wr->setUpdating (false); } @@ -397,8 +422,8 @@ RegisteredColorPicker::on_changed (guint32 rgba) SPDesktop *dt = SP_ACTIVE_DESKTOP; if (!dt) return; - local_repr = sp_desktop_namedview(dt)->getRepr(); - local_doc = sp_desktop_document(dt); + local_repr = dt->getNamedView()->getRepr(); + local_doc = dt->getDocument(); } gchar c[32]; diff --git a/src/ui/widget/registered-widget.h b/src/ui/widget/registered-widget.h index 1f505a3cd..9d2489712 100644 --- a/src/ui/widget/registered-widget.h +++ b/src/ui/widget/registered-widget.h @@ -27,7 +27,7 @@ #include "document.h" #include "document-undo.h" -#include "desktop-handles.h" +#include "desktop.h" #include "sp-namedview.h" #include <gtkmm/checkbutton.h> @@ -99,8 +99,8 @@ protected: if (!local_repr) { // no repr specified, use active desktop's namedview's repr SPDesktop* dt = SP_ACTIVE_DESKTOP; - local_repr = reinterpret_cast<SPObject *>(sp_desktop_namedview(dt))->getRepr(); - local_doc = sp_desktop_document(dt); + local_repr = reinterpret_cast<SPObject *>(dt->getNamedView())->getRepr(); + local_doc = dt->getDocument(); } bool saved = DocumentUndo::getUndoSensitive(local_doc); @@ -206,6 +206,14 @@ protected: void on_changed(); }; +// Allow RegisteredScalarUnit to output lengths in 'user units' (which may have direction dependent +// scale factors). +enum RSU_UserUnits { + RSU_none, + RSU_x, + RSU_y +}; + class RegisteredScalarUnit : public RegisteredWidget<ScalarUnit> { public: ~RegisteredScalarUnit(); @@ -215,12 +223,14 @@ public: const RegisteredUnitMenu &rum, Registry& wr, Inkscape::XML::Node* repr_in = NULL, - SPDocument *doc_in = NULL ); + SPDocument *doc_in = NULL, + RSU_UserUnits _user_units = RSU_none ); protected: sigc::connection _value_changed_connection; UnitMenu *_um; void on_value_changed(); + RSU_UserUnits _user_units; }; class RegisteredScalar : public RegisteredWidget<Scalar> { diff --git a/src/ui/widget/selected-style.cpp b/src/ui/widget/selected-style.cpp index aebef2c4e..9e283fc64 100644 --- a/src/ui/widget/selected-style.cpp +++ b/src/ui/widget/selected-style.cpp @@ -20,13 +20,13 @@ #include "ui/widget/color-preview.h" #include "selection.h" -#include "desktop-handles.h" + #include "style.h" #include "desktop-style.h" #include "sp-namedview.h" #include "sp-linear-gradient.h" -#include "sp-mesh-gradient.h" #include "sp-radial-gradient.h" +#include "sp-mesh.h" #include "sp-pattern.h" #include "ui/dialog/dialog-manager.h" #include "ui/dialog/fill-and-stroke.h" @@ -480,7 +480,7 @@ SelectedStyle::setDesktop(SPDesktop *desktop) _desktop = desktop; g_object_set_data (G_OBJECT(_opacity_sb.gobj()), "dtw", _desktop->canvas); - Inkscape::Selection *selection = sp_desktop_selection (desktop); + Inkscape::Selection *selection = desktop->getSelection(); selection_changed_connection = new sigc::connection (selection->connectChanged( sigc::bind ( @@ -498,7 +498,7 @@ SelectedStyle::setDesktop(SPDesktop *desktop) this ) )); - _sw_unit = sp_desktop_namedview(desktop)->display_units; + _sw_unit = desktop->getNamedView()->display_units; // Set the doc default unit active in the units list gint length = g_slist_length(_unit_mis); @@ -541,8 +541,7 @@ void SelectedStyle::dragDataReceived( GtkWidget */*widget*/, sp_repr_css_set_property( css, (tracker->item == SS_FILL) ? "fill":"stroke", c ); sp_desktop_set_style( tracker->parent->_desktop, css ); sp_repr_css_attr_unref( css ); - DocumentUndo::done( sp_desktop_document(tracker->parent->_desktop) , SP_VERB_NONE, - _("Drop color")); + DocumentUndo::done( tracker->parent->_desktop->getDocument(), SP_VERB_NONE, _("Drop color")); } } break; @@ -554,7 +553,7 @@ void SelectedStyle::on_fill_remove() { sp_repr_css_set_property (css, "fill", "none"); sp_desktop_set_style (_desktop, css, true, true); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Remove fill")); } @@ -563,7 +562,7 @@ void SelectedStyle::on_stroke_remove() { sp_repr_css_set_property (css, "stroke", "none"); sp_desktop_set_style (_desktop, css, true, true); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Remove stroke")); } @@ -572,7 +571,7 @@ void SelectedStyle::on_fill_unset() { sp_repr_css_unset_property (css, "fill"); sp_desktop_set_style (_desktop, css, true, true); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Unset fill")); } @@ -588,7 +587,7 @@ void SelectedStyle::on_stroke_unset() { sp_repr_css_unset_property (css, "stroke-dasharray"); sp_desktop_set_style (_desktop, css, true, true); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Unset stroke")); } @@ -597,7 +596,7 @@ void SelectedStyle::on_fill_opaque() { sp_repr_css_set_property (css, "fill-opacity", "1"); sp_desktop_set_style (_desktop, css, true); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Make fill opaque")); } @@ -606,7 +605,7 @@ void SelectedStyle::on_stroke_opaque() { sp_repr_css_set_property (css, "stroke-opacity", "1"); sp_desktop_set_style (_desktop, css, true); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Make fill opaque")); } @@ -618,7 +617,7 @@ void SelectedStyle::on_fill_lastused() { sp_repr_css_set_property (css, "fill", c); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Apply last set color to fill")); } @@ -630,7 +629,7 @@ void SelectedStyle::on_stroke_lastused() { sp_repr_css_set_property (css, "stroke", c); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Apply last set color to stroke")); } @@ -641,7 +640,7 @@ void SelectedStyle::on_fill_lastselected() { sp_repr_css_set_property (css, "fill", c); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Apply last selected color to fill")); } @@ -652,7 +651,7 @@ void SelectedStyle::on_stroke_lastselected() { sp_repr_css_set_property (css, "stroke", c); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Apply last selected color to stroke")); } @@ -678,7 +677,7 @@ void SelectedStyle::on_fill_invert() { sp_repr_css_set_property (css, "fill", c); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Invert fill")); } @@ -702,7 +701,7 @@ void SelectedStyle::on_stroke_invert() { sp_repr_css_set_property (css, "stroke", c); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Invert stroke")); } @@ -714,7 +713,7 @@ void SelectedStyle::on_fill_white() { sp_repr_css_set_property (css, "fill-opacity", "1"); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("White fill")); } @@ -726,7 +725,7 @@ void SelectedStyle::on_stroke_white() { sp_repr_css_set_property (css, "stroke-opacity", "1"); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("White stroke")); } @@ -738,7 +737,7 @@ void SelectedStyle::on_fill_black() { sp_repr_css_set_property (css, "fill-opacity", "1.0"); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Black fill")); } @@ -750,7 +749,7 @@ void SelectedStyle::on_stroke_black() { sp_repr_css_set_property (css, "stroke-opacity", "1.0"); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Black stroke")); } @@ -793,7 +792,7 @@ void SelectedStyle::on_fill_paste() { sp_repr_css_set_property (css, "fill", text.c_str()); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Paste fill")); } } @@ -811,7 +810,7 @@ void SelectedStyle::on_stroke_paste() { sp_repr_css_set_property (css, "stroke", text.c_str()); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Paste stroke")); } } @@ -865,7 +864,7 @@ void SelectedStyle::on_fillstroke_swap() { sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Swap fill and stroke")); } @@ -940,7 +939,7 @@ SelectedStyle::on_opacity_click(GdkEventButton *event) sp_repr_css_set_property (css, "opacity", opacity); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Change opacity")); return true; } @@ -967,7 +966,7 @@ void SelectedStyle::on_popup_preset(int i) { // FIXME: update dash patterns! sp_desktop_set_style (_desktop, css, true); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_DIALOG_SWATCHES, + DocumentUndo::done(_desktop->getDocument(), SP_VERB_DIALOG_SWATCHES, _("Change stroke width")); } @@ -978,7 +977,7 @@ SelectedStyle::update() return; // create temporary style - SPStyle *query = sp_style_new (sp_desktop_document(_desktop)); + SPStyle query(_desktop->getDocument()); for (int i = SS_FILL; i <= SS_STROKE; i++) { Gtk::EventBox *place = (i == SS_FILL)? &_fill_place : &_stroke_place; @@ -996,7 +995,7 @@ SelectedStyle::update() _popup_copy[i].set_sensitive(false); // query style from desktop. This returns a result flag and fills query with the style of subselection, if any, or selection - int result = sp_desktop_query_style (_desktop, query, + int result = sp_desktop_query_style (_desktop, &query, (i == SS_FILL)? QUERY_STYLE_PROPERTY_FILL : QUERY_STYLE_PROPERTY_STROKE); switch (result) { case QUERY_STYLE_NOTHING: @@ -1021,12 +1020,12 @@ SelectedStyle::update() } SPIPaint *paint; if (i == SS_FILL) { - paint = &(query->fill); + paint = &(query.fill); } else { - paint = &(query->stroke); + paint = &(query.stroke); } if (paint->set && paint->isPaintserver()) { - SPPaintServer *server = (i == SS_FILL)? SP_STYLE_FILL_SERVER (query) : SP_STYLE_STROKE_SERVER (query); + SPPaintServer *server = (i == SS_FILL)? SP_STYLE_FILL_SERVER (&query) : SP_STYLE_STROKE_SERVER (&query); if ( server ) { Inkscape::XML::Node *srepr = server->getRepr(); _paintserver_id[i] += "url(#"; @@ -1046,7 +1045,7 @@ SelectedStyle::update() place->set_tooltip_text(__rgradient[i]); _mode[i] = SS_RGRADIENT; #ifdef WITH_MESH - } else if (SP_IS_MESHGRADIENT(server)) { + } else if (SP_IS_MESH(server)) { SPGradient *vector = SP_GRADIENT(server)->getVector(); sp_gradient_image_set_gradient(SP_GRADIENT_IMAGE(_gradient_preview_m[i]), vector); place->add(_gradient_box_m[i]); @@ -1063,7 +1062,7 @@ SelectedStyle::update() } } else if (paint->set && paint->isColor()) { guint32 color = paint->value.color.toRGBA32( - SP_SCALE24_TO_FLOAT ((i == SS_FILL)? query->fill_opacity.value : query->stroke_opacity.value)); + SP_SCALE24_TO_FLOAT ((i == SS_FILL)? query.fill_opacity.value : query.stroke_opacity.value)); _lastselected[i] = _thisselected[i]; _thisselected[i] = color; // include opacity ((Inkscape::UI::Widget::ColorPreview*)_color_preview[i])->setRgba32 (color); @@ -1106,7 +1105,7 @@ SelectedStyle::update() clearTooltip(_opacity_place); clearTooltip(_opacity_sb); - int result = sp_desktop_query_style (_desktop, query, QUERY_STYLE_PROPERTY_MASTEROPACITY); + int result = sp_desktop_query_style (_desktop, &query, QUERY_STYLE_PROPERTY_MASTEROPACITY); switch (result) { case QUERY_STYLE_NOTHING: @@ -1123,16 +1122,16 @@ SelectedStyle::update() _opacity_blocked = true; _opacity_sb.set_sensitive(true); #if WITH_GTKMM_3_0 - _opacity_adjustment->set_value(SP_SCALE24_TO_FLOAT(query->opacity.value) * 100); + _opacity_adjustment->set_value(SP_SCALE24_TO_FLOAT(query.opacity.value) * 100); #else - _opacity_adjustment.set_value(SP_SCALE24_TO_FLOAT(query->opacity.value) * 100); + _opacity_adjustment.set_value(SP_SCALE24_TO_FLOAT(query.opacity.value) * 100); #endif _opacity_blocked = false; break; } // Now query stroke_width - int result_sw = sp_desktop_query_style (_desktop, query, QUERY_STYLE_PROPERTY_STROKEWIDTH); + int result_sw = sp_desktop_query_style (_desktop, &query, QUERY_STYLE_PROPERTY_STROKEWIDTH); switch (result_sw) { case QUERY_STYLE_NOTHING: _stroke_width.set_markup(""); @@ -1144,9 +1143,9 @@ SelectedStyle::update() { double w; if (_sw_unit) { - w = Inkscape::Util::Quantity::convert(query->stroke_width.computed, "px", _sw_unit); + w = Inkscape::Util::Quantity::convert(query.stroke_width.computed, "px", _sw_unit); } else { - w = query->stroke_width.computed; + w = query.stroke_width.computed; } current_stroke_width = w; @@ -1169,8 +1168,6 @@ SelectedStyle::update() default: break; } - - sp_style_unref(query); } void SelectedStyle::opacity_0(void) {_opacity_sb.set_value(0);} @@ -1241,13 +1238,13 @@ void SelectedStyle::on_opacity_changed () // me. As a result, scrolling the spinbutton once results in runaway change until it hits 1.0 // or 0.0. (And no, this is not a race with ::update, I checked that.) // Sigh. So we disable interruptibility while we're setting the new value. - sp_desktop_canvas(_desktop)->forceFullRedrawAfterInterruptions(0); + _desktop->getCanvas()->forceFullRedrawAfterInterruptions(0); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - DocumentUndo::maybeDone(sp_desktop_document(_desktop), "fillstroke:opacity", SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::maybeDone(_desktop->getDocument(), "fillstroke:opacity", SP_VERB_DIALOG_FILL_STROKE, _("Change opacity")); // resume interruptibility - sp_desktop_canvas(_desktop)->endForcedFullRedraws(); + _desktop->getCanvas()->endForcedFullRedraws(); spinbutton_defocus(GTK_WIDGET(_opacity_sb.gobj())); _opacity_blocked = false; } @@ -1385,25 +1382,25 @@ RotateableSwatch::do_motion(double by, guint modifier) { diff = color_adjust(hsla, by, cc, modifier); if (modifier == 3) { // alpha - DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey, + DocumentUndo::maybeDone(parent->getDesktop()->getDocument(), undokey, SP_VERB_DIALOG_FILL_STROKE, (_("Adjust alpha"))); double ch = hsla[3]; parent->getDesktop()->event_context->message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Adjusting <b>alpha</b>: was %.3g, now <b>%.3g</b> (diff %.3g); with <b>Ctrl</b> to adjust lightness, with <b>Shift</b> to adjust saturation, without modifiers to adjust hue"), ch - diff, ch, diff); } else if (modifier == 2) { // saturation - DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey, + DocumentUndo::maybeDone(parent->getDesktop()->getDocument(), undokey, SP_VERB_DIALOG_FILL_STROKE, (_("Adjust saturation"))); double ch = hsla[1]; parent->getDesktop()->event_context->message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Adjusting <b>saturation</b>: was %.3g, now <b>%.3g</b> (diff %.3g); with <b>Ctrl</b> to adjust lightness, with <b>Alt</b> to adjust alpha, without modifiers to adjust hue"), ch - diff, ch, diff); } else if (modifier == 1) { // lightness - DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey, + DocumentUndo::maybeDone(parent->getDesktop()->getDocument(), undokey, SP_VERB_DIALOG_FILL_STROKE, (_("Adjust lightness"))); double ch = hsla[2]; parent->getDesktop()->event_context->message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Adjusting <b>lightness</b>: was %.3g, now <b>%.3g</b> (diff %.3g); with <b>Shift</b> to adjust saturation, with <b>Alt</b> to adjust alpha, without modifiers to adjust hue"), ch - diff, ch, diff); } else { // hue - DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey, + DocumentUndo::maybeDone(parent->getDesktop()->getDocument(), undokey, SP_VERB_DIALOG_FILL_STROKE, (_("Adjust hue"))); double ch = hsla[0]; parent->getDesktop()->event_context->message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Adjusting <b>hue</b>: was %.3g, now <b>%.3g</b> (diff %.3g); with <b>Shift</b> to adjust saturation, with <b>Alt</b> to adjust alpha, with <b>Ctrl</b> to adjust lightness"), ch - diff, ch, diff); @@ -1440,18 +1437,18 @@ RotateableSwatch::do_release(double by, guint modifier) { } if (modifier == 3) { // alpha - DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey, + DocumentUndo::maybeDone(parent->getDesktop()->getDocument(), undokey, SP_VERB_DIALOG_FILL_STROKE, ("Adjust alpha")); } else if (modifier == 2) { // saturation - DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey, + DocumentUndo::maybeDone(parent->getDesktop()->getDocument(), undokey, SP_VERB_DIALOG_FILL_STROKE, ("Adjust saturation")); } else if (modifier == 1) { // lightness - DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey, + DocumentUndo::maybeDone(parent->getDesktop()->getDocument(), undokey, SP_VERB_DIALOG_FILL_STROKE, ("Adjust lightness")); } else { // hue - DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey, + DocumentUndo::maybeDone(parent->getDesktop()->getDocument(), undokey, SP_VERB_DIALOG_FILL_STROKE, ("Adjust hue")); } @@ -1523,7 +1520,7 @@ RotateableStrokeWidth::do_motion(double by, guint modifier) { if (modifier == 3) { // Alt, do nothing } else { double diff = value_adjust(startvalue, by, modifier, false); - DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey, + DocumentUndo::maybeDone(parent->getDesktop()->getDocument(), undokey, SP_VERB_DIALOG_FILL_STROKE, (_("Adjust stroke width"))); parent->getDesktop()->event_context->message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Adjusting <b>stroke width</b>: was %.3g, now <b>%.3g</b> (diff %.3g)"), startvalue, startvalue + diff, diff); } @@ -1537,7 +1534,7 @@ RotateableStrokeWidth::do_release(double by, guint modifier) { } else { value_adjust(startvalue, by, modifier, true); startvalue_set = false; - DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey, + DocumentUndo::maybeDone(parent->getDesktop()->getDocument(), undokey, SP_VERB_DIALOG_FILL_STROKE, (_("Adjust stroke width"))); } diff --git a/src/ui/widget/style-subject.cpp b/src/ui/widget/style-subject.cpp index d9bf7e2aa..a48370d9b 100644 --- a/src/ui/widget/style-subject.cpp +++ b/src/ui/widget/style-subject.cpp @@ -11,7 +11,7 @@ #include "sp-object.h" #include "xml/sp-css-attr.h" #include "desktop-style.h" -#include "desktop-handles.h" + #include "selection.h" #include "style.h" @@ -49,7 +49,7 @@ StyleSubject::Selection::~Selection() { Inkscape::Selection *StyleSubject::Selection::_getSelection() const { SPDesktop *desktop = getDesktop(); if (desktop) { - return sp_desktop_selection(desktop); + return desktop->getSelection(); } else { return NULL; } @@ -88,7 +88,7 @@ void StyleSubject::Selection::_afterDesktopSwitch(SPDesktop *desktop) { _sel_modified.disconnect(); if (desktop) { _subsel_changed = desktop->connectToolSubselectionChanged(sigc::hide(sigc::mem_fun(*this, &Selection::_emitChanged))); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (selection) { _sel_changed = selection->connectChanged(sigc::hide(sigc::mem_fun(*this, &Selection::_emitChanged))); _sel_modified = selection->connectModified(sigc::hide(sigc::hide(sigc::mem_fun(*this, &Selection::_emitChanged)))); diff --git a/src/ui/widget/style-swatch.cpp b/src/ui/widget/style-swatch.cpp index 157fd2ad9..fa8543c46 100644 --- a/src/ui/widget/style-swatch.cpp +++ b/src/ui/widget/style-swatch.cpp @@ -260,13 +260,12 @@ void StyleSwatch::setStyle(SPCSSAttr *css) Glib::ustring css_string; sp_repr_css_write_string (_css, css_string); - SPStyle *temp_spstyle = sp_style_new(SP_ACTIVE_DOCUMENT); + + SPStyle style(SP_ACTIVE_DOCUMENT); if (!css_string.empty()) { - sp_style_merge_from_style_string (temp_spstyle, css_string.c_str()); + style.mergeString(css_string.c_str()); } - - setStyle (temp_spstyle); - sp_style_unref (temp_spstyle); + setStyle (&style); } void StyleSwatch::setStyle(SPStyle *query) diff --git a/src/ui/widget/tolerance-slider.cpp b/src/ui/widget/tolerance-slider.cpp index aac7451f4..ff525c679 100644 --- a/src/ui/widget/tolerance-slider.cpp +++ b/src/ui/widget/tolerance-slider.cpp @@ -28,7 +28,8 @@ #include "inkscape.h" #include "document.h" #include "document-undo.h" -#include "desktop-handles.h" +#include "desktop.h" + #include "sp-namedview.h" #include "registry.h" @@ -195,10 +196,10 @@ void ToleranceSlider::update (double val) _wr->setUpdating (true); - SPDocument *doc = sp_desktop_document(dt); + SPDocument *doc = dt->getDocument(); bool saved = DocumentUndo::getUndoSensitive(doc); DocumentUndo::setUndoSensitive(doc, false); - Inkscape::XML::Node *repr = sp_desktop_namedview(dt)->getRepr(); + Inkscape::XML::Node *repr = dt->getNamedView()->getRepr(); repr->setAttribute(_key.c_str(), os.str().c_str()); DocumentUndo::setUndoSensitive(doc, saved); diff --git a/src/undo-stack-observer.h b/src/undo-stack-observer.h index 1057ace8f..dadb4764e 100644 --- a/src/undo-stack-observer.h +++ b/src/undo-stack-observer.h @@ -10,7 +10,7 @@ #ifndef SEEN_UNDO_COMMIT_OBSERVER_H #define SEEN_UNDO_COMMIT_OBSERVER_H -#include "gc-managed.h" +#include "inkgc/gc-managed.h" namespace Inkscape { diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index 732e01b0c..8fd8c8c66 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -31,7 +31,6 @@ set(util_SRC list.h longest-common-suffix.h map-list.h - mathfns.h reference.h reverse-list.h share.h @@ -43,5 +42,5 @@ set(util_SRC ziptool.h ) -# add_inkscape_lib(util_LIB "${util_SRC}") -add_inkscape_source("${util_SRC}") +add_inkscape_lib(util_LIB "${util_SRC}") +# add_inkscape_source("${util_SRC}") diff --git a/src/util/Makefile_insert b/src/util/Makefile_insert index 6d2e63278..c23dffbca 100644 --- a/src/util/Makefile_insert +++ b/src/util/Makefile_insert @@ -1,8 +1,13 @@ ## Makefile.am fragment sourced by src/Makefile.am. -ink_common_sources += \ - util/ziptool.h \ - util/ziptool.cpp \ +util/all: util/libutil.a + +util/clean: + rm -f util/libutil.a $(util_libutil_a_OBJECTS) + +util_libutil_a_SOURCES = \ + util/ziptool.h \ + util/ziptool.cpp \ util/accumulators.h \ util/compose.hpp \ util/copy.h \ @@ -26,7 +31,6 @@ ink_common_sources += \ util/list-copy.h \ util/longest-common-suffix.h \ util/map-list.h \ - util/mathfns.h \ util/reference.h \ util/reverse-list.h \ util/share.h \ diff --git a/src/util/list.h b/src/util/list.h index de5a458e9..563b6091c 100644 --- a/src/util/list.h +++ b/src/util/list.h @@ -12,7 +12,7 @@ #include <cstddef> #include <iterator> -#include "gc-managed.h" +#include "inkgc/gc-managed.h" #include "util/reference.h" namespace Inkscape { diff --git a/src/util/share.h b/src/util/share.h index 6b5e6a4ef..8f1e7045a 100644 --- a/src/util/share.h +++ b/src/util/share.h @@ -12,7 +12,7 @@ #ifndef SEEN_INKSCAPE_UTIL_SHARE_H #define SEEN_INKSCAPE_UTIL_SHARE_H -#include "gc-core.h" +#include "inkgc/gc-core.h" #include <cstring> #include <cstddef> diff --git a/src/util/units.cpp b/src/util/units.cpp index 8ad3560dd..2c72ec3ae 100644 --- a/src/util/units.cpp +++ b/src/util/units.cpp @@ -16,6 +16,7 @@ #include <cmath> #include <cerrno> #include <iomanip> +#include <iostream> #include <glib.h> #include <glibmm/regex.h> #include <glibmm/fileutils.h> @@ -46,6 +47,7 @@ enum UnitCode { UNIT_CODE_CM = MAKE_UNIT_CODE('c','m'), UNIT_CODE_IN = MAKE_UNIT_CODE('i','n'), UNIT_CODE_FT = MAKE_UNIT_CODE('f','t'), + UNIT_CODE_MT = MAKE_UNIT_CODE('m',' '), UNIT_CODE_EM = MAKE_UNIT_CODE('e','m'), UNIT_CODE_EX = MAKE_UNIT_CODE('e','x'), UNIT_CODE_PERCENT = MAKE_UNIT_CODE('%',0) @@ -73,6 +75,7 @@ unsigned const svg_length_lookup[] = { UNIT_CODE_CM, UNIT_CODE_IN, UNIT_CODE_FT, + UNIT_CODE_MT, UNIT_CODE_EM, UNIT_CODE_EX, UNIT_CODE_PERCENT diff --git a/src/vanishing-point.cpp b/src/vanishing-point.cpp index 13dd03ee3..b62aacbc5 100644 --- a/src/vanishing-point.cpp +++ b/src/vanishing-point.cpp @@ -16,7 +16,7 @@ #include <glibmm/i18n.h> #include "vanishing-point.h" -#include "desktop-handles.h" + #include "desktop.h" #include "display/sp-canvas-item.h" #include "display/sp-ctrlline.h" @@ -94,7 +94,7 @@ vp_knot_moved_handler (SPKnot *knot, Geom::Point const &ppointer, guint state, g Geom::Point p = ppointer; // FIXME: take from prefs - double snap_dist = SNAP_DIST / inkscape_active_desktop()->current_zoom(); + double snap_dist = SNAP_DIST / SP_ACTIVE_DESKTOP->current_zoom(); /* * We use dragging_started to indicate if we have already checked for the need to split Draggers up. @@ -110,7 +110,7 @@ vp_knot_moved_handler (SPKnot *knot, Geom::Point const &ppointer, guint state, g for (std::set<VanishingPoint*, less_ptr>::iterator vp = sel_vps.begin(); vp != sel_vps.end(); ++vp) { // for each VP that has selected boxes: Persp3D *old_persp = (*vp)->get_perspective(); - sel_boxes = (*vp)->selectedBoxes(sp_desktop_selection(inkscape_active_desktop())); + sel_boxes = (*vp)->selectedBoxes(SP_ACTIVE_DESKTOP->getSelection()); // we create a new perspective ... Persp3D *new_persp = persp3d_create_xml_element (dragger->parent->document, old_persp->perspective_impl); @@ -129,7 +129,7 @@ vp_knot_moved_handler (SPKnot *knot, Geom::Point const &ppointer, guint state, g } // FIXME: Do we need to create a new dragger as well? dragger->updateZOrders (); - DocumentUndo::done(sp_desktop_document (inkscape_active_desktop()), SP_VERB_CONTEXT_3DBOX, + DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_CONTEXT_3DBOX, _("Split vanishing points")); return; } @@ -174,7 +174,7 @@ vp_knot_moved_handler (SPKnot *knot, Geom::Point const &ppointer, guint state, g // deleted according to changes in the svg representation, not based on any user input // as is currently the case. - DocumentUndo::done(sp_desktop_document (inkscape_active_desktop()), SP_VERB_CONTEXT_3DBOX, + DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_CONTEXT_3DBOX, _("Merge vanishing points")); return; @@ -182,7 +182,7 @@ vp_knot_moved_handler (SPKnot *knot, Geom::Point const &ppointer, guint state, g } // We didn't snap to another dragger, so we'll try a regular snap - SPDesktop *desktop = inkscape_active_desktop(); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; SnapManager &m = desktop->namedview->snap_manager; m.setup(desktop); Inkscape::SnappedPoint s = m.freeSnap(Inkscape::SnapCandidatePoint(p, Inkscape::SNAPSOURCE_OTHER_HANDLE)); @@ -277,7 +277,7 @@ VPDragger::VPDragger(VPDrag *parent, Geom::Point p, VanishingPoint &vp) if (vp.is_finite()) { // create the knot - this->knot = new SPKnot(inkscape_active_desktop(), NULL); + this->knot = new SPKnot(SP_ACTIVE_DESKTOP, NULL); this->knot->setMode(SP_KNOT_MODE_XOR); this->knot->setFill(VP_KNOT_COLOR_NORMAL, VP_KNOT_COLOR_NORMAL, VP_KNOT_COLOR_NORMAL); this->knot->setStroke(0x000000ff, 0x000000ff, 0x000000ff); @@ -394,7 +394,7 @@ VPDragger::VPsOfSelectedBoxes() { std::set<VanishingPoint*, less_ptr> sel_vps; VanishingPoint *vp; // FIXME: Should we take the selection from the parent VPDrag? I guess it shouldn't make a difference. - Inkscape::Selection *sel = sp_desktop_selection(inkscape_active_desktop()); + Inkscape::Selection *sel = SP_ACTIVE_DESKTOP->getSelection(); for (GSList const* i = sel->itemList(); i != NULL; i = i->next) { SPItem *item = static_cast<SPItem *>(i->data); SPBox3D *box = dynamic_cast<SPBox3D *>(item); @@ -488,7 +488,7 @@ VPDragger::printVPs() { VPDrag::VPDrag (SPDocument *document) { this->document = document; - this->selection = sp_desktop_selection(inkscape_active_desktop()); + this->selection = SP_ACTIVE_DESKTOP->getSelection(); this->draggers = NULL; this->lines = NULL; @@ -635,7 +635,7 @@ VPDrag::updateBoxHandles () return; } - Inkscape::UI::Tools::ToolBase *ec = inkscape_active_event_context(); + Inkscape::UI::Tools::ToolBase *ec = INKSCAPE.active_event_context(); g_assert (ec != NULL); if (ec->shape_editor != NULL) { ec->shape_editor->update_knotholder(); @@ -708,7 +708,7 @@ void VPDrag::drawLinesForFace(const SPBox3D *box, Proj::Axis axis) //, guint cor // draw perspective lines for infinite VPs boost::optional<Geom::Point> pt1, pt2, pt3, pt4; Persp3D *persp = box3d_get_perspective(box); - SPDesktop *desktop = inkscape_active_desktop (); // FIXME: Store the desktop in VPDrag + SPDesktop *desktop = SP_ACTIVE_DESKTOP; // FIXME: Store the desktop in VPDrag Box3D::PerspectiveLine pl (corner1, axis, persp); pt1 = pl.intersection_with_viewbox(desktop); @@ -782,7 +782,7 @@ VPDrag::swap_perspectives_of_VPs(Persp3D *persp2, Persp3D *persp1) void VPDrag::addLine(Geom::Point const &p1, Geom::Point const &p2, Inkscape::CtrlLineType type) { - SPCtrlLine *line = ControlManager::getManager().createControlLine(sp_desktop_controls(inkscape_active_desktop()), p1, p2, type); + SPCtrlLine *line = ControlManager::getManager().createControlLine(SP_ACTIVE_DESKTOP->getControls(), p1, p2, type); sp_canvas_item_show(line); this->lines = g_slist_append(this->lines, line); } diff --git a/src/verbs.cpp b/src/verbs.cpp index 33810fba2..5febeeb7c 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -41,7 +41,7 @@ #include <gtkmm/stock.h> #include "desktop.h" -#include "desktop-handles.h" + #include "display/curve.h" #include "document.h" #include "ui/tools/freehand-base.h" @@ -52,7 +52,7 @@ #include "helper/action.h" #include "helper/action-context.h" #include "help.h" -#include "inkscape-private.h" +#include "inkscape.h" #include "ui/interface.h" #include "layer-fns.h" #include "layer-manager.h" @@ -906,10 +906,10 @@ void FileVerb::perform(SPAction *action, void *data) // sp_file_export_to_ocal(*parent); // break; case SP_VERB_FILE_NEXT_DESKTOP: - inkscape_switch_desktops_next(); + INKSCAPE.switch_desktops_next(); break; case SP_VERB_FILE_PREV_DESKTOP: - inkscape_switch_desktops_prev(); + INKSCAPE.switch_desktops_prev(); break; case SP_VERB_FILE_CLOSE_VIEW: sp_ui_close_view(NULL); @@ -948,10 +948,10 @@ void EditVerb::perform(SPAction *action, void *data) switch (reinterpret_cast<std::size_t>(data)) { case SP_VERB_EDIT_UNDO: - sp_undo(dt, sp_desktop_document(dt)); + sp_undo(dt, dt->getDocument()); break; case SP_VERB_EDIT_REDO: - sp_redo(dt, sp_desktop_document(dt)); + sp_redo(dt, dt->getDocument()); break; case SP_VERB_EDIT_CUT: sp_selection_cut(dt); @@ -1203,11 +1203,11 @@ void SelectionVerb::perform(SPAction *action, void *data) SelectionHelper::reverse(dt); break; case SP_VERB_SELECTION_TRACE: - inkscape_dialogs_unhide(); + INKSCAPE.dialogs_unhide(); dt->_dlg_mgr->showDialog("Trace"); break; case SP_VERB_SELECTION_PIXEL_ART: - inkscape_dialogs_unhide(); + INKSCAPE.dialogs_unhide(); dt->_dlg_mgr->showDialog("PixelArt"); break; case SP_VERB_SELECTION_CREATE_BITMAP: @@ -1221,7 +1221,7 @@ void SelectionVerb::perform(SPAction *action, void *data) sp_selected_path_break_apart(dt); break; case SP_VERB_SELECTION_ARRANGE: - inkscape_dialogs_unhide(); + INKSCAPE.dialogs_unhide(); dt->_dlg_mgr->showDialog("TileDialog"); //FIXME: denis: What's this string (to be changed) break; default: @@ -1256,7 +1256,7 @@ void LayerVerb::perform(SPAction *action, void *data) SPObject *next=Inkscape::next_layer(dt->currentRoot(), dt->currentLayer()); if (next) { dt->setCurrentLayer(next); - DocumentUndo::done(sp_desktop_document(dt), SP_VERB_LAYER_NEXT, + DocumentUndo::done(dt->getDocument(), SP_VERB_LAYER_NEXT, _("Switch to next layer")); dt->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Switched to next layer.")); } else { @@ -1268,7 +1268,7 @@ void LayerVerb::perform(SPAction *action, void *data) SPObject *prev=Inkscape::previous_layer(dt->currentRoot(), dt->currentLayer()); if (prev) { dt->setCurrentLayer(prev); - DocumentUndo::done(sp_desktop_document(dt), SP_VERB_LAYER_PREV, + DocumentUndo::done(dt->getDocument(), SP_VERB_LAYER_PREV, _("Switch to previous layer")); dt->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Switched to previous layer.")); } else { @@ -1338,7 +1338,7 @@ void LayerVerb::perform(SPAction *action, void *data) description = _("Lower layer"); break; }; - DocumentUndo::done(sp_desktop_document(dt), verb, description); + DocumentUndo::done(dt->getDocument(), verb, description); if (message) { dt->messageStack()->flash(Inkscape::NORMAL_MESSAGE, message); g_free((void *) message); @@ -1384,7 +1384,7 @@ void LayerVerb::perform(SPAction *action, void *data) dt->setCurrentLayer(new_layer); } #endif - DocumentUndo::done(sp_desktop_document(dt), SP_VERB_LAYER_DUPLICATE, + DocumentUndo::done(dt->getDocument(), SP_VERB_LAYER_DUPLICATE, _("Duplicate layer")); // TRANSLATORS: this means "The layer has been duplicated." @@ -1396,7 +1396,7 @@ void LayerVerb::perform(SPAction *action, void *data) } case SP_VERB_LAYER_DELETE: { if ( dt->currentLayer() != dt->currentRoot() ) { - sp_desktop_selection(dt)->clear(); + dt->getSelection()->clear(); SPObject *old_layer=dt->currentLayer(); sp_object_ref(old_layer, NULL); @@ -1420,7 +1420,7 @@ void LayerVerb::perform(SPAction *action, void *data) dt->setCurrentLayer(survivor); } - DocumentUndo::done(sp_desktop_document(dt), SP_VERB_LAYER_DELETE, + DocumentUndo::done(dt->getDocument(), SP_VERB_LAYER_DELETE, _("Delete layer")); // TRANSLATORS: this means "The layer has been deleted." @@ -1435,23 +1435,23 @@ void LayerVerb::perform(SPAction *action, void *data) dt->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("No current layer.")); } else { dt->toggleLayerSolo( dt->currentLayer() ); - DocumentUndo::done(sp_desktop_document(dt), SP_VERB_LAYER_SOLO, _("Toggle layer solo")); + DocumentUndo::done(dt->getDocument(), SP_VERB_LAYER_SOLO, _("Toggle layer solo")); } break; } case SP_VERB_LAYER_SHOW_ALL: { dt->toggleHideAllLayers( false ); - DocumentUndo::maybeDone(sp_desktop_document(dt), "layer:showall", SP_VERB_LAYER_SHOW_ALL, _("Show all layers")); + DocumentUndo::maybeDone(dt->getDocument(), "layer:showall", SP_VERB_LAYER_SHOW_ALL, _("Show all layers")); break; } case SP_VERB_LAYER_HIDE_ALL: { dt->toggleHideAllLayers( true ); - DocumentUndo::maybeDone(sp_desktop_document(dt), "layer:hideall", SP_VERB_LAYER_HIDE_ALL, _("Hide all layers")); + DocumentUndo::maybeDone(dt->getDocument(), "layer:hideall", SP_VERB_LAYER_HIDE_ALL, _("Hide all layers")); break; } case SP_VERB_LAYER_LOCK_ALL: { dt->toggleLockAllLayers( true ); - DocumentUndo::maybeDone(sp_desktop_document(dt), "layer:lockall", SP_VERB_LAYER_LOCK_ALL, _("Lock all layers")); + DocumentUndo::maybeDone(dt->getDocument(), "layer:lockall", SP_VERB_LAYER_LOCK_ALL, _("Lock all layers")); break; } case SP_VERB_LAYER_LOCK_OTHERS: { @@ -1459,13 +1459,13 @@ void LayerVerb::perform(SPAction *action, void *data) dt->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("No current layer.")); } else { dt->toggleLockOtherLayers( dt->currentLayer() ); - DocumentUndo::done(sp_desktop_document(dt), SP_VERB_LAYER_LOCK_OTHERS, _("Lock other layers")); + DocumentUndo::done(dt->getDocument(), SP_VERB_LAYER_LOCK_OTHERS, _("Lock other layers")); } break; } case SP_VERB_LAYER_UNLOCK_ALL: { dt->toggleLockAllLayers( false ); - DocumentUndo::maybeDone(sp_desktop_document(dt), "layer:unlockall", SP_VERB_LAYER_UNLOCK_ALL, _("Unlock all layers")); + DocumentUndo::maybeDone(dt->getDocument(), "layer:unlockall", SP_VERB_LAYER_UNLOCK_ALL, _("Unlock all layers")); break; } case SP_VERB_LAYER_TOGGLE_LOCK: @@ -1548,12 +1548,12 @@ void ObjectVerb::perform( SPAction *action, void *data) break; case SP_VERB_OBJECT_FLIP_HORIZONTAL: sp_selection_scale_relative(sel, center, Geom::Scale(-1.0, 1.0)); - DocumentUndo::done(sp_desktop_document(dt), SP_VERB_OBJECT_FLIP_HORIZONTAL, + DocumentUndo::done(dt->getDocument(), SP_VERB_OBJECT_FLIP_HORIZONTAL, _("Flip horizontally")); break; case SP_VERB_OBJECT_FLIP_VERTICAL: sp_selection_scale_relative(sel, center, Geom::Scale(1.0, -1.0)); - DocumentUndo::done(sp_desktop_document(dt), SP_VERB_OBJECT_FLIP_VERTICAL, + DocumentUndo::done(dt->getDocument(), SP_VERB_OBJECT_FLIP_VERTICAL, _("Flip vertically")); break; case SP_VERB_OBJECT_SET_MASK: @@ -1592,10 +1592,6 @@ void TagVerb::perform( SPAction *action, void *data) if (!dt) return; - //Inkscape::UI::Tools::ToolBase *ec = dt->event_context; - - Inkscape::Selection *sel = sp_desktop_selection(dt); - Inkscape::XML::Document * doc; Inkscape::XML::Node * repr; gchar *id; @@ -1835,7 +1831,7 @@ void TextVerb::perform(SPAction *action, void */*data*/) g_return_if_fail(ensure_desktop_valid(action)); SPDesktop *dt = sp_action_get_desktop(action); - SPDocument *doc = sp_desktop_document(dt); + SPDocument *doc = dt->getDocument(); (void)doc; Inkscape::XML::Node *repr = dt->namedview->getRepr(); (void)repr; @@ -1850,7 +1846,7 @@ void ZoomVerb::perform(SPAction *action, void *data) SPDesktop *dt = sp_action_get_desktop(action); Inkscape::UI::Tools::ToolBase *ec = dt->event_context; - SPDocument *doc = sp_desktop_document(dt); + SPDocument *doc = dt->getDocument(); Inkscape::XML::Node *repr = dt->namedview->getRepr(); @@ -2006,7 +2002,7 @@ void ZoomVerb::perform(SPAction *action, void *data) dt->toggleColorProfAdjust(); break; case SP_VERB_VIEW_ICON_PREVIEW: - inkscape_dialogs_unhide(); + INKSCAPE.dialogs_unhide(); dt->_dlg_mgr->showDialog("IconPreviewPanel"); break; @@ -2025,7 +2021,7 @@ void DialogVerb::perform(SPAction *action, void *data) { if (reinterpret_cast<std::size_t>(data) != SP_VERB_DIALOG_TOGGLE) { // unhide all when opening a new dialog - inkscape_dialogs_unhide(); + INKSCAPE.dialogs_unhide(); } g_return_if_fail(ensure_desktop_valid(action)); @@ -2088,7 +2084,7 @@ void DialogVerb::perform(SPAction *action, void *data) dt->_dlg_mgr->showDialog("UndoHistory"); break; case SP_VERB_DIALOG_TOGGLE: - inkscape_dialogs_toggle(); + INKSCAPE.dialogs_toggle(); break; case SP_VERB_DIALOG_CLONETILER: //clonetiler_dialog(); @@ -2166,7 +2162,7 @@ void HelpVerb::perform(SPAction *action, void *data) */ case SP_VERB_HELP_MEMORY: - inkscape_dialogs_unhide(); + INKSCAPE.dialogs_unhide(); dt->_dlg_mgr->showDialog("Memory"); break; default: @@ -2330,7 +2326,7 @@ void FitCanvasVerb::perform(SPAction *action, void *data) { g_return_if_fail(ensure_desktop_valid(action)); SPDesktop *dt = sp_action_get_desktop(action); - SPDocument *doc = sp_desktop_document(dt); + SPDocument *doc = dt->getDocument(); if (!doc) return; switch (reinterpret_cast<std::size_t>(data)) { @@ -2396,7 +2392,7 @@ void LockAndHideVerb::perform(SPAction *action, void *data) { g_return_if_fail(ensure_desktop_valid(action)); SPDesktop *dt = sp_action_get_desktop(action); - SPDocument *doc = sp_desktop_document(dt); + SPDocument *doc = dt->getDocument(); if (!doc) return; switch (reinterpret_cast<std::size_t>(data)) { @@ -2432,7 +2428,7 @@ Verb *Verb::_base_verbs[] = { new Verb(SP_VERB_NONE, "None", NC_("Verb", "None"), N_("Does nothing"), NULL, NULL), // File - new FileVerb(SP_VERB_FILE_NEW, "FileNew", N_("Default"), N_("Create new document from the default template"), + new FileVerb(SP_VERB_FILE_NEW, "FileNew", N_("_New"), N_("Create new document from the default template"), INKSCAPE_ICON("document-new")), new FileVerb(SP_VERB_FILE_OPEN, "FileOpen", N_("_Open..."), N_("Open an existing document"), INKSCAPE_ICON("document-open")), @@ -2462,7 +2458,7 @@ Verb *Verb::_base_verbs[] = { new FileVerb(SP_VERB_FILE_CLOSE_VIEW, "FileClose", N_("_Close"), N_("Close this document window"), INKSCAPE_ICON("window-close")), new FileVerb(SP_VERB_FILE_QUIT, "FileQuit", N_("_Quit"), N_("Quit Inkscape"), INKSCAPE_ICON("application-exit")), - new FileVerb(SP_VERB_FILE_TEMPLATES, "FileTemplates", N_("_Templates..."), + new FileVerb(SP_VERB_FILE_TEMPLATES, "FileTemplates", N_("New from _Template..."), N_("Create new project from template"), INKSCAPE_ICON("dialog-templates")), // Edit diff --git a/src/viewbox.cpp b/src/viewbox.cpp index 662b05686..e1da23efa 100644 --- a/src/viewbox.cpp +++ b/src/viewbox.cpp @@ -161,23 +161,31 @@ void SPViewBox::set_preserveAspectRatio(const gchar* value) { } // Apply scaling from viewbox -void SPViewBox::apply_viewbox(const Geom::Rect& in) { +void SPViewBox::apply_viewbox(const Geom::Rect& in, double scale_none) { /* Determine actual viewbox in viewport coordinates */ - /* These are floats since SVGLength is a float: See bug 1374614 */ - float x = 0.0; - float y = 0.0; - float width = in.width(); - float height = in.height(); - // std::cout << " width: " << width << " height: " << height << std::endl; - - if (this->aspect_align != SP_ASPECT_NONE) { - /* Things are getting interesting */ - double scalex = in.width() / ((float) this->viewBox.width()); - double scaley = in.height() / ((float) this->viewBox.height()); - double scale = (this->aspect_clip == SP_ASPECT_MEET) ? MIN (scalex, scaley) : MAX (scalex, scaley); - width = this->viewBox.width() * scale; - height = this->viewBox.height() * scale; + // scale_none is the scale that would apply if the viewbox and page size are same size + // it is passed here because it is a double-precision variable, while 'in' is originally float + double x = 0.0; + double y = 0.0; + double scale_x = in.width() / this->viewBox.width(); + double scale_y = in.height() / this->viewBox.height(); + double scale_uniform = 1.0; // used only if scaling is uniform + + if (Geom::are_near(scale_x / scale_y, 1.0, Geom::EPSILON)) { + // scaling is already uniform, reduce numerical error + scale_uniform = (scale_x + scale_y)/2.0; + if (Geom::are_near(scale_uniform / scale_none, 1.0, Geom::EPSILON)) + scale_uniform = scale_none; // objects are same size, reduce numerical error + scale_x = scale_uniform; + scale_y = scale_uniform; + } else if (this->aspect_align != SP_ASPECT_NONE) { + // scaling is not uniform, but force it to be + scale_uniform = (this->aspect_clip == SP_ASPECT_MEET) ? MIN (scale_x, scale_y) : MAX (scale_x, scale_y); + scale_x = scale_uniform; + scale_y = scale_uniform; + double width = this->viewBox.width() * scale_uniform; + double height = this->viewBox.height() * scale_uniform; /* Now place viewbox to requested position */ switch (this->aspect_align) { @@ -218,12 +226,12 @@ void SPViewBox::apply_viewbox(const Geom::Rect& in) { /* Viewbox transform from scale and position */ Geom::Affine q; - q[0] = width / ((float) this->viewBox.width()); + q[0] = scale_x; q[1] = 0.0; q[2] = 0.0; - q[3] = height / ((float) this->viewBox.height()); - q[4] = x - q[0] * ((float) this->viewBox.left()); - q[5] = y - q[3] * ((float) this->viewBox.top()); + q[3] = scale_y; + q[4] = x - scale_x * this->viewBox.left(); + q[5] = y - scale_y * this->viewBox.top(); // std::cout << " q\n" << q << std::endl; @@ -231,7 +239,7 @@ void SPViewBox::apply_viewbox(const Geom::Rect& in) { this->c2p = q * this->c2p; } -SPItemCtx SPViewBox::get_rctx(const SPItemCtx* ictx) { +SPItemCtx SPViewBox::get_rctx(const SPItemCtx* ictx, double scale_none) { /* Create copy of item context */ SPItemCtx rctx = *ictx; @@ -242,7 +250,7 @@ SPItemCtx SPViewBox::get_rctx(const SPItemCtx* ictx) { if (this->viewBox_set) { // Adjusts c2p for viewbox - apply_viewbox( rctx.viewport ); + apply_viewbox( rctx.viewport, scale_none ); } rctx.i2doc = this->c2p * rctx.i2doc; diff --git a/src/viewbox.h b/src/viewbox.h index 1898cd98f..c71abb610 100644 --- a/src/viewbox.h +++ b/src/viewbox.h @@ -41,9 +41,9 @@ public: void set_preserveAspectRatio(const gchar* value); /* Adjusts c2p for viewbox */ - void apply_viewbox(const Geom::Rect& in); + void apply_viewbox(const Geom::Rect& in, double scale_none = 1.0); - SPItemCtx get_rctx( const SPItemCtx* ictx); + SPItemCtx get_rctx( const SPItemCtx* ictx, double scale_none = 1.0); }; diff --git a/src/widgets/arc-toolbar.cpp b/src/widgets/arc-toolbar.cpp index ca582924b..8a64854be 100644 --- a/src/widgets/arc-toolbar.cpp +++ b/src/widgets/arc-toolbar.cpp @@ -31,7 +31,7 @@ #include <glibmm/i18n.h> #include "arc-toolbar.h" -#include "desktop-handles.h" + #include "desktop.h" #include "document-undo.h" #include "widgets/ege-adjustment-action.h" @@ -81,7 +81,7 @@ sp_arctb_startend_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *v { SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" )); - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setDouble(Glib::ustring("/tools/shapes/arc/") + value_name, gtk_adjustment_get_value(adj)); } @@ -97,7 +97,7 @@ sp_arctb_startend_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *v gchar* namespaced_name = g_strconcat("sodipodi:", value_name, NULL); bool modmade = false; - for (GSList const *items = sp_desktop_selection(desktop)->itemList(); + for (GSList const *items = desktop->getSelection()->itemList(); items != NULL; items = items->next) { @@ -128,7 +128,7 @@ sp_arctb_startend_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *v sp_arctb_sensitivize( tbl, gtk_adjustment_get_value(adj), gtk_adjustment_get_value(other) ); if (modmade) { - DocumentUndo::maybeDone(sp_desktop_document(desktop), value_name, SP_VERB_CONTEXT_ARC, + DocumentUndo::maybeDone(desktop->getDocument(), value_name, SP_VERB_CONTEXT_ARC, _("Arc: Change start/end")); } @@ -150,7 +150,7 @@ static void sp_arctb_end_value_changed(GtkAdjustment *adj, GObject *tbl) static void sp_arctb_open_state_changed( EgeSelectOneAction *act, GObject *tbl ) { SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" )); - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setBool("/tools/shapes/arc/open", ege_select_one_action_get_active(act) != 0); } @@ -166,7 +166,7 @@ static void sp_arctb_open_state_changed( EgeSelectOneAction *act, GObject *tbl ) bool modmade = false; if ( ege_select_one_action_get_active(act) != 0 ) { - for (GSList const *items = sp_desktop_selection(desktop)->itemList(); + for (GSList const *items = desktop->getSelection()->itemList(); items != NULL; items = items->next) { @@ -179,7 +179,7 @@ static void sp_arctb_open_state_changed( EgeSelectOneAction *act, GObject *tbl ) } } } else { - for (GSList const *items = sp_desktop_selection(desktop)->itemList(); + for (GSList const *items = desktop->getSelection()->itemList(); items != NULL; items = items->next) { @@ -194,7 +194,7 @@ static void sp_arctb_open_state_changed( EgeSelectOneAction *act, GObject *tbl ) } if (modmade) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_ARC, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_ARC, _("Arc: Change open/closed")); } @@ -413,8 +413,8 @@ static void arc_toolbox_check_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBa static sigc::connection changed; if (SP_IS_ARC_CONTEXT(ec)) { - changed = sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_arc_toolbox_selection_changed), holder)); - sp_arc_toolbox_selection_changed(sp_desktop_selection(desktop), holder); + changed = desktop->getSelection()->connectChanged(sigc::bind(sigc::ptr_fun(sp_arc_toolbox_selection_changed), holder)); + sp_arc_toolbox_selection_changed(desktop->getSelection(), holder); } else { if (changed) changed.disconnect(); diff --git a/src/widgets/box3d-toolbar.cpp b/src/widgets/box3d-toolbar.cpp index 02d102a11..31b897ced 100644 --- a/src/widgets/box3d-toolbar.cpp +++ b/src/widgets/box3d-toolbar.cpp @@ -32,7 +32,7 @@ #include "box3d-toolbar.h" #include "box3d.h" -#include "desktop-handles.h" + #include "desktop.h" #include "document-undo.h" #include "document.h" @@ -193,22 +193,22 @@ static void box3d_toolbox_selection_changed(Inkscape::Selection *selection, GObj Inkscape::GC::anchor(persp_repr); sp_repr_add_listener(persp_repr, &box3d_persp_tb_repr_events, tbl); sp_repr_synthesize_events(persp_repr, &box3d_persp_tb_repr_events, tbl); - } - inkscape_active_document()->setCurrentPersp3D(persp3d_get_from_repr(persp_repr)); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setString("/tools/shapes/3dbox/persp", persp_repr->attribute("id")); + SP_ACTIVE_DOCUMENT->setCurrentPersp3D(persp3d_get_from_repr(persp_repr)); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setString("/tools/shapes/3dbox/persp", persp_repr->attribute("id")); - g_object_set_data(tbl, "freeze", GINT_TO_POINTER(TRUE)); - box3d_resync_toolbar(persp_repr, tbl); - g_object_set_data(tbl, "freeze", GINT_TO_POINTER(FALSE)); + g_object_set_data(tbl, "freeze", GINT_TO_POINTER(TRUE)); + box3d_resync_toolbar(persp_repr, tbl); + g_object_set_data(tbl, "freeze", GINT_TO_POINTER(FALSE)); + } } } static void box3d_angle_value_changed(GtkAdjustment *adj, GObject *dataKludge, Proj::Axis axis) { SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( dataKludge, "desktop" )); - SPDocument *document = sp_desktop_document(desktop); + SPDocument *document = desktop->getDocument(); // quit if run by the attr_changed or selection changed listener if (g_object_get_data( dataKludge, "freeze" )) { @@ -218,7 +218,7 @@ static void box3d_angle_value_changed(GtkAdjustment *adj, GObject *dataKludge, P // in turn, prevent listener from responding g_object_set_data(dataKludge, "freeze", GINT_TO_POINTER(TRUE)); - std::list<Persp3D *> sel_persps = sp_desktop_selection(desktop)->perspList(); + std::list<Persp3D *> sel_persps = desktop->getSelection()->perspList(); if (sel_persps.empty()) { // this can happen when the document is created; we silently ignore it return; @@ -255,7 +255,7 @@ static void box3d_angle_z_value_changed(GtkAdjustment *adj, GObject *dataKludge) static void box3d_vp_state_changed( GtkToggleAction *act, GtkAction * /*box3d_angle*/, Proj::Axis axis ) { // TODO: Take all selected perspectives into account - std::list<Persp3D *> sel_persps = sp_desktop_selection(inkscape_active_desktop())->perspList(); + std::list<Persp3D *> sel_persps = SP_ACTIVE_DESKTOP->getSelection()->perspList(); if (sel_persps.empty()) { // this can happen when the document is created; we silently ignore it return; @@ -287,7 +287,7 @@ void box3d_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); EgeAdjustmentAction* eact = 0; - SPDocument *document = sp_desktop_document (desktop); + SPDocument *document = desktop->getDocument(); Persp3DImpl *persp_impl = document->getCurrentPersp3DImpl(); EgeAdjustmentAction* box3d_angle_x = 0; @@ -420,8 +420,8 @@ static void box3d_toolbox_check_ec(SPDesktop* desktop, Inkscape::UI::Tools::Tool { static sigc::connection changed; if (SP_IS_BOX3D_CONTEXT(ec)) { - changed = sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(box3d_toolbox_selection_changed), holder)); - box3d_toolbox_selection_changed(sp_desktop_selection(desktop), holder); + changed = desktop->getSelection()->connectChanged(sigc::bind(sigc::ptr_fun(box3d_toolbox_selection_changed), holder)); + box3d_toolbox_selection_changed(desktop->getSelection(), holder); } else { if (changed) changed.disconnect(); diff --git a/src/widgets/connector-toolbar.cpp b/src/widgets/connector-toolbar.cpp index 6ce926dc1..c906f7de4 100644 --- a/src/widgets/connector-toolbar.cpp +++ b/src/widgets/connector-toolbar.cpp @@ -32,7 +32,7 @@ #include "connector-toolbar.h" #include "conn-avoid-ref.h" -#include "desktop-handles.h" + #include "desktop.h" #include "document-undo.h" #include "widgets/ege-adjustment-action.h" @@ -76,8 +76,8 @@ static void sp_connector_path_set_ignore(void) static void sp_connector_orthogonal_toggled( GtkToggleAction* act, GObject *tbl ) { SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" )); - Inkscape::Selection * selection = sp_desktop_selection(desktop); - SPDocument *doc = sp_desktop_document(desktop); + Inkscape::Selection * selection = desktop->getSelection(); + SPDocument *doc = desktop->getDocument(); if (!DocumentUndo::getUndoSensitive(doc)) { return; @@ -126,8 +126,8 @@ static void sp_connector_orthogonal_toggled( GtkToggleAction* act, GObject *tbl static void connector_curvature_changed(GtkAdjustment *adj, GObject* tbl) { SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" )); - Inkscape::Selection * selection = sp_desktop_selection(desktop); - SPDocument *doc = sp_desktop_document(desktop); + Inkscape::Selection * selection = desktop->getSelection(); + SPDocument *doc = desktop->getDocument(); if (!DocumentUndo::getUndoSensitive(doc)) { return; @@ -176,7 +176,7 @@ static void connector_curvature_changed(GtkAdjustment *adj, GObject* tbl) static void connector_spacing_changed(GtkAdjustment *adj, GObject* tbl) { SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" )); - SPDocument *doc = sp_desktop_document(desktop); + SPDocument *doc = desktop->getDocument(); if (!DocumentUndo::getUndoSensitive(doc)) { return; @@ -233,11 +233,11 @@ static void sp_connector_graph_layout(void) int saved_compensation = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); - graphlayout(sp_desktop_selection(SP_ACTIVE_DESKTOP)->itemList()); + graphlayout(SP_ACTIVE_DESKTOP->getSelection()->itemList()); prefs->setInt("/options/clonecompensation/value", saved_compensation); - DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, _("Arrange connector network")); + DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, _("Arrange connector network")); } static void sp_directed_graph_layout_toggled( GtkToggleAction* act, GObject * /*tbl*/ ) @@ -402,7 +402,7 @@ void sp_connector_toolbox_prep( SPDesktop *desktop, GtkActionGroup* mainActions, gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act), ( tbuttonstate ? TRUE : FALSE )); g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_directed_graph_layout_toggled), holder ); - sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_connector_toolbox_selection_changed), holder)); + desktop->getSelection()->connectChanged(sigc::bind(sigc::ptr_fun(sp_connector_toolbox_selection_changed), holder)); } // Avoid overlaps toggle button diff --git a/src/widgets/dash-selector.cpp b/src/widgets/dash-selector.cpp index 479895022..9d591d33d 100644 --- a/src/widgets/dash-selector.cpp +++ b/src/widgets/dash-selector.cpp @@ -118,18 +118,18 @@ void SPDashSelector::init_dashes() { int pos = 0; if (!dash_prefs.empty()) { - SPStyle *style = sp_style_new (NULL); + SPStyle style; dashes = g_new (double *, dash_prefs.size() + 2); // +1 for custom slot, +1 for terminator slot for (std::vector<Glib::ustring>::iterator i = dash_prefs.begin(); i != dash_prefs.end(); ++i) { - sp_style_read_from_prefs(style, *i); + style.readFromPrefs( *i ); - if (!style->stroke_dasharray.values.empty()) { - dashes[pos] = g_new (double, style->stroke_dasharray.values.size() + 1); + if (!style.stroke_dasharray.values.empty()) { + dashes[pos] = g_new (double, style.stroke_dasharray.values.size() + 1); double *d = dashes[pos]; unsigned i = 0; - for (; i < style->stroke_dasharray.values.size(); i++) { - d[i] = style->stroke_dasharray.values[i]; + for (; i < style.stroke_dasharray.values.size(); i++) { + d[i] = style.stroke_dasharray.values[i]; } d[i] = -1; } else { diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index 2aab68812..fd3756220 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -32,7 +32,7 @@ #include "conn-avoid-ref.h" #include "desktop.h" #include "desktop-events.h" -#include "desktop-handles.h" + #include "desktop-widget.h" #include "display/sp-canvas.h" #include "display/canvas-arena.h" @@ -45,7 +45,7 @@ #include "helper/action-context.h" #include "util/units.h" #include "ui/widget/unit-tracker.h" -#include "inkscape-private.h" +#include "inkscape.h" #include "ui/interface.h" #include "macros.h" #include "preferences.h" @@ -795,7 +795,7 @@ static void sp_desktop_widget_dispose(GObject *object) dtw->layer_selector->setDesktop(NULL); dtw->layer_selector->unreference(); - inkscape_remove_desktop (dtw->desktop); // clears selection too + INKSCAPE.remove_desktop (dtw->desktop); // clears selection too dtw->modified_connection.disconnect(); dtw->desktop->destroy(); Inkscape::GC::release (dtw->desktop); @@ -1091,7 +1091,7 @@ SPDesktopWidget::shutdown() { g_assert(desktop != NULL); - if (inkscape_is_sole_desktop_for_document(*desktop)) { + if (INKSCAPE.sole_desktop_for_document(*desktop)) { SPDocument *doc = desktop->doc(); if (doc->isModifiedSinceSave()) { GtkWidget *dialog; @@ -1672,7 +1672,7 @@ SPDesktopWidget* SPDesktopWidget::createInstance(SPNamedView *namedview) dtw->desktop = new SPDesktop(); dtw->stub = new SPDesktopWidget::WidgetStub (dtw); dtw->desktop->init (namedview, dtw->canvas, dtw->stub); - inkscape_add_desktop (dtw->desktop); + INKSCAPE.add_desktop (dtw->desktop); // Add the shape geometry to libavoid for autorouting connectors. // This needs desktop set for its spacing preferences. @@ -1740,8 +1740,8 @@ void SPDesktopWidget::namedviewModified(SPObject *obj, guint flags) this->dt2r = 1. / nv->display_units->factor; this->ruler_origin = Geom::Point(0,0); //nv->gridorigin; Why was the grid origin used here? - sp_ruler_set_unit(SP_RULER (this->vruler), nv->getDefaultUnit()); - sp_ruler_set_unit(SP_RULER (this->hruler), nv->getDefaultUnit()); + sp_ruler_set_unit(SP_RULER (this->vruler), nv->getDisplayUnit()); + sp_ruler_set_unit(SP_RULER (this->hruler), nv->getDisplayUnit()); /* This loops through all the grandchildren of aux toolbox, * and for each that it finds, it performs an sp_search_by_data_recursive(), @@ -1818,7 +1818,7 @@ bool SPDesktopWidget::onFocusInEvent(GdkEventFocus*) } } - inkscape_activate_desktop (desktop); + INKSCAPE.activate_desktop (desktop); return false; } diff --git a/src/widgets/eraser-toolbar.cpp b/src/widgets/eraser-toolbar.cpp index f547cbd8b..1f79b50f2 100644 --- a/src/widgets/eraser-toolbar.cpp +++ b/src/widgets/eraser-toolbar.cpp @@ -32,7 +32,7 @@ #include "eraser-toolbar.h" #include "calligraphy-toolbar.h" // TODO: needed for update_presets_list -#include "desktop-handles.h" + #include "desktop.h" #include "document-undo.h" #include "widgets/ege-adjustment-action.h" @@ -61,7 +61,7 @@ static void sp_erasertb_mode_changed( EgeSelectOneAction *act, GObject *tbl ) { SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" )); bool eraserMode = ege_select_one_action_get_active( act ) != 0; - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setBool( "/tools/eraser/mode", eraserMode ); } diff --git a/src/widgets/fill-style.cpp b/src/widgets/fill-style.cpp index d1d318abe..d60a92b8b 100644 --- a/src/widgets/fill-style.cpp +++ b/src/widgets/fill-style.cpp @@ -35,7 +35,7 @@ #include "desktop.h" #include "selection.h" -#include "desktop-handles.h" + #include "desktop-style.h" #include "display/sp-canvas.h" #include "document-private.h" @@ -252,13 +252,13 @@ void FillNStroke::performUpdate() update = true; // create temporary style - SPStyle *query = sp_style_new(desktop->doc()); + SPStyle query(desktop->doc()); // query style from desktop into it. This returns a result flag and fills query with the style of subselection, if any, or selection - int result = sp_desktop_query_style(desktop, query, (kind == FILL) ? QUERY_STYLE_PROPERTY_FILL : QUERY_STYLE_PROPERTY_STROKE); + int result = sp_desktop_query_style(desktop, &query, (kind == FILL) ? QUERY_STYLE_PROPERTY_FILL : QUERY_STYLE_PROPERTY_STROKE); - SPIPaint &targPaint = (kind == FILL) ? query->fill : query->stroke; - SPIScale24 &targOpacity = (kind == FILL) ? query->fill_opacity : query->stroke_opacity; + SPIPaint &targPaint = (kind == FILL) ? query.fill : query.stroke; + SPIScale24 &targOpacity = (kind == FILL) ? query.fill_opacity : query.stroke_opacity; switch (result) { case QUERY_STYLE_NOTHING: @@ -272,11 +272,11 @@ void FillNStroke::performUpdate() case QUERY_STYLE_MULTIPLE_AVERAGED: // TODO: treat this slightly differently, e.g. display "averaged" somewhere in paint selector case QUERY_STYLE_MULTIPLE_SAME: { - SPPaintSelector::Mode pselmode = SPPaintSelector::getModeForStyle(*query, kind); + SPPaintSelector::Mode pselmode = SPPaintSelector::getModeForStyle(query, kind); psel->setMode(pselmode); if (kind == FILL) { - psel->setFillrule(query->fill_rule.computed == ART_WIND_RULE_NONZERO? + psel->setFillrule(query.fill_rule.computed == ART_WIND_RULE_NONZERO? SPPaintSelector::FILLRULE_NONZERO : SPPaintSelector::FILLRULE_EVENODD); } @@ -284,7 +284,7 @@ void FillNStroke::performUpdate() psel->setColorAlpha(targPaint.value.color, SP_SCALE24_TO_FLOAT(targOpacity.value)); } else if (targPaint.set && targPaint.isPaintserver()) { - SPPaintServer *server = (kind == FILL) ? query->getFillPaintServer() : query->getStrokePaintServer(); + SPPaintServer *server = (kind == FILL) ? query.getFillPaintServer() : query.getStrokePaintServer(); if (server && SP_IS_GRADIENT(server) && SP_GRADIENT(server)->getVector()->isSwatch()) { SPGradient *vector = SP_GRADIENT(server)->getVector(); @@ -318,8 +318,6 @@ void FillNStroke::performUpdate() } } - sp_style_unref(query); - update = false; } @@ -480,8 +478,8 @@ void FillNStroke::updateFromPaint() } update = true; - SPDocument *document = sp_desktop_document(desktop); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + SPDocument *document = desktop->getDocument(); + Inkscape::Selection *selection = desktop->getSelection(); GSList const *items = selection->itemList(); @@ -516,18 +514,18 @@ void FillNStroke::updateFromPaint() { if (kind == FILL) { // FIXME: fix for GTK breakage, see comment in SelectedStyle::on_opacity_changed; here it results in losing release events - sp_desktop_canvas(desktop)->forceFullRedrawAfterInterruptions(0); + desktop->getCanvas()->forceFullRedrawAfterInterruptions(0); } psel->setFlatColor( desktop, (kind == FILL) ? "fill" : "stroke", (kind == FILL) ? "fill-opacity" : "stroke-opacity" ); - DocumentUndo::maybeDone(sp_desktop_document(desktop), (kind == FILL) ? undo_F_label : undo_S_label, SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::maybeDone(desktop->getDocument(), (kind == FILL) ? undo_F_label : undo_S_label, SP_VERB_DIALOG_FILL_STROKE, (kind == FILL) ? _("Set fill color") : _("Set stroke color")); if (kind == FILL) { // resume interruptibility - sp_desktop_canvas(desktop)->endForcedFullRedraws(); + desktop->getCanvas()->endForcedFullRedraws(); } // on release, toggle undo_label so that the next drag will not be lumped with this one @@ -562,10 +560,10 @@ void FillNStroke::updateFromPaint() if (!vector) { /* No vector in paint selector should mean that we just changed mode */ - SPStyle *query = sp_style_new(desktop->doc()); - int result = objects_query_fillstroke(const_cast<GSList *>(items), query, kind == FILL); + SPStyle query(desktop->doc()); + int result = objects_query_fillstroke(const_cast<GSList *>(items), &query, kind == FILL); if (result == QUERY_STYLE_MULTIPLE_SAME) { - SPIPaint &targPaint = (kind == FILL) ? query->fill : query->stroke; + SPIPaint &targPaint = (kind == FILL) ? query.fill : query.stroke; SPColor common; if (!targPaint.isColor()) { common = sp_desktop_get_color(desktop, kind == FILL); @@ -577,7 +575,6 @@ void FillNStroke::updateFromPaint() vector->setSwatch(); } } - sp_style_unref(query); for (GSList const *i = items; i != NULL; i = i->next) { //FIXME: see above diff --git a/src/widgets/gradient-selector.cpp b/src/widgets/gradient-selector.cpp index a5e16aed2..42e59cbfe 100644 --- a/src/widgets/gradient-selector.cpp +++ b/src/widgets/gradient-selector.cpp @@ -30,6 +30,7 @@ #include "helper/action.h" #include "helper/action-context.h" #include "preferences.h" +#include "widgets/icon.h" #include <glibmm/i18n.h> #include <xml/repr.h> @@ -101,6 +102,15 @@ static void sp_gradient_selector_class_init(SPGradientSelectorClass *klass) object_class->dispose = sp_gradient_selector_dispose; } +static void gradsel_style_button(GtkWidget *gtkbtn, char const *iconName) +{ + Gtk::Button *btn = Glib::wrap(GTK_BUTTON(gtkbtn)); + GtkWidget *child = sp_icon_new(Inkscape::ICON_SIZE_SMALL_TOOLBAR, iconName); + gtk_widget_show(child); + btn->add(*manage(Glib::wrap(child))); + btn->set_relief(Gtk::RELIEF_NONE); +} + static void sp_gradient_selector_init(SPGradientSelector *sel) { sel->safelyInit = true; @@ -179,13 +189,8 @@ static void sp_gradient_selector_init(SPGradientSelector *sel) //sel->nonsolid.push_back(hb); gtk_box_pack_start( GTK_BOX(sel), hb, FALSE, FALSE, 0 ); -#if GTK_CHECK_VERSION(3,10,0) - sel->add = gtk_button_new_from_icon_name(INKSCAPE_ICON("list-add"), GTK_ICON_SIZE_SMALL_TOOLBAR); -#else - sel->add = gtk_button_new (); - GtkWidget *img = gtk_image_new_from_icon_name(INKSCAPE_ICON("list-add"), GTK_ICON_SIZE_SMALL_TOOLBAR); - gtk_button_set_image(GTK_BUTTON(sel->add), img); -#endif + sel->add = gtk_button_new(); + gradsel_style_button(sel->add, INKSCAPE_ICON("list-add")); sel->nonsolid.push_back(sel->add); gtk_box_pack_start (GTK_BOX (hb), sel->add, FALSE, FALSE, 0); @@ -196,13 +201,8 @@ static void sp_gradient_selector_init(SPGradientSelector *sel) gtk_widget_set_tooltip_text( sel->add, _("Create a duplicate gradient")); // FIXME: Probably better to either use something from the icon naming spec or ship our own "edit-gradient" icon -#if GTK_CHECK_VERSION(3,10,0) - sel->edit = gtk_button_new_from_icon_name(INKSCAPE_ICON("gtk-edit"), GTK_ICON_SIZE_SMALL_TOOLBAR); -#else - sel->edit = gtk_button_new (); - img = gtk_image_new_from_icon_name(INKSCAPE_ICON("gtk-edit"), GTK_ICON_SIZE_SMALL_TOOLBAR); - gtk_button_set_image(GTK_BUTTON(sel->edit), img); -#endif + sel->edit = gtk_button_new(); + gradsel_style_button(sel->edit, INKSCAPE_ICON("gtk-edit")); sel->nonsolid.push_back(sel->edit); gtk_box_pack_start (GTK_BOX (hb), sel->edit, FALSE, FALSE, 0); @@ -211,13 +211,8 @@ static void sp_gradient_selector_init(SPGradientSelector *sel) gtk_button_set_relief(GTK_BUTTON(sel->edit), GTK_RELIEF_NONE); gtk_widget_set_tooltip_text( sel->edit, _("Edit gradient")); -#if GTK_CHECK_VERSION(3,10,0) - sel->del = gtk_button_new_from_icon_name(INKSCAPE_ICON("list-remove"), GTK_ICON_SIZE_SMALL_TOOLBAR); -#else sel->del = gtk_button_new (); - img = gtk_image_new_from_icon_name(INKSCAPE_ICON("list-remove"), GTK_ICON_SIZE_SMALL_TOOLBAR); - gtk_button_set_image(GTK_BUTTON(sel->del), img); -#endif + gradsel_style_button(sel->del, INKSCAPE_ICON("list-remove")); sel->swatch_widgets.push_back(sel->del); gtk_box_pack_start (GTK_BOX (hb), sel->del, FALSE, FALSE, 0); @@ -227,8 +222,6 @@ static void sp_gradient_selector_init(SPGradientSelector *sel) gtk_widget_set_tooltip_text( sel->del, _("Delete swatch")); gtk_widget_show_all(hb); - - } static void sp_gradient_selector_dispose(GObject *object) diff --git a/src/widgets/gradient-toolbar.cpp b/src/widgets/gradient-toolbar.cpp index b6378b251..7ce04403b 100644 --- a/src/widgets/gradient-toolbar.cpp +++ b/src/widgets/gradient-toolbar.cpp @@ -18,7 +18,7 @@ #include "ui/widget/color-preview.h" #include <glibmm/i18n.h> -#include "desktop-handles.h" + #include "desktop.h" #include "document-undo.h" #include "document.h" @@ -128,7 +128,7 @@ gboolean gr_vector_list(GtkWidget *combo_box, SPDesktop *desktop, bool selection return sensitive; } - SPDocument *document = sp_desktop_document(desktop); + SPDocument *document = desktop->getDocument(); GtkTreeIter iter; GtkListStore *store = (GtkListStore *)gtk_combo_box_get_model(GTK_COMBO_BOX(combo_box)); @@ -167,13 +167,15 @@ gboolean gr_vector_list(GtkWidget *combo_box, SPDesktop *desktop, bool selection if (gr_selected == NULL) { gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, 0, _("No gradient"), 1, NULL, 2, NULL, -1); - sensitive = FALSE; + // Dead assignment: Value stored to 'sensitive' is never read + //sensitive = FALSE; } if (gr_multi) { gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, 0, _("Multiple gradients"), 1, NULL, 2, NULL, -1); - sensitive = FALSE; + // Dead assignment: Value stored to 'sensitive' is never read + //sensitive = FALSE; } guint idx = 0; @@ -356,7 +358,7 @@ static void gr_tb_selection_changed(Inkscape::Selection * /*selection*/, gpointe return; } - Inkscape::Selection *selection = sp_desktop_selection(desktop); // take from desktop, not from args + Inkscape::Selection *selection = desktop->getSelection(); // take from desktop, not from args if (selection) { ToolBase *ev = desktop->getEventContext(); GrDrag *drag = NULL; @@ -560,7 +562,7 @@ static void gr_add_stop(GtkWidget * /*button*/, GtkWidget *vb) return; } - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); if (!selection) { return; } @@ -582,7 +584,7 @@ static void gr_remove_stop(GtkWidget * /*button*/, GtkWidget *vb) return; } - Inkscape::Selection *selection = sp_desktop_selection(desktop); // take from desktop, not from args + Inkscape::Selection *selection = desktop->getSelection(); // take from desktop, not from args if (!selection) { return; } @@ -786,7 +788,8 @@ static gboolean update_stop_list( GtkWidget *stop_combo, SPGradient *gradient, S gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, 0, label.c_str(), 1, pb, 2, stop, -1); - sensitive = FALSE; + // Dead assignment: Value stored to 'sensitive' is never read + //sensitive = FALSE; } } @@ -918,12 +921,12 @@ static void gr_gradient_combo_changed(EgeSelectOneAction *act, gpointer data) gr = sp_gradient_ensure_vector_normalized(gr); SPDesktop *desktop = static_cast<SPDesktop *>(data); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); ToolBase *ev = desktop->getEventContext(); gr_apply_gradient(selection, ev? ev->get_drag() : NULL, gr); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_GRADIENT, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_GRADIENT, _("Assign gradient to object")); } @@ -936,7 +939,7 @@ static void gr_spread_change(EgeSelectOneAction *act, GtkWidget *widget) } SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(G_OBJECT(widget), "desktop")); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); SPGradient *gradient = 0; gr_get_dt_selected_gradient(selection, gradient); @@ -945,7 +948,7 @@ static void gr_spread_change(EgeSelectOneAction *act, GtkWidget *widget) gradient->setSpread(spread); gradient->updateRepr(); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_GRADIENT, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_GRADIENT, _("Set gradient repeat")); } } @@ -1246,8 +1249,8 @@ static void gradient_toolbox_check_ec(SPDesktop* desktop, Inkscape::UI::Tools::T static sigc::connection connDefsModified; if (SP_IS_GRADIENT_CONTEXT(ec)) { - Inkscape::Selection *selection = sp_desktop_selection(desktop); - SPDocument *document = sp_desktop_document(desktop); + Inkscape::Selection *selection = desktop->getSelection(); + SPDocument *document = desktop->getDocument(); // connect to selection modified and changed signals connChanged = selection->connectChanged(sigc::bind(sigc::ptr_fun(&gr_tb_selection_changed), holder)); diff --git a/src/widgets/gradient-vector.cpp b/src/widgets/gradient-vector.cpp index 6607c90d2..d2c46ffec 100644 --- a/src/widgets/gradient-vector.cpp +++ b/src/widgets/gradient-vector.cpp @@ -1012,13 +1012,28 @@ GtkWidget * sp_gradient_vector_editor_new(SPGradient *gradient, SPStop *stop) sp_transientize(dlg); wd.win = dlg; wd.stop = 0; - g_signal_connect(G_OBJECT(INKSCAPE), "activate_desktop", G_CALLBACK(sp_transientize_callback), &wd); - g_signal_connect(G_OBJECT(dlg), "event", G_CALLBACK(sp_dialog_event_handler), dlg); - g_signal_connect(G_OBJECT(dlg), "destroy", G_CALLBACK(sp_gradient_vector_dialog_destroy), dlg); - g_signal_connect(G_OBJECT(dlg), "delete_event", G_CALLBACK(sp_gradient_vector_dialog_delete), dlg); - g_signal_connect(G_OBJECT(INKSCAPE), "shut_down", G_CALLBACK(sp_gradient_vector_dialog_delete), dlg); - g_signal_connect( G_OBJECT(INKSCAPE), "dialogs_hide", G_CALLBACK(sp_dialog_hide), dlg ); - g_signal_connect( G_OBJECT(INKSCAPE), "dialogs_unhide", G_CALLBACK(sp_dialog_unhide), dlg ); + + GObject *obj = G_OBJECT(dlg); + sigc::connection *conn = NULL; + + conn = new sigc::connection(INKSCAPE.signal_activate_desktop.connect(sigc::bind(sigc::ptr_fun(&sp_transientize_callback), &wd))); + g_object_set_data(obj, "desktop-activate-connection", conn); + + g_signal_connect(obj, "event", G_CALLBACK(sp_dialog_event_handler), dlg); + g_signal_connect(obj, "destroy", G_CALLBACK(sp_gradient_vector_dialog_destroy), dlg); + g_signal_connect(obj, "delete_event", G_CALLBACK(sp_gradient_vector_dialog_delete), dlg); + + conn = new sigc::connection(INKSCAPE.signal_shut_down.connect( + sigc::hide_return( + sigc::bind(sigc::ptr_fun(&sp_gradient_vector_dialog_delete), (GtkWidget *) NULL, (GdkEvent *) NULL, (GtkWidget *) NULL) + ))); + g_object_set_data(obj, "shutdown-connection", conn); + + conn = new sigc::connection(INKSCAPE.signal_dialogs_hide.connect(sigc::bind(sigc::ptr_fun(>k_widget_hide), dlg))); + g_object_set_data(obj, "dialog-hide-connection", conn); + + conn = new sigc::connection(INKSCAPE.signal_dialogs_unhide.connect(sigc::bind(sigc::ptr_fun(>k_widget_show), dlg))); + g_object_set_data(obj, "dialog-unhide-connection", conn); gtk_container_set_border_width(GTK_CONTAINER(dlg), PAD); @@ -1141,7 +1156,29 @@ static void sp_gradient_vector_dialog_destroy(GtkWidget * /*object*/, gpointer / static void sp_gradient_vector_dialog_destroy(GtkObject * /*object*/, gpointer /*data*/) #endif { - sp_signal_disconnect_by_data(INKSCAPE, dlg); + GObject *obj = G_OBJECT(dlg); + assert(obj != NULL); + + sigc::connection *conn = static_cast<sigc::connection *>(g_object_get_data(obj, "desktop-activate-connection")); + assert(conn != NULL); + conn->disconnect(); + delete conn; + + conn = static_cast<sigc::connection *>(g_object_get_data(obj, "shutdown-connection")); + assert(conn != NULL); + conn->disconnect(); + delete conn; + + conn = static_cast<sigc::connection *>(g_object_get_data(obj, "dialog-hide-connection")); + assert(conn != NULL); + conn->disconnect(); + delete conn; + + conn = static_cast<sigc::connection *>(g_object_get_data(obj, "dialog-unhide-connection")); + assert(conn != NULL); + conn->disconnect(); + delete conn; + wd.win = dlg = NULL; wd.stop = 0; } diff --git a/src/widgets/icon.cpp b/src/widgets/icon.cpp index a6e53d638..afc4fcfb0 100644 --- a/src/widgets/icon.cpp +++ b/src/widgets/icon.cpp @@ -1261,7 +1261,7 @@ std::list<gchar*> &IconImpl::icons_svg_paths() static bool initialized = false; if (!initialized) { // Fall back from user prefs dir into system locations. - gchar *userdir = profile_path("icons"); + gchar *userdir = Inkscape::Application::profile_path("icons"); sources.push_back(g_build_filename(userdir,"icons.svg", NULL)); sources.push_back(g_build_filename(INKSCAPE_PIXMAPDIR, "icons.svg", NULL)); g_free(userdir); @@ -1572,7 +1572,7 @@ void IconImpl::addPreRender( GtkIconSize lsize, gchar const *name ) } gboolean IconImpl::prerenderTask(gpointer /*data*/) { - if ( inkscapeIsCrashing() ) { + if ( Inkscape::Application::isCrashing() ) { // stop } else if (!pendingRenders.empty()) { bool workDone = false; @@ -1584,7 +1584,7 @@ gboolean IconImpl::prerenderTask(gpointer /*data*/) { } while (!pendingRenders.empty() && !workDone); } - if (!inkscapeIsCrashing() && !pendingRenders.empty()) { + if (!Inkscape::Application::isCrashing() && !pendingRenders.empty()) { return TRUE; } else { callbackHooked = false; diff --git a/src/widgets/lpe-toolbar.cpp b/src/widgets/lpe-toolbar.cpp index c6da46956..387bf6dee 100644 --- a/src/widgets/lpe-toolbar.cpp +++ b/src/widgets/lpe-toolbar.cpp @@ -30,7 +30,7 @@ #include "live_effects/lpe-line_segment.h" #include "lpe-toolbar.h" -#include "desktop-handles.h" + #include "desktop.h" #include "document-undo.h" #include "widgets/ege-select-one-action.h" @@ -91,7 +91,7 @@ static void sp_lpetool_mode_changed(EgeSelectOneAction *act, GObject *tbl) SP_LPETOOL_CONTEXT(desktop->event_context)->mode = type; } - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setInt( "/tools/lpetool/mode", mode ); } @@ -280,7 +280,7 @@ static void lpetool_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBas void sp_lpetool_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) { UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); - tracker->setActiveUnit(sp_desktop_namedview(desktop)->display_units); + tracker->setActiveUnit(desktop->getNamedView()->display_units); g_object_set_data(holder, "tracker", tracker); Unit const *unit = tracker->getActiveUnit(); g_return_if_fail(unit != NULL); @@ -413,9 +413,9 @@ static void lpetool_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::To if (SP_IS_LPETOOL_CONTEXT(ec)) { // Watch selection - c_selection_modified = sp_desktop_selection(desktop)->connectModified(sigc::bind(sigc::ptr_fun(sp_lpetool_toolbox_sel_modified), holder)); - c_selection_changed = sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_lpetool_toolbox_sel_changed), holder)); - sp_lpetool_toolbox_sel_changed(sp_desktop_selection(desktop), holder); + c_selection_modified = desktop->getSelection()->connectModified(sigc::bind(sigc::ptr_fun(sp_lpetool_toolbox_sel_modified), holder)); + c_selection_changed = desktop->getSelection()->connectChanged(sigc::bind(sigc::ptr_fun(sp_lpetool_toolbox_sel_changed), holder)); + sp_lpetool_toolbox_sel_changed(desktop->getSelection(), holder); } else { if (c_selection_modified) c_selection_modified.disconnect(); diff --git a/src/widgets/measure-toolbar.cpp b/src/widgets/measure-toolbar.cpp index 1a4678332..5a4785b1f 100644 --- a/src/widgets/measure-toolbar.cpp +++ b/src/widgets/measure-toolbar.cpp @@ -31,7 +31,7 @@ #include <glibmm/i18n.h> #include "measure-toolbar.h" -#include "desktop-handles.h" + #include "desktop.h" #include "document-undo.h" #include "widgets/ege-adjustment-action.h" @@ -55,7 +55,7 @@ sp_measure_fontsize_value_changed(GtkAdjustment *adj, GObject *tbl) { SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" )); - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setInt(Glib::ustring("/tools/measure/fontsize"), gtk_adjustment_get_value(adj)); diff --git a/src/widgets/mesh-toolbar.cpp b/src/widgets/mesh-toolbar.cpp index 897d84278..bf406e632 100644 --- a/src/widgets/mesh-toolbar.cpp +++ b/src/widgets/mesh-toolbar.cpp @@ -38,13 +38,13 @@ #include "document-private.h" #include "document-undo.h" #include "desktop.h" -#include "desktop-handles.h" + #include <glibmm/i18n.h> #include "ui/tools/gradient-tool.h" #include "ui/tools/mesh-tool.h" #include "gradient-drag.h" -#include "sp-mesh-gradient.h" +#include "sp-mesh.h" #include "gradient-chemistry.h" #include "gradient-selector.h" #include "selection.h" @@ -74,34 +74,117 @@ static bool blocked = false; //######################## /* + * Get the current selection and dragger status from the desktop + */ +void ms_read_selection( Inkscape::Selection *selection, + SPMesh *&ms_selected, + bool &ms_selected_multi, + SPMeshType &ms_type, + bool &ms_type_multi ) +{ + + // Read desktop selection + bool first = true; + ms_type = SP_MESH_TYPE_COONS; + + for (GSList const* i = selection->itemList(); i; i = i->next) { + SPItem *item = SP_ITEM(i->data); + SPStyle *style = item->style; + + if (style && (style->fill.isPaintserver())) { + SPPaintServer *server = item->style->getFillPaintServer(); + if ( SP_IS_MESH(server) ) { + + SPMesh *gradient = SP_MESH(server); // ->getVector(); + SPMeshType type = gradient->type; + + if (gradient != ms_selected) { + if (ms_selected) { + ms_selected_multi = true; + } else { + ms_selected = gradient; + } + } + if( type != ms_type ) { + if (ms_type != SP_MESH_TYPE_COONS && !first) { + ms_type_multi = true; + } else { + ms_type = type; + } + } + first = false; + } + } + + if (style && (style->stroke.isPaintserver())) { + SPPaintServer *server = item->style->getStrokePaintServer(); + if ( SP_IS_MESH(server) ) { + + SPMesh *gradient = SP_MESH(server); // ->getVector(); + SPMeshType type = gradient->type; + + if (gradient != ms_selected) { + if (ms_selected) { + ms_selected_multi = true; + } else { + ms_selected = gradient; + } + } + if( type != ms_type ) { + if (ms_type != SP_MESH_TYPE_COONS && !first) { + ms_type_multi = true; + } else { + ms_type = type; + } + } + first = false; + } + } + } + } + +/* * Core function, setup all the widgets whenever something changes on the desktop */ -static void ms_tb_selection_changed(Inkscape::Selection * /*selection*/, gpointer /*data*/) +static void ms_tb_selection_changed(Inkscape::Selection * /*selection*/, gpointer data) { - // DOES NOTHING AT MOMENT // std::cout << "ms_tb_selection_changed" << std::endl; - // if (blocked) - // return; - - // GtkWidget *widget = GTK_WIDGET(data); + if (blocked) + return; - // SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(G_OBJECT(widget), "desktop")); - // if (!desktop) { - // return; - // } + GtkWidget *widget = GTK_WIDGET(data); - // Inkscape::Selection *selection = sp_desktop_selection(desktop); // take from desktop, not from args - // if (selection) { - // ToolBase *ev = sp_desktop_event_context(desktop); - // GrDrag *drag = NULL; - // if (ev) { - // drag = ev->get_drag(); - // // Hide/show handles? - // } + SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(G_OBJECT(widget), "desktop")); + if (!desktop) { + return; + } - // } + Inkscape::Selection *selection = desktop->getSelection(); // take from desktop, not from args + if (selection) { + // ToolBase *ev = sp_desktop_event_context(desktop); + // GrDrag *drag = NULL; + // if (ev) { + // drag = ev->get_drag(); + // // Hide/show handles? + // } + + SPMesh *ms_selected = 0; + SPMeshType ms_type = SP_MESH_TYPE_COONS; + bool ms_selected_multi = false; + bool ms_type_multi = false; + ms_read_selection( selection, ms_selected, ms_selected_multi, ms_type, ms_type_multi ); + // std::cout << " type: " << ms_type << std::endl; + + EgeSelectOneAction* type = (EgeSelectOneAction *) g_object_get_data(G_OBJECT(widget), "mesh_select_type_action"); + gtk_action_set_sensitive( GTK_ACTION(type), (ms_selected && !ms_selected_multi) ); + if (ms_selected) { + blocked = TRUE; + ege_select_one_action_set_active( type, ms_type ); + blocked = FALSE; + } + } } @@ -126,15 +209,42 @@ static void ms_defs_modified(SPObject * /*defs*/, guint /*flags*/, GObject *widg ms_tb_selection_changed(NULL, widget); } +void ms_get_dt_selected_gradient(Inkscape::Selection *selection, SPMesh *&ms_selected) +{ + SPMesh *gradient = 0; + + for (GSList const* i = selection->itemList(); i; i = i->next) { + SPItem *item = SP_ITEM(i->data); // get the items gradient, not the getVector() version + SPStyle *style = item->style; + SPPaintServer *server = 0; + + if (style && (style->fill.isPaintserver())) { + server = item->style->getFillPaintServer(); + } + if (style && (style->stroke.isPaintserver())) { + server = item->style->getStrokePaintServer(); + } + + if ( SP_IS_MESH(server) ) { + gradient = SP_MESH(server); + } + } + + if (gradient) { + ms_selected = gradient; + } +} + + /* * Callback functions for user actions */ -static void ms_new_type_changed( EgeSelectOneAction *act, GObject * /*tbl*/ ) +static void ms_new_geometry_changed( EgeSelectOneAction *act, GObject * /*tbl*/ ) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gint typemode = ege_select_one_action_get_active( act ) == 0 ? SP_GRADIENT_MESH_TYPE_NORMAL : SP_GRADIENT_MESH_TYPE_CONICAL; - prefs->setInt("/tools/mesh/mesh_type", typemode); + gint geometrymode = ege_select_one_action_get_active( act ) == 0 ? SP_MESH_GEOMETRY_NORMAL : SP_MESH_GEOMETRY_CONICAL; + prefs->setInt("/tools/mesh/mesh_geometry", geometrymode); } static void ms_new_fillstroke_changed( EgeSelectOneAction *act, GObject * /*tbl*/ ) @@ -178,6 +288,30 @@ static void ms_col_changed(GtkAdjustment *adj, GObject * /*tbl*/ ) blocked = FALSE; } +static void ms_type_changed(EgeSelectOneAction *act, GtkWidget *widget) +{ + // std::cout << "ms_type_changed" << std::endl; + if (blocked) { + return; + } + + SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(G_OBJECT(widget), "desktop")); + Inkscape::Selection *selection = desktop->getSelection(); + SPMesh *gradient = 0; + ms_get_dt_selected_gradient(selection, gradient); + + if (gradient) { + SPMeshType type = (SPMeshType) ege_select_one_action_get_active(act); + // std::cout << " type: " << type << std::endl; + gradient->type = type; + gradient->type_set = true; + gradient->updateRepr(); + + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_GRADIENT, + _("Set mesh type")); + } +} + static void mesh_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder); /** @@ -215,9 +349,9 @@ void sp_mesh_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, GObj ege_select_one_action_set_tooltip_column( act, 1 ); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gint mode = prefs->getInt("/tools/mesh/mesh_type", SP_GRADIENT_MESH_TYPE_NORMAL) != SP_GRADIENT_MESH_TYPE_NORMAL; + gint mode = prefs->getInt("/tools/mesh/mesh_geometry", SP_MESH_GEOMETRY_NORMAL) != SP_MESH_GEOMETRY_NORMAL; ege_select_one_action_set_active( act, mode ); - g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(ms_new_type_changed), holder ); + g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(ms_new_geometry_changed), holder ); } /* New gradient on fill or stroke*/ @@ -322,6 +456,35 @@ void sp_mesh_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, GObj g_object_set_data(holder, "desktop", desktop); desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(mesh_toolbox_watch_ec), holder)); + + /* Warning */ + { + GtkAction* act = gtk_action_new( "MeshWarningAction", + _("WARNING: Mesh SVG Syntax Subject to Change"), NULL, NULL ); + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + + /* Typeing method */ + { + GtkListStore* model = gtk_list_store_new( 2, G_TYPE_STRING, G_TYPE_INT ); + + GtkTreeIter iter; + gtk_list_store_append( model, &iter ); + gtk_list_store_set( model, &iter, 0, C_("Type", "Coons"), 1, SP_MESH_TYPE_COONS, -1 ); + + gtk_list_store_append( model, &iter ); + gtk_list_store_set( model, &iter, 0, _("Bicubic"), 1, SP_MESH_TYPE_BICUBIC, -1 ); + + EgeSelectOneAction* act = ege_select_one_action_new( "MeshSmoothAction", _("Coons"), + _("Coons: no smoothing. Bicubic: smoothing across patch boundaries."), + NULL, GTK_TREE_MODEL(model) ); + g_object_set( act, "short_label", _("Smoothing:"), NULL ); + ege_select_one_action_set_appearance( act, "compact" ); + gtk_action_set_sensitive( GTK_ACTION(act), FALSE ); + g_signal_connect( G_OBJECT(act), "changed", G_CALLBACK(ms_type_changed), holder ); + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + g_object_set_data( holder, "mesh_select_type_action", act ); + } } static void mesh_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder) @@ -334,8 +497,8 @@ static void mesh_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolB if (SP_IS_MESH_CONTEXT(ec)) { // connect to selection modified and changed signals - Inkscape::Selection *selection = sp_desktop_selection (desktop); - SPDocument *document = sp_desktop_document (desktop); + Inkscape::Selection *selection = desktop->getSelection(); + SPDocument *document = desktop->getDocument(); c_selection_changed = selection->connectChanged(sigc::bind(sigc::ptr_fun(&ms_tb_selection_changed), holder)); c_selection_modified = selection->connectModified(sigc::bind(sigc::ptr_fun(&ms_tb_selection_modified), holder)); diff --git a/src/widgets/node-toolbar.cpp b/src/widgets/node-toolbar.cpp index 1224ab355..113061519 100644 --- a/src/widgets/node-toolbar.cpp +++ b/src/widgets/node-toolbar.cpp @@ -31,7 +31,7 @@ #include "ui/tool/multi-path-manipulator.h" #include <glibmm/i18n.h> #include "node-toolbar.h" -#include "desktop-handles.h" + #include "desktop.h" #include "document-undo.h" #include "widgets/ege-adjustment-action.h" @@ -264,7 +264,7 @@ static void sp_node_path_value_changed(GtkAdjustment *adj, GObject *tbl, Geom::D } Unit const *unit = tracker->getActiveUnit(); - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { prefs->setDouble(Glib::ustring("/tools/nodes/") + (d == Geom::X ? "x" : "y"), Quantity::convert(gtk_adjustment_get_value(adj), unit, "px")); } @@ -330,7 +330,7 @@ static void node_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* void sp_node_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) { UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); - Unit doc_units = *sp_desktop_namedview(desktop)->display_units; + Unit doc_units = *desktop->getNamedView()->display_units; tracker->setActiveUnit(&doc_units); g_object_set_data( holder, "tracker", tracker ); @@ -614,7 +614,7 @@ void sp_node_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje gtk_action_group_add_action( mainActions, act ); } - sp_node_toolbox_sel_changed(sp_desktop_selection(desktop), holder); + sp_node_toolbox_sel_changed(desktop->getSelection(), holder); desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(node_toolbox_watch_ec), holder)); } // end of sp_node_toolbox_prep() @@ -627,11 +627,11 @@ static void node_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolB if (INK_IS_NODE_TOOL(ec)) { // watch selection - c_selection_changed = sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_node_toolbox_sel_changed), holder)); - c_selection_modified = sp_desktop_selection(desktop)->connectModified(sigc::bind(sigc::ptr_fun(sp_node_toolbox_sel_modified), holder)); + c_selection_changed = desktop->getSelection()->connectChanged(sigc::bind(sigc::ptr_fun(sp_node_toolbox_sel_changed), holder)); + c_selection_modified = desktop->getSelection()->connectModified(sigc::bind(sigc::ptr_fun(sp_node_toolbox_sel_modified), holder)); c_subselection_changed = desktop->connectToolSubselectionChanged(sigc::bind(sigc::ptr_fun(sp_node_toolbox_coord_changed), holder)); - sp_node_toolbox_sel_changed(sp_desktop_selection(desktop), holder); + sp_node_toolbox_sel_changed(desktop->getSelection(), holder); } else { if (c_selection_changed) c_selection_changed.disconnect(); diff --git a/src/widgets/paint-selector.cpp b/src/widgets/paint-selector.cpp index 6ef910f61..948c80db3 100644 --- a/src/widgets/paint-selector.cpp +++ b/src/widgets/paint-selector.cpp @@ -37,8 +37,8 @@ #include "sp-color-notebook.h" #include "sp-linear-gradient.h" -#include "sp-mesh-gradient.h" #include "sp-radial-gradient.h" +#include "sp-mesh.h" /* fixme: Move it from dialogs to here */ #include "gradient-selector.h" #include <inkscape.h> @@ -777,7 +777,7 @@ static void sp_paint_selector_set_mode_gradient(SPPaintSelector *psel, SPPaintSe } #ifdef WITH_MESH else { - SP_GRADIENT_SELECTOR(gsel)->setMode(SPGradientSelector::MODE_RADIAL); + SP_GRADIENT_SELECTOR(gsel)->setMode(SPGradientSelector::MODE_MESH); gtk_label_set_markup(GTK_LABEL(psel->label), _("<b>Mesh gradient</b>")); } #endif @@ -1244,7 +1244,7 @@ SPPaintSelector::Mode SPPaintSelector::getModeForStyle(SPStyle const & style, Fi } else if (SP_IS_RADIALGRADIENT(server)) { mode = MODE_GRADIENT_RADIAL; #ifdef WITH_MESH - } else if (SP_IS_MESHGRADIENT(server)) { + } else if (SP_IS_MESH(server)) { mode = MODE_GRADIENT_MESH; #endif } else if (SP_IS_PATTERN(server)) { diff --git a/src/widgets/rect-toolbar.cpp b/src/widgets/rect-toolbar.cpp index 5356ebb0d..46f6d1c23 100644 --- a/src/widgets/rect-toolbar.cpp +++ b/src/widgets/rect-toolbar.cpp @@ -31,7 +31,7 @@ #include <glibmm/i18n.h> #include "rect-toolbar.h" -#include "desktop-handles.h" + #include "desktop.h" #include "document-undo.h" #include "widgets/ege-adjustment-action.h" @@ -90,7 +90,7 @@ static void sp_rtb_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const * Unit const *unit = tracker->getActiveUnit(); g_return_if_fail(unit != NULL); - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setDouble(Glib::ustring("/tools/shapes/rect/") + value_name, Quantity::convert(gtk_adjustment_get_value(adj), unit, "px")); @@ -105,11 +105,11 @@ static void sp_rtb_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const * g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE)); bool modmade = false; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); for (GSList const *items = selection->itemList(); items != NULL; items = items->next) { if (SP_IS_RECT(items->data)) { if (gtk_adjustment_get_value(adj) != 0) { - (SP_RECT(items->data)->*setter)(Quantity::convert(gtk_adjustment_get_value(adj), unit, sp_desktop_namedview(desktop)->svg_units)); + (SP_RECT(items->data)->*setter)(Quantity::convert(gtk_adjustment_get_value(adj), unit, "px")); } else { SP_OBJECT(items->data)->getRepr()->setAttribute(value_name, NULL); } @@ -120,7 +120,7 @@ static void sp_rtb_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const * sp_rtb_sensitivize( tbl ); if (modmade) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_RECT, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_RECT, _("Change rectangle")); } @@ -181,7 +181,6 @@ static void rect_tb_event_attr_changed(Inkscape::XML::Node * /*repr*/, gchar con UnitTracker* tracker = reinterpret_cast<UnitTracker*>( g_object_get_data( tbl, "tracker" ) ); Unit const *unit = tracker->getActiveUnit(); - Unit const *svg_unit = sp_desktop_namedview(SP_ACTIVE_DESKTOP)->svg_units; g_return_if_fail(unit != NULL); gpointer item = g_object_get_data( tbl, "item" ); @@ -190,28 +189,28 @@ static void rect_tb_event_attr_changed(Inkscape::XML::Node * /*repr*/, gchar con GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "rx" ) ); gdouble rx = SP_RECT(item)->getVisibleRx(); - gtk_adjustment_set_value(adj, Quantity::convert(rx, svg_unit, unit)); + gtk_adjustment_set_value(adj, Quantity::convert(rx, "px", unit)); } { GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "ry" ) ); gdouble ry = SP_RECT(item)->getVisibleRy(); - gtk_adjustment_set_value(adj, Quantity::convert(ry, svg_unit, unit)); + gtk_adjustment_set_value(adj, Quantity::convert(ry, "px", unit)); } { GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "width" ) ); gdouble width = SP_RECT(item)->getVisibleWidth(); - gtk_adjustment_set_value(adj, Quantity::convert(width, svg_unit, unit)); + gtk_adjustment_set_value(adj, Quantity::convert(width, "px", unit)); } { GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "height" ) ); gdouble height = SP_RECT(item)->getVisibleHeight(); - gtk_adjustment_set_value(adj, Quantity::convert(height, svg_unit, unit)); + gtk_adjustment_set_value(adj, Quantity::convert(height, "px", unit)); } } @@ -307,7 +306,7 @@ void sp_rect_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); //tracker->addUnit( SP_UNIT_PERCENT, 0 ); // fixme: add % meaning per cent of the width/height - tracker->setActiveUnit( sp_desktop_namedview(desktop)->display_units ); + tracker->setActiveUnit(unit_table.getUnit("px")); g_object_set_data( holder, "tracker", tracker ); /* W */ @@ -404,12 +403,20 @@ static void rect_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolB { static sigc::connection changed; - // TODO fixme: use of dynamic_cast<> seems wrong here. + // use of dynamic_cast<> seems wrong here -- we just need to check the current tool + if (dynamic_cast<Inkscape::UI::Tools::RectTool *>(ec)) { - changed = sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_rect_toolbox_selection_changed), holder)); + Inkscape::Selection *sel = desktop->getSelection(); + + changed = sel->connectChanged(sigc::bind(sigc::ptr_fun(sp_rect_toolbox_selection_changed), holder)); + + // Synthesize an emission to trigger the update + sp_rect_toolbox_selection_changed(sel, holder); } else { - if (changed) + if (changed) { changed.disconnect(); + purge_repr_listener(NULL, holder); + } } } diff --git a/src/widgets/ruler.cpp b/src/widgets/ruler.cpp index 8e818843d..ab486eeeb 100644 --- a/src/widgets/ruler.cpp +++ b/src/widgets/ruler.cpp @@ -144,7 +144,8 @@ static gboolean sp_ruler_expose (GtkWidget *widget, GdkEventExpose *event); #endif static void sp_ruler_draw_ticks (SPRuler *ruler); -static void sp_ruler_draw_pos (SPRuler *ruler); +static void sp_ruler_draw_pos (SPRuler *ruler, + cairo_t *cr); static void sp_ruler_make_pixmap (SPRuler *ruler); static PangoLayout * sp_ruler_get_layout (GtkWidget *widget, @@ -710,7 +711,7 @@ sp_ruler_draw (GtkWidget *widget, cairo_set_source_surface(cr, priv->backing_store, 0, 0); cairo_paint(cr); - sp_ruler_draw_pos (ruler); + sp_ruler_draw_pos (ruler, cr); return FALSE; } @@ -735,7 +736,8 @@ sp_ruler_make_pixmap (SPRuler *ruler) } static void -sp_ruler_draw_pos (SPRuler *ruler) +sp_ruler_draw_pos (SPRuler *ruler, + cairo_t *cr) { GtkWidget *widget = GTK_WIDGET (ruler); @@ -797,25 +799,31 @@ sp_ruler_draw_pos (SPRuler *ruler) if ((bs_width > 0) && (bs_height > 0)) { - cairo_t *cr = gdk_cairo_create (gtk_widget_get_window (widget)); gdouble lower; gdouble upper; gdouble position; gdouble increment; - cairo_rectangle (cr, - allocation.x, allocation.y, - allocation.width, allocation.height); - cairo_clip (cr); - - cairo_translate (cr, allocation.x, allocation.y); - - /* If a backing store exists, restore the ruler */ - if (priv->backing_store) + if (! cr) + { + cr = gdk_cairo_create (gtk_widget_get_window (widget)); + cairo_translate (cr, allocation.x, allocation.y); + cairo_rectangle (cr, allocation.x, allocation.y, allocation.width, allocation.height); + cairo_clip (cr); + + cairo_translate (cr, allocation.x, allocation.y); + + /* If a backing store exists, restore the ruler */ + if (priv->backing_store) + { + cairo_set_source_surface (cr, priv->backing_store, 0, 0); + cairo_rectangle (cr, priv->xsrc, priv->ysrc, bs_width, bs_height); + cairo_fill (cr); + } + } + else { - cairo_set_source_surface (cr, priv->backing_store, 0, 0); - cairo_rectangle (cr, priv->xsrc, priv->ysrc, bs_width, bs_height); - cairo_fill (cr); + cairo_reference (cr); } position = sp_ruler_get_position (ruler); @@ -1126,7 +1134,7 @@ sp_ruler_set_position (SPRuler *ruler, priv->position = position; g_object_notify (G_OBJECT (ruler), "position"); - sp_ruler_draw_pos (ruler); + sp_ruler_draw_pos (ruler, NULL); } } diff --git a/src/widgets/select-toolbar.cpp b/src/widgets/select-toolbar.cpp index 80fe93356..e49c4c00a 100644 --- a/src/widgets/select-toolbar.cpp +++ b/src/widgets/select-toolbar.cpp @@ -21,7 +21,7 @@ #include "ui/widget/spinbutton.h" #include <glibmm/i18n.h> #include "select-toolbar.h" -#include "desktop-handles.h" + #include "desktop.h" #include "display/sp-canvas.h" #include "document-undo.h" @@ -106,7 +106,7 @@ static void sp_selection_layout_widget_modify_selection(SPWidget *spw, Inkscape::Selection *selection, guint flags, gpointer data) { SPDesktop *desktop = static_cast<SPDesktop *>(data); - if ((sp_desktop_selection(desktop) == selection) // only respond to changes in our desktop + if ((desktop->getSelection() == selection) // only respond to changes in our desktop && (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_PARENT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG ))) @@ -119,7 +119,7 @@ static void sp_selection_layout_widget_change_selection(SPWidget *spw, Inkscape::Selection *selection, gpointer data) { SPDesktop *desktop = static_cast<SPDesktop *>(data); - if (sp_desktop_selection(desktop) == selection) { // only respond to changes in our desktop + if (desktop->getSelection() == selection) { // only respond to changes in our desktop gboolean setActive = (selection && !selection->isEmpty()); std::vector<GtkAction*> *contextActions = reinterpret_cast<std::vector<GtkAction*> *>(g_object_get_data(G_OBJECT(spw), "contextActions")); if ( contextActions ) { @@ -153,8 +153,8 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw) g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(TRUE)); SPDesktop *desktop = SP_ACTIVE_DESKTOP; - Inkscape::Selection *selection = sp_desktop_selection(desktop); - SPDocument *document = sp_desktop_document(desktop); + Inkscape::Selection *selection = desktop->getSelection(); + SPDocument *document = desktop->getDocument(); document->ensureUpToDate (); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -241,7 +241,7 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw) if (actionkey != NULL) { // FIXME: fix for GTK breakage, see comment in SelectedStyle::on_opacity_changed - sp_desktop_canvas(desktop)->forceFullRedrawAfterInterruptions(0); + desktop->getCanvas()->forceFullRedrawAfterInterruptions(0); bool transform_stroke = prefs->getBool("/options/transform/stroke", true); bool preserve = prefs->getBool("/options/preservetransform/value", false); @@ -262,7 +262,7 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw) _("Transform by toolbar")); // resume interruptibility - sp_desktop_canvas(desktop)->endForcedFullRedraws(); + desktop->getCanvas()->endForcedFullRedraws(); } g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(FALSE)); @@ -470,10 +470,10 @@ void sp_select_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb contextActions->push_back( act ); // Create the parent widget for x y w h tracker. - GtkWidget *spw = sp_widget_new_global(INKSCAPE); + GtkWidget *spw = sp_widget_new_global(); // Remember the desktop's canvas widget, to be used for defocusing. - g_object_set_data(G_OBJECT(spw), "dtw", sp_desktop_canvas(desktop)); + g_object_set_data(G_OBJECT(spw), "dtw", desktop->getCanvas()); // The vb frame holds all other widgets and is used to set sensitivity depending on selection state. #if GTK_CHECK_VERSION(3,0,0) @@ -488,7 +488,7 @@ void sp_select_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb // Create the units menu. UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); tracker->addUnit(unit_table.getUnit("%")); - tracker->setActiveUnit( sp_desktop_namedview(desktop)->display_units ); + tracker->setActiveUnit( desktop->getNamedView()->display_units ); g_object_set_data( G_OBJECT(spw), "tracker", tracker ); g_signal_connect( G_OBJECT(spw), "destroy", G_CALLBACK(destroy_tracker), spw ); @@ -546,7 +546,7 @@ void sp_select_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb g_signal_connect(G_OBJECT(spw), "change_selection", G_CALLBACK(sp_selection_layout_widget_change_selection), desktop); // Update now. - sp_selection_layout_widget_update(SP_WIDGET(spw), SP_ACTIVE_DESKTOP ? sp_desktop_selection(SP_ACTIVE_DESKTOP) : NULL); + sp_selection_layout_widget_update(SP_WIDGET(spw), SP_ACTIVE_DESKTOP ? SP_ACTIVE_DESKTOP->getSelection() : NULL); for ( std::vector<GtkAction*>::iterator iter = contextActions->begin(); iter != contextActions->end(); ++iter) { diff --git a/src/widgets/sp-widget.cpp b/src/widgets/sp-widget.cpp index fdf5ec500..5ab6b1bb5 100644 --- a/src/widgets/sp-widget.cpp +++ b/src/widgets/sp-widget.cpp @@ -15,6 +15,7 @@ #include "macros.h" #include "document.h" +#include "inkscape.h" #include "sp-widget.h" #include "helper/sp-marshal.h" @@ -55,15 +56,15 @@ public: #endif static void sizeAllocate(GtkWidget *widget, GtkAllocation *allocation); - static void modifySelectionCB(Application *inkscape, Selection *selection, guint flags, SPWidget *spw); - static void changeSelectionCB(Application *inkscape, Selection *selection, SPWidget *spw); - static void setSelectionCB(Application *inkscape, Selection *selection, SPWidget *spw); + static void modifySelectionCB(Selection *selection, guint flags, SPWidget *spw); + static void changeSelectionCB(Selection *selection, SPWidget *spw); + static void setSelectionCB(Selection *selection, SPWidget *spw); - static GtkWidget *constructGlobal(SPWidget *spw, InkscapeApplication *inkscape); + static GtkWidget *constructGlobal(SPWidget *spw); - void modifySelection(Application *inkscape, Selection *selection, guint flags); - void changeSelection(Application *inkscape, Selection *selection); - void setSelection(Application *inkscape, Selection *selection); + void modifySelection(Selection *selection, guint flags); + void changeSelection(Selection *selection); + void setSelection(Selection *selection); private: SPWidget &_target; @@ -132,7 +133,6 @@ sp_widget_class_init(SPWidgetClass *klass) static void sp_widget_init(SPWidget *spw) { - spw->inkscape = NULL; spw->_impl = new SPWidgetImpl(*spw); // ctor invoked after all other init } @@ -151,16 +151,12 @@ void SPWidgetImpl::dispose(GObject *object) { SPWidget *spw = reinterpret_cast<SPWidget *>(object); - if (spw->inkscape) { - // Disconnect signals - - // the checks are necessary because when destroy is caused by the program shutting down, - // the inkscape object may already be (partly?) invalid --bb - if (G_IS_OBJECT(spw->inkscape) && G_OBJECT_GET_CLASS(spw->inkscape)) { - sp_signal_disconnect_by_data(spw->inkscape, spw); - } - spw->inkscape = NULL; - } + // Disconnect signals + if (Application::exists()) { + spw->selModified.disconnect(); + spw->selChanged.disconnect(); + spw->selSet.disconnect(); + } delete spw->_impl; spw->_impl = 0; @@ -174,11 +170,20 @@ void SPWidgetImpl::show(GtkWidget *widget) { SPWidget *spw = SP_WIDGET(widget); - if (spw->inkscape) { + if (Application::exists()) { // Connect signals - g_signal_connect(spw->inkscape, "modify_selection", G_CALLBACK(SPWidgetImpl::modifySelectionCB), spw); - g_signal_connect(spw->inkscape, "change_selection", G_CALLBACK(SPWidgetImpl::changeSelectionCB), spw); - g_signal_connect(spw->inkscape, "set_selection", G_CALLBACK(SPWidgetImpl::setSelectionCB), spw); + spw->selModified = INKSCAPE.signal_selection_modified.connect( + sigc::bind( + sigc::ptr_fun(SPWidgetImpl::modifySelectionCB), spw) + ); + spw->selChanged = INKSCAPE.signal_selection_changed.connect( + sigc::bind( + sigc::ptr_fun(SPWidgetImpl::changeSelectionCB), spw) + ); + spw->selSet = INKSCAPE.signal_selection_set.connect( + sigc::bind( + sigc::ptr_fun(SPWidgetImpl::setSelectionCB), spw) + ); } if (GTK_WIDGET_CLASS(sp_widget_parent_class)->show) { @@ -190,9 +195,11 @@ void SPWidgetImpl::hide(GtkWidget *widget) { SPWidget *spw = SP_WIDGET (widget); - if (spw->inkscape) { + if (Application::exists()) { // Disconnect signals - sp_signal_disconnect_by_data(spw->inkscape, spw); + spw->selModified.disconnect(); + spw->selChanged.disconnect(); + spw->selSet.disconnect(); } if (GTK_WIDGET_CLASS(sp_widget_parent_class)->hide) { @@ -264,15 +271,21 @@ void SPWidgetImpl::sizeAllocate(GtkWidget *widget, GtkAllocation *allocation) } } -GtkWidget *SPWidgetImpl::constructGlobal(SPWidget *spw, InkscapeApplication *inkscape) +GtkWidget *SPWidgetImpl::constructGlobal(SPWidget *spw) { - g_return_val_if_fail(!spw->inkscape, NULL); - - spw->inkscape = inkscape; if (gtk_widget_get_visible(GTK_WIDGET(spw))) { - g_signal_connect(inkscape, "modify_selection", G_CALLBACK(SPWidgetImpl::modifySelectionCB), spw); - g_signal_connect(inkscape, "change_selection", G_CALLBACK(SPWidgetImpl::changeSelectionCB), spw); - g_signal_connect(inkscape, "set_selection", G_CALLBACK(SPWidgetImpl::setSelectionCB), spw); + spw->selModified = INKSCAPE.signal_selection_modified.connect( + sigc::bind( + sigc::ptr_fun(SPWidgetImpl::modifySelectionCB), spw) + ); + spw->selChanged = INKSCAPE.signal_selection_changed.connect( + sigc::bind( + sigc::ptr_fun(SPWidgetImpl::changeSelectionCB), spw) + ); + spw->selSet = INKSCAPE.signal_selection_set.connect( + sigc::bind( + sigc::ptr_fun(SPWidgetImpl::setSelectionCB), spw) + ); } g_signal_emit(spw, signals[CONSTRUCT], 0); @@ -280,32 +293,32 @@ GtkWidget *SPWidgetImpl::constructGlobal(SPWidget *spw, InkscapeApplication *ink return GTK_WIDGET(spw); } -void SPWidgetImpl::modifySelectionCB(Application *inkscape, Selection *selection, guint flags, SPWidget *spw) +void SPWidgetImpl::modifySelectionCB(Selection *selection, guint flags, SPWidget *spw) { - spw->_impl->modifySelection(inkscape, selection, flags); + spw->_impl->modifySelection(selection, flags); } -void SPWidgetImpl::changeSelectionCB(Application *inkscape, Selection *selection, SPWidget *spw) +void SPWidgetImpl::changeSelectionCB(Selection *selection, SPWidget *spw) { - spw->_impl->changeSelection(inkscape, selection); + spw->_impl->changeSelection(selection); } -void SPWidgetImpl::setSelectionCB(Application *inkscape, Selection *selection, SPWidget *spw) +void SPWidgetImpl::setSelectionCB(Selection *selection, SPWidget *spw) { - spw->_impl->setSelection(inkscape, selection); + spw->_impl->setSelection(selection); } -void SPWidgetImpl::modifySelection(Application * /*inkscape*/, Selection *selection, guint flags) +void SPWidgetImpl::modifySelection(Selection *selection, guint flags) { g_signal_emit(&_target, signals[MODIFY_SELECTION], 0, selection, flags); } -void SPWidgetImpl::changeSelection(Application * /*inkscape*/, Selection *selection) +void SPWidgetImpl::changeSelection(Selection *selection) { g_signal_emit(&_target, signals[CHANGE_SELECTION], 0, selection); } -void SPWidgetImpl::setSelection(Application * /*inkscape*/, Selection *selection) +void SPWidgetImpl::setSelection(Selection *selection) { // Emit "set_selection" signal g_signal_emit(&_target, signals[SET_SELECTION], 0, selection); @@ -316,11 +329,11 @@ void SPWidgetImpl::setSelection(Application * /*inkscape*/, Selection *selection // Methods -GtkWidget *sp_widget_new_global(InkscapeApplication *inkscape) +GtkWidget *sp_widget_new_global() { SPWidget *spw = reinterpret_cast<SPWidget*>(g_object_new(SP_TYPE_WIDGET, NULL)); - if (!SPWidgetImpl::constructGlobal(spw, inkscape)) { + if (!SPWidgetImpl::constructGlobal(spw)) { g_object_unref(spw); spw = 0; } diff --git a/src/widgets/sp-widget.h b/src/widgets/sp-widget.h index 6227c3a72..a53062cf4 100644 --- a/src/widgets/sp-widget.h +++ b/src/widgets/sp-widget.h @@ -16,6 +16,7 @@ */ #include <gtk/gtk.h> +#include "inkscape.h" #define SP_TYPE_WIDGET (sp_widget_get_type()) #define SP_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_WIDGET, SPWidget)) @@ -23,9 +24,8 @@ #define SP_IS_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_WIDGET)) #define SP_IS_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_WIDGET)) -struct InkscapeApplication; - namespace Inkscape { + class Selection; class SPWidgetImpl; } @@ -33,10 +33,15 @@ class SPWidgetImpl; struct SPWidget { friend class Inkscape::SPWidgetImpl; + static GType getType(); + GtkBin bin; - InkscapeApplication *inkscape; Inkscape::SPWidgetImpl *_impl; +private: + sigc::connection selModified; + sigc::connection selChanged; + sigc::connection selSet; }; struct SPWidgetClass { @@ -53,7 +58,7 @@ struct SPWidgetClass { GType sp_widget_get_type(); /** Generic constructor for global widget. */ -GtkWidget *sp_widget_new_global(InkscapeApplication *inkscape); +GtkWidget *sp_widget_new_global(); #endif // SEEN_SP_WIDGET_H /* diff --git a/src/widgets/sp-xmlview-content.cpp b/src/widgets/sp-xmlview-content.cpp index 9243760bd..a1d8475ba 100644 --- a/src/widgets/sp-xmlview-content.cpp +++ b/src/widgets/sp-xmlview-content.cpp @@ -15,7 +15,7 @@ #include "xml/node-event-vector.h" #include "sp-xmlview-content.h" -#include "desktop-handles.h" +#include "desktop.h" #include "document-private.h" #include "document-undo.h" #include "inkscape.h" @@ -147,7 +147,7 @@ sp_xmlview_content_changed (GtkTextBuffer *tb, SPXMLViewContent *text) text->repr->setContent(data); g_free (data); text->blocked = FALSE; - DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_DIALOG_XML_EDITOR, + DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_DIALOG_XML_EDITOR, _("Type text in a text node")); } } diff --git a/src/widgets/spiral-toolbar.cpp b/src/widgets/spiral-toolbar.cpp index e85b024ed..3fb0015c1 100644 --- a/src/widgets/spiral-toolbar.cpp +++ b/src/widgets/spiral-toolbar.cpp @@ -31,7 +31,7 @@ #include <glibmm/i18n.h> #include "spiral-toolbar.h" -#include "desktop-handles.h" + #include "desktop.h" #include "document-undo.h" #include "widgets/ege-adjustment-action.h" @@ -62,7 +62,7 @@ static void sp_spl_tb_value_changed(GtkAdjustment *adj, GObject *tbl, Glib::ustr { SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" )); - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setDouble("/tools/shapes/spiral/" + value_name, gtk_adjustment_get_value(adj)); @@ -79,7 +79,7 @@ static void sp_spl_tb_value_changed(GtkAdjustment *adj, GObject *tbl, Glib::ustr gchar* namespaced_name = g_strconcat("sodipodi:", value_name.data(), NULL); bool modmade = false; - for (GSList const *items = sp_desktop_selection(desktop)->itemList(); + for (GSList const *items = desktop->getSelection()->itemList(); items != NULL; items = items->next) { @@ -96,7 +96,7 @@ static void sp_spl_tb_value_changed(GtkAdjustment *adj, GObject *tbl, Glib::ustr g_free(namespaced_name); if (modmade) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_SPIRAL, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_SPIRAL, _("Change spiral")); } @@ -296,7 +296,7 @@ void sp_spiral_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GOb sigc::connection *connection = new sigc::connection( - sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_spiral_toolbox_selection_changed), holder)) + desktop->getSelection()->connectChanged(sigc::bind(sigc::ptr_fun(sp_spiral_toolbox_selection_changed), holder)) ); g_signal_connect( holder, "destroy", G_CALLBACK(delete_connection), connection ); g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder ); diff --git a/src/widgets/star-toolbar.cpp b/src/widgets/star-toolbar.cpp index 6213263fc..cf12391c1 100644 --- a/src/widgets/star-toolbar.cpp +++ b/src/widgets/star-toolbar.cpp @@ -31,7 +31,7 @@ #include <glibmm/i18n.h> #include "star-toolbar.h" -#include "desktop-handles.h" + #include "desktop.h" #include "document-undo.h" #include "widgets/ege-adjustment-action.h" @@ -64,7 +64,7 @@ static void sp_stb_magnitude_value_changed( GtkAdjustment *adj, GObject *dataKlu { SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( dataKludge, "desktop" )); - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { // do not remember prefs if this call is initiated by an undo change, because undoing object // creation sets bogus values to its attributes before it is deleted Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -82,7 +82,7 @@ static void sp_stb_magnitude_value_changed( GtkAdjustment *adj, GObject *dataKlu bool modmade = false; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); GSList const *items = selection->itemList(); for (; items != NULL; items = items->next) { SPItem *item = reinterpret_cast<SPItem*>(items->data); @@ -99,7 +99,7 @@ static void sp_stb_magnitude_value_changed( GtkAdjustment *adj, GObject *dataKlu } } if (modmade) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_STAR, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_STAR, _("Star: Change number of corners")); } @@ -110,7 +110,7 @@ static void sp_stb_proportion_value_changed( GtkAdjustment *adj, GObject *dataKl { SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( dataKludge, "desktop" )); - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { if (!IS_NAN(gtk_adjustment_get_value(adj))) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setDouble("/tools/shapes/star/proportion", @@ -127,7 +127,7 @@ static void sp_stb_proportion_value_changed( GtkAdjustment *adj, GObject *dataKl g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(TRUE) ); bool modmade = false; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); GSList const *items = selection->itemList(); for (; items != NULL; items = items->next) { SPItem *item = reinterpret_cast<SPItem *>(items->data); @@ -152,7 +152,7 @@ static void sp_stb_proportion_value_changed( GtkAdjustment *adj, GObject *dataKl } if (modmade) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_STAR, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_STAR, _("Star: Change spoke ratio")); } @@ -164,7 +164,7 @@ static void sp_stb_sides_flat_state_changed( EgeSelectOneAction *act, GObject *d SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( dataKludge, "desktop" )); bool flat = ege_select_one_action_get_active( act ) == 0; - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setBool( "/tools/shapes/star/isflatsided", flat); } @@ -177,7 +177,7 @@ static void sp_stb_sides_flat_state_changed( EgeSelectOneAction *act, GObject *d // in turn, prevent listener from responding g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(TRUE) ); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); GSList const *items = selection->itemList(); GtkAction* prop_action = GTK_ACTION( g_object_get_data( dataKludge, "prop_action" ) ); bool modmade = false; @@ -197,7 +197,7 @@ static void sp_stb_sides_flat_state_changed( EgeSelectOneAction *act, GObject *d } if (modmade) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_STAR, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_STAR, flat ? _("Make polygon") : _("Make star")); } @@ -208,7 +208,7 @@ static void sp_stb_rounded_value_changed( GtkAdjustment *adj, GObject *dataKludg { SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( dataKludge, "desktop" )); - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setDouble("/tools/shapes/star/rounded", (gdouble) gtk_adjustment_get_value(adj)); } @@ -223,7 +223,7 @@ static void sp_stb_rounded_value_changed( GtkAdjustment *adj, GObject *dataKludg bool modmade = false; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); GSList const *items = selection->itemList(); for (; items != NULL; items = items->next) { SPItem *item = reinterpret_cast<SPItem*>(items->data); @@ -236,7 +236,7 @@ static void sp_stb_rounded_value_changed( GtkAdjustment *adj, GObject *dataKludg } } if (modmade) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_STAR, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_STAR, _("Star: Change rounding")); } @@ -247,7 +247,7 @@ static void sp_stb_randomized_value_changed( GtkAdjustment *adj, GObject *dataKl { SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( dataKludge, "desktop" )); - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setDouble("/tools/shapes/star/randomized", (gdouble) gtk_adjustment_get_value(adj)); @@ -263,7 +263,7 @@ static void sp_stb_randomized_value_changed( GtkAdjustment *adj, GObject *dataKl bool modmade = false; - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); GSList const *items = selection->itemList(); for (; items != NULL; items = items->next) { SPItem *item = reinterpret_cast<SPItem *>(items->data); @@ -276,7 +276,7 @@ static void sp_stb_randomized_value_changed( GtkAdjustment *adj, GObject *dataKl } } if (modmade) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_STAR, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_STAR, _("Star: Change randomization")); } @@ -582,8 +582,8 @@ static void star_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolB static sigc::connection changed; if (dynamic_cast<Inkscape::UI::Tools::StarTool const*>(ec) != NULL) { - changed = sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_star_toolbox_selection_changed), holder)); - sp_star_toolbox_selection_changed(sp_desktop_selection(desktop), holder); + changed = desktop->getSelection()->connectChanged(sigc::bind(sigc::ptr_fun(sp_star_toolbox_selection_changed), holder)); + sp_star_toolbox_selection_changed(desktop->getSelection(), holder); } else { if (changed) changed.disconnect(); diff --git a/src/widgets/stroke-marker-selector.cpp b/src/widgets/stroke-marker-selector.cpp index 23da54e94..e273faad7 100644 --- a/src/widgets/stroke-marker-selector.cpp +++ b/src/widgets/stroke-marker-selector.cpp @@ -26,7 +26,7 @@ #include "style.h" #include "ui/dialog-events.h" -#include "desktop-handles.h" + #include "desktop-style.h" #include "preferences.h" #include "path-prefix.h" @@ -64,8 +64,8 @@ MarkerComboBox::MarkerComboBox(gchar const *id, int l) : sp_pixbuf_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("no-marker") ) ) ); sandbox = ink_markers_preview_doc (); - desktop = inkscape_active_desktop(); - doc = sp_desktop_document(desktop); + desktop = SP_ACTIVE_DESKTOP; + doc = desktop->getDocument(); modified_connection = doc->getDefs()->connectModified( sigc::hide(sigc::hide(sigc::bind(sigc::ptr_fun(&MarkerComboBox::handleDefsModified), this))) ); @@ -92,7 +92,7 @@ void MarkerComboBox::setDesktop(SPDesktop *desktop) } this->desktop = desktop; - doc = sp_desktop_document(desktop); + doc = desktop->getDocument(); if (doc) { modified_connection = doc->getDefs()->connectModified( sigc::hide(sigc::hide(sigc::bind(sigc::ptr_fun(&MarkerComboBox::handleDefsModified), this))) ); @@ -578,25 +578,25 @@ gboolean MarkerComboBox::separator_cb (GtkTreeModel *model, GtkTreeIter *iter, g */ SPDocument *MarkerComboBox::ink_markers_preview_doc () { -gchar const *buffer = "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\" xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">" +gchar const *buffer = "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\" xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" id=\"MarkerSample\">" " <defs id=\"defs\" />" " <g id=\"marker-start\">" -" <path style=\"fill:none;stroke:black;stroke-width:1.7;marker-start:url(#sample);marker-mid:none;marker-end:none\"" +" <path style=\"fill:gray;stroke:darkgray;stroke-width:1.7;marker-start:url(#sample);marker-mid:none;marker-end:none\"" " d=\"M 12.5,13 L 25,13\" id=\"path1\" />" " <rect style=\"fill:none;stroke:none\" id=\"rect2\"" " width=\"25\" height=\"25\" x=\"0\" y=\"0\" />" " </g>" " <g id=\"marker-mid\">" -" <path style=\"fill:none;stroke:black;stroke-width:1.7;marker-start:none;marker-mid:url(#sample);marker-end:none\"" +" <path style=\"fill:gray;stroke:darkgray;stroke-width:1.7;marker-start:none;marker-mid:url(#sample);marker-end:none\"" " d=\"M 0,113 L 12.5,113 L 25,113\" id=\"path11\" />" " <rect style=\"fill:none;stroke:none\" id=\"rect22\"" " width=\"25\" height=\"25\" x=\"0\" y=\"100\" />" " </g>" " <g id=\"marker-end\">" -" <path style=\"fill:none;stroke:black;stroke-width:1.7;marker-start:none;marker-mid:none;marker-end:url(#sample)\"" +" <path style=\"fill:gray;stroke:darkgray;stroke-width:1.7;marker-start:none;marker-mid:none;marker-end:url(#sample)\"" " d=\"M 0,213 L 12.5,213\" id=\"path111\" />" " <rect style=\"fill:none;stroke:none\" id=\"rect222\"" " width=\"25\" height=\"25\" x=\"0\" y=\"200\" />" diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index 7c85689a2..5ca06a795 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -204,8 +204,8 @@ StrokeStyle::StrokeStyle() : unitSelector->addUnit(*unit_table.getUnit("%")); _old_unit = unitSelector->getUnit(); if (desktop) { - unitSelector->setUnit(sp_desktop_namedview(desktop)->svg_units->abbr); - _old_unit = sp_desktop_namedview(desktop)->svg_units; + unitSelector->setUnit(desktop->getNamedView()->display_units->abbr); + _old_unit = desktop->getNamedView()->display_units; } widthSpin->setUnitMenu(unitSelector); unitChangedConn = unitSelector->signal_changed().connect(sigc::mem_fun(*this, &StrokeStyle::unitChangedCB)); @@ -456,7 +456,7 @@ void StrokeStyle::markerSelectCB(MarkerComboBox *marker_combo, StrokeStyle *spw, spw->update = true; - SPDocument *document = sp_desktop_document(spw->desktop); + SPDocument *document = spw->desktop->getDocument(); if (!document) { return; } @@ -471,10 +471,10 @@ void StrokeStyle::markerSelectCB(MarkerComboBox *marker_combo, StrokeStyle *spw, // Also update the marker combobox, so the document's markers // show up at the top of the combobox -// sp_stroke_style_line_update( SP_WIDGET(spw), desktop ? sp_desktop_selection(desktop) : NULL); +// sp_stroke_style_line_update( SP_WIDGET(spw), desktop ? desktop->getSelection() : NULL); //spw->updateMarkerHist(which); - Inkscape::Selection *selection = sp_desktop_selection(spw->desktop); + Inkscape::Selection *selection = spw->desktop->getSelection(); GSList const *items = selection->itemList(); for (; items != NULL; items = items->next) { SPItem *item = reinterpret_cast<SPItem *>(items->data); @@ -810,18 +810,18 @@ StrokeStyle::updateLine() update = true; - Inkscape::Selection *sel = desktop ? sp_desktop_selection(desktop) : NULL; + Inkscape::Selection *sel = desktop ? desktop->getSelection() : NULL; FillOrStroke kind = GPOINTER_TO_INT(get_data("kind")) ? FILL : STROKE; // create temporary style - SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); + SPStyle query(SP_ACTIVE_DOCUMENT); // query into it - int result_sw = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKEWIDTH); - int result_ml = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKEMITERLIMIT); - int result_cap = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKECAP); - int result_join = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKEJOIN); - SPIPaint &targPaint = (kind == FILL) ? query->fill : query->stroke; + int result_sw = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_STROKEWIDTH); + int result_ml = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_STROKEMITERLIMIT); + int result_cap = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_STROKECAP); + int result_join = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_STROKEJOIN); + SPIPaint &targPaint = (kind == FILL) ? query.fill : query.stroke; if (!sel || sel->isEmpty()) { // Nothing selected, grey-out all controls in the stroke-style dialog @@ -839,14 +839,14 @@ StrokeStyle::updateLine() // same width, or only one object; no sense to keep percent, switch to absolute Inkscape::Util::Unit const *tempunit = unitSelector->getUnit(); if (tempunit->type != Inkscape::Util::UNIT_TYPE_LINEAR) { - unitSelector->setUnit(sp_desktop_namedview(SP_ACTIVE_DESKTOP)->display_units->abbr); + unitSelector->setUnit(SP_ACTIVE_DESKTOP->getNamedView()->display_units->abbr); } } Inkscape::Util::Unit const *unit = unitSelector->getUnit(); if (unit->type == Inkscape::Util::UNIT_TYPE_LINEAR) { - double avgwidth = Inkscape::Util::Quantity::convert(query->stroke_width.computed, "px", unit); + double avgwidth = Inkscape::Util::Quantity::convert(query.stroke_width.computed, "px", unit); #if WITH_GTKMM_3_0 (*widthAdj)->set_value(avgwidth); #else @@ -879,27 +879,25 @@ StrokeStyle::updateLine() if (result_ml != QUERY_STYLE_NOTHING) #if WITH_GTKMM_3_0 - (*miterLimitAdj)->set_value(query->stroke_miterlimit.value); // TODO: reflect averagedness? + (*miterLimitAdj)->set_value(query.stroke_miterlimit.value); // TODO: reflect averagedness? #else - miterLimitAdj->set_value(query->stroke_miterlimit.value); // TODO: reflect averagedness? + miterLimitAdj->set_value(query.stroke_miterlimit.value); // TODO: reflect averagedness? #endif if (result_join != QUERY_STYLE_MULTIPLE_DIFFERENT && result_join != QUERY_STYLE_NOTHING ) { - setJoinType(query->stroke_linejoin.value); + setJoinType(query.stroke_linejoin.value); } else { setJoinButtons(NULL); } if (result_cap != QUERY_STYLE_MULTIPLE_DIFFERENT && result_cap != QUERY_STYLE_NOTHING ) { - setCapType (query->stroke_linecap.value); + setCapType (query.stroke_linecap.value); } else { setCapButtons(NULL); } - sp_style_unref(query); - if (!sel || sel->isEmpty()) return; @@ -957,8 +955,8 @@ StrokeStyle::scaleLine() update = true; - SPDocument *document = sp_desktop_document (desktop); - Inkscape::Selection *selection = sp_desktop_selection (desktop); + SPDocument *document = desktop->getDocument(); + Inkscape::Selection *selection = desktop->getSelection(); GSList const *items = selection->itemList(); @@ -1113,8 +1111,7 @@ void StrokeStyle::buttonToggledCB(StrokeStyleButton *tb, StrokeStyle *spw) sp_repr_css_attr_unref(css); css = 0; - DocumentUndo::done(sp_desktop_document(spw->desktop), SP_VERB_DIALOG_FILL_STROKE, - _("Set stroke style")); + DocumentUndo::done(spw->desktop->getDocument(), SP_VERB_DIALOG_FILL_STROKE, _("Set stroke style")); } } @@ -1200,7 +1197,7 @@ StrokeStyle::updateAllMarkers(GSList const *objects) if (update) { setMarkerColor(marker, combo->get_loc(), SP_ITEM(object)); - SPDocument *document = sp_desktop_document(desktop); + SPDocument *document = desktop->getDocument(); DocumentUndo::done(document, SP_VERB_DIALOG_FILL_STROKE, _("Set marker color")); } diff --git a/src/widgets/stroke-style.h b/src/widgets/stroke-style.h index 15e394097..83048cb76 100644 --- a/src/widgets/stroke-style.h +++ b/src/widgets/stroke-style.h @@ -33,7 +33,6 @@ #include <glibmm/i18n.h> #include "desktop.h" -#include "desktop-handles.h" #include "desktop-style.h" #include "ui/dialog-events.h" #include "display/canvas-bpath.h" // for SP_STROKE_LINEJOIN_* diff --git a/src/widgets/text-toolbar.cpp b/src/widgets/text-toolbar.cpp index d62bb8027..3d2e6eef8 100644 --- a/src/widgets/text-toolbar.cpp +++ b/src/widgets/text-toolbar.cpp @@ -31,7 +31,7 @@ #include "libnrtype/font-lister.h" #include <glibmm/i18n.h> #include "text-toolbar.h" -#include "desktop-handles.h" + #include "desktop-style.h" #include "desktop.h" #include "document-undo.h" @@ -165,7 +165,7 @@ static void sp_text_fontfamily_value_changed( Ink_ComboBoxEntry_Action *act, GOb sp_desktop_set_style (desktop, css, true, true); // Results in selection change called twice. sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("Text: Change font family")); } @@ -220,21 +220,19 @@ static void sp_text_fontsize_value_changed( Ink_ComboBoxEntry_Action *act, GObje sp_desktop_set_style (desktop, css, true, true); // If no selected objects, set default. - SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); + SPStyle query(SP_ACTIVE_DOCUMENT); int result_numbers = - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); if (result_numbers == QUERY_STYLE_NOTHING) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->mergeStyle("/tools/text/style", css); } else { // Save for undo - DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:size", SP_VERB_NONE, + DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:size", SP_VERB_NONE, _("Text: Change font size")); } - sp_style_unref(query); - sp_repr_css_attr_unref (css); g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); @@ -267,7 +265,7 @@ static void sp_text_fontstyle_value_changed( Ink_ComboBoxEntry_Action *act, GObj sp_desktop_set_style (desktop, css, true, true); sp_repr_css_attr_unref (css); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("Text: Change font style")); } @@ -292,8 +290,8 @@ static void sp_text_script_changed( InkToggleAction* act, GObject *tbl ) #endif // Query baseline - SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); - int result_baseline = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_BASELINES); + SPStyle query(SP_ACTIVE_DOCUMENT); + int result_baseline = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_BASELINES); bool setSuper = false; bool setSub = false; @@ -307,14 +305,14 @@ static void sp_text_script_changed( InkToggleAction* act, GObject *tbl ) } } else { // Superscript - gboolean superscriptSet = (query->baseline_shift.set && - query->baseline_shift.type == SP_BASELINE_SHIFT_LITERAL && - query->baseline_shift.literal == SP_CSS_BASELINE_SHIFT_SUPER ); + gboolean superscriptSet = (query.baseline_shift.set && + query.baseline_shift.type == SP_BASELINE_SHIFT_LITERAL && + query.baseline_shift.literal == SP_CSS_BASELINE_SHIFT_SUPER ); // Subscript - gboolean subscriptSet = (query->baseline_shift.set && - query->baseline_shift.type == SP_BASELINE_SHIFT_LITERAL && - query->baseline_shift.literal == SP_CSS_BASELINE_SHIFT_SUB ); + gboolean subscriptSet = (query.baseline_shift.set && + query.baseline_shift.type == SP_BASELINE_SHIFT_LITERAL && + query.baseline_shift.literal == SP_CSS_BASELINE_SHIFT_SUB ); setSuper = !superscriptSet && prop == 0; setSub = !subscriptSet && prop == 1; @@ -345,7 +343,7 @@ static void sp_text_script_changed( InkToggleAction* act, GObject *tbl ) // Save for undo if(result_baseline != QUERY_STYLE_NOTHING) { - DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:script", SP_VERB_NONE, + DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:script", SP_VERB_NONE, _("Text: Change superscript or subscript")); } g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); @@ -367,7 +365,7 @@ static void sp_text_align_mode_changed( EgeSelectOneAction *act, GObject *tbl ) SPDesktop *desktop = SP_ACTIVE_DESKTOP; // move the x of all texts to preserve the same bbox - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); for (GSList const *items = selection->itemList(); items != NULL; items = items->next) { if (SP_IS_TEXT(SP_ITEM(items->data))) { SPItem *item = SP_ITEM(items->data); @@ -473,10 +471,9 @@ static void sp_text_align_mode_changed( EgeSelectOneAction *act, GObject *tbl ) } } - SPStyle *query = - sp_style_new (SP_ACTIVE_DOCUMENT); + SPStyle query(SP_ACTIVE_DOCUMENT); int result_numbers = - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); // If querying returned nothing, update default style. if (result_numbers == QUERY_STYLE_NOTHING) @@ -485,12 +482,10 @@ static void sp_text_align_mode_changed( EgeSelectOneAction *act, GObject *tbl ) prefs->mergeStyle("/tools/text/style", css); } - sp_style_unref(query); - sp_desktop_set_style (desktop, css, true, true); if (result_numbers != QUERY_STYLE_NOTHING) { - DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_CONTEXT_TEXT, + DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_CONTEXT_TEXT, _("Text: Change alignment")); } sp_repr_css_attr_unref (css); @@ -521,7 +516,7 @@ static void sp_text_lineheight_value_changed( GtkAdjustment *adj, GObject *tbl ) // Until deprecated sodipodi:linespacing purged: - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = desktop->getSelection(); GSList const *items = selection->itemList(); bool modmade = false; for (; items != NULL; items = items->next) { @@ -533,20 +528,19 @@ static void sp_text_lineheight_value_changed( GtkAdjustment *adj, GObject *tbl ) // Save for undo if(modmade) { - DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:line-height", SP_VERB_NONE, + DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:line-height", SP_VERB_NONE, _("Text: Change line-height")); } // If no selected objects, set default. - SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); + SPStyle query(SP_ACTIVE_DOCUMENT); int result_numbers = - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); if (result_numbers == QUERY_STYLE_NOTHING) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->mergeStyle("/tools/text/style", css); } - sp_style_unref(query); sp_repr_css_attr_unref (css); @@ -573,19 +567,18 @@ static void sp_text_wordspacing_value_changed( GtkAdjustment *adj, GObject *tbl sp_desktop_set_style (desktop, css, true, false); // If no selected objects, set default. - SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); + SPStyle query(SP_ACTIVE_DOCUMENT); int result_numbers = - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); if (result_numbers == QUERY_STYLE_NOTHING) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->mergeStyle("/tools/text/style", css); } else { // Save for undo - DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:word-spacing", SP_VERB_NONE, + DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:word-spacing", SP_VERB_NONE, _("Text: Change word-spacing")); } - sp_style_unref(query); sp_repr_css_attr_unref (css); @@ -612,9 +605,9 @@ static void sp_text_letterspacing_value_changed( GtkAdjustment *adj, GObject *tb sp_desktop_set_style (desktop, css, true, false); // If no selected objects, set default. - SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); + SPStyle query(SP_ACTIVE_DOCUMENT); int result_numbers = - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); if (result_numbers == QUERY_STYLE_NOTHING) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -623,12 +616,10 @@ static void sp_text_letterspacing_value_changed( GtkAdjustment *adj, GObject *tb else { // Save for undo - DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:letter-spacing", SP_VERB_NONE, + DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:letter-spacing", SP_VERB_NONE, _("Text: Change letter-spacing")); } - sp_style_unref(query); - sp_repr_css_attr_unref (css); g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); @@ -663,7 +654,7 @@ static void sp_text_dx_value_changed( GtkAdjustment *adj, GObject *tbl ) if(modmade) { // Save for undo - DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:dx", SP_VERB_NONE, + DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:dx", SP_VERB_NONE, _("Text: Change dx (kern)")); } g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); @@ -697,7 +688,7 @@ static void sp_text_dy_value_changed( GtkAdjustment *adj, GObject *tbl ) if(modmade) { // Save for undo - DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:dy", SP_VERB_NONE, + DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:dy", SP_VERB_NONE, _("Text: Change dy")); } @@ -732,7 +723,7 @@ static void sp_text_rotation_value_changed( GtkAdjustment *adj, GObject *tbl ) // Save for undo if(modmade) { - DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:rotate", SP_VERB_NONE, + DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:rotate", SP_VERB_NONE, _("Text: Change rotate")); } @@ -765,10 +756,9 @@ static void sp_text_orientation_mode_changed( EgeSelectOneAction *act, GObject * } } - SPStyle *query = - sp_style_new (SP_ACTIVE_DOCUMENT); + SPStyle query(SP_ACTIVE_DOCUMENT); int result_numbers = - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); // If querying returned nothing, update default style. if (result_numbers == QUERY_STYLE_NOTHING) @@ -780,7 +770,7 @@ static void sp_text_orientation_mode_changed( EgeSelectOneAction *act, GObject * sp_desktop_set_style (SP_ACTIVE_DESKTOP, css, true, true); if(result_numbers != QUERY_STYLE_NOTHING) { - DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_CONTEXT_TEXT, + DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_CONTEXT_TEXT, _("Text: Change orientation")); } sp_repr_css_attr_unref (css); @@ -829,7 +819,7 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ std::cout << "sp_text_toolbox_selection_changed: start " << count << std::endl; std::cout << " Selected items:" << std::endl; - for (GSList const *items = sp_desktop_selection(SP_ACTIVE_DESKTOP)->itemList(); + for (GSList const *items = SP_ACTIVE_DESKTOP->getSelection()->itemList(); items != NULL; items = items->next) { @@ -860,7 +850,7 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); if (!subselection) { - fontlister->update_font_list( sp_desktop_document( SP_ACTIVE_DESKTOP )); + fontlister->update_font_list( SP_ACTIVE_DESKTOP->getDocument()); } fontlister->selection_update(); @@ -873,7 +863,7 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ // Only flowed text can be justified, only normal text can be kerned... // Find out if we have flowed text now so we can use it several places gboolean isFlow = false; - for (GSList const *items = sp_desktop_selection(SP_ACTIVE_DESKTOP)->itemList(); + for (GSList const *items = SP_ACTIVE_DESKTOP->getSelection()->itemList(); items != NULL; items = items->next) { // const gchar* id = reinterpret_cast<SPItem *>(items->data)->getId(); @@ -892,11 +882,11 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ * Numbers (font-size, letter-spacing, word-spacing, line-height, text-anchor, writing-mode) * Font specification (Inkscape private attribute) */ - SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); - int result_family = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY); - int result_style = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTSTYLE); - int result_numbers = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); - int result_baseline = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_BASELINES); + SPStyle query(SP_ACTIVE_DOCUMENT); + int result_family = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTFAMILY); + int result_style = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTSTYLE); + int result_numbers = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + int result_baseline = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_BASELINES); /* * If no text in selection (querying returned nothing), read the style from @@ -905,14 +895,13 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ */ if (result_family == QUERY_STYLE_NOTHING || result_style == QUERY_STYLE_NOTHING || result_numbers == QUERY_STYLE_NOTHING) { // There are no texts in selection, read from preferences. - sp_style_read_from_prefs(query, "/tools/text"); + query.readFromPrefs("/tools/text"); #ifdef DEBUG_TEXT std::cout << " read style from prefs:" << std::endl; - sp_print_font( query ); + sp_print_font( &query ); #endif if (g_object_get_data(tbl, "text_style_from_prefs")) { // Do not reset the toolbar style from prefs if we already did it last time - sp_style_unref(query); g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); #ifdef DEBUG_TEXT std::cout << " text_style_from_prefs: toolbar already set" << std:: endl; @@ -937,7 +926,7 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ // Size (average of text selected) Inkscape::Preferences *prefs = Inkscape::Preferences::get(); int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT); - double size = sp_style_css_size_px_to_units(query->font_size.computed, unit); + double size = sp_style_css_size_px_to_units(query.font_size.computed, unit); //gchar size_text[G_ASCII_DTOSTR_BUF_SIZE]; //g_ascii_dtostr (size_text, sizeof (size_text), size); @@ -961,9 +950,9 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ // Superscript gboolean superscriptSet = ((result_baseline == QUERY_STYLE_SINGLE || result_baseline == QUERY_STYLE_MULTIPLE_SAME ) && - query->baseline_shift.set && - query->baseline_shift.type == SP_BASELINE_SHIFT_LITERAL && - query->baseline_shift.literal == SP_CSS_BASELINE_SHIFT_SUPER ); + query.baseline_shift.set && + query.baseline_shift.type == SP_BASELINE_SHIFT_LITERAL && + query.baseline_shift.literal == SP_CSS_BASELINE_SHIFT_SUPER ); InkToggleAction* textSuperscriptAction = INK_TOGGLE_ACTION( g_object_get_data( tbl, "TextSuperscriptAction" ) ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(textSuperscriptAction), superscriptSet ); @@ -972,9 +961,9 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ // Subscript gboolean subscriptSet = ((result_baseline == QUERY_STYLE_SINGLE || result_baseline == QUERY_STYLE_MULTIPLE_SAME ) && - query->baseline_shift.set && - query->baseline_shift.type == SP_BASELINE_SHIFT_LITERAL && - query->baseline_shift.literal == SP_CSS_BASELINE_SHIFT_SUB ); + query.baseline_shift.set && + query.baseline_shift.type == SP_BASELINE_SHIFT_LITERAL && + query.baseline_shift.literal == SP_CSS_BASELINE_SHIFT_SUB ); InkToggleAction* textSubscriptAction = INK_TOGGLE_ACTION( g_object_get_data( tbl, "TextSubscriptAction" ) ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(textSubscriptAction), subscriptSet ); @@ -1001,26 +990,26 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ // ege_select_one_action_set_sensitive( textAlignAction, 3, isFlow ); int activeButton = 0; - if (query->text_align.computed == SP_CSS_TEXT_ALIGN_JUSTIFY) + if (query.text_align.computed == SP_CSS_TEXT_ALIGN_JUSTIFY) { activeButton = 3; } else { - if (query->text_anchor.computed == SP_CSS_TEXT_ANCHOR_START) activeButton = 0; - if (query->text_anchor.computed == SP_CSS_TEXT_ANCHOR_MIDDLE) activeButton = 1; - if (query->text_anchor.computed == SP_CSS_TEXT_ANCHOR_END) activeButton = 2; + if (query.text_anchor.computed == SP_CSS_TEXT_ANCHOR_START) activeButton = 0; + if (query.text_anchor.computed == SP_CSS_TEXT_ANCHOR_MIDDLE) activeButton = 1; + if (query.text_anchor.computed == SP_CSS_TEXT_ANCHOR_END) activeButton = 2; } ege_select_one_action_set_active( textAlignAction, activeButton ); // Line height (spacing) double height; - if (query->line_height.normal) { + if (query.line_height.normal) { height = Inkscape::Text::Layout::LINE_HEIGHT_NORMAL; } else { - if (query->line_height.unit == SP_CSS_UNIT_PERCENT) { - height = query->line_height.value; + if (query.line_height.unit == SP_CSS_UNIT_PERCENT) { + height = query.line_height.value; } else { - height = query->line_height.computed; + height = query.line_height.computed; } } @@ -1032,8 +1021,8 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ // Word spacing double wordSpacing; - if (query->word_spacing.normal) wordSpacing = 0.0; - else wordSpacing = query->word_spacing.computed; // Assume no units (change in desktop-style.cpp) + if (query.word_spacing.normal) wordSpacing = 0.0; + else wordSpacing = query.word_spacing.computed; // Assume no units (change in desktop-style.cpp) GtkAction* wordSpacingAction = GTK_ACTION( g_object_get_data( tbl, "TextWordSpacingAction" ) ); GtkAdjustment *wordSpacingAdjustment = @@ -1043,8 +1032,8 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ // Letter spacing double letterSpacing; - if (query->letter_spacing.normal) letterSpacing = 0.0; - else letterSpacing = query->letter_spacing.computed; // Assume no units (change in desktop-style.cpp) + if (query.letter_spacing.normal) letterSpacing = 0.0; + else letterSpacing = query.letter_spacing.computed; // Assume no units (change in desktop-style.cpp) GtkAction* letterSpacingAction = GTK_ACTION( g_object_get_data( tbl, "TextLetterSpacingAction" ) ); GtkAdjustment *letterSpacingAdjustment = @@ -1053,7 +1042,7 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ // Orientation - int activeButton2 = (query->writing_mode.computed == SP_CSS_WRITING_MODE_LR_TB ? 0 : 1); + int activeButton2 = (query.writing_mode.computed == SP_CSS_WRITING_MODE_LR_TB ? 0 : 1); EgeSelectOneAction* textOrientationAction = EGE_SELECT_ONE_ACTION( g_object_get_data( tbl, "TextOrientationAction" ) ); @@ -1064,27 +1053,25 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ #ifdef DEBUG_TEXT std::cout << " GUI: fontfamily.value: " - << (query->font_family.value ? query->font_family.value : "No value") + << (query.font_family.value ? query.font_family.value : "No value") << std::endl; - std::cout << " GUI: font_size.computed: " << query->font_size.computed << std::endl; - std::cout << " GUI: font_weight.computed: " << query->font_weight.computed << std::endl; - std::cout << " GUI: font_style.computed: " << query->font_style.computed << std::endl; - std::cout << " GUI: text_anchor.computed: " << query->text_anchor.computed << std::endl; - std::cout << " GUI: text_align.computed: " << query->text_align.computed << std::endl; - std::cout << " GUI: line_height.computed: " << query->line_height.computed - << " line_height.value: " << query->line_height.value - << " line_height.unit: " << query->line_height.unit << std::endl; - std::cout << " GUI: word_spacing.computed: " << query->word_spacing.computed - << " word_spacing.value: " << query->word_spacing.value - << " word_spacing.unit: " << query->word_spacing.unit << std::endl; - std::cout << " GUI: letter_spacing.computed: " << query->letter_spacing.computed - << " letter_spacing.value: " << query->letter_spacing.value - << " letter_spacing.unit: " << query->letter_spacing.unit << std::endl; - std::cout << " GUI: writing_mode.computed: " << query->writing_mode.computed << std::endl; + std::cout << " GUI: font_size.computed: " << query.font_size.computed << std::endl; + std::cout << " GUI: font_weight.computed: " << query.font_weight.computed << std::endl; + std::cout << " GUI: font_style.computed: " << query.font_style.computed << std::endl; + std::cout << " GUI: text_anchor.computed: " << query.text_anchor.computed << std::endl; + std::cout << " GUI: text_align.computed: " << query.text_align.computed << std::endl; + std::cout << " GUI: line_height.computed: " << query.line_height.computed + << " line_height.value: " << query.line_height.value + << " line_height.unit: " << query.line_height.unit << std::endl; + std::cout << " GUI: word_spacing.computed: " << query.word_spacing.computed + << " word_spacing.value: " << query.word_spacing.value + << " word_spacing.unit: " << query.word_spacing.unit << std::endl; + std::cout << " GUI: letter_spacing.computed: " << query.letter_spacing.computed + << " letter_spacing.value: " << query.letter_spacing.value + << " letter_spacing.unit: " << query.letter_spacing.unit << std::endl; + std::cout << " GUI: writing_mode.computed: " << query.writing_mode.computed << std::endl; #endif - sp_style_unref(query); - // Kerning (xshift), yshift, rotation. NB: These are not CSS attributes. if( SP_IS_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context) ) { Inkscape::UI::Tools::TextTool *const tc = SP_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context); @@ -1169,7 +1156,7 @@ static void sp_text_toolbox_select_cb( GtkEntry* entry, GtkEntryIconPosition /*p GSList *selectList = NULL; SPDesktop *desktop = SP_ACTIVE_DESKTOP; - SPDocument *document = sp_desktop_document( desktop ); + SPDocument *document = desktop->getDocument(); GSList *allList = get_all_items(NULL, document->getRoot(), desktop, false, false, true, NULL); for (GSList *i = allList; i != NULL; i = i->next) { @@ -1196,7 +1183,7 @@ static void sp_text_toolbox_select_cb( GtkEntry* entry, GtkEntryIconPosition /*p } // Update selection - Inkscape::Selection *selection = sp_desktop_selection (desktop ); + Inkscape::Selection *selection = desktop->getSelection(); selection->clear(); //std::cout << " list length: " << g_slist_length ( selectList ) << std::endl; selection->setList(selectList); @@ -1214,7 +1201,7 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje { // Font list Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); - fontlister->update_font_list( sp_desktop_document( SP_ACTIVE_DESKTOP )); + fontlister->update_font_list( SP_ACTIVE_DESKTOP->getDocument()); Glib::RefPtr<Gtk::ListStore> store = fontlister->get_font_list(); GtkListStore* model = store->gobj(); @@ -1623,7 +1610,7 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje } // Is this necessary to call? Shouldn't hurt. - sp_text_toolbox_selection_changed(sp_desktop_selection(desktop), holder); + sp_text_toolbox_selection_changed(desktop->getSelection(), holder); desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(text_toolbox_watch_ec), holder)); @@ -1642,8 +1629,8 @@ static void text_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolB if (SP_IS_TEXT_CONTEXT(ec)) { // Watch selection - c_selection_changed = sp_desktop_selection(desktop)->connectChanged(bind(ptr_fun(sp_text_toolbox_selection_changed), holder, false)); - c_selection_modified = sp_desktop_selection (desktop)->connectModified(bind(ptr_fun(sp_text_toolbox_selection_modified), holder)); + c_selection_changed = desktop->getSelection()->connectChanged(bind(ptr_fun(sp_text_toolbox_selection_changed), holder, false)); + c_selection_modified = desktop->getSelection()->connectModified(bind(ptr_fun(sp_text_toolbox_selection_modified), holder)); c_subselection_changed = desktop->connectToolSubselectionChanged(bind(ptr_fun(sp_text_toolbox_subselection_changed), holder)); } else { if (c_selection_changed) diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 9e55d1cf6..5d52db6f2 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -40,7 +40,6 @@ #include <glibmm/i18n.h> #include "../desktop.h" -#include "../desktop-handles.h" #include "../desktop-style.h" #include "document-undo.h" #include "widgets/ege-adjustment-action.h" @@ -522,6 +521,8 @@ static gchar const * ui_descr = // " <toolitem action='MeshEditFillAction' />" // " <toolitem action='MeshEditStrokeAction' />" // " <toolitem action='MeshShowHandlesAction' />" + " <toolitem action='MeshWarningAction' />" + " <toolitem action='MeshSmoothAction' />" " <separator />" " </toolbar>" @@ -1511,7 +1512,7 @@ static void toggle_snap_callback(GtkToggleAction *act, gpointer data) //data poi g_assert(ptr != NULL); SPDesktop *dt = reinterpret_cast<SPDesktop*>(ptr); - SPNamedView *nv = sp_desktop_namedview(dt); + SPNamedView *nv = dt->getNamedView(); SPDocument *doc = nv->document; if (dt == NULL || nv == NULL) { @@ -1871,7 +1872,7 @@ void ToolboxFactory::updateSnapToolbox(SPDesktop *desktop, ToolBase * /*eventcon g_assert(desktop != NULL); g_assert(toolbox != NULL); - SPNamedView *nv = sp_desktop_namedview(desktop); + SPNamedView *nv = desktop->getNamedView(); if (nv == NULL) { g_warning("Namedview cannot be retrieved (in updateSnapToolbox)!"); return; diff --git a/src/xml/attribute-record.h b/src/xml/attribute-record.h index a61329b83..7caeab6b6 100644 --- a/src/xml/attribute-record.h +++ b/src/xml/attribute-record.h @@ -6,7 +6,7 @@ #define SEEN_XML_SP_REPR_ATTR_H #include <glib.h> -#include "gc-managed.h" +#include "inkgc/gc-managed.h" #include "util/share.h" #define SP_REPR_ATTRIBUTE_KEY(a) g_quark_to_string((a)->key) diff --git a/src/xml/composite-node-observer.h b/src/xml/composite-node-observer.h index 3e4b1673a..6e93a57da 100644 --- a/src/xml/composite-node-observer.h +++ b/src/xml/composite-node-observer.h @@ -15,7 +15,7 @@ #ifndef SEEN_INKSCAPE_XML_COMPOSITE_NODE_OBSERVER_H #define SEEN_INKSCAPE_XML_COMPOSITE_NODE_OBSERVER_H -#include "gc-managed.h" +#include "inkgc/gc-managed.h" #include "xml/node-observer.h" #include "util/list-container.h" diff --git a/src/xml/event.h b/src/xml/event.h index d25ea0e07..73e68daeb 100644 --- a/src/xml/event.h +++ b/src/xml/event.h @@ -24,7 +24,7 @@ typedef unsigned int GQuark; #include <iterator> #include "util/share.h" #include "util/forward-pointer-iterator.h" -#include "gc-managed.h" +#include "inkgc/gc-managed.h" #include "xml/node.h" namespace Inkscape { diff --git a/src/xml/log-builder.h b/src/xml/log-builder.h index aa8f2c1c6..e94dd1daa 100644 --- a/src/xml/log-builder.h +++ b/src/xml/log-builder.h @@ -14,7 +14,7 @@ #ifndef SEEN_INKSCAPE_XML_LOG_BUILDER_H #define SEEN_INKSCAPE_XML_LOG_BUILDER_H -#include "gc-managed.h" +#include "inkgc/gc-managed.h" #include "xml/node-observer.h" namespace Inkscape { diff --git a/src/xml/node.h b/src/xml/node.h index 8bb70acc0..29cfdab46 100644 --- a/src/xml/node.h +++ b/src/xml/node.h @@ -469,6 +469,8 @@ public: * @deprecated Use synthesizeEvents(NodeObserver &) instead */ virtual void synthesizeEvents(NodeEventVector const *vector, void *data)=0; + + virtual void recursivePrintTree(unsigned level)=0; /*@}*/ diff --git a/src/xml/repr-util.cpp b/src/xml/repr-util.cpp index 12280ea5a..7c5d2d6fc 100644 --- a/src/xml/repr-util.cpp +++ b/src/xml/repr-util.cpp @@ -32,6 +32,7 @@ #include <2geom/point.h> #include "svg/stringstream.h" #include "svg/css-ostringstream.h" +#include "svg/svg-length.h" #include "xml/repr.h" #include "xml/repr-sorting.h" @@ -502,6 +503,20 @@ unsigned int sp_repr_set_svg_double(Inkscape::XML::Node *repr, gchar const *key, return true; } +/** + * For attributes where an exponent is allowed. + * + * Not suitable for property attributes. + */ +unsigned int sp_repr_set_svg_length(Inkscape::XML::Node *repr, gchar const *key, SVGLength &val) +{ + g_return_val_if_fail(repr != NULL, FALSE); + g_return_val_if_fail(key != NULL, FALSE); + + repr->setAttribute(key, val.write()); + return true; +} + unsigned sp_repr_set_point(Inkscape::XML::Node *repr, gchar const *key, Geom::Point const & val) { g_return_val_if_fail(repr != NULL, FALSE); diff --git a/src/xml/repr.h b/src/xml/repr.h index e1d7fdfd6..c3ba40e45 100644 --- a/src/xml/repr.h +++ b/src/xml/repr.h @@ -30,6 +30,7 @@ #define SP_DC_NS_URI "http://purl.org/dc/elements/1.1/" class SPCSSAttr; +class SVGLength; namespace Inkscape { namespace IO { @@ -115,6 +116,7 @@ unsigned sp_repr_set_boolean(Inkscape::XML::Node *repr, char const *key, unsigne unsigned sp_repr_set_int(Inkscape::XML::Node *repr, char const *key, int val); unsigned sp_repr_set_css_double(Inkscape::XML::Node *repr, char const *key, double val); unsigned sp_repr_set_svg_double(Inkscape::XML::Node *repr, char const *key, double val); +unsigned sp_repr_set_svg_length(Inkscape::XML::Node *repr, char const *key, SVGLength &val); unsigned sp_repr_set_point(Inkscape::XML::Node *repr, char const *key, Geom::Point const & val); unsigned sp_repr_get_point(Inkscape::XML::Node *repr, char const *key, Geom::Point *val); diff --git a/src/xml/simple-node.cpp b/src/xml/simple-node.cpp index 4965f81c8..3cbedc80b 100644 --- a/src/xml/simple-node.cpp +++ b/src/xml/simple-node.cpp @@ -606,6 +606,26 @@ void SimpleNode::synthesizeEvents(NodeObserver &observer) { synthesizeEvents(&OBSERVER_EVENT_VECTOR, &observer); } +void SimpleNode::recursivePrintTree(unsigned level) { + + if (level == 0) { + std::cout << "XML Node Tree" << std::endl; + } + std::cout << "XML: "; + for (unsigned i = 0; i < level; ++i) { + std::cout << " "; + } + char const *id=attribute("id"); + if (id) { + std::cout << id << std::endl; + } else { + std::cout << name() << std::endl; + } + for (SimpleNode *child = _first_child; child != NULL; child = child->_next) { + child->recursivePrintTree( level+1 ); + } +} + Node *SimpleNode::root() { Node *parent=this; while (parent->parent()) { diff --git a/src/xml/simple-node.h b/src/xml/simple-node.h index 1fcb9193b..d09392249 100644 --- a/src/xml/simple-node.h +++ b/src/xml/simple-node.h @@ -19,6 +19,7 @@ #define SEEN_INKSCAPE_XML_SIMPLE_NODE_H #include <cassert> +#include <iostream> #include "xml/node.h" #include "xml/attribute-record.h" @@ -120,6 +121,8 @@ public: _subtree_observers.remove(observer); } + void recursivePrintTree(unsigned level = 0); + protected: SimpleNode(int code, Document *document); SimpleNode(SimpleNode const &repr, Document *document); diff --git a/src/xml/subtree.h b/src/xml/subtree.h index 11bf515f1..bc6ae913a 100644 --- a/src/xml/subtree.h +++ b/src/xml/subtree.h @@ -15,7 +15,7 @@ #ifndef SEEN_INKSCAPE_XML_SUBTREE_H #define SEEN_INKSCAPE_XML_SUBTREE_H -#include "gc-managed.h" +#include "inkgc/gc-managed.h" #include "xml/composite-node-observer.h" namespace Inkscape { |
