=== modified file 'src/helper/stock-items.cpp' --- src/helper/stock-items.cpp 2012-08-04 02:20:42 +0000 +++ src/helper/stock-items.cpp 2012-08-05 07:29:31 +0000 @@ -173,7 +173,7 @@ // if necessary it will import the object. Copes with name clashes through use of the inkscape:stockid property // This should be set to be the same as the id in the libary file. -SPObject *get_stock_item(gchar const *urn) +SPObject *get_stock_item(gchar const *urn, gboolean alwaysfork/*=FALSE*/) { g_assert(urn != NULL); @@ -202,7 +202,7 @@ return NULL; } SPObject *object = NULL; - if (!strcmp(base, "marker")) { + if (!strcmp(base, "marker") && !alwaysfork) { for ( SPObject *child = defs->firstChild(); child; child = child->getNext() ) { if (child->getRepr()->attribute("inkscape:stockid") && @@ -214,7 +214,7 @@ } } - else if (!strcmp(base,"pattern")) { + else if (!strcmp(base,"pattern") && !alwaysfork) { for ( SPObject *child = defs->firstChild() ; child; child = child->getNext() ) { if (child->getRepr()->attribute("inkscape:stockid") && @@ -226,7 +226,7 @@ } } - else if (!strcmp(base,"gradient")) { + else if (!strcmp(base,"gradient") && !alwaysfork) { for ( SPObject *child = defs->firstChild(); child; child = child->getNext() ) { if (child->getRepr()->attribute("inkscape:stockid") && @@ -239,7 +239,7 @@ } - if (object == NULL) { + if (object == NULL || alwaysfork) { if (!strcmp(base, "marker")) { object = sp_marker_load_from_svg(name_p, doc); @@ -259,11 +259,22 @@ } else { - + SPDesktop *desktop = inkscape_active_desktop(); SPDocument *doc = sp_desktop_document(desktop); SPObject *object = doc->getObjectById(urn); + if (object) { + + SPDefs *defs = doc->getDefs(); + Inkscape::XML::Document *xml_doc = doc->getReprDoc(); + Inkscape::XML::Node *mark_repr = object->getRepr()->duplicate(xml_doc); + defs->getRepr()->addChild(mark_repr, NULL); + mark_repr->setAttribute("inkscape:stockid", object->getId()); + object = doc->getObjectByRepr(mark_repr); + Inkscape::GC::release(mark_repr); + } + return object; } } === modified file 'src/helper/stock-items.h' --- src/helper/stock-items.h 2011-12-08 11:53:54 +0000 +++ src/helper/stock-items.h 2012-08-05 07:29:31 +0000 @@ -17,6 +17,6 @@ class SPObject; -SPObject *get_stock_item(gchar const *urn); +SPObject *get_stock_item(gchar const *urn, gboolean alwaysfork=FALSE); #endif // SEEN_INK_STOCK_ITEMS_H === modified file 'src/widgets/stroke-marker-selector.cpp' --- src/widgets/stroke-marker-selector.cpp 2012-08-04 02:35:13 +0000 +++ src/widgets/stroke-marker-selector.cpp 2012-08-05 09:07:54 +0000 @@ -238,7 +238,10 @@ { markurn = g_strdup(markid); } - SPObject *mark = get_stock_item(markurn); + SPObject *mark = get_stock_item(markurn, TRUE); + if (!mark) { + mark = get_stock_item(markurn); + } g_free(markurn); if (mark) { Inkscape::XML::Node *repr = mark->getRepr(); @@ -253,7 +256,16 @@ void MarkerComboBox::set_active_history() { - set_selected(get_active()->get_value(marker_columns.marker)); + + const gchar *markid = get_active()->get_value(marker_columns.marker); + + // If forked from a stockid, add the stockid + SPObject const *marker = doc->getObjectById(markid); + if (marker && marker->getRepr()->attribute("inkscape:stockid")) { + markid = marker->getRepr()->attribute("inkscape:stockid"); + } + + set_selected(markid); } @@ -384,10 +396,10 @@ for (; marker_list != NULL; marker_list = marker_list->next) { Inkscape::XML::Node *repr = reinterpret_cast(marker_list->data)->getRepr(); - gchar const *markid = repr->attribute("id"); + gchar const *markid = repr->attribute("inkscape:stockid") ? repr->attribute("inkscape:stockid") : repr->attribute("id"); // generate preview - Gtk::Image *prv = create_marker_image (22, markid, source, drawing, visionkey); + Gtk::Image *prv = create_marker_image (22, repr->attribute("id"), source, drawing, visionkey); prv->show(); // Add history before separator, others after @@ -398,6 +410,8 @@ row = *(marker_store->append()); row[marker_columns.label] = gr_ellipsize_text(markid, 20); + // Non "stock" markers can also have "inkscape:stockid" (when using extension ColorMarkers), + // So use !is_history instead to determine is it is "stock" (ie in the markers.svg file) row[marker_columns.stock] = !history; row[marker_columns.marker] = g_strdup(markid); row[marker_columns.image] = prv; === modified file 'src/widgets/stroke-style.cpp' --- src/widgets/stroke-style.cpp 2012-08-04 02:20:42 +0000 +++ src/widgets/stroke-style.cpp 2012-08-05 09:22:29 +0000 @@ -331,7 +331,6 @@ tb->show(); tb->set_mode(false); hb->pack_start(*tb, false, false, 0); - // TODO set_data(icon, tb); tb->set_data(key, (gpointer*)data); @@ -367,6 +366,7 @@ /* Get Marker */ gchar const *marker = marker_combo->get_active_marker_uri(); + SPCSSAttr *css = sp_repr_css_attr_new(); gchar const *combo_id = marker_combo->get_id(); sp_repr_css_set_property(css, combo_id, marker); @@ -386,7 +386,9 @@ Inkscape::XML::Node *selrepr = item->getRepr(); if (selrepr) { sp_repr_css_change_recursive(selrepr, css, "style"); + spw->setMarkerColor(item, spw->getMarkerObj(marker, document)); } + item->requestModified(SP_OBJECT_MODIFIED_FLAG); item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); } @@ -519,6 +521,67 @@ } /** + * Change the color of the marker to match the color of the line. + * Marker stroke color is set to line stroke color. + * Fill color : + * 1. If the line has fill, use that for the marker fill, + * 2. If the marker has no fill and no stroke assume its solid. use line stroke for both fill and stroke the line stroke + * 3. If the marker has fill color, use the marker fill color + * + */ +void +StrokeStyle::setMarkerColor(SPItem *line, SPObject *marker) +{ + + if (!marker) { + return; + } + + Inkscape::XML::Node *repr = marker->getRepr()->firstChild(); + if (repr) { + + // Current line style + SPCSSAttr *css_item = sp_css_attr_from_object(line, SP_STYLE_FLAG_ALWAYS); + const char *lstroke = sp_repr_css_property(css_item, "stroke", "none"); + const char *lstroke_opacity = sp_repr_css_property(css_item, "stroke-opacity", "1"); + const char *lfill = sp_repr_css_property(css_item, "fill", "none"); + const char *lfill_opacity = sp_repr_css_property(css_item, "fill-opacity", "1"); + + // Current marker style + SPCSSAttr *css_marker = sp_css_attr_from_object(marker->firstChild(), SP_STYLE_FLAG_ALWAYS); + const char *mfill = sp_repr_css_property(css_marker, "fill", "none"); + const char *mstroke = sp_repr_css_property(css_marker, "fill", "none"); + + // Create new marker style with the lines stroke + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_set_property(css, "stroke", lstroke); + sp_repr_css_set_property(css, "stroke-opacity", lstroke_opacity); + + if (strcmp(lfill, "none") ) { + // 1. If the line has fill, use that for the marker fill + sp_repr_css_set_property(css, "fill", lfill); + sp_repr_css_set_property(css, "fill-opacity", lfill_opacity); + } + else { + // FIXME : Can we get none instead of #000000 here ? + if (!strcmp(mfill, "#000000") && !strcmp(mstroke, "#000000")) { + // 2. If the marker has no fill and no stroke assume its solid. use line stroke for both fill and stroke the line stroke + sp_repr_css_set_property(css, "fill", lstroke); + sp_repr_css_set_property(css, "fill-opacity", lstroke_opacity); + } + } + + sp_repr_css_change_recursive(repr, css, "style"); + // privates are garbage-collectable + repr->setAttribute("inkscape:collect", "always"); + } + + marker->requestModified(SP_OBJECT_MODIFIED_FLAG); + marker->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); + +} + +/** * Sets selector widgets' dash style from an SPStyle object. */ void @@ -602,7 +665,6 @@ Inkscape::Selection *sel = desktop ? sp_desktop_selection(desktop) : NULL; - // TODO FillOrStroke kind = GPOINTER_TO_INT(get_data("kind")) ? FILL : STROKE; // create temporary style @@ -882,7 +944,6 @@ if (tb->get_active()) { - // TODO gchar const *join = static_cast(tb->get_data("join")); gchar const *cap @@ -988,7 +1049,7 @@ // If the object has this type of markers, // Extract the name of the marker that the object uses - SPObject *marker = getMarkerName(object->style->marker[keyloc[i].loc].value, object->document); + SPObject *marker = getMarkerObj(object->style->marker[keyloc[i].loc].value, object->document); // Scroll the combobox to that marker combo->set_current(marker); @@ -1007,7 +1068,7 @@ * the caller should free the buffer when they no longer need it. */ SPObject* -StrokeStyle::getMarkerName(gchar const *n, SPDocument *doc) +StrokeStyle::getMarkerObj(gchar const *n, SPDocument *doc) { gchar const *p = n; while (*p != '\0' && *p != '#') { === modified file 'src/widgets/stroke-style.h' --- src/widgets/stroke-style.h 2012-08-04 01:55:39 +0000 +++ src/widgets/stroke-style.h 2012-08-05 09:19:36 +0000 @@ -92,7 +92,7 @@ private: - SPObject *getMarkerName(gchar const *n, SPDocument *doc); + SPObject *getMarkerObj(gchar const *n, SPDocument *doc); void updateLine(); void updateAllMarkers(GSList const *objects); void updateMarkerHist(SPMarkerLoc const which); @@ -103,6 +103,8 @@ void setCapButtons(Gtk::ToggleButton *active); void scaleLine(); void setScaledDash(SPCSSAttr *css, int ndash, double *dash, double offset, double scale); + void setMarkerColor(SPItem *item, SPObject *marker); + Gtk::RadioButton * makeRadioButton(Gtk::RadioButton *tb, char const *icon, Gtk::HBox *hb, gchar const *key, gchar const *data); static gboolean setStrokeWidthUnit(SPUnitSelector *,