diff options
Diffstat (limited to 'src')
47 files changed, 667 insertions, 539 deletions
diff --git a/src/color-profile.cpp b/src/color-profile.cpp index 09eaa36e5..ed4b9029e 100644 --- a/src/color-profile.cpp +++ b/src/color-profile.cpp @@ -339,7 +339,7 @@ void ColorProfile::set(unsigned key, gchar const *value) { Inkscape::URI hrefUri(escaped); //# 3. Resolve the href according the docBase. This follows // the w3c specs. All absolute and relative issues are considered - std::string fullpath = docUri.getFullPath(hrefUri.getFullPath("")); + std::string fullpath = hrefUri.getFullPath(docUri.getFullPath("")); gchar* fullname = g_uri_unescape_string(fullpath.c_str(), ""); this->impl->_clearProfile(); diff --git a/src/color.cpp b/src/color.cpp index 5eb0d91ef..dccd603b0 100644 --- a/src/color.cpp +++ b/src/color.cpp @@ -84,9 +84,10 @@ SPColor& SPColor::operator= (SPColor const& other) */ bool SPColor::operator == (SPColor const& other) const { - bool match = (v.c[0] != other.v.c[0]) - && (v.c[1] != other.v.c[1]) - && (v.c[2] != other.v.c[2]); + bool match = + (v.c[0] == other.v.c[0]) && + (v.c[1] == other.v.c[1]) && + (v.c[2] == other.v.c[2]); match &= profileMatches( icc, other.icc ); diff --git a/src/display/drawing-item.cpp b/src/display/drawing-item.cpp index 6c7f99d42..ee52b4165 100644 --- a/src/display/drawing-item.cpp +++ b/src/display/drawing-item.cpp @@ -127,6 +127,7 @@ DrawingItem::DrawingItem(Drawing &drawing) , _propagate(0) // , _renders_opacity(0) , _pick_children(0) + , _antialias(1) , _isolation(SP_CSS_ISOLATION_AUTO) , _blend_mode(SP_CSS_BLEND_NORMAL) {} @@ -229,6 +230,8 @@ DrawingItem::prependChild(DrawingItem *item) void DrawingItem::clearChildren() { + if (_children.empty()) return; + _markForRendering(); // prevent children from referencing the parent during deletion // this way, children won't try to remove themselves from a list @@ -266,8 +269,19 @@ DrawingItem::setTransform(Geom::Affine const &new_trans) void DrawingItem::setOpacity(float opacity) { - _opacity = opacity; - _markForRendering(); + if (_opacity != opacity) { + _opacity = opacity; + _markForRendering(); + } +} + +void +DrawingItem::setAntialiasing(bool a) +{ + if (_antialias != a) { + _antialias = a; + _markForRendering(); + } } void @@ -289,8 +303,10 @@ DrawingItem::setBlendMode(unsigned blend_mode) void DrawingItem::setVisible(bool v) { - _visible = v; - _markForRendering(); + if (_visible != v) { + _visible = v; + _markForRendering(); + } } /// This is currently unused @@ -568,6 +584,12 @@ DrawingItem::render(DrawingContext &dc, Geom::IntRect const &area, unsigned flag Geom::OptIntRect carea = Geom::intersect(area, _drawbox); if (!carea) return RENDER_OK; + if (_antialias) { + cairo_set_antialias(dc.raw(), CAIRO_ANTIALIAS_DEFAULT); + } else { + cairo_set_antialias(dc.raw(), CAIRO_ANTIALIAS_NONE); + } + // render from cache if possible if (_cached) { if (_cache) { diff --git a/src/display/drawing-item.h b/src/display/drawing-item.h index 913706021..db803cf60 100644 --- a/src/display/drawing-item.h +++ b/src/display/drawing-item.h @@ -108,6 +108,7 @@ public: void setCached(bool c, bool persistent = false); void setOpacity(float opacity); + void setAntialiasing(bool a); void setIsolation(unsigned isolation); // CSS Compositing and Blending void setBlendMode(unsigned blend_mode); void setTransform(Geom::Affine const &trans); @@ -205,6 +206,7 @@ protected: //unsigned _renders_opacity : 1; ///< Whether object needs temporary surface for opacity unsigned _pick_children : 1; ///< For groups: if true, children are returned from pick(), /// otherwise the group is returned + unsigned _antialias : 1; ///< Whether to use antialiasing unsigned _isolation : 1; unsigned _blend_mode : 4; diff --git a/src/display/drawing-surface.cpp b/src/display/drawing-surface.cpp index 30579134b..d2540de66 100644 --- a/src/display/drawing-surface.cpp +++ b/src/display/drawing-surface.cpp @@ -215,7 +215,7 @@ DrawingCache::prepare() bool is_identity = _pending_transform.isIdentity(); if (is_identity && _pending_area == old_area) return; // no change - bool is_integer_translation = false; + bool is_integer_translation = is_identity; if (!is_identity && _pending_transform.isTranslation()) { Geom::IntPoint t = _pending_transform.translation().round(); if (Geom::are_near(Geom::Point(t), _pending_transform.translation())) { @@ -224,6 +224,7 @@ DrawingCache::prepare() if (old_area + t == _pending_area) { // if the areas match, the only thing to do // is to ensure that the clean area is not too large + // we can exit early cairo_rectangle_int_t limit = _convertRect(_pending_area); cairo_region_intersect_rectangle(_clean_region, &limit); _origin += t; @@ -232,33 +233,36 @@ DrawingCache::prepare() } } } - // otherwise, we need to transform the cache + + // the area has changed, so the cache content needs to be copied Geom::IntPoint old_origin = old_area.min(); cairo_surface_t *old_surface = _surface; _surface = NULL; _pixels = _pending_area.dimensions(); _origin = _pending_area.min(); - cairo_t *ct = createRawContext(); - if (!is_identity) { - ink_cairo_transform(ct, _pending_transform); - } - cairo_set_source_surface(ct, old_surface, old_origin[X], old_origin[Y]); - cairo_set_operator(ct, CAIRO_OPERATOR_SOURCE); - cairo_paint(ct); - - cairo_surface_destroy(old_surface); - cairo_destroy(ct); + if (is_integer_translation) { + // transform the cache only for integer translations and identities + cairo_t *ct = createRawContext(); + if (!is_identity) { + ink_cairo_transform(ct, _pending_transform); + } + cairo_set_source_surface(ct, old_surface, old_origin[X], old_origin[Y]); + cairo_set_operator(ct, CAIRO_OPERATOR_SOURCE); + cairo_pattern_set_filter(cairo_get_source(ct), CAIRO_FILTER_NEAREST); + cairo_paint(ct); + cairo_destroy(ct); - if (!is_identity && !is_integer_translation) { + cairo_rectangle_int_t limit = _convertRect(_pending_area); + cairo_region_intersect_rectangle(_clean_region, &limit); + } else { // dirty everything cairo_region_destroy(_clean_region); _clean_region = cairo_region_create(); - } else { - cairo_rectangle_int_t limit = _convertRect(_pending_area); - cairo_region_intersect_rectangle(_clean_region, &limit); } + //std::cout << _pending_transform << old_area << _pending_area << std::endl; + cairo_surface_destroy(old_surface); _pending_transform.setIdentity(); } diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index c502daf64..6d903867b 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -35,7 +35,6 @@ #include "display/cairo-utils.h" #include "debug/gdk-event-latency-tracker.h" #include "desktop.h" -#include "sp-namedview.h" using Inkscape::Debug::GdkEventLatencyTracker; diff --git a/src/document.cpp b/src/document.cpp index d71fd97df..dc7ed254c 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -1133,12 +1133,11 @@ static gint sp_document_idle_handler(gpointer data) { SPDocument *doc = static_cast<SPDocument *>(data); - if (doc->_updateDocument()) { + bool status = !doc->_updateDocument(); // method TRUE if it does NOT need further modification, so invert + if (!status) { doc->modified_id = 0; - return false; - } else { - return true; } + return status; } /** @@ -1552,7 +1551,8 @@ void SPDocument::importDefs(SPDocument *source) SPGradient *gr = SP_GRADIENT(src); for (SPObject *trg = this->getDefs()->firstChild() ; trg ; trg = trg->getNext()) { if (trg && SP_IS_GRADIENT(trg) && src != trg) { - if (gr->isEquivalent(SP_GRADIENT(trg))) { + if (gr->isEquivalent(SP_GRADIENT(trg)) && + gr->isAligned(SP_GRADIENT(trg))) { // Change object references to the existing equivalent gradient change_def_references(src, trg); duplicate = true; diff --git a/src/extension/internal/emf-print.cpp b/src/extension/internal/emf-print.cpp index 9cc662a27..4bb892821 100644 --- a/src/extension/internal/emf-print.cpp +++ b/src/extension/internal/emf-print.cpp @@ -1562,7 +1562,7 @@ unsigned int PrintEmf::image( unsigned int h, /** height of bitmap */ unsigned int rs, /** row stride (normally w*4) */ Geom::Affine const &tf_rect, /** affine transform only used for defining location and size of rect, for all other tranforms, use the one from m_tr_stack */ - SPStyle const *style) /** provides indirect link to image object */ + SPStyle const * /*style*/) /** provides indirect link to image object */ { double x1, y1, dw, dh; char *rec = NULL; diff --git a/src/extension/internal/grid.cpp b/src/extension/internal/grid.cpp index c120df719..0059bbec2 100644 --- a/src/extension/internal/grid.cpp +++ b/src/extension/internal/grid.cpp @@ -59,31 +59,31 @@ Grid::load (Inkscape::Extension::Extension */*module*/) namespace { Glib::ustring build_lines(Geom::Rect bounding_area, - float offset[], float spacing[]) + Geom::Point const &offset, Geom::Point const &spacing) { Geom::Point point_offset(0.0, 0.0); SVG::PathString path_data; - for ( int axis = 0 ; axis < 2 ; ++axis ) { + for ( int axis = Geom::X ; axis <= Geom::Y ; ++axis ) { point_offset[axis] = offset[axis]; for (Geom::Point start_point = bounding_area.min(); - start_point[axis] + offset[axis] <= (bounding_area.max())[axis]; - start_point[axis] += spacing[axis]) { + start_point[axis] + offset[axis] <= (bounding_area.max())[axis]; + start_point[axis] += spacing[axis]) { Geom::Point end_point = start_point; end_point[1-axis] = (bounding_area.max())[1-axis]; path_data.moveTo(start_point + point_offset) - .lineTo(end_point + point_offset); + .lineTo(end_point + point_offset); } } - // std::cout << "Path data:" << path_data.c_str() << std::endl; - return path_data; - } - + // std::cout << "Path data:" << path_data.c_str() << std::endl; + return path_data; } +} // namespace + /** \brief This actually draws the grid. \param module The effect that was called (unused) @@ -115,16 +115,15 @@ Grid::effect (Inkscape::Extension::Effect *module, Inkscape::UI::View::View *doc gdouble scale = Inkscape::Util::Quantity::convert(1, "px", (document->doc())->getDefaultUnit()); bounding_area *= Geom::Scale(scale); - float spacings[2] = { scale*module->get_param_float("xspacing"), - scale*module->get_param_float("yspacing") }; - float line_width = scale*module->get_param_float("lineWidth"); - float offsets[2] = { scale*module->get_param_float("xoffset"), - scale*module->get_param_float("yoffset") }; + Geom::Point spacings( scale * module->get_param_float("xspacing"), + scale * module->get_param_float("yspacing") ); + gdouble line_width = scale * module->get_param_float("lineWidth"); + Geom::Point offsets( scale * module->get_param_float("xoffset"), + scale * module->get_param_float("yoffset") ); Glib::ustring path_data(""); - path_data = build_lines(bounding_area, - offsets, spacings); + path_data = build_lines(bounding_area, offsets, spacings); Inkscape::XML::Document * xml_doc = document->doc()->getReprDoc(); //XML Tree being used directly here while it shouldn't be. @@ -144,9 +143,7 @@ Grid::effect (Inkscape::Extension::Effect *module, Inkscape::UI::View::View *doc path->setAttribute("style", style.c_str()); current_layer->appendChild(path); - Inkscape::GC::release(path); - - return; + Inkscape::GC::release(path); } /** \brief A class to make an adjustment that uses Extension params */ diff --git a/src/extension/internal/pdfinput/pdf-parser.cpp b/src/extension/internal/pdfinput/pdf-parser.cpp index 7edb758fd..30e120d26 100644 --- a/src/extension/internal/pdfinput/pdf-parser.cpp +++ b/src/extension/internal/pdfinput/pdf-parser.cpp @@ -718,10 +718,7 @@ void PdfParser::opSetMiterLimit(Object args[], int /*numArgs*/) // TODO not good that numArgs is ignored but args[] is used: void PdfParser::opSetLineWidth(Object args[], int /*numArgs*/) { - if (args[0].getNum() > 0.0) - state->setLineWidth(args[0].getNum()); - else - state->setLineWidth(1.0); // default + state->setLineWidth(args[0].getNum()); builder->updateStyle(state); } diff --git a/src/extension/internal/pdfinput/svg-builder.cpp b/src/extension/internal/pdfinput/svg-builder.cpp index 20cd74cdb..71e6dc6ae 100644 --- a/src/extension/internal/pdfinput/svg-builder.cpp +++ b/src/extension/internal/pdfinput/svg-builder.cpp @@ -56,9 +56,6 @@ namespace Internal { #define TRACE(_args) IFTRACE(g_print _args) -static double ttm[6] = {1, 0, 0, 1, 0, 0}; // temporary transform matrix -static bool ttm_is_set = false; // flag to forbid setting ttm - /** * \struct SvgTransparencyGroup * \brief Holds information about a PDF transparency group @@ -94,6 +91,9 @@ 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) { @@ -216,9 +216,9 @@ Inkscape::XML::Node *SvgBuilder::pushGroup() { } } if (_container->parent()->attribute("inkscape:groupmode") != NULL) { - ttm[0] = ttm[3] = 1.0; // clear ttm if parent is a layer - ttm[1] = ttm[2] = ttm[4] = ttm[5] = 0.0; - ttm_is_set = false; + _ttm[0] = _ttm[3] = 1.0; // clear ttm if parent is a layer + _ttm[1] = _ttm[2] = _ttm[4] = _ttm[5] = 0.0; + _ttm_is_set = false; } return _container; } @@ -298,14 +298,6 @@ static gchar *svgInterpretPath(GfxPath *path) { * Uses the given SPCSSAttr for storing the style properties */ void SvgBuilder::_setStrokeStyle(SPCSSAttr *css, GfxState *state) { - - // Check line width - if ( state->getLineWidth() <= 0.0 ) { - // Ignore stroke - sp_repr_css_set_property(css, "stroke", "none"); - return; - } - // Stroke color/pattern if ( state->getStrokeColorSpace()->getMode() == csPattern ) { gchar *urltext = _createPattern(state->getStrokePattern(), state, true); @@ -326,7 +318,14 @@ void SvgBuilder::_setStrokeStyle(SPCSSAttr *css, GfxState *state) { // Line width Inkscape::CSSOStringStream os_width; - os_width << state->getLineWidth(); + double lw = state->getLineWidth(); + if (lw > 0.0) { + os_width << lw; + } else { + // emit a stroke which is 1px in toplevel user units + double pxw = Inkscape::Util::Quantity::convert(1.0, "pt", "px"); + os_width << 1.0 / state->transformWidth(pxw); + } sp_repr_css_set_property(css, "stroke-width", os_width.str().c_str()); // Line cap @@ -570,14 +569,14 @@ bool SvgBuilder::getTransform(double *transform) { void SvgBuilder::setTransform(double c0, double c1, double c2, double c3, double c4, double c5) { // do not remember the group which is a layer - if ((_container->attribute("inkscape:groupmode") == NULL) && !ttm_is_set) { - ttm[0] = c0; - ttm[1] = c1; - ttm[2] = c2; - ttm[3] = c3; - ttm[4] = c4; - ttm[5] = c5; - ttm_is_set = true; + if ((_container->attribute("inkscape:groupmode") == NULL) && !_ttm_is_set) { + _ttm[0] = c0; + _ttm[1] = c1; + _ttm[2] = c2; + _ttm[3] = c3; + _ttm[4] = c4; + _ttm[5] = c5; + _ttm_is_set = true; } // Avoid transforming a group with an already set clip-path @@ -633,15 +632,15 @@ gchar *SvgBuilder::_createPattern(GfxPattern *pattern, GfxState *state, bool is_ // construct a (pattern space) -> (current space) transform matrix ptm = shading_pattern->getMatrix(); - det = ttm[0] * ttm[3] - ttm[1] * ttm[2]; + det = _ttm[0] * _ttm[3] - _ttm[1] * _ttm[2]; if (det) { double ittm[6]; // invert ttm - ittm[0] = ttm[3] / det; - ittm[1] = -ttm[1] / det; - ittm[2] = -ttm[2] / det; - ittm[3] = ttm[0] / det; - ittm[4] = (ttm[2] * ttm[5] - ttm[3] * ttm[4]) / det; - ittm[5] = (ttm[1] * ttm[4] - ttm[0] * ttm[5]) / det; + ittm[0] = _ttm[3] / det; + ittm[1] = -_ttm[1] / det; + ittm[2] = -_ttm[2] / det; + ittm[3] = _ttm[0] / det; + ittm[4] = (_ttm[2] * _ttm[5] - _ttm[3] * _ttm[4]) / det; + ittm[5] = (_ttm[1] * _ttm[4] - _ttm[0] * _ttm[5]) / det; m[0] = ptm[0] * ittm[0] + ptm[1] * ittm[2]; m[1] = ptm[0] * ittm[1] + ptm[1] * ittm[3]; m[2] = ptm[2] * ittm[0] + ptm[3] * ittm[2]; @@ -676,15 +675,15 @@ gchar *SvgBuilder::_createTilingPattern(GfxTilingPattern *tiling_pattern, double *p2u = tiling_pattern->getMatrix(); double m[6] = {1, 0, 0, 1, 0, 0}; double det; - det = ttm[0] * ttm[3] - ttm[1] * ttm[2]; // see LP Bug 1168908 + det = _ttm[0] * _ttm[3] - _ttm[1] * _ttm[2]; // see LP Bug 1168908 if (det) { double ittm[6]; // invert ttm - ittm[0] = ttm[3] / det; - ittm[1] = -ttm[1] / det; - ittm[2] = -ttm[2] / det; - ittm[3] = ttm[0] / det; - ittm[4] = (ttm[2] * ttm[5] - ttm[3] * ttm[4]) / det; - ittm[5] = (ttm[1] * ttm[4] - ttm[0] * ttm[5]) / det; + ittm[0] = _ttm[3] / det; + ittm[1] = -_ttm[1] / det; + ittm[2] = -_ttm[2] / det; + ittm[3] = _ttm[0] / det; + ittm[4] = (_ttm[2] * _ttm[5] - _ttm[3] * _ttm[4]) / det; + ittm[5] = (_ttm[1] * _ttm[4] - _ttm[0] * _ttm[5]) / det; m[0] = p2u[0] * ittm[0] + p2u[1] * ittm[2]; m[1] = p2u[0] * ittm[1] + p2u[1] * ittm[3]; m[2] = p2u[2] * ittm[0] + p2u[3] * ittm[2]; diff --git a/src/extension/internal/pdfinput/svg-builder.h b/src/extension/internal/pdfinput/svg-builder.h index 610822959..f1ce02cf0 100644 --- a/src/extension/internal/pdfinput/svg-builder.h +++ b/src/extension/internal/pdfinput/svg-builder.h @@ -223,6 +223,8 @@ private: Inkscape::XML::Node *_preferences; // Preferences container node double _width; // Document size in px double _height; // Document size in px + double _ttm[6]; ///< temporary transform matrix + bool _ttm_is_set; }; diff --git a/src/extension/internal/wmf-print.cpp b/src/extension/internal/wmf-print.cpp index 232891c9c..5a552ad83 100644 --- a/src/extension/internal/wmf-print.cpp +++ b/src/extension/internal/wmf-print.cpp @@ -1103,7 +1103,7 @@ unsigned int PrintWmf::image( unsigned int h, /** height of bitmap */ unsigned int rs, /** row stride (normally w*4) */ Geom::Affine const &tf_rect, /** affine transform only used for defining location and size of rect, for all other tranforms, use the one from m_tr_stack */ - SPStyle const *style) /** provides indirect link to image object */ + SPStyle const * /*style*/) /** provides indirect link to image object */ { double x1, y1, dw, dh; char *rec = NULL; diff --git a/src/file.cpp b/src/file.cpp index 35039fed3..51e629c7d 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -690,7 +690,7 @@ file_save(Gtk::Window &parentWindow, SPDocument *doc, const Glib::ustring &uri, SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("Document not saved.")); return FALSE; } catch (Inkscape::Extension::Output::no_overwrite &e) { - return sp_file_save_dialog(parentWindow, doc, Inkscape::Extension::FILE_SAVE_METHOD_SAVE_AS); + return sp_file_save_dialog(parentWindow, doc, save_method); } catch (...) { SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("Document not saved.")); return FALSE; @@ -855,7 +855,7 @@ sp_file_save_dialog(Gtk::Window &parentWindow, SPDocument *doc, Inkscape::Extens int i = 1; if ( !doc->getURI() ) { // We are saving for the first time; create a unique default filename - save_loc = save_loc + Glib::ustring(_("drawing")) + filename_extension; + save_loc = save_loc + _("drawing") + filename_extension; while (Inkscape::IO::file_test(save_loc.c_str(), G_FILE_TEST_EXISTS)) { save_loc = save_path; @@ -922,9 +922,9 @@ sp_file_save_dialog(Gtk::Window &parentWindow, SPDocument *doc, Inkscape::Extens Inkscape::Extension::Output *omod = dynamic_cast<Inkscape::Extension::Output *>(selectionType); if (omod) { - Glib::ustring save_extension = (std::string)omod->get_extension(); - if ( !hasEnding(fileName, save_extension.c_str()) ) { - fileName += save_extension.c_str(); + Glib::ustring save_extension = (omod->get_extension()) ? (omod->get_extension()) : ""; + if ( !hasEnding(fileName, save_extension) ) { + fileName += save_extension; } } @@ -1385,8 +1385,6 @@ sp_file_export_dialog(Gtk::Window &parentWindow) if (doc->uri == NULL) { - char formatBuf[256]; - Glib::ustring filename_extension = ".svg"; extension = dynamic_cast<Inkscape::Extension::Output *> (Inkscape::Extension::db.get(default_extension.c_str())); @@ -1400,15 +1398,12 @@ sp_file_export_dialog(Gtk::Window &parentWindow) if (!Inkscape::IO::file_test(export_path.c_str(), (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) - export_path = ""; + export_path = Glib::ustring(""); - if (export_path.size()<1) + if (export_path.empty()) export_path = g_get_home_dir(); - export_loc = export_path; - export_loc.append(G_DIR_SEPARATOR_S); - snprintf(formatBuf, 255, _("drawing%s"), filename_extension.c_str()); - export_loc.append(formatBuf); + export_loc = export_path + G_DIR_SEPARATOR_S + _("drawing") + filename_extension; } else @@ -1420,7 +1415,7 @@ sp_file_export_dialog(Gtk::Window &parentWindow) // is this needed any more, now that everything is handled in // Inkscape::IO? Glib::ustring export_path_local = Glib::filename_from_utf8(export_path); - if ( export_path_local.size() > 0) + if (!export_path_local.empty()) export_path = export_path_local; //# Show the Export dialog diff --git a/src/filters/image.cpp b/src/filters/image.cpp index 6e50a0e3c..116939e0f 100644 --- a/src/filters/image.cpp +++ b/src/filters/image.cpp @@ -42,7 +42,6 @@ namespace { } SPFeImage::SPFeImage() : SPFilterPrimitive() { - this->document = NULL; this->href = NULL; this->from_element = 0; this->SVGElemRef = NULL; @@ -60,10 +59,8 @@ SPFeImage::~SPFeImage() { * our name must be associated with a repr via "sp_object_type_register". Best done through * sp-object-repr.cpp's repr_name_entries array. */ -void SPFeImage::build(SPDocument *document, Inkscape::XML::Node *repr) { - // Save document reference so we can load images with relative paths. - this->document = document; - +void SPFeImage::build(SPDocument *document, Inkscape::XML::Node *repr) +{ SPFilterPrimitive::build(document, repr); /*LOAD ATTRIBUTES FROM REPR HERE*/ diff --git a/src/filters/image.h b/src/filters/image.h index 452e08134..9299f259e 100644 --- a/src/filters/image.h +++ b/src/filters/image.h @@ -32,7 +32,6 @@ public: unsigned int aspect_align : 4; unsigned int aspect_clip : 1; - SPDocument *document; bool from_element; SPItem* SVGElem; Inkscape::URIReference* SVGElemRef; diff --git a/src/helper/pixbuf-ops.cpp b/src/helper/pixbuf-ops.cpp index 1ba6628c5..d44b2207b 100644 --- a/src/helper/pixbuf-ops.cpp +++ b/src/helper/pixbuf-ops.cpp @@ -75,8 +75,7 @@ bool sp_export_jpg_file(SPDocument *doc, gchar const *filename, gchar c[32]; g_snprintf(c, 32, "%f", quality); gboolean saved = gdk_pixbuf_save(pixbuf->getPixbufRaw(), filename, "jpeg", NULL, "quality", c, NULL); - g_free(c); - + return saved; } diff --git a/src/id-clash.cpp b/src/id-clash.cpp index 76b8e6ff8..f59b3b920 100644 --- a/src/id-clash.cpp +++ b/src/id-clash.cpp @@ -215,9 +215,10 @@ change_clashing_ids(SPDocument *imported_doc, SPDocument *current_doc, SPObject *cd_obj = current_doc->getObjectById(id); if (cd_obj && SP_IS_GRADIENT(cd_obj)) { - SPGradient *cd_gr = SP_GRADIENT(cd_obj); - if (cd_gr->isEquivalent(SP_GRADIENT(elem))) { - fix_clashing_ids = false; + SPGradient *cd_gr = SP_GRADIENT(cd_obj); + if ( cd_gr->isEquivalent(SP_GRADIENT(elem)) && + cd_gr->isAligned(SP_GRADIENT(elem))) { + fix_clashing_ids = false; } } } diff --git a/src/preferences-skeleton.h b/src/preferences-skeleton.h index ebc5386e3..2211baddb 100644 --- a/src/preferences-skeleton.h +++ b/src/preferences-skeleton.h @@ -475,10 +475,6 @@ static char const preferences_skeleton[] = " </group>\n" " </group>\n" " </group>\n" -" <group id = \"whiteboard\">\n" -" <group id = \"server\" name = \"jabber.org\" port = \"5222\" username = \"\" ssl = \"0\"/>\n" -" <group id = \"room\" name = \"inkboard\" server = \"gristle.org\"/>\n" -" </group>\n" " <group id=\"debug\">\n" " <group id=\"latency\" skew=\"1\"/>\n" " </group>\n" diff --git a/src/preferences.cpp b/src/preferences.cpp index b4b873dc8..2fec3b307 100644 --- a/src/preferences.cpp +++ b/src/preferences.cpp @@ -438,9 +438,7 @@ void Preferences::setBool(Glib::ustring const &pref_path, bool value) */ void Preferences::setInt(Glib::ustring const &pref_path, int value) { - gchar intstr[32]; - g_snprintf(intstr, 32, "%d", value); - _setRawValue(pref_path, intstr); + _setRawValue(pref_path, Glib::ustring::compose("%1",value)); } /** @@ -451,9 +449,7 @@ void Preferences::setInt(Glib::ustring const &pref_path, int value) */ void Preferences::setDouble(Glib::ustring const &pref_path, double value) { - gchar buf[G_ASCII_DTOSTR_BUF_SIZE]; - g_ascii_dtostr(buf, G_ASCII_DTOSTR_BUF_SIZE, value); - _setRawValue(pref_path, buf); + _setRawValue(pref_path, Glib::ustring::compose("%1",value)); } /** @@ -465,11 +461,8 @@ void Preferences::setDouble(Glib::ustring const &pref_path, double value) */ void Preferences::setDoubleUnit(Glib::ustring const &pref_path, double value, Glib::ustring const &unit_abbr) { - gchar buf[G_ASCII_DTOSTR_BUF_SIZE]; - g_ascii_dtostr(buf, G_ASCII_DTOSTR_BUF_SIZE, value); - Glib::ustring str(buf); - str += unit_abbr; - _setRawValue(pref_path, str.c_str()); + Glib::ustring str = Glib::ustring::compose("%1%2",value,unit_abbr); + _setRawValue(pref_path, str); } void Preferences::setColor(Glib::ustring const &pref_path, guint32 value) @@ -487,14 +480,14 @@ void Preferences::setColor(Glib::ustring const &pref_path, guint32 value) */ void Preferences::setString(Glib::ustring const &pref_path, Glib::ustring const &value) { - _setRawValue(pref_path, value.c_str()); + _setRawValue(pref_path, value); } void Preferences::setStyle(Glib::ustring const &pref_path, SPCSSAttr *style) { Glib::ustring css_str; sp_repr_css_write_string(style, css_str); - _setRawValue(pref_path, css_str.c_str()); + _setRawValue(pref_path, css_str); } void Preferences::mergeStyle(Glib::ustring const &pref_path, SPCSSAttr *style) @@ -503,7 +496,7 @@ void Preferences::mergeStyle(Glib::ustring const &pref_path, SPCSSAttr *style) sp_repr_css_merge(current, style); Glib::ustring css_str; sp_repr_css_write_string(current, css_str); - _setRawValue(pref_path, css_str.c_str()); + _setRawValue(pref_path, css_str); sp_repr_css_attr_unref(current); } @@ -738,7 +731,7 @@ void Preferences::_getRawValue(Glib::ustring const &path, gchar const *&result) } } -void Preferences::_setRawValue(Glib::ustring const &path, gchar const *value) +void Preferences::_setRawValue(Glib::ustring const &path, Glib::ustring const &value) { // create node and attribute keys Glib::ustring node_key, attr_key; @@ -746,7 +739,7 @@ void Preferences::_setRawValue(Glib::ustring const &path, gchar const *value) // set the attribute Inkscape::XML::Node *node = _getNode(node_key, true); - node->setAttribute(attr_key.c_str(), value); + node->setAttribute(attr_key.c_str(), value.c_str()); } // The _extract* methods are where the actual wrok is done - they define how preferences are stored diff --git a/src/preferences.h b/src/preferences.h index 66fa11542..d5429815e 100644 --- a/src/preferences.h +++ b/src/preferences.h @@ -532,7 +532,7 @@ private: void _loadDefaults(); void _load(); void _getRawValue(Glib::ustring const &path, gchar const *&result); - void _setRawValue(Glib::ustring const &path, gchar const *value); + void _setRawValue(Glib::ustring const &path, Glib::ustring const &value); void _reportError(Glib::ustring const &, Glib::ustring const &); void _keySplit(Glib::ustring const &pref_path, Glib::ustring &node_key, Glib::ustring &attr_key); XML::Node *_getNode(Glib::ustring const &pref_path, bool create=false); diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index fad2dff5b..5a981c6a0 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -794,7 +794,7 @@ void sp_selection_ungroup(Inkscape::Selection *selection, SPDesktop *desktop) GSList *groups = NULL; for (GSList *item = old_select; item; item = item->next) { SPItem *obj = static_cast<SPItem*>(item->data); - if (SP_IS_GROUP(obj) && !SP_IS_SWITCH(obj)) { + if (SP_IS_GROUP(obj)) { groups = g_slist_prepend(groups, obj); } } diff --git a/src/sp-gradient.cpp b/src/sp-gradient.cpp index 04fb18cf3..115cb754a 100644 --- a/src/sp-gradient.cpp +++ b/src/sp-gradient.cpp @@ -111,31 +111,93 @@ gboolean SPGradient::isEquivalent(SPGradient *that) { //TODO Make this work for mesh gradients - if (this->getStopCount() != that->getStopCount()) - return FALSE; + bool status = FALSE; + + while(1){ // not really a loop, used to avoid deep nesting or multiple exit points from function + if (this->getStopCount() != that->getStopCount()) { break; } + if (this->hasStops() != that->hasStops()) { break; } + if (!this->getVector() || !that->getVector()) { break; } + 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))) { + /* OK! */ + } + else { break; } - if (this->hasStops() != that->hasStops()) - return FALSE; + SPStop *as = this->getVector()->getFirstStop(); + SPStop *bs = that->getVector()->getFirstStop(); - if (!this->getVector() || !that->getVector()) - return FALSE; + bool effective = TRUE; + while (effective && (as && bs)) { + if (!as->getEffectiveColor().isClose(bs->getEffectiveColor(), 0.001) || + as->offset != bs->offset) { + effective = FALSE; + break; + } + else { + as = as->getNextStop(); + bs = bs->getNextStop(); + } + } + if(!effective)break; - SPStop *as = this->getVector()->getFirstStop(); - SPStop *bs = that->getVector()->getFirstStop(); + status = TRUE; + break; + } + return status; +} - while (as && bs) { - if (!as->getEffectiveColor().isClose(bs->getEffectiveColor(), 0.001) || - as->offset != bs->offset) { - return FALSE; +/** + * return true if this gradient is "aligned" to that gradient. + * Aligned means that they have exactly the same coordinates and transform. + * @param that - A gradient to compare this to + */ +gboolean SPGradient::isAligned(SPGradient *that) +{ + bool status = FALSE; + + while(1){ // not really a loop, used to avoid deep nesting or multiple exit points from function + if(this->gradientTransform_set != that->gradientTransform_set) { break; } + if(this->gradientTransform_set && + (this->gradientTransform != that->gradientTransform)) { break; } + if (SP_IS_LINEARGRADIENT(this) && SP_IS_LINEARGRADIENT(that)) { + SPLinearGradient *sg=SP_LINEARGRADIENT(this); + SPLinearGradient *tg=SP_LINEARGRADIENT(that); + + if( !sg->x1._set || !tg->x1._set || // assume that if these are set so will be all the others + (sg->x1.computed != tg->x1.computed) || + (sg->y1.computed != tg->y1.computed) || + (sg->x2.computed != tg->x2.computed) || + (sg->y2.computed != tg->y2.computed) + ) { break; } + } else if (SP_IS_RADIALGRADIENT(this) && SP_IS_LINEARGRADIENT(that)) { + SPRadialGradient *sg=SP_RADIALGRADIENT(this); + SPRadialGradient *tg=SP_RADIALGRADIENT(that); + if( !sg->cx._set || !tg->cx._set || // assume that if these are set so will be all the others + (sg->cx.computed != tg->cx.computed) || + (sg->cy.computed != tg->cy.computed) || + (sg->r.computed != tg->r.computed ) || + (sg->fx.computed != tg->fx.computed) || + (sg->fy.computed != tg->fy.computed) + ) { break; } + } else if (SP_IS_MESHGRADIENT(this) && SP_IS_MESHGRADIENT(that)) { + SPMeshGradient *sg=SP_MESHGRADIENT(this); + SPMeshGradient *tg=SP_MESHGRADIENT(that); + + if( !sg->x._set || !tg->x._set || + !sg->y._set || !tg->y._set || + (sg->x.computed != tg->x.computed) || + (sg->y.computed != tg->y.computed) + ) { break; } + } else { + break; } - as = as->getNextStop(); - bs = bs->getNextStop(); + status = TRUE; + break; } - - return TRUE; + return status; } - /* * Gradient */ diff --git a/src/sp-gradient.h b/src/sp-gradient.h index 46eb41cdb..1dfff22ee 100644 --- a/src/sp-gradient.h +++ b/src/sp-gradient.h @@ -147,6 +147,7 @@ public: int getStopCount() const; gboolean isEquivalent(SPGradient *b); + gboolean isAligned(SPGradient *b); /** Mesh Gradients **************/ diff --git a/src/sp-item.cpp b/src/sp-item.cpp index cd8e2119b..6160739ed 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -634,6 +634,7 @@ void SPItem::update(SPCtx* /*ctx*/, guint flags) { 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->blend_mode.value ); v->arenaitem->setVisible(!item->isHidden()); diff --git a/src/sp-use.cpp b/src/sp-use.cpp index 14f51159b..e8fe3687f 100644 --- a/src/sp-use.cpp +++ b/src/sp-use.cpp @@ -220,7 +220,11 @@ const char* SPUse::displayName() const { gchar* SPUse::description() const { if (this->child) { if( SP_IS_SYMBOL( this->child ) ) { - return g_strdup_printf(_("called %s"), Glib::Markup::escape_text(Glib::ustring( g_dpgettext2(NULL, "Symbol", this->child->title()))).c_str()); + if (this->child->title()) { + return g_strdup_printf(_("called %s"), Glib::Markup::escape_text(Glib::ustring( g_dpgettext2(NULL, "Symbol", this->child->title()))).c_str()); + } else { + return g_strdup_printf(_("called %s"), _("Unnamed Symbol")); + } } static unsigned recursion_depth = 0; diff --git a/src/style-test.h b/src/style-test.h index 90654ce83..c88c1c30a 100644 --- a/src/style-test.h +++ b/src/style-test.h @@ -87,13 +87,25 @@ public: // TestCase("fill:url(#painter) inherit", 0, "#painter"), TestCase("fill:inherit"), -// General tests (in order of appearance in sp_style_read), SPIPaint tested above +// General tests (in general order of appearance in sp_style_read), SPIPaint tested above TestCase("visibility:hidden"), // SPIEnum TestCase("visibility:collapse"), TestCase("visibility:visible"), TestCase("display:none"), // SPIEnum TestCase("overflow:visible"), // SPIEnum TestCase("overflow:auto"), // SPIEnum + + // Not directly read + TestCase("font:bold 12px Arial", + "font-size:12px;font-style:normal;font-variant:normal;font-weight:bold;font-family:Arial"), + // line-height not read in + //TestCase("font:bold 12px/24px 'Times New Roman'", + // "font-size:12px;font-style:normal;font-variant:normal;font-weight:bold;line-height:24px;font-family:Times New Roman"), + TestCase("font-family:sans-serif"), // SPIString, text_private + TestCase("font-family:Arial"), + TestCase("font-variant:normal;font-stretch:normal;-inkscape-font-specification:Nimbus Roman No9 L Bold Italic"), + // Needs to be fixed (quotes should be around each font-family): + TestCase("font-family:Georgia, 'Minion Web'","font-family:'Georgia, \"Minion Web\"'"), TestCase("font-size:12", "font-size:12px"), // SPIFontSize TestCase("font-size:12px"), TestCase("font-size:12pt", "font-size:15px"), @@ -105,11 +117,15 @@ public: TestCase("font-weight:normal"), TestCase("font-weight:bolder"), TestCase("font-stretch:condensed"), // SPIEnum + + // Should be moved down TestCase("text-indent:12em"), // SPILength? TestCase("text-align:center"), // SPIEnum TestCase("text-decoration: underline"), // SPITextDecoration TestCase("text-decoration: underline wavy #0000ff"), // SPITextDecoration CSS3 TestCase("text-decoration: overline double #ff0000"), + + // Should be moved up TestCase("line-height:24px"), // SPILengthOrNormal TestCase("line-height:1.5"), TestCase("letter-spacing:2px"), // SPILengthOrNormal @@ -121,6 +137,7 @@ public: TestCase("baseline-shift:sub"), TestCase("baseline-shift:12.5%"), TestCase("baseline-shift:2px"), + TestCase("opacity:0.1"), // SPIScale24 // ... TestCase("stroke-width:2px"), // SPILength @@ -138,7 +155,6 @@ public: TestCase("stroke-dashoffset:13"), // SPILength TestCase("stroke-dashoffset:10px"), // ... - TestCase("font-family:sans-serif"), // SPIString, text_private //TestCase("filter:url(#myfilter)"), // SPIFilter segfault in read TestCase("filter:inherit"), diff --git a/src/style.cpp b/src/style.cpp index de5b23854..c57cf6349 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -1936,7 +1936,15 @@ sp_style_merge_from_parent(SPStyle *const style, SPStyle const *const parent) if (!style->color_rendering.set || style->color_rendering.inherit) { style->color_rendering.computed = parent->color_rendering.computed; } - + if (!style->image_rendering.set || style->image_rendering.inherit) { + style->image_rendering.computed = parent->image_rendering.computed; + } + if (!style->shape_rendering.set || style->shape_rendering.inherit) { + style->shape_rendering.computed = parent->shape_rendering.computed; + } + if (!style->text_rendering.set || style->text_rendering.inherit) { + style->text_rendering.computed = parent->text_rendering.computed; + } } template <typename T> @@ -4365,7 +4373,7 @@ sp_style_write_ilengthornormal(gchar *p, gint const len, gchar const *const key, * Write SPIDashArray object into string. */ static gint -sp_style_write_idasharray(gchar *p, gint const len, gchar const *const key, +sp_style_write_idasharray(gchar *p, gint const len, gchar const *const /*key*/, SPIDashArray const *const val, SPIDashArray const *const base, guint const flags) { if ((flags & SP_STYLE_FLAG_ALWAYS) diff --git a/src/trace/siox.cpp b/src/trace/siox.cpp index 0706cfed1..065e891ed 100644 --- a/src/trace/siox.cpp +++ b/src/trace/siox.cpp @@ -889,7 +889,7 @@ SioxImage Siox::extractForeground(const SioxImage &originalImage, return workImage; } - trace("knownBg:%u knownFg:%u", knownBg.size(), knownFg.size()); + trace("knownBg:%u knownFg:%u", static_cast<unsigned int>(knownBg.size()), static_cast<unsigned int>(knownFg.size())); std::vector<CieLab> bgSignature ; diff --git a/src/ui/dialog/calligraphic-profile-rename.h b/src/ui/dialog/calligraphic-profile-rename.h index 3256338eb..fa13db196 100644 --- a/src/ui/dialog/calligraphic-profile-rename.h +++ b/src/ui/dialog/calligraphic-profile-rename.h @@ -16,7 +16,7 @@ #endif #if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H -#include <glibmm/threads.h> +# include <glibmm/threads.h> #endif #include <gtkmm/dialog.h> diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 0411c789c..a31ab1a09 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -35,6 +35,7 @@ #include "sp-namedview.h" #include "sp-root.h" #include "sp-script.h" +#include "style.h" #include "svg/stringstream.h" #include "tools-switch.h" #include "ui/widget/color-picker.h" @@ -106,6 +107,7 @@ DocumentProperties::DocumentProperties() _page_metadata1(Gtk::manage(new UI::Widget::NotebookPage(1, 1))), _page_metadata2(Gtk::manage(new UI::Widget::NotebookPage(1, 1))), //--------------------------------------------------------------- + _rcb_antialias(_("Use antialiasing"), _("If unset, no antialiasing will be done on the drawing"), "shape-rendering", _wr, false, NULL, NULL, NULL, "crispEdges"), _rcb_canb(_("Show page _border"), _("If set, rectangular page border is shown"), "showborder", _wr, false), _rcb_bord(_("Border on _top of drawing"), _("If set, border is always on top of the drawing"), "borderlayer", _wr, false), _rcb_shad(_("_Show border shadow"), _("If set, page border shows a shadow on its right and lower side"), "inkscape:showpageshadow", _wr, false), @@ -239,7 +241,8 @@ inline void attach_all(Gtk::Table &table, Gtk::Widget *const arr[], unsigned con yoptions = Gtk::FILL|Gtk::EXPAND; } if (docum_prop_flag) { - if( i==(n-4) || i==(n-6) ) { + // this sets the padding for subordinate widgets on the "Page" page + if( i==(n-8) || i==(n-10) ) { #if WITH_GTKMM_3_0 arr[i+1]->set_hexpand(); arr[i+1]->set_margin_left(20); @@ -316,28 +319,28 @@ void DocumentProperties::build_page() Gtk::Label* label_gen = manage (new Gtk::Label); label_gen->set_markup (_("<b>General</b>")); - Gtk::Label* label_col = manage (new Gtk::Label); - label_col->set_markup (_("<b>Color</b>")); - Gtk::Label* label_bor = manage (new Gtk::Label); - label_bor->set_markup (_("<b>Border</b>")); Gtk::Label *label_for = manage (new Gtk::Label); label_for->set_markup (_("<b>Page Size</b>")); + Gtk::Label* label_dsp = manage (new Gtk::Label); + label_dsp->set_markup (_("<b>Display</b>")); _page_sizer.init(); Gtk::Widget *const widget_array[] = { label_gen, 0, 0, &_rum_deflt, - label_col, 0, - _rcp_bg._label, &_rcp_bg, + //label_col, 0, + //_rcp_bg._label, &_rcp_bg, 0, 0, label_for, 0, 0, &_page_sizer, 0, 0, - label_bor, 0, + label_dsp, 0, 0, &_rcb_canb, 0, &_rcb_bord, 0, &_rcb_shad, + 0, &_rcb_antialias, + _rcp_bg._label, &_rcp_bg, _rcp_bord._label, &_rcp_bord, }; @@ -1473,6 +1476,10 @@ void DocumentProperties::update() _rcp_bord.setRgba32 (nv->bordercolor); _rcb_shad.setActive (nv->showpageshadow); + SPRoot *root = dt->getDocument()->getRoot(); + _rcb_antialias.set_xml_target(root->getRepr(), dt->getDocument()); + _rcb_antialias.setActive(root->style->shape_rendering.computed != SP_CSS_SHAPE_RENDERING_CRISPEDGES); + if (nv->doc_units) { _rum_deflt.setUnit (nv->doc_units->abbr); } diff --git a/src/ui/dialog/document-properties.h b/src/ui/dialog/document-properties.h index e3ca91731..495f3177d 100644 --- a/src/ui/dialog/document-properties.h +++ b/src/ui/dialog/document-properties.h @@ -117,6 +117,7 @@ protected: UI::Widget::Registry _wr; //--------------------------------------------------------------- + UI::Widget::RegisteredCheckButton _rcb_antialias; UI::Widget::RegisteredCheckButton _rcb_canb; UI::Widget::RegisteredCheckButton _rcb_bord; UI::Widget::RegisteredCheckButton _rcb_shad; diff --git a/src/ui/dialog/export.cpp b/src/ui/dialog/export.cpp index f0a5f1bf5..913713e5c 100644 --- a/src/ui/dialog/export.cpp +++ b/src/ui/dialog/export.cpp @@ -1049,7 +1049,7 @@ void Export::onExport () dpi = atof(dpi_hint); } if (dpi == 0.0) { - dpi = DPI_BASE; + dpi = getValue(xdpi_adj); } Geom::OptRect area = item->desktopVisualBounds(); diff --git a/src/ui/dialog/filter-effects-dialog.cpp b/src/ui/dialog/filter-effects-dialog.cpp index 65bebbd14..c2367c2a2 100644 --- a/src/ui/dialog/filter-effects-dialog.cpp +++ b/src/ui/dialog/filter-effects-dialog.cpp @@ -1515,7 +1515,7 @@ void FilterEffectsDialog::FilterModifier::on_name_edited(const Glib::ustring& pa } } -bool FilterEffectsDialog::FilterModifier::on_filter_move(const Glib::RefPtr<Gdk::DragContext>& /*context*/, int x, int y, guint /*time*/) { +bool FilterEffectsDialog::FilterModifier::on_filter_move(const Glib::RefPtr<Gdk::DragContext>& /*context*/, int /*x*/, int /*y*/, guint /*time*/) { //const Gtk::TreeModel::Path& /*path*/) { /* The code below is bugged. Use of "object->getRepr()->setPosition(0)" is dangerous! diff --git a/src/ui/dialog/object-properties.cpp b/src/ui/dialog/object-properties.cpp index 8f36cba43..28e9b360b 100644 --- a/src/ui/dialog/object-properties.cpp +++ b/src/ui/dialog/object-properties.cpp @@ -28,9 +28,9 @@ #include "object-properties.h" #include "widgets/sp-attribute-widget.h" -#include "../../desktop-handles.h" -#include "../../document.h" -#include "../../document-undo.h" +#include "desktop-handles.h" +#include "document.h" +#include "document-undo.h" #include "verbs.h" #include "inkscape.h" #include "selection.h" @@ -51,482 +51,479 @@ namespace Inkscape { namespace UI { namespace Dialog { -ObjectProperties::ObjectProperties (void) : - UI::Widget::Panel ("", "/dialogs/object/", SP_VERB_DIALOG_ITEM), - blocked (false), - CurrentItem(NULL), -#if WITH_GTKMM_3_0 - TopTable(Gtk::manage(new Gtk::Grid())), -#else - TopTable(Gtk::manage(new Gtk::Table(4, 4))), -#endif - LabelID(_("_ID:"), 1), - LabelLabel(_("_Label:"), 1), - LabelTitle(_("_Title:"),1), - LabelImageRendering(_("_Image Rendering:"),1), - LabelDescription(_("_Description:"),1), - FrameDescription("", FALSE), - HBoxCheck(FALSE, 0), -#if WITH_GTKMM_3_0 - CheckTable(Gtk::manage(new Gtk::Grid())), -#else - CheckTable(Gtk::manage(new Gtk::Table(1, 2, true))), -#endif - CBHide(_("_Hide"), 1), - CBLock(_("L_ock"), 1), - BSet (_("_Set"), 1), - LabelInteractivity(_("_Interactivity"), 1), - attrTable(Gtk::manage(new SPAttributeTable())), - desktop(NULL), - deskTrack(), - selectChangedConn(), - subselChangedConn() +ObjectProperties::ObjectProperties() + : UI::Widget::Panel ("", "/dialogs/object/", SP_VERB_DIALOG_ITEM) + , _blocked (false) + , _current_item(NULL) + , _label_id(_("_ID:"), 1) + , _label_label(_("_Label:"), 1) + , _label_title(_("_Title:"), 1) + , _label_image_rendering(_("_Image Rendering:"), 1) + , _cb_hide(_("_Hide"), 1) + , _cb_lock(_("L_ock"), 1) + , _attr_table(Gtk::manage(new SPAttributeTable())) + , _desktop(NULL) { //initialize labels for the table at the bottom of the dialog - int_attrs.push_back("onclick"); - int_attrs.push_back("onmouseover"); - int_attrs.push_back("onmouseout"); - int_attrs.push_back("onmousedown"); - int_attrs.push_back("onmouseup"); - int_attrs.push_back("onmousemove"); - int_attrs.push_back("onfocusin"); - int_attrs.push_back("onfocusout"); - int_attrs.push_back("onload"); - - int_labels.push_back("onclick:"); - int_labels.push_back("onmouseover:"); - int_labels.push_back("onmouseout:"); - int_labels.push_back("onmousedown:"); - int_labels.push_back("onmouseup:"); - int_labels.push_back("onmousemove:"); - int_labels.push_back("onfocusin:"); - int_labels.push_back("onfocusout:"); - int_labels.push_back("onload:"); - - desktopChangeConn = deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &ObjectProperties::setTargetDesktop) ); - deskTrack.connect(GTK_WIDGET(gobj())); - -#if WITH_GTKMM_3_0 - CheckTable->set_row_homogeneous(); - CheckTable->set_column_homogeneous(true); -#endif - - MakeWidget(); + _int_attrs.push_back("onclick"); + _int_attrs.push_back("onmouseover"); + _int_attrs.push_back("onmouseout"); + _int_attrs.push_back("onmousedown"); + _int_attrs.push_back("onmouseup"); + _int_attrs.push_back("onmousemove"); + _int_attrs.push_back("onfocusin"); + _int_attrs.push_back("onfocusout"); + _int_attrs.push_back("onload"); + + _int_labels.push_back("onclick:"); + _int_labels.push_back("onmouseover:"); + _int_labels.push_back("onmouseout:"); + _int_labels.push_back("onmousedown:"); + _int_labels.push_back("onmouseup:"); + _int_labels.push_back("onmousemove:"); + _int_labels.push_back("onfocusin:"); + _int_labels.push_back("onfocusout:"); + _int_labels.push_back("onload:"); + + _desktop_changed_connection = _desktop_tracker.connectDesktopChanged( + sigc::mem_fun(*this, &ObjectProperties::_setTargetDesktop) + ); + _desktop_tracker.connect(GTK_WIDGET(gobj())); + + _init(); } -ObjectProperties::~ObjectProperties (void) +ObjectProperties::~ObjectProperties() { - subselChangedConn.disconnect(); - selectChangedConn.disconnect(); - desktopChangeConn.disconnect(); - deskTrack.disconnect(); + _subselection_changed_connection.disconnect(); + _selection_changed_connection.disconnect(); + _desktop_changed_connection.disconnect(); + _desktop_tracker.disconnect(); } -void ObjectProperties::MakeWidget(void) +void ObjectProperties::_init() { Gtk::Box *contents = _getContents(); contents->set_spacing(0); - - TopTable->set_border_width(4); #if WITH_GTKMM_3_0 - TopTable->set_row_spacing(4); - TopTable->set_column_spacing(0); + Gtk::Grid *grid_top = Gtk::manage(new Gtk::Grid()); + grid_top->set_row_spacing(4); + grid_top->set_column_spacing(0); #else - TopTable->set_row_spacings(4); - TopTable->set_col_spacings(0); + Gtk::Table *grid_top = Gtk::manage(new Gtk::Table(4, 4)); + grid_top->set_row_spacings(4); + grid_top->set_col_spacings(0); #endif - contents->pack_start (*TopTable, false, false, 0); + grid_top->set_border_width(4); + + contents->pack_start(*grid_top, false, false, 0); + /* Create the label for the object id */ - LabelID.set_label (LabelID.get_label() + " "); - LabelID.set_alignment (1, 0.5); + _label_id.set_label(_label_id.get_label() + " "); + _label_id.set_alignment(1, 0.5); #if WITH_GTKMM_3_0 - LabelID.set_valign(Gtk::ALIGN_CENTER); - TopTable->attach(LabelID, 0, 0, 1, 1); + _label_id.set_valign(Gtk::ALIGN_CENTER); + grid_top->attach(_label_id, 0, 0, 1, 1); #else - TopTable->attach(LabelID, 0, 1, 0, 1, - Gtk::SHRINK | Gtk::FILL, - Gtk::AttachOptions(), 0, 0 ); + grid_top->attach(_label_id, 0, 1, 0, 1, + Gtk::SHRINK | Gtk::FILL, + Gtk::AttachOptions(), 0, 0 ); #endif + /* Create the entry box for the object id */ - EntryID.set_tooltip_text (_("The id= attribute (only letters, digits, and the characters .-_: allowed)")); - EntryID.set_max_length (64); + _entry_id.set_tooltip_text(_("The id= attribute (only letters, digits, and the characters .-_: allowed)")); + _entry_id.set_max_length(64); #if WITH_GTKMM_3_0 - EntryID.set_valign(Gtk::ALIGN_CENTER); - TopTable->attach(EntryID, 1, 0, 1, 1); + _entry_id.set_valign(Gtk::ALIGN_CENTER); + grid_top->attach(_entry_id, 1, 0, 1, 1); #else - TopTable->attach(EntryID, 1, 2, 0, 1, + grid_top->attach(_entry_id, 1, 2, 0, 1, Gtk::EXPAND | Gtk::FILL, Gtk::AttachOptions(), 0, 0 ); #endif - LabelID.set_mnemonic_widget (EntryID); + _label_id.set_mnemonic_widget(_entry_id); // pressing enter in the id field is the same as clicking Set: - EntryID.signal_activate().connect(sigc::mem_fun(this, &ObjectProperties::label_changed)); + _entry_id.signal_activate().connect(sigc::mem_fun(this, &ObjectProperties::_labelChanged)); // focus is in the id field initially: - EntryID.grab_focus(); + _entry_id.grab_focus(); + /* Create the label for the object label */ - LabelLabel.set_label (LabelLabel.get_label() + " "); - LabelLabel.set_alignment (1, 0.5); + _label_label.set_label(_label_label.get_label() + " "); + _label_label.set_alignment(1, 0.5); #if WITH_GTKMM_3_0 - LabelLabel.set_valign(Gtk::ALIGN_CENTER); - TopTable->attach(LabelLabel, 0, 1, 1, 1); + _label_label.set_valign(Gtk::ALIGN_CENTER); + grid_top->attach(_label_label, 0, 1, 1, 1); #else - TopTable->attach(LabelLabel, 0, 1, 1, 2, + grid_top->attach(_label_label, 0, 1, 1, 2, Gtk::SHRINK | Gtk::FILL, Gtk::AttachOptions(), 0, 0 ); #endif + /* Create the entry box for the object label */ - EntryLabel.set_tooltip_text (_("A freeform label for the object")); - EntryLabel.set_max_length (256); + _entry_label.set_tooltip_text(_("A freeform label for the object")); + _entry_label.set_max_length(256); #if WITH_GTKMM_3_0 - EntryLabel.set_hexpand(); - EntryLabel.set_valign(Gtk::ALIGN_CENTER); - TopTable->attach(EntryLabel, 1, 1, 1, 1); + _entry_label.set_hexpand(); + _entry_label.set_valign(Gtk::ALIGN_CENTER); + grid_top->attach(_entry_label, 1, 1, 1, 1); #else - TopTable->attach(EntryLabel, 1, 2, 1, 2, + grid_top->attach(_entry_label, 1, 2, 1, 2, Gtk::EXPAND | Gtk::FILL, Gtk::AttachOptions(), 0, 0 ); #endif - LabelLabel.set_mnemonic_widget (EntryLabel); + _label_label.set_mnemonic_widget(_entry_label); // pressing enter in the label field is the same as clicking Set: - EntryLabel.signal_activate().connect(sigc::mem_fun(this, &ObjectProperties::label_changed)); + _entry_label.signal_activate().connect(sigc::mem_fun(this, &ObjectProperties::_labelChanged)); + /* Create the label for the object title */ - LabelTitle.set_label (LabelTitle.get_label() + " "); - LabelTitle.set_alignment (1, 0.5); + _label_title.set_label(_label_title.get_label() + " "); + _label_title.set_alignment (1, 0.5); #if WITH_GTKMM_3_0 - LabelTitle.set_valign(Gtk::ALIGN_CENTER); - TopTable->attach(LabelTitle, 0, 2, 1, 1); + _label_title.set_valign(Gtk::ALIGN_CENTER); + grid_top->attach(_label_title, 0, 2, 1, 1); #else - TopTable->attach(LabelTitle, 0, 1, 2, 3, + grid_top->attach(_label_title, 0, 1, 2, 3, Gtk::SHRINK | Gtk::FILL, Gtk::AttachOptions(), 0, 0 ); #endif /* Create the entry box for the object title */ - EntryTitle.set_sensitive (FALSE); - EntryTitle.set_max_length (256); + _entry_title.set_sensitive (FALSE); + _entry_title.set_max_length (256); #if WITH_GTKMM_3_0 - EntryTitle.set_hexpand(); - EntryTitle.set_valign(Gtk::ALIGN_CENTER); - TopTable->attach(EntryTitle, 1, 2, 1, 1); + _entry_title.set_hexpand(); + _entry_title.set_valign(Gtk::ALIGN_CENTER); + grid_top->attach(_entry_title, 1, 2, 1, 1); #else - TopTable->attach(EntryTitle, 1, 2, 2, 3, + grid_top->attach(_entry_title, 1, 2, 2, 3, Gtk::EXPAND | Gtk::FILL, Gtk::AttachOptions(), 0, 0 ); #endif - LabelTitle.set_mnemonic_widget (EntryTitle); + _label_title.set_mnemonic_widget(_entry_title); // pressing enter in the label field is the same as clicking Set: - EntryTitle.signal_activate().connect(sigc::mem_fun(this, &ObjectProperties::label_changed)); + _entry_title.signal_activate().connect(sigc::mem_fun(this, &ObjectProperties::_labelChanged)); /* Create the frame for the object description */ - FrameDescription.set_label_widget (LabelDescription); - FrameDescription.set_padding (0,0,0,0); - contents->pack_start (FrameDescription, true, true, 0); + Gtk::Label *label_desc = Gtk::manage(new Gtk::Label(_("_Description:"), 1)); + UI::Widget::Frame *frame_desc = Gtk::manage(new UI::Widget::Frame("", FALSE)); + frame_desc->set_label_widget(*label_desc); + frame_desc->set_padding (0,0,0,0); + contents->pack_start(*frame_desc, true, true, 0); /* Create the text view box for the object description */ - FrameTextDescription.set_border_width(4); - FrameTextDescription.set_sensitive (FALSE); - FrameDescription.add (FrameTextDescription); - FrameTextDescription.set_shadow_type (Gtk::SHADOW_IN); + _ft_description.set_border_width(4); + _ft_description.set_sensitive(FALSE); + frame_desc->add(_ft_description); + _ft_description.set_shadow_type(Gtk::SHADOW_IN); - TextViewDescription.set_wrap_mode(Gtk::WRAP_WORD); - TextViewDescription.get_buffer()->set_text(""); - FrameTextDescription.add (TextViewDescription); - TextViewDescription.add_mnemonic_label(LabelDescription); + _tv_description.set_wrap_mode(Gtk::WRAP_WORD); + _tv_description.get_buffer()->set_text(""); + _ft_description.add(_tv_description); + _tv_description.add_mnemonic_label(*label_desc); /* Image rendering */ /* Create the label for the object ImageRendering */ - LabelImageRendering.set_label (LabelImageRendering.get_label() + " "); - LabelImageRendering.set_alignment (1, 0.5); + _label_image_rendering.set_label(_label_image_rendering.get_label() + " "); + _label_image_rendering.set_alignment(1, 0.5); #if WITH_GTKMM_3_0 - LabelImageRendering.set_valign(Gtk::ALIGN_CENTER); - TopTable->attach(LabelImageRendering, 0, 3, 1, 1); + _label_image_rendering.set_valign(Gtk::ALIGN_CENTER); + grid_top->attach(_label_image_rendering, 0, 3, 1, 1); #else - TopTable->attach(LabelImageRendering, 0, 1, 3, 4, - Gtk::SHRINK | Gtk::FILL, - Gtk::AttachOptions(), 0, 0 ); + grid_top->attach(_label_image_rendering, 0, 1, 3, 4, + Gtk::SHRINK | Gtk::FILL, + Gtk::AttachOptions(), 0, 0 ); #endif /* Create the combo box text for the 'image-rendering' property */ - ComboBoxTextImageRendering.append( "auto" ); - ComboBoxTextImageRendering.append( "optimizeQuality" ); - ComboBoxTextImageRendering.append( "optimizeSpeed" ); - ComboBoxTextImageRendering.set_tooltip_text (_("The 'image-rendering' property can influence how a bitmap is up-scaled:\n\t'auto' no preference;\n\t'optimizeQuality' smooth;\n\t'optimizeSpeed' blocky.\nNote that this behaviour is not defined in the SVG 1.1 specification and not all browsers follow this interpretation.")); + _combo_image_rendering.append( "auto" ); + _combo_image_rendering.append( "optimizeQuality" ); + _combo_image_rendering.append( "optimizeSpeed" ); + _combo_image_rendering.set_tooltip_text(_("The 'image-rendering' property can influence how a bitmap is up-scaled:\n\t'auto' no preference;\n\t'optimizeQuality' smooth;\n\t'optimizeSpeed' blocky.\nNote that this behaviour is not defined in the SVG 1.1 specification and not all browsers follow this interpretation.")); #if WITH_GTKMM_3_0 - ComboBoxTextImageRendering.set_valign(Gtk::ALIGN_CENTER); - TopTable->attach(ComboBoxTextImageRendering, 1, 3, 1, 1); + _combo_image_rendering.set_valign(Gtk::ALIGN_CENTER); + grid_top->attach(_combo_image_rendering, 1, 3, 1, 1); #else - TopTable->attach(ComboBoxTextImageRendering, 1, 2, 3, 4, + grid_top->attach(_combo_image_rendering, 1, 2, 3, 4, Gtk::EXPAND | Gtk::FILL, Gtk::AttachOptions(), 0, 0 ); #endif - LabelImageRendering.set_mnemonic_widget (ComboBoxTextImageRendering); + _label_image_rendering.set_mnemonic_widget(_combo_image_rendering); - ComboBoxTextImageRendering.signal_changed().connect(sigc::mem_fun(this, &ObjectProperties::image_rendering_changed)); + _combo_image_rendering.signal_changed().connect( + sigc::mem_fun(this, &ObjectProperties::_imageRenderingChanged) + ); /* Check boxes */ - contents->pack_start (HBoxCheck, FALSE, FALSE, 0); - CheckTable->set_border_width(4); - HBoxCheck.pack_start(*CheckTable, true, true, 0); + Gtk::HBox *hb_checkboxes = Gtk::manage(new Gtk::HBox()); + contents->pack_start(*hb_checkboxes, FALSE, FALSE, 0); + +#if WITH_GTKMM_3_0 + Gtk::Grid *grid_cb = Gtk::manage(new Gtk::Grid()); + grid_cb->set_row_homogeneous(); + grid_cb->set_column_homogeneous(true); +#else + Gtk::Table *grid_cb = Gtk::manage(new Gtk::Table(1, 2, true)); +#endif + + grid_cb->set_border_width(4); + hb_checkboxes->pack_start(*grid_cb, true, true, 0); /* Hide */ - CBHide.set_tooltip_text (_("Check to make the object invisible")); + _cb_hide.set_tooltip_text (_("Check to make the object invisible")); #if WITH_GTKMM_3_0 - CBHide.set_hexpand(); - CBHide.set_valign(Gtk::ALIGN_CENTER); - CheckTable->attach(CBHide, 0, 0, 1, 1); + _cb_hide.set_hexpand(); + _cb_hide.set_valign(Gtk::ALIGN_CENTER); + grid_cb->attach(_cb_hide, 0, 0, 1, 1); #else - CheckTable->attach(CBHide, 0, 1, 0, 1, + grid_cb->attach(_cb_hide, 0, 1, 0, 1, Gtk::EXPAND | Gtk::FILL, Gtk::AttachOptions(), 0, 0 ); #endif - CBHide.signal_toggled().connect(sigc::mem_fun(this, &ObjectProperties::hidden_toggled)); + _cb_hide.signal_toggled().connect(sigc::mem_fun(this, &ObjectProperties::_hiddenToggled)); /* Lock */ // TRANSLATORS: "Lock" is a verb here - CBLock.set_tooltip_text (_("Check to make the object insensitive (not selectable by mouse)")); + _cb_lock.set_tooltip_text(_("Check to make the object insensitive (not selectable by mouse)")); #if WITH_GTKMM_3_0 - CBLock.set_hexpand(); - CBLock.set_valign(Gtk::ALIGN_CENTER); - CheckTable->attach(CBLock, 1, 0, 1, 1); + _cb_lock.set_hexpand(); + _cb_lock.set_valign(Gtk::ALIGN_CENTER); + grid_cb->attach(_cb_lock, 1, 0, 1, 1); #else - CheckTable->attach(CBLock, 1, 2, 0, 1, - Gtk::EXPAND | Gtk::FILL, - Gtk::AttachOptions(), 0, 0 ); + grid_cb->attach(_cb_lock, 1, 2, 0, 1, + Gtk::EXPAND | Gtk::FILL, + Gtk::AttachOptions(), 0, 0 ); #endif - CBLock.signal_toggled().connect(sigc::mem_fun(this, &ObjectProperties::sensitivity_toggled)); + _cb_lock.signal_toggled().connect(sigc::mem_fun(this, &ObjectProperties::_sensitivityToggled)); /* Button for setting the object's id, label, title and description. */ + Gtk::Button *btn_set = Gtk::manage(new Gtk::Button(_("_Set"), 1)); #if WITH_GTKMM_3_0 - BSet.set_hexpand(); - BSet.set_valign(Gtk::ALIGN_CENTER); - CheckTable->attach(BSet, 2, 0, 1, 1); + btn_set->set_hexpand(); + btn_set->set_valign(Gtk::ALIGN_CENTER); + grid_cb->attach(*btn_set, 2, 0, 1, 1); #else - CheckTable->attach(BSet, 2, 3, 0, 1, - Gtk::EXPAND | Gtk::FILL, - Gtk::AttachOptions(), 0, 0 ); + grid_cb->attach(*btn_set, 2, 3, 0, 1, + Gtk::EXPAND | Gtk::FILL, + Gtk::AttachOptions(), 0, 0 ); #endif - BSet.signal_clicked().connect(sigc::mem_fun(this, &ObjectProperties::label_changed)); + btn_set->signal_clicked().connect(sigc::mem_fun(this, &ObjectProperties::_labelChanged)); /* Create the frame for interactivity options */ - EInteractivity.set_label_widget (LabelInteractivity); - contents->pack_start (EInteractivity, FALSE, FALSE, 0); - show_all (); - widget_setup(); + Gtk::Label *label_interactivity = Gtk::manage(new Gtk::Label(_("_Interactivity"), 1)); + _exp_interactivity.set_label_widget(*label_interactivity); + contents->pack_start(_exp_interactivity, FALSE, FALSE, 0); + + show_all(); + update(); } -void ObjectProperties::widget_setup(void) +void ObjectProperties::update() { - if (blocked || !desktop) - { + if (_blocked || !_desktop) { return; } - if (SP_ACTIVE_DESKTOP != desktop) - { + if (SP_ACTIVE_DESKTOP != _desktop) { return; } - Inkscape::Selection *selection = sp_desktop_selection (SP_ACTIVE_DESKTOP); + Inkscape::Selection *selection = sp_desktop_selection(SP_ACTIVE_DESKTOP); Gtk::Box *contents = _getContents(); if (!selection->singleItem()) { contents->set_sensitive (false); - CurrentItem = NULL; + _current_item = NULL; //no selection anymore or multiple objects selected, means that we need //to close the connections to the previously selected object - attrTable->clear(); + _attr_table->clear(); return; } else { contents->set_sensitive (true); } SPItem *item = selection->singleItem(); - if (CurrentItem == item) + if (_current_item == item) { //otherwise we would end up wasting resources through the modify selection - //callback when moving an object (endlessly setting the labels and recreating attrTable) + //callback when moving an object (endlessly setting the labels and recreating _attr_table) return; } - blocked = true; + _blocked = true; - CBLock.set_active (item->isLocked()); /* Sensitive */ - CBHide.set_active (item->isExplicitlyHidden()); /* Hidden */ + _cb_lock.set_active(item->isLocked()); /* Sensitive */ + _cb_hide.set_active(item->isExplicitlyHidden()); /* Hidden */ if (item->cloned) { /* ID */ - EntryID.set_text (""); - EntryID.set_sensitive (FALSE); - LabelID.set_text (_("Ref")); + _entry_id.set_text(""); + _entry_id.set_sensitive(FALSE); + _label_id.set_text(_("Ref")); /* Label */ - EntryLabel.set_text (""); - EntryLabel.set_sensitive (FALSE); - LabelLabel.set_text (_("Ref")); + _entry_label.set_text(""); + _entry_label.set_sensitive(FALSE); + _label_label.set_text(_("Ref")); } else { SPObject *obj = static_cast<SPObject*>(item); /* ID */ - EntryID.set_text (obj->getId()); - EntryID.set_sensitive (TRUE); - LabelID.set_markup_with_mnemonic (_("_ID:")); + _entry_id.set_text(obj->getId()); + _entry_id.set_sensitive(TRUE); + _label_id.set_markup_with_mnemonic(_("_ID:") + Glib::ustring(" ")); /* Label */ - EntryLabel.set_text(obj->defaultLabel()); - EntryLabel.set_sensitive (TRUE); + _entry_label.set_text(obj->defaultLabel()); + _entry_label.set_sensitive(TRUE); /* Title */ gchar *title = obj->title(); if (title) { - EntryTitle.set_text(title); + _entry_title.set_text(title); g_free(title); } else { - EntryTitle.set_text(""); + _entry_title.set_text(""); } - EntryTitle.set_sensitive(TRUE); + _entry_title.set_sensitive(TRUE); /* Image Rendering */ - if( SP_IS_IMAGE( item ) ) { - ComboBoxTextImageRendering.show(); - LabelImageRendering.show(); + if (SP_IS_IMAGE(item)) { + _combo_image_rendering.show(); + _label_image_rendering.show(); char const *str = obj->getStyleProperty( "image-rendering", "auto" ); - if( strcmp( str, "auto" ) == 0 ) { - ComboBoxTextImageRendering.set_active(0); - } else if( strcmp( str, "optimizeQuality" ) == 0 ) { - ComboBoxTextImageRendering.set_active(1); - } else { - ComboBoxTextImageRendering.set_active(2); + if (strcmp( str, "auto" ) == 0) { + _combo_image_rendering.set_active(0); + } else if (strcmp(str, "optimizeQuality") == 0) { + _combo_image_rendering.set_active(1); + } else { + _combo_image_rendering.set_active(2); } } else { - ComboBoxTextImageRendering.hide(); - ComboBoxTextImageRendering.unset_active(); - LabelImageRendering.hide(); + _combo_image_rendering.hide(); + _combo_image_rendering.unset_active(); + _label_image_rendering.hide(); } /* Description */ gchar *desc = obj->desc(); if (desc) { - TextViewDescription.get_buffer()->set_text(desc); + _tv_description.get_buffer()->set_text(desc); g_free(desc); } else { - TextViewDescription.get_buffer()->set_text(""); + _tv_description.get_buffer()->set_text(""); } - FrameTextDescription.set_sensitive(TRUE); + _ft_description.set_sensitive(TRUE); - if (CurrentItem == NULL) - { - attrTable->set_object(obj, int_labels, int_attrs, (GtkWidget*)EInteractivity.gobj()); - } - else - { - attrTable->change_object(obj); + if (_current_item == NULL) { + _attr_table->set_object(obj, _int_labels, _int_attrs, (GtkWidget*) _exp_interactivity.gobj()); + } else { + _attr_table->change_object(obj); } - attrTable->show_all(); + _attr_table->show_all(); } - CurrentItem = item; - blocked = false; + _current_item = item; + _blocked = false; } -void ObjectProperties::label_changed(void) +void ObjectProperties::_labelChanged() { - if (blocked) - { + if (_blocked) { return; } SPItem *item = sp_desktop_selection(SP_ACTIVE_DESKTOP)->singleItem(); g_return_if_fail (item != NULL); - blocked = true; + _blocked = true; /* Retrieve the label widget for the object's id */ - //bug 1290573: getId() crashes after undo (cannot create string from NULL ptr) - gchar *id = g_strdup(EntryID.get_text().c_str()); - g_strcanon (id, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.:", '_'); - if (!strcmp (id, item->getId())) { - LabelID.set_markup_with_mnemonic(_("_ID:")); + gchar *id = g_strdup(_entry_id.get_text().c_str()); + g_strcanon(id, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.:", '_'); + if (strcmp(id, item->getId()) == 0) { + _label_id.set_markup_with_mnemonic(_("_ID:")); } else if (!*id || !isalnum (*id)) { - LabelID.set_text (_("Id invalid! ")); + _label_id.set_text(_("Id invalid! ")); } else if (SP_ACTIVE_DOCUMENT->getObjectById(id) != NULL) { - LabelID.set_text (_("Id exists! ")); + _label_id.set_text(_("Id exists! ")); } else { SPException ex; - LabelID.set_markup_with_mnemonic(_("_ID:")); - SP_EXCEPTION_INIT (&ex); + _label_id.set_markup_with_mnemonic(_("_ID:")); + SP_EXCEPTION_INIT(&ex); item->setAttribute("id", id, &ex); DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_ITEM, _("Set object ID")); } - g_free (id); + g_free(id); /* Retrieve the label widget for the object's label */ - Glib::ustring label = EntryLabel.get_text(); + Glib::ustring label = _entry_label.get_text(); /* Give feedback on success of setting the drawing object's label * using the widget's label text */ SPObject *obj = static_cast<SPObject*>(item); - if (label.compare (obj->defaultLabel())) { + if (label.compare(obj->defaultLabel())) { obj->setLabel(label.c_str()); DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_ITEM, _("Set object label")); } /* Retrieve the title */ - if (obj->setTitle(EntryTitle.get_text().c_str())) + if (obj->setTitle(_entry_title.get_text().c_str())) { DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_ITEM, _("Set object title")); + } /* Retrieve the description */ Gtk::TextBuffer::iterator start, end; - TextViewDescription.get_buffer()->get_bounds(start, end); - Glib::ustring desc = TextViewDescription.get_buffer()->get_text(start, end, TRUE); - if (obj->setDesc(desc.c_str())) + _tv_description.get_buffer()->get_bounds(start, end); + Glib::ustring desc = _tv_description.get_buffer()->get_text(start, end, TRUE); + if (obj->setDesc(desc.c_str())) { DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_ITEM, _("Set object description")); + } - blocked = false; + _blocked = false; } -void ObjectProperties::image_rendering_changed(void) +void ObjectProperties::_imageRenderingChanged() { - if (blocked) - { + if (_blocked) { return; } SPItem *item = sp_desktop_selection(SP_ACTIVE_DESKTOP)->singleItem(); g_return_if_fail (item != NULL); - blocked = true; + _blocked = true; - Glib::ustring scale = ComboBoxTextImageRendering.get_active_text(); + Glib::ustring scale = _combo_image_rendering.get_active_text(); // We should unset if the parent computed value is auto and the desired value is auto. SPCSSAttr *css = sp_repr_css_attr_new(); @@ -537,64 +534,67 @@ void ObjectProperties::image_rendering_changed(void) } sp_repr_css_attr_unref( css ); - blocked = false; + _blocked = false; } -void ObjectProperties::sensitivity_toggled (void) +void ObjectProperties::_sensitivityToggled() { - if (blocked) - { + if (_blocked) { return; } SPItem *item = sp_desktop_selection(SP_ACTIVE_DESKTOP)->singleItem(); - g_return_if_fail (item != NULL); + g_return_if_fail(item != NULL); - blocked = true; - item->setLocked(CBLock.get_active()); + _blocked = true; + item->setLocked(_cb_lock.get_active()); DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_ITEM, - CBLock.get_active()? _("Lock object") : _("Unlock object")); - blocked = false; + _cb_lock.get_active() ? _("Lock object") : _("Unlock object")); + _blocked = false; } -void ObjectProperties::hidden_toggled(void) +void ObjectProperties::_hiddenToggled() { - if (blocked) - { + if (_blocked) { return; } SPItem *item = sp_desktop_selection(SP_ACTIVE_DESKTOP)->singleItem(); - g_return_if_fail (item != NULL); + g_return_if_fail(item != NULL); - blocked = true; - item->setExplicitlyHidden(CBHide.get_active()); + _blocked = true; + item->setExplicitlyHidden(_cb_hide.get_active()); DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_ITEM, - CBHide.get_active()? _("Hide object") : _("Unhide object")); - blocked = false; + _cb_hide.get_active() ? _("Hide object") : _("Unhide object")); + _blocked = false; } -void ObjectProperties::setDesktop(SPDesktop *desktop) +void ObjectProperties::_setDesktop(SPDesktop *desktop) { Panel::setDesktop(desktop); - deskTrack.setBase(desktop); + _desktop_tracker.setBase(desktop); } -void ObjectProperties::setTargetDesktop(SPDesktop *desktop) +void ObjectProperties::_setTargetDesktop(SPDesktop *desktop) { - if (this->desktop != desktop) { - if (this->desktop) { - subselChangedConn.disconnect(); - selectChangedConn.disconnect(); + if (this->_desktop != desktop) { + if (this->_desktop) { + _subselection_changed_connection.disconnect(); + _selection_changed_connection.disconnect(); } - this->desktop = desktop; + this->_desktop = desktop; if (desktop && desktop->selection) { - selectChangedConn = desktop->selection->connectChanged(sigc::hide(sigc::mem_fun(*this, &ObjectProperties::widget_setup))); - subselChangedConn = desktop->connectToolSubselectionChanged(sigc::hide(sigc::mem_fun(*this, &ObjectProperties::widget_setup))); + _selection_changed_connection = desktop->selection->connectChanged( + sigc::hide(sigc::mem_fun(*this, &ObjectProperties::update)) + ); + _subselection_changed_connection = desktop->connectToolSubselectionChanged( + sigc::hide(sigc::mem_fun(*this, &ObjectProperties::update)) + ); } - widget_setup(); + update(); } } + } } } diff --git a/src/ui/dialog/object-properties.h b/src/ui/dialog/object-properties.h index 721c12c56..093f273f6 100644 --- a/src/ui/dialog/object-properties.h +++ b/src/ui/dialog/object-properties.h @@ -69,98 +69,64 @@ namespace Dialog { */ class ObjectProperties : public Widget::Panel { public: - ObjectProperties (); - ~ObjectProperties (); + ObjectProperties(); + ~ObjectProperties(); static ObjectProperties &getInstance() { return *new ObjectProperties(); } - /** - * Updates entries and other child widgets on selection change, object modification, etc. - */ - void widget_setup(void); + /// Updates entries and other child widgets on selection change, object modification, etc. + void update(); private: - bool blocked; - SPItem *CurrentItem; //to store the current item, for not wasting resources - std::vector<Glib::ustring> int_attrs; - std::vector<Glib::ustring> int_labels; + bool _blocked; + SPItem *_current_item; //to store the current item, for not wasting resources + std::vector<Glib::ustring> _int_attrs; + std::vector<Glib::ustring> _int_labels; + + Gtk::Label _label_id; //the label for the object ID + Gtk::Entry _entry_id; //the entry for the object ID + Gtk::Label _label_label; //the label for the object label + Gtk::Entry _entry_label; //the entry for the object label + Gtk::Label _label_title; //the label for the object title + Gtk::Entry _entry_title; //the entry for the object title + Gtk::Label _label_image_rendering; // the label for 'image-rendering' + Gtk::ComboBoxText _combo_image_rendering; // the combo box text for 'image-rendering' -#if WITH_GTKMM_3_0 - Gtk::Grid *TopTable; //the table with the object properties -#else - Gtk::Table *TopTable; //the table with the object properties -#endif + Gtk::Frame _ft_description; //the frame for the text of the object description + Gtk::TextView _tv_description; //the text view object showing the object description - Gtk::Label LabelID; //the label for the object ID - Gtk::Entry EntryID; //the entry for the object ID - Gtk::Label LabelLabel; //the label for the object label - Gtk::Entry EntryLabel; //the entry for the object label - Gtk::Label LabelTitle; //the label for the object title - Gtk::Entry EntryTitle; //the entry for the object title - Gtk::Label LabelImageRendering; // the label for 'image-rendering' - Gtk::ComboBoxText ComboBoxTextImageRendering; // the combo box text for 'image-rendering' + Gtk::CheckButton _cb_hide; //the check button hide + Gtk::CheckButton _cb_lock; //the check button lock + + Gtk::Expander _exp_interactivity; //the expander for interactivity + SPAttributeTable *_attr_table; //the widget for showing the on... names at the bottom - Gtk::Label LabelDescription; //the label for the object description - UI::Widget::Frame FrameDescription; //the frame for the object description - Gtk::Frame FrameTextDescription; //the frame for the text of the object description - Gtk::TextView TextViewDescription; //the text view object showing the object description + SPDesktop *_desktop; + DesktopTracker _desktop_tracker; + sigc::connection _desktop_changed_connection; + sigc::connection _selection_changed_connection; + sigc::connection _subselection_changed_connection; - Gtk::HBox HBoxCheck; // the HBox for the check boxes + /// Constructor auxiliary function creating the child widgets. + void _init(); -#if WITH_GTKMM_3_0 - Gtk::Grid *CheckTable; //the table for the check boxes -#else - Gtk::Table *CheckTable; //the table for the check boxes -#endif + /// Sets object properties (ID, label, title, description) on user input. + void _labelChanged(); - Gtk::CheckButton CBHide; //the check button hide - Gtk::CheckButton CBLock; //the check button lock - Gtk::Button BSet; //the button set - - Gtk::Label LabelInteractivity; //the label for interactivity - Gtk::Expander EInteractivity; //the label for interactivity - SPAttributeTable *attrTable; //the widget for showing the on... names at the bottom - - SPDesktop *desktop; - DesktopTracker deskTrack; - sigc::connection desktopChangeConn; - sigc::connection selectChangedConn; - sigc::connection subselChangedConn; - - /** - * Constructor auxiliary function creating the child widgets. - */ - void MakeWidget(void); - - /** - * Sets object properties (ID, label, title, description) on user input. - */ - void label_changed(void); - - /** - * Callback for 'image-rendering'. - */ - void image_rendering_changed(void); - - /** - * Callback for checkbox Lock. - */ - void sensitivity_toggled (void); - - /** - * Callback for checkbox Hide. - */ - void hidden_toggled(void); - - /** - * Can be invoked for setting the desktop. Currently not used. - */ - void setDesktop(SPDesktop *desktop); + /// Callback for 'image-rendering'. + void _imageRenderingChanged(); + + /// Callback for checkbox Lock. + void _sensitivityToggled(); + + /// Callback for checkbox Hide. + void _hiddenToggled(); + + /// Can be invoked for setting the desktop. Currently not used. + void _setDesktop(SPDesktop *desktop); - /** - * Is invoked by the desktop tracker when the desktop changes. - */ - void setTargetDesktop(SPDesktop *desktop); + /// Is invoked by the desktop tracker when the desktop changes. + void _setTargetDesktop(SPDesktop *desktop); }; } diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index 2095546fb..338233042 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -21,6 +21,7 @@ #include <gtkmm/stock.h> #include <glibmm/i18n.h> +#include <glibmm/main.h> #include "desktop.h" #include "desktop-style.h" @@ -511,7 +512,11 @@ void ObjectsPanel::_setCompositingValues(SPItem *item) _blurConnection.block(); //Set the opacity +#if WITH_GTKMM_3_0 + _opacity_adjustment->set_value((item->style->opacity.set ? SP_SCALE24_TO_FLOAT(item->style->opacity.value) : 1) * _opacity_adjustment->get_upper()); +#else _opacity_adjustment.set_value((item->style->opacity.set ? SP_SCALE24_TO_FLOAT(item->style->opacity.value) : 1) * _opacity_adjustment.get_upper()); +#endif SPFeBlend *spblend = NULL; SPGaussianBlur *spblur = NULL; if (item->style->getFilter()) @@ -711,11 +716,11 @@ bool ObjectsPanel::_handleKeyEvent(GdkEventKey *event) } } break; - case GDK_Home: + case GDK_KEY_Home: //Move item(s) to top of containing group/layer _fireAction( empty ? SP_VERB_LAYER_TO_TOP : SP_VERB_SELECTION_TO_FRONT ); break; - case GDK_End: + case GDK_KEY_End: //Move item(s) to bottom of containing group/layer _fireAction( empty ? SP_VERB_LAYER_TO_BOTTOM : SP_VERB_SELECTION_TO_BACK ); break; @@ -1474,7 +1479,11 @@ void ObjectsPanel::_opacityChangedIter(const Gtk::TreeIter& iter) if (item) { item->style->opacity.set = TRUE; +#if WITH_GTKMM_3_0 + item->style->opacity.value = SP_SCALE24_FROM_FLOAT(_opacity_adjustment->get_value() / _opacity_adjustment->get_upper()); +#else item->style->opacity.value = SP_SCALE24_FROM_FLOAT(_opacity_adjustment.get_value() / _opacity_adjustment.get_upper()); +#endif item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); } } @@ -1759,7 +1768,7 @@ ObjectsPanel::ObjectsPanel() : _opacity_hbox.pack_start(_opacity_label_unit, false, false, 3); _opacity_hscale.set_draw_value(false); #if WITH_GTKMM_3_0 - _opacityConnection = _opacity_adjustment->signal_value_changed().connect(sigc::mem_fun(*this, &ObjectCompositeSettings::_opacityValueChanged)); + _opacityConnection = _opacity_adjustment->signal_value_changed().connect(sigc::mem_fun(*this, &ObjectsPanel::_opacityValueChanged)); _opacity_label.set_mnemonic_widget(_opacity_hscale); #else _opacityConnection = _opacity_adjustment.signal_value_changed().connect(sigc::mem_fun(*this, &ObjectsPanel::_opacityValueChanged)); @@ -1875,8 +1884,14 @@ ObjectsPanel::ObjectsPanel() : _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); //Collapse all - btn = Gtk::manage( new Gtk::Button(Gtk::Stock::UNINDENT) ); + btn = Gtk::manage( new Gtk::Button() ); btn->set_tooltip_text(_("Collapse All")); +#if GTK_CHECK_VERSION(3,10,0) + btn->set_from_icon_name(INKSCAPE_ICON("gtk-unindent-ltr"), Gtk::ICON_SIZE_SMALL_TOOLBAR); +#else + image_remove->set_from_icon_name(INKSCAPE_ICON("gtk-unindent-ltr"), Gtk::ICON_SIZE_SMALL_TOOLBAR); + btn->set_image(*image_remove); +#endif 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/objects.h b/src/ui/dialog/objects.h index 7b07afd63..74c2382ac 100644 --- a/src/ui/dialog/objects.h +++ b/src/ui/dialog/objects.h @@ -12,6 +12,14 @@ #ifndef SEEN_OBJECTS_PANEL_H #define SEEN_OBJECTS_PANEL_H +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H +# include <glibmm/threads.h> +#endif + #include <gtkmm/box.h> #include <gtkmm/treeview.h> #include <gtkmm/treestore.h> diff --git a/src/ui/dialog/undo-history.cpp b/src/ui/dialog/undo-history.cpp index 2412c3ec9..53691cd37 100644 --- a/src/ui/dialog/undo-history.cpp +++ b/src/ui/dialog/undo-history.cpp @@ -235,7 +235,7 @@ void UndoHistory::setDesktop(SPDesktop* desktop) } } -void UndoHistory::_connectDocument(SPDesktop* desktop, SPDocument *document) +void UndoHistory::_connectDocument(SPDesktop* desktop, SPDocument * /*document*/) { // disconnect from prior if (_event_log) { diff --git a/src/ui/dialog/xml-tree.cpp b/src/ui/dialog/xml-tree.cpp index 0e1e9f7a6..55d0aff09 100644 --- a/src/ui/dialog/xml-tree.cpp +++ b/src/ui/dialog/xml-tree.cpp @@ -100,6 +100,9 @@ XmlTree::XmlTree (void) : status.set_alignment( 0.0, 0.5); status.set_size_request(1, -1); status.set_markup(""); +#if WITH_GTKMM_3_0 + status.set_line_wrap(true); +#endif status_box.pack_start( status, TRUE, TRUE, 0); contents->pack_end(status_box, false, false, 2); diff --git a/src/ui/widget/addtoicon.cpp b/src/ui/widget/addtoicon.cpp index 3d6091f70..ce665295b 100644 --- a/src/ui/widget/addtoicon.cpp +++ b/src/ui/widget/addtoicon.cpp @@ -8,6 +8,14 @@ */ +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H +# include <glibmm/threads.h> +#endif + #include "ui/widget/addtoicon.h" #include <gtkmm/icontheme.h> diff --git a/src/ui/widget/clipmaskicon.cpp b/src/ui/widget/clipmaskicon.cpp index de7638bfe..6331d70d8 100644 --- a/src/ui/widget/clipmaskicon.cpp +++ b/src/ui/widget/clipmaskicon.cpp @@ -7,6 +7,13 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H +# include <glibmm/threads.h> +#endif #include "ui/widget/clipmaskicon.h" diff --git a/src/ui/widget/layertypeicon.cpp b/src/ui/widget/layertypeicon.cpp index bfe855b28..3d6182bf8 100644 --- a/src/ui/widget/layertypeicon.cpp +++ b/src/ui/widget/layertypeicon.cpp @@ -7,6 +7,13 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H +# include <glibmm/threads.h> +#endif #include "ui/widget/layertypeicon.h" diff --git a/src/ui/widget/registered-widget.cpp b/src/ui/widget/registered-widget.cpp index ae6a7d1e0..175f6471c 100644 --- a/src/ui/widget/registered-widget.cpp +++ b/src/ui/widget/registered-widget.cpp @@ -49,8 +49,10 @@ RegisteredCheckButton::~RegisteredCheckButton() _toggled_connection.disconnect(); } -RegisteredCheckButton::RegisteredCheckButton (const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Registry& wr, bool right, Inkscape::XML::Node* repr_in, SPDocument *doc_in) +RegisteredCheckButton::RegisteredCheckButton (const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Registry& wr, bool right, Inkscape::XML::Node* repr_in, SPDocument *doc_in, char const *active_str, char const *inactive_str) : RegisteredWidget<Gtk::CheckButton>() + , _active_str(active_str) + , _inactive_str(inactive_str) { init_parent(key, wr, repr_in, doc_in); @@ -88,7 +90,7 @@ RegisteredCheckButton::on_toggled() return; _wr->setUpdating (true); - write_to_xml(get_active() ? "true" : "false"); + write_to_xml(get_active() ? _active_str : _inactive_str); //The slave button is greyed out if the master button is unchecked for (std::list<Gtk::Widget*>::const_iterator i = _slavewidgets.begin(); i != _slavewidgets.end(); ++i) { (*i)->set_sensitive(get_active()); diff --git a/src/ui/widget/registered-widget.h b/src/ui/widget/registered-widget.h index 883a9e1a2..d64c09c16 100644 --- a/src/ui/widget/registered-widget.h +++ b/src/ui/widget/registered-widget.h @@ -55,6 +55,11 @@ public: event_description = _event_description; write_undo = true; } + void set_xml_target(Inkscape::XML::Node *xml_node, SPDocument *document) + { + repr = xml_node; + doc = document; + } bool is_updating() {if (_wr) return _wr->isUpdating(); else return false;} @@ -136,7 +141,7 @@ private: class RegisteredCheckButton : public RegisteredWidget<Gtk::CheckButton> { public: virtual ~RegisteredCheckButton(); - RegisteredCheckButton (const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Registry& wr, bool right=true, Inkscape::XML::Node* repr_in=NULL, SPDocument *doc_in=NULL); + RegisteredCheckButton (const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Registry& wr, bool right=true, Inkscape::XML::Node* repr_in=NULL, SPDocument *doc_in=NULL, char const *active_str = "true", char const *inactive_str = "false"); void setActive (bool); @@ -153,6 +158,7 @@ public: // if a callback checks it, it must reset it back to false protected: + char const *_active_str, *_inactive_str; sigc::connection _toggled_connection; void on_toggled(); }; diff --git a/src/uri-references.cpp b/src/uri-references.cpp index 1da890c56..6db2ed21f 100644 --- a/src/uri-references.cpp +++ b/src/uri-references.cpp @@ -115,10 +115,10 @@ void URIReference::attach(const URI &uri) throw(BadURIException) /* FIXME !!! validate id as an NCName somewhere */ + _connection.disconnect(); delete _uri; _uri = new URI(uri); - _connection.disconnect(); _setObject(document->getObjectById(id)); _connection = document->connectIdChanged(id, sigc::mem_fun(*this, &URIReference::_setObject)); diff --git a/src/uri.cpp b/src/uri.cpp index e81d108c9..2eaf4ecc1 100644 --- a/src/uri.cpp +++ b/src/uri.cpp @@ -149,6 +149,9 @@ gchar *URI::to_native_filename(gchar const* uri) throw(BadURIException) * and thus redundent. Caller is expected to check against the document's path. */ const std::string URI::getFullPath(std::string const base) const { + if (!_impl->getPath()) { + return ""; + } std::string path = std::string(_impl->getPath()); // Calculate the absolute path from an available base if(!base.empty() && !path.empty() && path[0] != '/') { |
