diff --git a/src/ui/toolbar/text-toolbar.cpp b/src/ui/toolbar/text-toolbar.cpp index 6aa053527925a2ea4768bae5edb24337a5080f37..db768a142d012fb3d67eeec50e4db21be531308d 100644 --- a/src/ui/toolbar/text-toolbar.cpp +++ b/src/ui/toolbar/text-toolbar.cpp @@ -1248,332 +1248,336 @@ TextToolbar::direction_changed(int mode) void TextToolbar::lineheight_value_changed() { - // quit if run by the _changed callbacks - if (_freeze) { - return; - } - _freeze = true; - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - // Get user selected unit and save as preference - Unit const *unit = _tracker->getActiveUnit(); - // @Tav same disabled unit - g_return_if_fail(unit != nullptr); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + if (SP_IS_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context)) { + // quit if run by the _changed callbacks + if (_freeze) { + return; + } + _freeze = true; + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + // Get user selected unit and save as preference + Unit const *unit = _tracker->getActiveUnit(); + // @Tav same disabled unit + g_return_if_fail(unit != nullptr); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - // This nonsense is to get SP_CSS_UNIT_xx value corresponding to unit so - // we can save it (allows us to adjust line height value when unit changes). + // This nonsense is to get SP_CSS_UNIT_xx value corresponding to unit so + // we can save it (allows us to adjust line height value when unit changes). - // Set css line height. - SPCSSAttr *css = sp_repr_css_attr_new (); - Inkscape::CSSOStringStream osfs; - if ( is_relative(unit) ) { - osfs << _line_height_adj->get_value() << unit->abbr; - } else { - // Inside SVG file, always use "px" for absolute units. - osfs << Quantity::convert(_line_height_adj->get_value(), unit, "px") << "px"; - } - sp_repr_css_set_property (css, "line-height", osfs.str().c_str()); - Inkscape::Selection *selection = desktop->getSelection(); - auto itemlist = selection->items(); - if (_outer) { - for (auto i = itemlist.begin(); i != itemlist.end(); ++i) { - if (dynamic_cast(*i) || dynamic_cast(*i)) { - SPItem *item = *i; - // Scale by inverse of accumulated parent transform - SPCSSAttr *css_set = sp_repr_css_attr_new(); - sp_repr_css_merge(css_set, css); - Geom::Affine const local(item->i2doc_affine()); - double const ex(local.descrim()); - if ((ex != 0.0) && (ex != 1.0)) { - sp_css_attr_scale(css_set, 1 / ex); + // Set css line height. + SPCSSAttr *css = sp_repr_css_attr_new (); + Inkscape::CSSOStringStream osfs; + if ( is_relative(unit) ) { + osfs << _line_height_adj->get_value() << unit->abbr; + } else { + // Inside SVG file, always use "px" for absolute units. + osfs << Quantity::convert(_line_height_adj->get_value(), unit, "px") << "px"; + } + sp_repr_css_set_property (css, "line-height", osfs.str().c_str()); + Inkscape::Selection *selection = desktop->getSelection(); + auto itemlist = selection->items(); + if (_outer) { + for (auto i = itemlist.begin(); i != itemlist.end(); ++i) { + if (dynamic_cast(*i) || dynamic_cast(*i)) { + SPItem *item = *i; + // Scale by inverse of accumulated parent transform + SPCSSAttr *css_set = sp_repr_css_attr_new(); + sp_repr_css_merge(css_set, css); + Geom::Affine const local(item->i2doc_affine()); + double const ex(local.descrim()); + if ((ex != 0.0) && (ex != 1.0)) { + sp_css_attr_scale(css_set, 1 / ex); + } + recursively_set_properties(item, css_set); + sp_repr_css_attr_unref(css_set); } - recursively_set_properties(item, css_set); - sp_repr_css_attr_unref(css_set); } - } - } else { - SPItem *parent = dynamic_cast(*itemlist.begin()); - SPStyle *parent_style = parent->style; - SPCSSAttr *parent_cssatr = sp_css_attr_from_style(parent_style, SP_STYLE_FLAG_IFSET); - Glib::ustring parent_lineheight = sp_repr_css_property(parent_cssatr, "line-height", "1.25"); - SPCSSAttr *cssfit = sp_repr_css_attr_new(); - sp_repr_css_set_property(cssfit, "line-height", parent_lineheight.c_str()); - double minheight = 0; - if (parent_style) { - minheight = parent_style->line_height.computed; - } - if (minheight) { - for (auto i : parent->childList(false)) { - SPItem *child = dynamic_cast(i); - if (!child) { - continue; + } else { + SPItem *parent = dynamic_cast(*itemlist.begin()); + SPStyle *parent_style = parent->style; + SPCSSAttr *parent_cssatr = sp_css_attr_from_style(parent_style, SP_STYLE_FLAG_IFSET); + Glib::ustring parent_lineheight = sp_repr_css_property(parent_cssatr, "line-height", "1.25"); + SPCSSAttr *cssfit = sp_repr_css_attr_new(); + sp_repr_css_set_property(cssfit, "line-height", parent_lineheight.c_str()); + double minheight = 0; + if (parent_style) { + minheight = parent_style->line_height.computed; + } + if (minheight) { + for (auto i : parent->childList(false)) { + SPItem *child = dynamic_cast(i); + if (!child) { + continue; + } + recursively_set_properties(child, cssfit); } - recursively_set_properties(child, cssfit); } + sp_repr_css_set_property(cssfit, "line-height", "0"); + parent->changeCSS(cssfit, "style"); + subselection_wrap_toggle(true); + sp_desktop_set_style(desktop, css, true, true); + subselection_wrap_toggle(false); + sp_repr_css_attr_unref(cssfit); } - sp_repr_css_set_property(cssfit, "line-height", "0"); - parent->changeCSS(cssfit, "style"); - subselection_wrap_toggle(true); - sp_desktop_set_style(desktop, css, true, true); - subselection_wrap_toggle(false); - sp_repr_css_attr_unref(cssfit); - } - // Only need to save for undo if a text item has been changed. - itemlist= selection->items(); - bool modmade = false; - for (auto i : itemlist) { - SPText *text = dynamic_cast(i); - SPFlowtext *flowtext = dynamic_cast(i); - if (text || flowtext) { - modmade = true; - break; - } - } - - // Save for undo - if (modmade) { - // Call ensureUpToDate() causes rebuild of text layout (with all proper style - // cascading, etc.). For multi-line text with sodipodi::role="line", we must explicitly - // save new 'x' and 'y' attribute values by calling updateRepr(). - // Partial fix for bug #1590141. - - desktop->getDocument()->ensureUpToDate(); + // Only need to save for undo if a text item has been changed. + itemlist= selection->items(); + bool modmade = false; for (auto i : itemlist) { SPText *text = dynamic_cast(i); SPFlowtext *flowtext = dynamic_cast(i); if (text || flowtext) { - (i)->updateRepr(); + modmade = true; + break; } } - if (!_outer) { - prepare_inner(); + + // Save for undo + if (modmade) { + // Call ensureUpToDate() causes rebuild of text layout (with all proper style + // cascading, etc.). For multi-line text with sodipodi::role="line", we must explicitly + // save new 'x' and 'y' attribute values by calling updateRepr(). + // Partial fix for bug #1590141. + + desktop->getDocument()->ensureUpToDate(); + for (auto i : itemlist) { + SPText *text = dynamic_cast(i); + SPFlowtext *flowtext = dynamic_cast(i); + if (text || flowtext) { + (i)->updateRepr(); + } + } + if (!_outer) { + prepare_inner(); + } + DocumentUndo::maybeDone(desktop->getDocument(), "ttb:line-height", SP_VERB_NONE, _("Text: Change line-height")); } - DocumentUndo::maybeDone(desktop->getDocument(), "ttb:line-height", SP_VERB_NONE, _("Text: Change line-height")); - } - // If no selected objects, set default. - SPStyle query(SP_ACTIVE_DOCUMENT); - int result_numbers = sp_desktop_query_style(desktop, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); - if (result_numbers == QUERY_STYLE_NOTHING) - { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->mergeStyle("/tools/text/style", css); - } + // If no selected objects, set default. + SPStyle query(SP_ACTIVE_DOCUMENT); + int result_numbers = sp_desktop_query_style(desktop, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + if (result_numbers == QUERY_STYLE_NOTHING) + { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->mergeStyle("/tools/text/style", css); + } - sp_repr_css_attr_unref (css); + sp_repr_css_attr_unref (css); - _freeze = false; + _freeze = false; + } } void TextToolbar::lineheight_unit_changed(int /* Not Used */) { - // quit if run by the _changed callbacks - if (_freeze) { - return; - } - _freeze = true; + if (SP_IS_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context)) { + // quit if run by the _changed callbacks + if (_freeze) { + return; + } + _freeze = true; - // Get old saved unit - int old_unit = _lineheight_unit; + // Get old saved unit + int old_unit = _lineheight_unit; - // Get user selected unit and save as preference - Unit const *unit = _tracker->getActiveUnit(); - g_return_if_fail(unit != nullptr); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + // Get user selected unit and save as preference + Unit const *unit = _tracker->getActiveUnit(); + g_return_if_fail(unit != nullptr); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - // This nonsense is to get SP_CSS_UNIT_xx value corresponding to unit. - SPILength temp_length; - Inkscape::CSSOStringStream temp_stream; - temp_stream << 1 << unit->abbr; - temp_length.read(temp_stream.str().c_str()); - prefs->setInt("/tools/text/lineheight/display_unit", temp_length.unit); - if (old_unit == temp_length.unit) { - _freeze = false; - return; - } + // This nonsense is to get SP_CSS_UNIT_xx value corresponding to unit. + SPILength temp_length; + Inkscape::CSSOStringStream temp_stream; + temp_stream << 1 << unit->abbr; + temp_length.read(temp_stream.str().c_str()); + prefs->setInt("/tools/text/lineheight/display_unit", temp_length.unit); + if (old_unit == temp_length.unit) { + _freeze = false; + return; + } - // Read current line height value - double line_height = _line_height_adj->get_value(); - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - Inkscape::Selection *selection = desktop->getSelection(); - auto itemlist = selection->items(); + // Read current line height value + double line_height = _line_height_adj->get_value(); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + Inkscape::Selection *selection = desktop->getSelection(); + auto itemlist = selection->items(); - // Convert between units - double font_size = 0; - double doc_scale = 1; - int count = 0; - bool has_flow = false; + // Convert between units + double font_size = 0; + double doc_scale = 1; + int count = 0; + bool has_flow = false; - for (auto i : itemlist) { - SPText *text = dynamic_cast(i); - SPFlowtext *flowtext = dynamic_cast(i); - if (text || flowtext) { - doc_scale = Geom::Affine(i->i2dt_affine()).descrim(); - font_size += i->style->font_size.computed * doc_scale; - ++count; - } - if (flowtext) { - has_flow = true; + for (auto i : itemlist) { + SPText *text = dynamic_cast(i); + SPFlowtext *flowtext = dynamic_cast(i); + if (text || flowtext) { + doc_scale = Geom::Affine(i->i2dt_affine()).descrim(); + font_size += i->style->font_size.computed * doc_scale; + ++count; + } + if (flowtext) { + has_flow = true; + } } - } - if (count > 0) { - font_size /= count; - } else { - font_size = 20; - } - if ((unit->abbr == "" || unit->abbr == "em") && (old_unit == SP_CSS_UNIT_NONE || old_unit == SP_CSS_UNIT_EM)) { - // Do nothing - } else if ((unit->abbr == "" || unit->abbr == "em") && old_unit == SP_CSS_UNIT_EX) { - line_height *= 0.5; - } else if ((unit->abbr) == "ex" && (old_unit == SP_CSS_UNIT_EM || old_unit == SP_CSS_UNIT_NONE)) { - line_height *= 2.0; - } else if ((unit->abbr == "" || unit->abbr == "em") && old_unit == SP_CSS_UNIT_PERCENT) { - line_height /= 100.0; - } else if ((unit->abbr) == "%" && (old_unit == SP_CSS_UNIT_EM || old_unit == SP_CSS_UNIT_NONE)) { - line_height *= 100; - } else if ((unit->abbr) == "ex" && old_unit == SP_CSS_UNIT_PERCENT) { - line_height /= 50.0; - } else if ((unit->abbr) == "%" && old_unit == SP_CSS_UNIT_EX) { - line_height *= 50; - } else if (is_relative(unit)) { - // Convert absolute to relative... for the moment use average font-size - if (old_unit == SP_CSS_UNIT_NONE) old_unit = SP_CSS_UNIT_EM; - line_height = Quantity::convert(line_height, sp_style_get_css_unit_string(old_unit), "px"); - - if (font_size > 0) { - line_height /= font_size; + if (count > 0) { + font_size /= count; + } else { + font_size = 20; } - if ((unit->abbr) == "%") { + if ((unit->abbr == "" || unit->abbr == "em") && (old_unit == SP_CSS_UNIT_NONE || old_unit == SP_CSS_UNIT_EM)) { + // Do nothing + } else if ((unit->abbr == "" || unit->abbr == "em") && old_unit == SP_CSS_UNIT_EX) { + line_height *= 0.5; + } else if ((unit->abbr) == "ex" && (old_unit == SP_CSS_UNIT_EM || old_unit == SP_CSS_UNIT_NONE)) { + line_height *= 2.0; + } else if ((unit->abbr == "" || unit->abbr == "em") && old_unit == SP_CSS_UNIT_PERCENT) { + line_height /= 100.0; + } else if ((unit->abbr) == "%" && (old_unit == SP_CSS_UNIT_EM || old_unit == SP_CSS_UNIT_NONE)) { line_height *= 100; - } else if ((unit->abbr) == "ex") { - line_height *= 2; + } else if ((unit->abbr) == "ex" && old_unit == SP_CSS_UNIT_PERCENT) { + line_height /= 50.0; + } else if ((unit->abbr) == "%" && old_unit == SP_CSS_UNIT_EX) { + line_height *= 50; + } else if (is_relative(unit)) { + // Convert absolute to relative... for the moment use average font-size + if (old_unit == SP_CSS_UNIT_NONE) old_unit = SP_CSS_UNIT_EM; + line_height = Quantity::convert(line_height, sp_style_get_css_unit_string(old_unit), "px"); + + if (font_size > 0) { + line_height /= font_size; + } + if ((unit->abbr) == "%") { + line_height *= 100; + } else if ((unit->abbr) == "ex") { + line_height *= 2; + } + } else if (old_unit == SP_CSS_UNIT_NONE || old_unit == SP_CSS_UNIT_PERCENT || old_unit == SP_CSS_UNIT_EM || + old_unit == SP_CSS_UNIT_EX) { + // Convert relative to absolute... for the moment use average font-size + if (old_unit == SP_CSS_UNIT_PERCENT) { + line_height /= 100.0; + } else if (old_unit == SP_CSS_UNIT_EX) { + line_height /= 2.0; + } + line_height *= font_size; + line_height = Quantity::convert(line_height, "px", unit); + } else { + // Convert between different absolute units (only used in GUI) + line_height = Quantity::convert(line_height, sp_style_get_css_unit_string(old_unit), unit); } - } else if (old_unit == SP_CSS_UNIT_NONE || old_unit == SP_CSS_UNIT_PERCENT || old_unit == SP_CSS_UNIT_EM || - old_unit == SP_CSS_UNIT_EX) { - // Convert relative to absolute... for the moment use average font-size - if (old_unit == SP_CSS_UNIT_PERCENT) { - line_height /= 100.0; - } else if (old_unit == SP_CSS_UNIT_EX) { - line_height /= 2.0; + // Set css line height. + SPCSSAttr *css = sp_repr_css_attr_new (); + Inkscape::CSSOStringStream osfs; + // Set css line height. + if ( is_relative(unit) ) { + osfs << line_height << unit->abbr; + } else { + osfs << Quantity::convert(line_height, unit, "px") << "px"; } - line_height *= font_size; - line_height = Quantity::convert(line_height, "px", unit); - } else { - // Convert between different absolute units (only used in GUI) - line_height = Quantity::convert(line_height, sp_style_get_css_unit_string(old_unit), unit); - } - // Set css line height. - SPCSSAttr *css = sp_repr_css_attr_new (); - Inkscape::CSSOStringStream osfs; - // Set css line height. - if ( is_relative(unit) ) { - osfs << line_height << unit->abbr; - } else { - osfs << Quantity::convert(line_height, unit, "px") << "px"; - } - sp_repr_css_set_property (css, "line-height", osfs.str().c_str()); + sp_repr_css_set_property (css, "line-height", osfs.str().c_str()); - // Update GUI with line_height value. - _line_height_adj->set_value(line_height); - // Update "climb rate" The custom action has a step property but no way to set it. - if (unit->abbr == "%") { - _line_height_adj->set_step_increment(1.0); - _line_height_adj->set_page_increment(10.0); - } else { - _line_height_adj->set_step_increment(0.1); - _line_height_adj->set_page_increment(1.0); - } - // Internal function to set line-height which is spacing mode dependent. - if (_outer) { - for (auto i = itemlist.begin(); i != itemlist.end(); ++i) { - if (dynamic_cast(*i) || dynamic_cast(*i)) { - SPItem *item = *i; - // Scale by inverse of accumulated parent transform - SPCSSAttr *css_set = sp_repr_css_attr_new(); - sp_repr_css_merge(css_set, css); - Geom::Affine const local(item->i2doc_affine()); - double const ex(local.descrim()); - if ((ex != 0.0) && (ex != 1.0)) { - sp_css_attr_scale(css_set, 1 / ex); + // Update GUI with line_height value. + _line_height_adj->set_value(line_height); + // Update "climb rate" The custom action has a step property but no way to set it. + if (unit->abbr == "%") { + _line_height_adj->set_step_increment(1.0); + _line_height_adj->set_page_increment(10.0); + } else { + _line_height_adj->set_step_increment(0.1); + _line_height_adj->set_page_increment(1.0); + } + // Internal function to set line-height which is spacing mode dependent. + if (_outer) { + for (auto i = itemlist.begin(); i != itemlist.end(); ++i) { + if (dynamic_cast(*i) || dynamic_cast(*i)) { + SPItem *item = *i; + // Scale by inverse of accumulated parent transform + SPCSSAttr *css_set = sp_repr_css_attr_new(); + sp_repr_css_merge(css_set, css); + Geom::Affine const local(item->i2doc_affine()); + double const ex(local.descrim()); + if ((ex != 0.0) && (ex != 1.0)) { + sp_css_attr_scale(css_set, 1 / ex); + } + recursively_set_properties(item, css_set); + sp_repr_css_attr_unref(css_set); } - recursively_set_properties(item, css_set); - sp_repr_css_attr_unref(css_set); } - } - } else { - SPItem *parent = dynamic_cast(*itemlist.begin()); - SPStyle *parent_style = parent->style; - SPCSSAttr *parent_cssatr = sp_css_attr_from_style(parent_style, SP_STYLE_FLAG_IFSET); - Glib::ustring parent_lineheight = sp_repr_css_property(parent_cssatr, "line-height", "1.25"); - SPCSSAttr *cssfit = sp_repr_css_attr_new(); - sp_repr_css_set_property(cssfit, "line-height", parent_lineheight.c_str()); - double minheight = 0; - if (parent_style) { - minheight = parent_style->line_height.computed; - } - if (minheight) { - for (auto i : parent->childList(false)) { - SPItem *child = dynamic_cast(i); - if (!child) { - continue; + } else { + SPItem *parent = dynamic_cast(*itemlist.begin()); + SPStyle *parent_style = parent->style; + SPCSSAttr *parent_cssatr = sp_css_attr_from_style(parent_style, SP_STYLE_FLAG_IFSET); + Glib::ustring parent_lineheight = sp_repr_css_property(parent_cssatr, "line-height", "1.25"); + SPCSSAttr *cssfit = sp_repr_css_attr_new(); + sp_repr_css_set_property(cssfit, "line-height", parent_lineheight.c_str()); + double minheight = 0; + if (parent_style) { + minheight = parent_style->line_height.computed; + } + if (minheight) { + for (auto i : parent->childList(false)) { + SPItem *child = dynamic_cast(i); + if (!child) { + continue; + } + recursively_set_properties(child, cssfit); } - recursively_set_properties(child, cssfit); } + sp_repr_css_set_property(cssfit, "line-height", "0"); + parent->changeCSS(cssfit, "style"); + subselection_wrap_toggle(true); + sp_desktop_set_style(desktop, css, true, true); + subselection_wrap_toggle(false); + sp_repr_css_attr_unref(cssfit); } - sp_repr_css_set_property(cssfit, "line-height", "0"); - parent->changeCSS(cssfit, "style"); - subselection_wrap_toggle(true); - sp_desktop_set_style(desktop, css, true, true); - subselection_wrap_toggle(false); - sp_repr_css_attr_unref(cssfit); - } - itemlist= selection->items(); - // Only need to save for undo if a text item has been changed. - bool modmade = false; - for (auto i : itemlist) { - SPText *text = dynamic_cast(i); - SPFlowtext *flowtext = dynamic_cast(i); - if (text || flowtext) { - modmade = true; - break; - } - } - // Save for undo - if(modmade) { - // Call ensureUpToDate() causes rebuild of text layout (with all proper style - // cascading, etc.). For multi-line text with sodipodi::role="line", we must explicitly - // save new 'x' and 'y' attribute values by calling updateRepr(). - // Partial fix for bug #1590141. - - desktop->getDocument()->ensureUpToDate(); + itemlist= selection->items(); + // Only need to save for undo if a text item has been changed. + bool modmade = false; for (auto i : itemlist) { SPText *text = dynamic_cast(i); SPFlowtext *flowtext = dynamic_cast(i); if (text || flowtext) { - (i)->updateRepr(); + modmade = true; + break; } } - if (_outer) { - prepare_inner(); + // Save for undo + if(modmade) { + // Call ensureUpToDate() causes rebuild of text layout (with all proper style + // cascading, etc.). For multi-line text with sodipodi::role="line", we must explicitly + // save new 'x' and 'y' attribute values by calling updateRepr(). + // Partial fix for bug #1590141. + + desktop->getDocument()->ensureUpToDate(); + for (auto i : itemlist) { + SPText *text = dynamic_cast(i); + SPFlowtext *flowtext = dynamic_cast(i); + if (text || flowtext) { + (i)->updateRepr(); + } + } + if (_outer) { + prepare_inner(); + } + DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:line-height", SP_VERB_NONE, + _("Text: Change line-height unit")); } - DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:line-height", SP_VERB_NONE, - _("Text: Change line-height unit")); - } - // If no selected objects, set default. - SPStyle query(SP_ACTIVE_DOCUMENT); - int result_numbers = - sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); - if (result_numbers == QUERY_STYLE_NOTHING) - { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->mergeStyle("/tools/text/style", css); - } + // If no selected objects, set default. + SPStyle query(SP_ACTIVE_DOCUMENT); + int result_numbers = + sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + if (result_numbers == QUERY_STYLE_NOTHING) + { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->mergeStyle("/tools/text/style", css); + } - sp_repr_css_attr_unref (css); + sp_repr_css_attr_unref (css); - _freeze = false; + _freeze = false; + } } void TextToolbar::fontsize_unit_changed(int /* Not Used */)