summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJabier Arraiza <jabier.arraiza@marker.es>2019-08-17 00:16:31 +0000
committerJabier Arraiza <jabier.arraiza@marker.es>2019-09-07 21:48:33 +0000
commit9055a9ebe90df5db1262ad777f08da2efa9753ce (patch)
treeac4175b93aa0125ef31ddf015c26dca3409d7846
parentAdd scrolled window to XMLDialog and CSS dialog to avoid auto growing when ad... (diff)
downloadinkscape-9055a9ebe90df5db1262ad777f08da2efa9753ce.tar.gz
inkscape-9055a9ebe90df5db1262ad777f08da2efa9753ce.zip
Add line height UX improvements
-rw-r--r--share/icons/hicolor/symbolic/actions/text_outer_style-symbolic.svg89
-rw-r--r--src/ui/dialog/inkscape-preferences.cpp3
-rw-r--r--src/ui/dialog/text-edit.cpp20
-rw-r--r--src/ui/dialog/text-edit.h1
-rw-r--r--src/ui/toolbar/text-toolbar.cpp1057
-rw-r--r--src/ui/toolbar/text-toolbar.h44
-rw-r--r--src/ui/tools/text-tool.cpp130
-rw-r--r--src/ui/tools/text-tool.h1
-rw-r--r--src/ui/widget/unit-tracker.cpp6
-rw-r--r--src/ui/widget/unit-tracker.h1
10 files changed, 653 insertions, 699 deletions
diff --git a/share/icons/hicolor/symbolic/actions/text_outer_style-symbolic.svg b/share/icons/hicolor/symbolic/actions/text_outer_style-symbolic.svg
index 675007e8e..3f095d41f 100644
--- a/share/icons/hicolor/symbolic/actions/text_outer_style-symbolic.svg
+++ b/share/icons/hicolor/symbolic/actions/text_outer_style-symbolic.svg
@@ -1,41 +1,78 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://web.resource.org/cc/"
+ xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="svg1"
width="28"
height="28"
- >
+ version="1.1"
+ sodipodi:docname="text_outer_style-symbolic.svg"
+ inkscape:version="1.0alpha2 (7029881c03, 2019-06-24, custom)">
+ <metadata
+ id="metadata94">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
<sodipodi:namedview
id="base"
showgrid="true"
- gridspacingy="1pt"
- gridspacingx="1pt"
- gridoriginy="0pt"
- gridoriginx="0pt"
- />
- <defs id="defs3">
-
- </defs>
-<g id="text_outer_style" transform="translate(0,0)">
- <rect height="28" id="text_outer_style_rect" style="fill:none" width="28" x="0" y="0"/>
- <g aria-label="T" style="font-weight:bold;font-size:20px;font-family:sans-serif;text-anchor:middle;fill:#4d4d4d;stroke:#000000;stroke-width:0.75">
- <path d="m 2.28125,2.4199219 h 13.4375 V 5.2617187 H 10.884766 V 17 H 7.125 V 5.2617187 H 2.28125 Z" id="BigT"/>
+ inkscape:document-rotation="0"
+ inkscape:zoom="5.6"
+ inkscape:cx="7.046511"
+ inkscape:cy="44.985506"
+ inkscape:window-width="1360"
+ inkscape:window-height="704"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg1">
+ <inkscape:grid
+ id="GridFromPre046Settings"
+ type="xygrid"
+ originx="0pt"
+ originy="0pt"
+ spacingx="1pt"
+ spacingy="1pt"
+ color="#3f3fff"
+ empcolor="#3f3fff"
+ opacity="0.15"
+ empopacity="0.38"
+ empspacing="5" />
+ </sodipodi:namedview>
+ <defs
+ id="defs3" />
+ <g
+ id="text_outer_style"
+ transform="translate(0,0)">
+ <rect
+ height="28"
+ id="text_outer_style_rect"
+ style="opacity:0"
+ width="28"
+ x="0"
+ y="0" />
+ <g
+ aria-label="T"
+ style="font-weight:bold;font-size:20px;font-family:sans-serif;text-anchor:middle;fill:#4d4d4d;stroke:#000000;stroke-width:0.75"
+ id="g82" />
+ <g
+ aria-label="T"
+ style="font-weight:bold;font-size:12px;font-family:sans-serif;text-anchor:middle;fill:#4d4d4d;stroke:#000000;stroke-width:0.75"
+ id="g85" />
+ <path
+ id="path921"
+ d="M 20,1.25 A 0.75,0.75 0 0 0 19.25,2 0.75,0.75 0 0 0 20,2.75 h 5.25 v 22.5 H 2.75 V 10 A 0.75,0.75 0 0 0 2,9.25 0.75,0.75 0 0 0 1.25,10 V 26 A 0.750075,0.750075 0 0 0 2,26.75 H 26 A 0.750075,0.750075 0 0 0 26.75,26 V 2 A 0.750075,0.750075 0 0 0 26,1.25 Z m -6.03125,12.001953 h 8.0625 v 1.705078 H 19.130859 V 22 H 16.875 V 14.957031 H 13.96875 Z M 2.28125,2.4199219 h 13.4375 V 5.2617187 H 10.884766 V 17 H 7.125 V 5.2617187 H 2.28125 Z" />
</g>
- <g aria-label="T" style="font-weight:bold;font-size:12px;font-family:sans-serif;text-anchor:middle;fill:#4d4d4d;stroke:#000000;stroke-width:0.75">
- <path d="m 13.96875,13.251953 h 8.0625 v 1.705078 H 19.130859 V 22 H 16.875 v -7.042969 h -2.90625 z" id="LittleT"/>
- </g>
- <path d="m 20,2 h 6 V 26 H 2 V 10" id="text_outer_style_path1" style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round"/>
- <path d="M 3,3 H 15" id="text_outer_style_path2" style="fill:none;stroke:#999999;stroke-width:0.75;stroke-linecap:round"/>
- <path d="M 7.8,5.5 V 16.25" id="text_outer_style_path3" style="fill:none;stroke:#999999;stroke-width:0.75;stroke-linecap:round"/>
- <path d="m 14.6,13.75 h 6.8" id="text_outer_style_path4" style="fill:#4d4d4d;stroke:#999999;stroke-width:0.5;stroke-linecap:round"/>
- <path d="m 17.5,14.85 v 6.5" id="text_outer_style_path5" style="fill:#4d4d4d;stroke:#999999;stroke-width:0.5;stroke-linecap:round"/>
-</g>
-
</svg>
diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp
index d8db99f4e..1288b6453 100644
--- a/src/ui/dialog/inkscape-preferences.cpp
+++ b/src/ui/dialog/inkscape-preferences.cpp
@@ -486,9 +486,6 @@ void InkscapePreferences::initPageTools()
int sizeValues[] = {SP_CSS_UNIT_PX, SP_CSS_UNIT_PT, SP_CSS_UNIT_PC, SP_CSS_UNIT_MM, SP_CSS_UNIT_CM, SP_CSS_UNIT_IN, SP_CSS_UNIT_EM/*, SP_CSS_UNIT_EX, SP_CSS_UNIT_PERCENT*/};
_page_text.add_group_header( _("Text units"));
- _font_unit_type.init( "/options/font/unitType", sizeLabels, sizeValues, G_N_ELEMENTS(sizeLabels), SP_CSS_UNIT_PT );
- _page_text.add_line( true, _("Text size unit type:"), _font_unit_type, "",
- _("Set the type of unit used in the text toolbar and text dialogs"), false);
_font_output_px.init ( _("Always output text size in pixels (px)"), "/options/font/textOutputPx", true);
// _page_text.add_line( false, "", _font_output_px, "", _("Always convert the text size units above into pixels (px) before saving to file"));
diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp
index fd8422652..e0faa68ed 100644
--- a/src/ui/dialog/text-edit.cpp
+++ b/src/ui/dialog/text-edit.cpp
@@ -37,6 +37,7 @@ extern "C" {
#include "document-undo.h"
#include "document.h"
#include "inkscape.h"
+#include "style.h"
#include "text-editing.h"
#include "verbs.h"
@@ -48,8 +49,8 @@ extern "C" {
#include "object/sp-textpath.h"
#include "svg/css-ostringstream.h"
-
#include "ui/icon-names.h"
+#include "ui/toolbar/text-toolbar.h"
#include "ui/widget/font-selector.h"
#include "util/units.h"
@@ -268,7 +269,7 @@ void TextEdit::onReadSelection ( gboolean dostyle, gboolean /*docontent*/ )
int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT);
double size = sp_style_css_size_px_to_units(query.font_size.computed, unit);
font_selector.update_size (size);
-
+ selected_fontsize = size;
// Update font features (variant) widget
//int result_features =
sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTVARIANTS);
@@ -422,18 +423,21 @@ void TextEdit::onApply()
unsigned items = 0;
auto item_list = desktop->getSelection()->items();
SPCSSAttr *css = fillTextStyle ();
- sp_desktop_set_style(desktop, css, true);
-
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
for(auto i=item_list.begin();i!=item_list.end();++i){
// apply style to the reprs of all text objects in the selection
if (SP_IS_TEXT (*i) || (SP_IS_FLOWTEXT (*i)) ) {
++items;
}
}
+ if (items == 1) {
+ double factor = font_selector.get_fontsize() / selected_fontsize;
+ prefs->setDouble("/options/font/scaleLineHeightFromFontSIze", factor);
+ }
+ sp_desktop_set_style(desktop, css, true);
if (items == 0) {
// no text objects; apply style to prefs for new objects
- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
prefs->mergeStyle("/tools/text/style", css);
setasdefault_button.set_sensitive ( false );
@@ -442,6 +446,12 @@ void TextEdit::onApply()
SPItem *item = SP_ACTIVE_DESKTOP->getSelection()->singleItem();
if (SP_IS_TEXT (item) || SP_IS_FLOWTEXT(item)) {
updateObjectText (item);
+ SPStyle *item_style = item->style;
+ if (SP_IS_TEXT(item) && item_style->inline_size.value == 0) {
+ css = sp_css_attr_from_style(item_style, SP_STYLE_FLAG_IFSET);
+ sp_repr_css_unset_property(css, "inline-size");
+ item->changeCSS(css, "style");
+ }
}
}
diff --git a/src/ui/dialog/text-edit.h b/src/ui/dialog/text-edit.h
index 0d09e24b5..cef6ddfea 100644
--- a/src/ui/dialog/text-edit.h
+++ b/src/ui/dialog/text-edit.h
@@ -188,6 +188,7 @@ private:
sigc::connection fontFeaturesChangedConn;
// Other
+ double selected_fontsize;
bool blocked;
const Glib::ustring samplephrase;
diff --git a/src/ui/toolbar/text-toolbar.cpp b/src/ui/toolbar/text-toolbar.cpp
index 1e7d6ffff..c2ddf29ba 100644
--- a/src/ui/toolbar/text-toolbar.cpp
+++ b/src/ui/toolbar/text-toolbar.cpp
@@ -42,6 +42,7 @@
#include "libnrtype/font-lister.h"
+#include "display/sp-canvas.h"
#include "object/sp-flowdiv.h"
#include "object/sp-flowtext.h"
#include "object/sp-root.h"
@@ -50,13 +51,14 @@
#include "style.h"
#include "svg/css-ostringstream.h"
-
#include "ui/icon-names.h"
+#include "ui/tools/select-tool.h"
#include "ui/tools/text-tool.h"
#include "ui/widget/combo-box-entry-tool-item.h"
#include "ui/widget/combo-tool-item.h"
#include "ui/widget/spin-button-tool-item.h"
#include "ui/widget/unit-tracker.h"
+#include "util/units.h"
#include "widgets/style-utils.h"
@@ -68,14 +70,27 @@ using Inkscape::UI::Widget::UnitTracker;
//#define DEBUG_TEXT
-//########################
+//########################setActiveUnitByAbbr
//## Text Toolbox ##
//########################
// Functions for debugging:
#ifdef DEBUG_TEXT
+recursively_set_properties(SP_OBJECT(*i), css_set, false);
+static void sp_print_font(SPStyle *query)
+{
+ TextTool::~TextTool()
+ {
+ delete this->shape_editor;
+ this->shape_editor = nullptr;
+
+ if (this->grabbed) {
+ sp_canvas_item_ungrab(this->grabbed);
+ this->grabbed = nullptr;
+ }
-static void sp_print_font( SPStyle *query ) {
+ Inkscape::Rubberband::get(this->desktop)->stop();
+ }
bool family_set = query->font_family.set;
bool style_set = query->font_style.set;
@@ -85,17 +100,19 @@ static void sp_print_font( SPStyle *query ) {
<< " Style set? " << style_set
<< " FontSpec set? " << fontspec_set
<< std::endl;
- std::cout << " Family: "
- << (query->font_family.value ? query->font_family.value : "No value")
- << " Style: " << query->font_style.computed
- << " Weight: " << query->font_weight.computed
- << " FontSpec: "
- << (query->font_specification.value ? query->font_specification.value : "No value")
- << std::endl;
- std::cout << " LineHeight: " << query->line_height.computed
- << " WordSpacing: " << query->word_spacing.computed
- << " LetterSpacing: " << query->letter_spacing.computed
- << std::endl;
+ std::cout << " Family: " << (query->font_family.value ? query->font_family.value : "No value")
+ << " Style: " << query->font_style.computed << " Weight: " << query->font_weight.computed
+ << " FontSpec: "_line_height_units_item->changeLabel("lines", 0);
+ << (query->font_specification.value ? query->font_specification.value : "No value") << std::endl;
+ std::cout << " LineHeight: "
+ << query->line_height.computedif(c_selection_changed) c_selection_changed.disconnect();
+ if (c_selection_modified)
+ c_selection_modified.disconnect();
+ if (c_subselection_changed)
+ c_subselection_changed.disconnect();
+ setActiveUnitByAbbr if (c_selection_modified_select_tool) c_selection_modified_select_tool.disconnect();
+ << " WordSpacing: " << query->word_spacing.computed << " LetterSpacing: " << query->letter_spacing.computed
+ << std::endl;
}
static void sp_print_fontweight( SPStyle *query ) {
@@ -103,7 +120,21 @@ static void sp_print_fontweight( SPStyle *query ) {
"NORMAL", "BOLD", "LIGHTER", "BOLDER", "Out of range"};
// Missing book = 380
int index = query->font_weight.computed;
- if( index < 0 || index > 13 ) index = 13;
+ if (index < 0 || index > 13)
+ index = 13;
+ TextTool::~TextTool()
+ {
+ delete this->shape_editor;
+ this->shape_editor = nullptr;
+
+ if (this->grabbed) {
+ sp_canvas_item_ungrab(this->grabbed);
+ this->grabbed = nullptr;
+ }
+
+ Inkscape::Rubberband::get(this->desktop)->stop();
+ _line_height_units_item->changeLabel("lines", 0);
+ }
std::cout << " Weight: " << names[ index ]
<< " (" << query->font_weight.computed << ")" << std::endl;
@@ -123,65 +154,26 @@ static bool is_relative( Unit const *unit ) {
return (unit->abbr == "" || unit->abbr == "em" || unit->abbr == "ex" || unit->abbr == "%");
}
+static bool is_relative(SPCSSUnit const unit)
+{
+ return (unit == SP_CSS_UNIT_NONE || unit == SP_CSS_UNIT_EM || unit == SP_CSS_UNIT_EX ||
+ unit == SP_CSS_UNIT_PERCENT);
+}
+
// Set property for object, but unset all descendents
// Should probably be moved to desktop_style.cpp
-static void recursively_set_properties( SPObject* object, SPCSSAttr *css ) {
+static void recursively_set_properties(SPObject *object, SPCSSAttr *css, bool unset_descendents = true)
+{
object->changeCSS (css, "style");
SPCSSAttr *css_unset = sp_repr_css_attr_unset_all( css );
std::vector<SPObject *> children = object->childList(false);
for (auto i: children) {
- recursively_set_properties (i, css_unset);
+ recursively_set_properties(i, unset_descendents ? css_unset : css);
}
sp_repr_css_attr_unref (css_unset);
}
-// Apply line height changes (line-height value changed or line-height unit changed)
-static void set_lineheight (SPCSSAttr *css) {
-
- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- bool outer = prefs->getInt("/tools/text/outer_style", false);
- gint mode = prefs->getInt("/tools/text/line_spacing_mode", 0);
- SPDesktop *desktop = SP_ACTIVE_DESKTOP;
-
- // Calling sp_desktop_set_style will result in a call to TextTool::_styleSet() which
- // will set the style on selected text inside the <text> element. If we want to set
- // the style on the outer <text> objects we need to bypass this call.
- if ( mode == 3 && !outer ) {
- // This will call sp_te_apply_style via signal
- sp_desktop_set_style (desktop, css, true, true);
- } else {
- Inkscape::Selection *selection = desktop->getSelection();
- auto itemlist= selection->items();
- for (auto i: itemlist) {
-
- if (dynamic_cast<SPText *>(i) || dynamic_cast<SPFlowtext *>(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);
- }
-
- if ( mode == 1 || mode == 2 || mode == 3) { // Minimum, Even, or Adjustable w/ outer.
- // We change only outer style
- item->changeCSS(css_set,"style");
- } else {
- // We change only inner style (Adaptive).
- for (auto child: item->childList(false)) {
- child->changeCSS(css_set,"style");
- }
- }
- }
- }
- }
-}
-
-
/*
* Set the default list of font sizes, scaled to the users preferred unit
*/
@@ -257,16 +249,21 @@ namespace UI {
namespace Toolbar {
TextToolbar::TextToolbar(SPDesktop *desktop)
- : Toolbar(desktop),
- _freeze(false),
- _tracker(new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR))
+ : Toolbar(desktop)
+ , _freeze(false)
+ , _subselection(false)
+ , _fullsubselection(false)
+ , _tracker(new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR))
+ , _tracker_fs(new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR))
{
/* Line height unit tracker */
_tracker->prependUnit(unit_table.getUnit("")); // Ratio
_tracker->addUnit(unit_table.getUnit("%"));
_tracker->addUnit(unit_table.getUnit("em"));
_tracker->addUnit(unit_table.getUnit("ex"));
- _tracker->setActiveUnit(unit_table.getUnit("%"));
+ _tracker->setActiveUnit(unit_table.getUnit(""));
+ _tracker->changeLabel("lines", 0);
+ _tracker_fs->setActiveUnit(unit_table.getUnit("mm"));
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
@@ -339,17 +336,6 @@ TextToolbar::TextToolbar(SPDesktop *desktop)
add_separator();
- /* Text outer style */
- {
- _outer_style_item = Gtk::manage(new Gtk::ToggleToolButton());
- _outer_style_item->set_label(_("Show outer style"));
- _outer_style_item->set_tooltip_text(_("Show style of outermost text element. The 'font-size' and 'line-height' values of the outermost text element determine the minimum line spacing in the block."));
- _outer_style_item->set_icon_name(INKSCAPE_ICON("text_outer_style"));
- add(*_outer_style_item);
- _outer_style_item->signal_toggled().connect(sigc::mem_fun(*this, &TextToolbar::outer_style_changed));
- // need to set_active status *after* a bunch of other widgets. See end of this function.
- }
-
/* Font size */
{
// List of font sizes for drop-down menu
@@ -375,92 +361,39 @@ TextToolbar::TextToolbar(SPDesktop *desktop)
_font_size_item->signal_changed().connect(sigc::mem_fun(*this, &TextToolbar::fontsize_value_changed));
add(*_font_size_item);
}
-
- /* Line height */
+ /* Font_ size units */
+ {
+ _font_size_units_item = _tracker_fs->create_tool_item(_("Units"), (""));
+ _font_size_units_item->signal_changed_after().connect(
+ sigc::mem_fun(*this, &TextToolbar::fontsize_unit_changed));
+ add(*_font_size_units_item);
+ }
{
// Drop down menu
std::vector<Glib::ustring> labels = {_("Smaller spacing"), "", "", "", "", C_("Text tool", "Normal"), "", "", "", "", "", _("Larger spacing")};
std::vector<double> values = { 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 2.0};
- auto line_height_val = prefs->getDouble("/tools/text/lineheight", 0.0);
+ auto line_height_val = 1.25;
_line_height_adj = Gtk::Adjustment::create(line_height_val, 0.0, 1000.0, 0.1, 1.0);
- _line_height_item = Gtk::manage(new UI::Widget::SpinButtonToolItem("text-line-height", _("Line:"), _line_height_adj, 0.1, 2));
+ _line_height_item =
+ Gtk::manage(new UI::Widget::SpinButtonToolItem("text-line-height", "", _line_height_adj, 0.1, 2));
_line_height_item->set_tooltip_text(_("Spacing between baselines"));
_line_height_item->set_custom_numeric_menu_data(values, labels);
_line_height_item->set_focus_widget(Glib::wrap(GTK_WIDGET(desktop->canvas)));
_line_height_adj->signal_value_changed().connect(sigc::mem_fun(*this, &TextToolbar::lineheight_value_changed));
//_tracker->addAdjustment(_line_height_adj->gobj()); // (Alex V) Why is this commented out?
- add(*_line_height_item);
_line_height_item->set_sensitive(true);
_line_height_item->set_icon(INKSCAPE_ICON("text_line_spacing"));
+ add(*_line_height_item);
}
-
/* Line height units */
{
_line_height_units_item = _tracker->create_tool_item( _("Units"), ("") );
- add(*_line_height_units_item);
_line_height_units_item->signal_changed_after().connect(sigc::mem_fun(*this, &TextToolbar::lineheight_unit_changed));
+ add(*_line_height_units_item);
}
- /* Text line height unset */
- {
- _line_height_unset_item = Gtk::manage(new Gtk::ToggleToolButton());
- _line_height_unset_item->set_label(_("Unset line height"));
- _line_height_unset_item->set_tooltip_text(_("If enabled, line height is set on part of selection. Click to unset."));
- _line_height_unset_item->set_icon_name(INKSCAPE_ICON("paint-unknown"));
- add(*_line_height_unset_item);
- _line_height_unset_item->signal_toggled().connect(sigc::mem_fun(*this, &TextToolbar::lineheight_unset_changed));
- _line_height_unset_item->set_active(prefs->getBool("/tools/text/line_height_unset", false));
- }
-
- /* Line spacing mode */
- {
- UI::Widget::ComboToolItemColumns columns;
-
- Glib::RefPtr<Gtk::ListStore> store = Gtk::ListStore::create(columns);
-
- Gtk::TreeModel::Row row;
-
- row = *(store->append());
- row[columns.col_label ] = _("Adaptive");
- row[columns.col_tooltip ] = _("Line spacing adapts to font size.");
- row[columns.col_icon ] = INKSCAPE_ICON("text_line_spacing");
- row[columns.col_sensitive] = true;
-
- row = *(store->append());
- row[columns.col_label ] = _("Minimum");
- row[columns.col_tooltip ] = _("Line spacing adapts to fonts size with set minimum spacing.");
- row[columns.col_icon ] = INKSCAPE_ICON("text_line_spacing");
- row[columns.col_sensitive] = true;
- row = *(store->append());
- row[columns.col_label ] = _("Even");
- row[columns.col_tooltip ] = _("Lines evenly spaced.");
- row[columns.col_icon ] = INKSCAPE_ICON("text_line_spacing");
- row[columns.col_sensitive] = true;
-
- row = *(store->append());
- row[columns.col_label ] = _("Adjustable ☠");
- row[columns.col_tooltip ] = _("Line spacing fully adjustable");
- row[columns.col_icon ] = INKSCAPE_ICON("text_line_spacing");
- row[columns.col_sensitive] = true;
-
- _line_spacing_item =
- UI::Widget::ComboToolItem::create(_("Line Spacing Mode"), // Label
- _("How should multiple baselines be spaced?\n Adaptive: Line spacing adapts to font size.\n Minimum: Like Adaptive, but with a set minimum.\n Even: Evenly spaced.\n Adjustable: No restrictions."), // Tooltip
- "Not Used", // Icon
- store ); // Tree store
- _line_spacing_item->use_icon(true);
- _line_spacing_item->use_label(true);
- gint mode = prefs->getInt("/tools/text/line_spacing_mode", 0);
- _line_spacing_item->set_active( mode );
-
- add(*_line_spacing_item);
-
- _line_spacing_item->signal_changed().connect(sigc::mem_fun(*this, &TextToolbar::line_spacing_mode_changed));
- }
-
- add_separator();
-
+ Gtk::SeparatorToolItem *separator = Gtk::manage(new Gtk::SeparatorToolItem());
/* Alignment */
{
UI::Widget::ComboToolItemColumns columns;
@@ -508,8 +441,6 @@ TextToolbar::TextToolbar(SPDesktop *desktop)
_align_item->signal_changed().connect(sigc::mem_fun(*this, &TextToolbar::align_mode_changed));
}
- add_separator();
-
/* Style - Superscript */
{
_superscript_item = Gtk::manage(new Gtk::ToggleToolButton());
@@ -534,8 +465,6 @@ TextToolbar::TextToolbar(SPDesktop *desktop)
_subscript_item->set_active(prefs->getBool("/tools/text/sub", false));
}
- add_separator();
-
/* Letter spacing */
{
// Drop down menu
@@ -549,6 +478,7 @@ TextToolbar::TextToolbar(SPDesktop *desktop)
_letter_spacing_item->set_focus_widget(Glib::wrap(GTK_WIDGET(desktop->canvas)));
_letter_spacing_adj->signal_value_changed().connect(sigc::mem_fun(*this, &TextToolbar::letterspacing_value_changed));
add(*_letter_spacing_item);
+
_letter_spacing_item->set_sensitive(true);
_letter_spacing_item->set_icon(INKSCAPE_ICON("text_letter_spacing"));
}
@@ -565,6 +495,7 @@ TextToolbar::TextToolbar(SPDesktop *desktop)
_word_spacing_item->set_custom_numeric_menu_data(values, labels);
_word_spacing_item->set_focus_widget(Glib::wrap(GTK_WIDGET(desktop->canvas)));
_word_spacing_adj->signal_value_changed().connect(sigc::mem_fun(*this, &TextToolbar::wordspacing_value_changed));
+
add(*_word_spacing_item);
_word_spacing_item->set_sensitive(true);
_word_spacing_item->set_icon(INKSCAPE_ICON("text_word_spacing"));
@@ -617,7 +548,6 @@ TextToolbar::TextToolbar(SPDesktop *desktop)
add(*_rotation_item);
}
- add_separator();
/* Writing mode (Horizontal, Vertical-LR, Vertical-RL) */
{
@@ -654,7 +584,6 @@ TextToolbar::TextToolbar(SPDesktop *desktop)
_writing_mode_item->use_label( false );
gint mode = prefs->getInt("/tools/text/writing_mode", 0);
_writing_mode_item->set_active( mode );
-
add(*_writing_mode_item);
_writing_mode_item->signal_changed().connect(sigc::mem_fun(*this, &TextToolbar::writing_mode_changed));
@@ -696,7 +625,6 @@ TextToolbar::TextToolbar(SPDesktop *desktop)
_orientation_item->use_label( false );
gint mode = prefs->getInt("/tools/text/text_orientation", 0);
_orientation_item->set_active( mode );
-
add(*_orientation_item);
_orientation_item->signal_changed().connect(sigc::mem_fun(*this, &TextToolbar::orientation_changed));
@@ -731,19 +659,13 @@ TextToolbar::TextToolbar(SPDesktop *desktop)
_direction_item->use_label(false);
gint mode = prefs->getInt("/tools/text/text_direction", 0);
_direction_item->set_active( mode );
-
add(*_direction_item);
_direction_item->signal_changed_after().connect(sigc::mem_fun(*this, &TextToolbar::direction_changed));
}
- // Text outer style (continued)
- _outer_style_item->set_active(prefs->getBool("/tools/text/outer_style", false));
-
show_all();
- // Is this necessary to call? Shouldn't hurt.
- selection_changed(desktop->getSelection());
-
+ // we emit a selection change on tool switch to text
desktop->connectEventContextChanged(sigc::mem_fun(*this, &TextToolbar::watch_ec));
}
@@ -777,7 +699,7 @@ TextToolbar::fontfamily_value_changed()
std::cout << " Old family: " << fontlister->get_font_family() << std::endl;
std::cout << " New family: " << new_family << std::endl;
std::cout << " Old active: " << fontlister->get_font_family_row() << std::endl;
- std::cout << " New active: " << act->active << std::endl;
+ // std::cout << " New active: " << act->active << std::endl;
#endif
if( new_family.compare( fontlister->get_font_family() ) != 0 ) {
// Changed font-family
@@ -864,20 +786,20 @@ TextToolbar::fontsize_value_changed()
osfs << size << sp_style_get_css_unit_string(unit);
}
sp_repr_css_set_property (css, "font-size", osfs.str().c_str());
+ double factor = size / selection_fontsize;
// Apply font size to selected objects.
// Calling sp_desktop_set_style will result in a call to TextTool::_styleSet() which
// will set the style on selected text inside the <text> element. If we want to set
// the style on the outer <text> objects we need to bypass this call.
- bool outer = prefs->getInt("/tools/text/outer_style", false);
SPDesktop *desktop = SP_ACTIVE_DESKTOP;
- if (outer) {
+ int textchids = 0;
+ if (_outer) {
Inkscape::Selection *selection = desktop->getSelection();
auto itemlist= selection->items();
for(auto i=itemlist.begin();i!=itemlist.end(); ++i){
if (dynamic_cast<SPText *>(*i) || dynamic_cast<SPFlowtext *>(*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);
@@ -886,16 +808,27 @@ TextToolbar::fontsize_value_changed()
if ( (ex != 0.0) && (ex != 1.0) ) {
sp_css_attr_scale(css_set, 1/ex);
}
-
- item->changeCSS(css_set,"style");
-
+ recursively_set_properties(item, css_set);
+ SPStyle *item_style = item->style;
+ if (item_style->inline_size.value == 0) {
+ css_set = sp_css_attr_from_style(item_style, SP_STYLE_FLAG_IFSET);
+ sp_repr_css_unset_property(css_set, "inline-size");
+ item->changeCSS(css_set, "style");
+ }
sp_repr_css_attr_unref(css_set);
}
}
} else {
sp_desktop_set_style (desktop, css, true, true);
}
-
+ Unit const *unit_lh = _tracker->getActiveUnit();
+ g_return_if_fail(unit_lh != nullptr);
+ if (!is_relative(unit_lh)) {
+ double lineheight = _line_height_adj->get_value();
+ _freeze = false;
+ _line_height_adj->set_value(lineheight * factor);
+ _freeze = true;
+ }
// If no selected objects, set default.
SPStyle query(SP_ACTIVE_DOCUMENT);
int result_numbers =
@@ -910,7 +843,7 @@ TextToolbar::fontsize_value_changed()
_("Text: Change font size"));
}
- sp_repr_css_attr_unref (css);
+ sp_repr_css_attr_unref(css);
_freeze = false;
}
@@ -1056,9 +989,11 @@ TextToolbar::align_mode_changed(int mode)
// move the x of all texts to preserve the same bbox
Inkscape::Selection *selection = desktop->getSelection();
auto itemlist= selection->items();
- for(auto i=itemlist.begin();i!=itemlist.end(); ++i){
- if (SP_IS_TEXT(*i)) {
- SPItem *item = *i;
+ for (auto i : itemlist) {
+ SPText *text = dynamic_cast<SPText *>(i);
+ SPFlowtext *flowtext = dynamic_cast<SPFlowtext *>(i);
+ if (text) {
+ SPItem *item = i;
unsigned writing_mode = item->style->writing_mode.value;
// below, variable names suggest horizontal move, but we check the writing direction
@@ -1352,20 +1287,15 @@ TextToolbar::lineheight_value_changed()
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).
- 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);
- _lineheight_unit = temp_length.unit;
// Set css line height.
SPCSSAttr *css = sp_repr_css_attr_new ();
@@ -1377,18 +1307,49 @@ TextToolbar::lineheight_value_changed()
osfs << Quantity::convert(_line_height_adj->get_value(), unit, "px") << "px";
}
sp_repr_css_set_property (css, "line-height", osfs.str().c_str());
-
- // Internal function to set line-height which is spacing mode dependent.
- set_lineheight (css);
-
- // Only need to save for undo if a text item has been changed.
- Inkscape::Selection *selection = SP_ACTIVE_DESKTOP->getSelection();
- bool modmade = false;
+ Inkscape::Selection *selection = desktop->getSelection();
auto itemlist= selection->items();
- for(auto i=itemlist.begin();i!=itemlist.end(); ++i){
- if (dynamic_cast<SPText *>(*i) || dynamic_cast<SPFlowtext *>(*i)) {
- modmade = true;
+ bool modmade = false;
+ if (_outer) {
+ for (auto i = itemlist.begin(); i != itemlist.end(); ++i) {
+ if (dynamic_cast<SPText *>(*i) || dynamic_cast<SPFlowtext *>(*i)) {
+ modmade = true;
+ 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);
+ }
+ }
+ } else {
+ SPItem *parent = dynamic_cast<SPItem *>(*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 = parent_style->line_height.computed;
+ if (minheight) {
+ for (auto i : parent->childList(false)) {
+ SPItem *child = dynamic_cast<SPItem *>(i);
+ double childheight = child->style->line_height.computed;
+ if (minheight == childheight) {
+ 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);
}
// Save for undo
@@ -1397,20 +1358,21 @@ TextToolbar::lineheight_value_changed()
// cascading, etc.). For multi-line text with sodipodi::role="line", we must explicitly
// save new <tspan> 'x' and 'y' attribute values by calling updateRepr().
// Partial fix for bug #1590141.
- SP_ACTIVE_DESKTOP->getDocument()->ensureUpToDate();
- for(auto i=itemlist.begin();i!=itemlist.end(); ++i){
- if (dynamic_cast<SPText *>(*i) || dynamic_cast<SPFlowtext *>(*i)) {
- (*i)->updateRepr();
+
+ desktop->getDocument()->ensureUpToDate();
+ for (auto i : itemlist) {
+ SPText *text = dynamic_cast<SPText *>(i);
+ SPFlowtext *flowtext = dynamic_cast<SPFlowtext *>(i);
+ if (text || flowtext) {
+ (i)->updateRepr();
}
}
- DocumentUndo::maybeDone(SP_ACTIVE_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 (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS);
+ 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();
@@ -1444,49 +1406,58 @@ TextToolbar::lineheight_unit_changed(int /* Not Used */)
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);
- _lineheight_unit = temp_length.unit;
+ if (!is_relative(SPCSSUnit(temp_length.unit))) {
+ prefs->setInt("/tools/text/lineheight/display_unit", temp_length.unit);
+ }
+ if (old_unit == temp_length.unit) {
+ 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();
// Convert between units
- if ((unit->abbr == "" || unit->abbr == "em") &&
- (old_unit == SP_CSS_UNIT_NONE || old_unit == SP_CSS_UNIT_EM)) {
+ double font_size = 0;
+ double doc_scale = 1;
+ int count = 0;
+ bool has_flow = false;
+
+ for (auto i : itemlist) {
+ SPText *text = dynamic_cast<SPText *>(i);
+ SPFlowtext *flowtext = dynamic_cast<SPFlowtext *>(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) ) {
+ } 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) ) {
+ } 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) {
+ } 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
- double font_size = 0;
- int count = 0;
- for(auto i=itemlist.begin();i!=itemlist.end(); ++i){
- if (SP_IS_TEXT (*i) || SP_IS_FLOWTEXT(*i)) {
- double doc_scale = Geom::Affine((*i)->i2dt_affine()).descrim();
- font_size += (*i)->style->font_size.computed * doc_scale;
- ++count;
- }
- }
- if (count > 0) {
- font_size /= count;
- } else {
- font_size = 20;
- }
-
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");
@@ -1498,24 +1469,9 @@ TextToolbar::lineheight_unit_changed(int /* Not Used */)
} 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) {
+ } 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
- double font_size = 0;
- int count = 0;
- for(auto i=itemlist.begin();i!=itemlist.end(); ++i){
- if (SP_IS_TEXT (*i) || SP_IS_FLOWTEXT (*i)) {
- double doc_scale = Geom::Affine((*i)->i2dt_affine()).descrim();
- font_size += (*i)->style->font_size.computed * doc_scale;
- ++count;
- }
- }
- if (count > 0) {
- font_size /= count;
- } else {
- font_size = 20;
- }
-
if (old_unit == SP_CSS_UNIT_PERCENT) {
line_height /= 100.0;
} else if (old_unit == SP_CSS_UNIT_EX) {
@@ -1527,10 +1483,10 @@ TextToolbar::lineheight_unit_changed(int /* Not Used */)
// 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 {
@@ -1540,7 +1496,6 @@ TextToolbar::lineheight_unit_changed(int /* Not Used */)
// 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);
@@ -1549,18 +1504,58 @@ TextToolbar::lineheight_unit_changed(int /* Not Used */)
_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.
- set_lineheight (css);
+ if (_outer) {
+ for (auto i = itemlist.begin(); i != itemlist.end(); ++i) {
+ if (dynamic_cast<SPText *>(*i) || dynamic_cast<SPFlowtext *>(*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);
+ }
+ }
+ } else {
+ SPItem *parent = dynamic_cast<SPItem *>(*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 = parent_style->line_height.computed;
+ if (minheight) {
+ for (auto i : parent->childList(false)) {
+ SPItem *child = dynamic_cast<SPItem *>(i);
+ double childheight = child->style->line_height.computed;
+ if (minheight == childheight) {
+ 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);
+ }
// Only need to save for undo if a text item has been changed.
bool modmade = false;
- for(auto i=itemlist.begin();i!=itemlist.end(); ++i){
- if (dynamic_cast<SPText *>(*i) || dynamic_cast<SPFlowtext *>(*i)) {
+ for (auto i : itemlist) {
+ SPText *text = dynamic_cast<SPText *>(i);
+ SPFlowtext *flowtext = dynamic_cast<SPFlowtext *>(i);
+ if (text || flowtext) {
modmade = true;
+ break;
}
}
-
// Save for undo
if(modmade) {
DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:line-height", SP_VERB_NONE,
@@ -1582,165 +1577,20 @@ TextToolbar::lineheight_unit_changed(int /* Not Used */)
_freeze = false;
}
-void
-TextToolbar::line_spacing_mode_changed(int mode)
+void TextToolbar::fontsize_unit_changed(int /* Not Used */)
{
// quit if run by the _changed callbacks
- if (_freeze) {
- return;
- }
- _freeze = true;
-
+ Unit const *unit = _tracker_fs->getActiveUnit();
+ g_return_if_fail(unit != nullptr);
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- prefs->setInt("/tools/text/line_spacing_mode", mode);
-
- SPDesktop *desktop = SP_ACTIVE_DESKTOP;
-
- // Note: only <text> and <flowRoot> text elements are in selection!
- // (No need to worry about <tspan>, <flowPara>, ...)
- Inkscape::Selection *selection = desktop->getSelection();
- std::vector<SPItem *> vec(selection->items().begin(), selection->items().end());
-
- for (auto i: vec) {
-
- // Only <text> and <flowRoot>, <flowRoot> => SPFlowtext
- if (dynamic_cast<SPText*>(i) || dynamic_cast<SPFlowtext*>(i)) {
- SPStyle* text_style = i->style;
-
- // Make list of <tspan>, <flowPara>, <flowSpan> children
- std::vector<SPObject *> children = i->childList(false);
- std::vector<SPItem *> children_item;
- for (auto j: children) {
- if (dynamic_cast<SPItem *>(j)) {
- children_item.push_back( dynamic_cast<SPItem *>(j) );
- }
- }
-
- SPStyle tspans; // Also flowPara/flowSpan
- int result_numbers = sp_desktop_query_style_from_list (children_item, &tspans, QUERY_STYLE_PROPERTY_FONTNUMBERS);
-
- Inkscape::CSSOStringStream osfs;
- if (text_style->line_height.computed != 0 || text_style->line_height.normal) {
-
- if (mode != 1 || text_style->line_height.unit == SP_CSS_UNIT_NONE || text_style->line_height.normal) {
- Glib::ustring line_height_string = text_style->line_height.write( SP_STYLE_FLAG_ALWAYS );
- line_height_string.erase(0, 12); // erase 'line-height:'
- osfs << line_height_string;
- } else {
- // Convert to unitless value
- double line_height_value = text_style->line_height.value;
- // Percent values are stored as value/100;
- if (text_style->line_height.unit == SP_CSS_UNIT_PERCENT) {
- line_height_value *= 100;
- }
- osfs << sp_style_css_size_units_to_px( line_height_value,
- text_style->line_height.unit,
- text_style->font_size.computed) /
- text_style->font_size.computed;
- }
-
- } else {
-
- if (mode != 1 || tspans.line_height.unit == SP_CSS_UNIT_NONE || tspans.line_height.normal) {
- Glib::ustring line_height_string = tspans.line_height.write( SP_STYLE_FLAG_ALWAYS );
- line_height_string.erase(0, 12); // erase 'line-height:'
- osfs << line_height_string;
- } else {
- // Convert to unitless value
- double line_height_value = tspans.line_height.value;
- // Percent values are stored as value/100;
- if (tspans.line_height.unit == SP_CSS_UNIT_PERCENT) {
- line_height_value *= 100;
- }
- osfs << sp_style_css_size_units_to_px( line_height_value,
- tspans.line_height.unit,
- tspans.font_size.computed) /
- tspans.font_size.computed;
- }
- }
-
- SPCSSAttr *css_text = sp_repr_css_attr_new();
- SPCSSAttr *css_tspan = sp_repr_css_attr_new();
-
- sp_repr_css_set_property (css_text, "line-height", osfs.str().c_str());
-
- switch (mode) {
- case 0: // Adaptive
- // <text>: Zero text
- sp_repr_css_set_property (css_text, "line-height", "0");
- // <tspan>: Old text value.
- sp_repr_css_set_property (css_tspan, "line-height", osfs.str().c_str());
- break;
-
- case 1: // Minimum
- // <text>: Set to old text (unitless) or if old text zero, set to old tspan.
- sp_repr_css_set_property (css_text, "line-height", osfs.str().c_str());
- // <tspan>: Unset
- sp_repr_css_unset_property (css_tspan, "line-height");
- break;
-
- case 2: // Even
- // <text>: Set to old text or if old text zero, set to old tspan.
- sp_repr_css_set_property (css_text, "line-height", osfs.str().c_str());
- // <tspan>: Set to zero
- sp_repr_css_set_property (css_tspan, "line-height", "0");
- break;
-
- case 3: // Adjustable
- // Do nothing ☠
- break;
- }
-
- if (mode != 3) {
- i->changeCSS (css_text, "style");
- for (auto j: children) {
- recursively_set_properties (j, css_tspan);
- //j->changeCSS (css_tspan, "style");
- }
- }
-
- sp_repr_css_attr_unref (css_text);
- sp_repr_css_attr_unref (css_tspan);
- }
- }
-
- // Set "Outer Style" toggle to match mode.
- switch (mode) {
- case 0: // Adaptive
- _outer_style_item->set_active(false);
- prefs->setInt("/tools/text/outer_style", false);
- break;
-
- case 1: // Minimum
- case 2: // Even
- _outer_style_item->set_active(true);
- prefs->setInt("/tools/text/outer_style", true);
- break;
-
- case 3: // Adjustable
- break;
- }
-
- // Outer style toggle set per mode so that line height widget should be enabled.
- _line_height_item->set_sensitive(true);
-
- // Update "climb rate"
- Unit const *unit = _tracker->getActiveUnit();
-
- 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);
- }
-
- DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT,
- _("Text: Change line spacing mode"));
-
- gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas));
- _freeze = false;
+ // This nonsense is to get SP_CSS_UNIT_xx value corresponding to unit.
+ SPILength temp_size;
+ Inkscape::CSSOStringStream temp_size_stream;
+ temp_size_stream << 1 << unit->abbr;
+ temp_size.read(temp_size_stream.str().c_str());
+ prefs->setInt("/options/font/unitType", temp_size.unit);
+ selection_changed(SP_ACTIVE_DESKTOP->selection);
}
void
@@ -1762,7 +1612,6 @@ TextToolbar::wordspacing_value_changed()
// Apply word-spacing to selected objects.
SPDesktop *desktop = SP_ACTIVE_DESKTOP;
sp_desktop_set_style (desktop, css, true, false);
-
// If no selected objects, set default.
SPStyle query(SP_ACTIVE_DOCUMENT);
int result_numbers =
@@ -1930,49 +1779,25 @@ TextToolbar::rotation_value_changed()
_freeze = false;
}
-// Unset line height on selection's inner text objects (tspan, etc.).
-void
-TextToolbar::lineheight_unset_changed()
-{
- // quit if run by the _changed callbacks
- if (_freeze) {
- return;
- }
-
- SPCSSAttr *css = sp_repr_css_attr_new();
- sp_repr_css_unset_property(css, "line-height");
-
- SPDesktop *desktop = SP_ACTIVE_DESKTOP;
- sp_desktop_set_style (desktop, css);
-
- sp_repr_css_attr_unref(css);
-
- DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT,
- _("Text: Unset line height."));
-
- _freeze = false;
-}
-
-// Changes selection to only text outer elements.
-void
-TextToolbar::outer_style_changed()
+void TextToolbar::selection_modified_select_tool(Inkscape::Selection *selection, guint flags)
{
- bool outer = _outer_style_item->get_active();
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- prefs->setInt("/tools/text/outer_style", outer);
-
- // Update widgets to reflect new state of Text Outer Style button.
- selection_changed(nullptr);
+ double factor = prefs->getDouble("/options/font/scaleLineHeightFromFontSIze", 1.0);
+ if (factor != 1.0) {
+ Unit const *unit_lh = _tracker->getActiveUnit();
+ g_return_if_fail(unit_lh != nullptr);
+ if (!is_relative(unit_lh)) {
+ double lineheight = _line_height_adj->get_value();
+ _freeze = false;
+ _line_height_adj->set_value(lineheight * factor);
+ _freeze = true;
+ }
+ prefs->setDouble("/options/font/scaleLineHeightFromFontSIze", 1.0);
+ }
}
-/*
- * This function sets up the text-tool tool-controls, setting the entry boxes
- * etc. to the values from the current selection or the default if no selection.
- * It is called whenever a text selection is changed, including stepping cursor
- * through text, or setting focus to text.
- */
-void
-TextToolbar::selection_changed(Inkscape::Selection * /*selection*/, bool subselection) // don't bother to update font list if subsel changed
+void TextToolbar::selection_changed(Inkscape::Selection * /*selection*/) // don't bother to update font list if subsel
+ // changed
{
#ifdef DEBUG_TEXT
static int count = 0;
@@ -2002,7 +1827,14 @@ TextToolbar::selection_changed(Inkscape::Selection * /*selection*/, bool subsele
return;
}
_freeze = true;
-
+ if (!this->_subselection) {
+ this->_outer = true;
+ ;
+ this->_sub_active_item = nullptr;
+ }
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ SPDocument *document = SP_ACTIVE_DOCUMENT;
Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance();
fontlister->selection_update();
@@ -2015,16 +1847,19 @@ TextToolbar::selection_changed(Inkscape::Selection * /*selection*/, bool subsele
// Only flowed text can be justified, only normal text can be kerned...
// Find out if we have flowed text now so we can use it several places
gboolean isFlow = false;
- auto itemlist= SP_ACTIVE_DESKTOP->getSelection()->items();
- for(auto i=itemlist.begin();i!=itemlist.end(); ++i){
- // std::cout << " " << ((*i)->getId()?(*i)->getId():"null") << std::endl;
- if( SP_IS_FLOWTEXT(*i)) {
+ auto itemlist = desktop->getSelection()->items();
+ std::vector<SPItem *> to_work;
+ for (auto i : itemlist) {
+ SPItem *item = dynamic_cast<SPItem *>(i);
+ SPText *text = dynamic_cast<SPText *>(i);
+ SPFlowtext *flowtext = dynamic_cast<SPFlowtext *>(i);
+ if (item && (text || flowtext)) {
+ to_work.push_back(item);
+ }
+ if (flowtext) {
isFlow = true;
- // std::cout << " Found flowed text" << std::endl;
- break;
}
}
-
/*
* Query from current selection:
* Font family (font-family)
@@ -2032,11 +1867,13 @@ TextToolbar::selection_changed(Inkscape::Selection * /*selection*/, bool subsele
* Numbers (font-size, letter-spacing, word-spacing, line-height, text-anchor, writing-mode)
* Font specification (Inkscape private attribute)
*/
- SPStyle query(SP_ACTIVE_DOCUMENT);
- int result_family = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTFAMILY);
- int result_style = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTSTYLE);
- int result_baseline = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_BASELINES);
- int result_wmode = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_WRITINGMODES);
+ SPStyle query(document);
+ SPStyle query_fallback(document);
+ SPStyle query_super_fallback(document);
+ int result_family = sp_desktop_query_style(desktop, &query, QUERY_STYLE_PROPERTY_FONTFAMILY);
+ int result_style = sp_desktop_query_style(desktop, &query, QUERY_STYLE_PROPERTY_FONTSTYLE);
+ int result_baseline = sp_desktop_query_style(desktop, &query, QUERY_STYLE_PROPERTY_BASELINES);
+ int result_wmode = sp_desktop_query_style(desktop, &query, QUERY_STYLE_PROPERTY_WRITINGMODES);
// Calling sp_desktop_query_style will result in a call to TextTool::_styleQueried().
// This returns the style of the selected text inside the <text> element... which
@@ -2044,15 +1881,22 @@ TextToolbar::selection_changed(Inkscape::Selection * /*selection*/, bool subsele
// <text> objects then we need to bypass the call to TextTool::_styleQueried().
// The desktop selection never includes the elements inside the <text> element.
int result_numbers = 0;
- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- SPDesktop *desktop = SP_ACTIVE_DESKTOP;
- bool outer = prefs->getInt("/tools/text/outer_style", false);
- if (outer) {
- Inkscape::Selection *selection = desktop->getSelection();
- std::vector<SPItem *> vec(selection->items().begin(), selection->items().end());
- result_numbers = sp_desktop_query_style_from_list (vec, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS);
+ int result_numbers_fallback = 0;
+ int result_numbers_super_fallback = 0;
+
+ if (_outer && this->_sub_active_item) {
+ std::vector<SPItem *> fallback{ this->_sub_active_item };
+ SPItem *sfallback = dynamic_cast<SPItem *>(this->_sub_active_item->parent);
+ std::vector<SPItem *> super_fallback{ sfallback };
+ result_numbers = sp_desktop_query_style(desktop, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS);
+ result_numbers_fallback =
+ sp_desktop_query_style_from_list(fallback, &query_fallback, QUERY_STYLE_PROPERTY_FONTNUMBERS);
+ result_numbers_super_fallback =
+ sp_desktop_query_style_from_list(super_fallback, &query_fallback, QUERY_STYLE_PROPERTY_FONTNUMBERS);
+ } else if (_outer) {
+ result_numbers = sp_desktop_query_style_from_list(to_work, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS);
} else {
- result_numbers = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS);
+ result_numbers = sp_desktop_query_style(desktop, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS);
}
/*
@@ -2094,18 +1938,33 @@ TextToolbar::selection_changed(Inkscape::Selection * /*selection*/, bool subsele
// If we have valid query data for text (font-family, font-specification) set toolbar accordingly.
{
// Size (average of text selected)
+
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT);
double size = sp_style_css_size_px_to_units(query.font_size.computed, unit);
+ if (!size && result_numbers_fallback != QUERY_STYLE_NOTHING) {
+ size = sp_style_css_size_px_to_units(query_fallback.font_size.computed, unit);
+ }
+ if (!size && result_numbers_super_fallback != QUERY_STYLE_NOTHING) {
+ size = sp_style_css_size_px_to_units(query_super_fallback.font_size.computed, unit);
+ }
+ auto unit_str = sp_style_get_css_unit_string(unit);
+ Glib::ustring tooltip = Glib::ustring::format(_("Font size"), " (", unit_str, ")");
+
+ _font_size_item->set_tooltip(tooltip.c_str());
Inkscape::CSSOStringStream os;
+ // We dot want to parse values just show
+ _tracker_fs->setActiveUnitByAbbr(sp_style_get_css_unit_string(unit));
int rounded_size = std::round(size);
if (std::abs((size - rounded_size)/size) < 0.0001) {
// We use rounded_size to avoid rounding errors when, say, converting stored 'px' values to displayed 'pt' values.
os << rounded_size;
+ selection_fontsize = rounded_size;
} else {
os << size;
+ selection_fontsize = size;
}
// Freeze to ignore callbacks.
@@ -2115,9 +1974,6 @@ TextToolbar::selection_changed(Inkscape::Selection * /*selection*/, bool subsele
_font_size_item->set_active_text( os.str().c_str() );
- Glib::ustring tooltip = Glib::ustring::format(_("Font size"), " (", sp_style_get_css_unit_string(unit), ")");
- _font_size_item->set_tooltip (tooltip.c_str());
-
// Superscript
gboolean superscriptSet =
((result_baseline == QUERY_STYLE_SINGLE || result_baseline == QUERY_STYLE_MULTIPLE_SAME ) &&
@@ -2160,50 +2016,36 @@ TextToolbar::selection_changed(Inkscape::Selection * /*selection*/, bool subsele
}
_align_item->set_active( activeButton );
- // Line height (spacing) and line height unit
- double height;
- int line_height_unit = -1;
- if (query.line_height.normal) {
- height = Inkscape::Text::Layout::LINE_HEIGHT_NORMAL;
- line_height_unit = SP_CSS_UNIT_NONE;
- } else {
- height = query.line_height.value;
- line_height_unit = query.line_height.unit;
+ double height = query.line_height.value;
+ gint line_height_unit = query.line_height.unit;
+
+ if (!height && result_numbers_fallback != QUERY_STYLE_NOTHING) {
+ height = query_fallback.line_height.value;
+ line_height_unit = query_fallback.line_height.unit;
+ }
+ if (!height && result_numbers_super_fallback != QUERY_STYLE_NOTHING) {
+ height = query_super_fallback.line_height.value;
+ line_height_unit = query_super_fallback.line_height.unit;
}
- switch (line_height_unit) {
- case SP_CSS_UNIT_NONE:
- case SP_CSS_UNIT_EM:
- case SP_CSS_UNIT_EX:
- break;
- case SP_CSS_UNIT_PERCENT:
- height *= 100.0; // Inkscape store % as fraction in .value
- break;
- case SP_CSS_UNIT_PX:
- // If unit is set to 'px', use the preferred display unit (if absolute).
- line_height_unit =
- prefs->getInt("/tools/text/lineheight/display_unit", SP_CSS_UNIT_PT);
- // But not if preferred unit is relative
- if (line_height_unit != SP_CSS_UNIT_NONE &&
- line_height_unit != SP_CSS_UNIT_EM &&
- line_height_unit != SP_CSS_UNIT_EX &&
- line_height_unit != SP_CSS_UNIT_PERCENT) {
- height =
- Quantity::convert(height, "px", sp_style_get_css_unit_string(line_height_unit));
- } else {
- line_height_unit = SP_CSS_UNIT_PX;
- }
- break;
- default:
- // If unit has been set by an external program to something other than 'px', use
- // that unit. But height is average of computed values (px) so we need to convert
- // back.
- height =
- Quantity::convert(height, "px", sp_style_get_css_unit_string(line_height_unit));
+ if (line_height_unit == SP_CSS_UNIT_PERCENT) {
+ height *= 100.0; // Inkscape store % as fraction in .value
}
+ // We dot want to parse values just show
+ if (!is_relative(SPCSSUnit(line_height_unit))) {
+ gint absunit = prefs->getInt("/tools/text/lineheight/display_unit", 1);
+ // For backwards comaptibility
+ if (is_relative(SPCSSUnit(absunit))) {
+ prefs->setInt("/tools/text/lineheight/display_unit", 1);
+ absunit = 1;
+ }
+ height = Quantity::convert(height, "px", sp_style_get_css_unit_string(absunit));
+ line_height_unit = absunit;
+ }
_line_height_adj->set_value(height);
+
// Update "climb rate"
if (line_height_unit == SP_CSS_UNIT_PERCENT) {
_line_height_adj->set_step_increment(1.0);
@@ -2216,88 +2058,13 @@ TextToolbar::selection_changed(Inkscape::Selection * /*selection*/, bool subsele
if( line_height_unit == SP_CSS_UNIT_NONE ) {
// Function 'sp_style_get_css_unit_string' returns 'px' for unit none.
// We need to avoid this.
- _tracker->setActiveUnitByAbbr("");
+ _tracker->setActiveUnitByAbbr("lines");
} else {
_tracker->setActiveUnitByAbbr(sp_style_get_css_unit_string(line_height_unit));
}
+
// Save unit so we can do conversions between new/old units.
_lineheight_unit = line_height_unit;
-
- // Enable and turn on only if selection includes an object with line height set.
- _line_height_unset_item->set_sensitive(query.line_height.set);
- _line_height_unset_item->set_active(query.line_height.set);
-
- // Line spacing mode: requires calculating mode for each <text> element and the <tspan>s within.
- Inkscape::Selection *selection = desktop->getSelection();
- std::vector<SPItem *> vec(selection->items().begin(), selection->items().end());
- int mode[4] = {0, 0, 0, 0};
- for (auto i: vec) {
- if (dynamic_cast<SPText*>(i) || dynamic_cast<SPFlowtext*>(i) ) {
- bool text_line_height_set = false;
- bool text_line_height_zero = false;
- bool text_line_height_has_units = false;
- bool tspan_line_height_all_unset = true;
- bool tspan_line_height_all_zero = true;
- bool tspan_line_height_all_non_zero = true;
- if (i->style && i->style->line_height.set) {
- text_line_height_set = true;
- if (i->style->line_height.computed == 0 && !(i->style->line_height.normal)) {
- text_line_height_zero = true;
- }
- if (i->style->line_height.unit != SP_CSS_UNIT_NONE && !(i->style->line_height.normal)) {
- text_line_height_has_units = true;
- }
- }
- // TO DO: recursively check children
- std::vector<SPObject*> children = i->childList(false);
- for (auto j: children) {
- if (dynamic_cast<SPTSpan*>(j) || dynamic_cast<SPFlowpara*>(j) || dynamic_cast<SPFlowtspan*>(j) ) {
- if (j->style && j->style->line_height.set) {
- tspan_line_height_all_unset = false;
- if (j->style->line_height.computed != 0 || j->style->line_height.normal) {
- tspan_line_height_all_zero = false;
- } else {
- tspan_line_height_all_non_zero = false;
- }
- }
- }
- }
-
- if ( text_line_height_zero && tspan_line_height_all_non_zero) mode[0]++;
- else if (!text_line_height_has_units && tspan_line_height_all_unset) mode[1]++;
- else if ( text_line_height_has_units && tspan_line_height_all_unset) mode[3]++;
- else if ( tspan_line_height_all_zero ) mode[2]++;
- else mode[3]++;
- }
- }
-
- int activeButtonLS = 3;
- if (mode[0] > 0 && mode[1] == 0 && mode[2] == 0 && mode[3] == 0) activeButtonLS = 0;
- if (mode[0] == 0 && mode[1] > 0 && mode[2] == 0 && mode[3] == 0) activeButtonLS = 1;
- if (mode[0] == 0 && mode[1] == 0 && mode[2] > 0 && mode[3] == 0) activeButtonLS = 2;
- // std::cout << " modes: " << mode[0]
- // << ", "<< mode[1]
- // << ", "<< mode[2]
- // << ", "<< mode[3] << std::endl;
- _line_spacing_item->set_active( activeButtonLS );
-
- // Enable/disable line height widget based on mode and Outer Style toggle.
- if ( (activeButtonLS == 0 && outer) || // Adaptive
- (activeButtonLS == 1 && !outer) || // Minimum
- (activeButtonLS == 2 && !outer) // Even
- ) {
- _line_height_item->set_sensitive(false);
- } else {
- _line_height_item->set_sensitive(true);
- }
-
- // In Minimum and Adaptive modes, don't allow unit change (must remain unitless).
- if (activeButtonLS == 0 || (activeButtonLS == 1 && outer)) {
- _line_height_units_item->set_sensitive(false);
- } else {
- _line_height_units_item->set_sensitive(true);
- }
-
// Word spacing
double wordSpacing;
if (query.word_spacing.normal) wordSpacing = 0.0;
@@ -2358,6 +2125,7 @@ TextToolbar::selection_changed(Inkscape::Selection * /*selection*/, bool subsele
<< " letter_spacing.value: " << query.letter_spacing.value
<< " letter_spacing.unit: " << query.letter_spacing.unit << std::endl;
std::cout << " GUI: writing_mode.computed: " << query.writing_mode.computed << std::endl;
+}
#endif
// Kerning (xshift), yshift, rotation. NB: These are not CSS attributes.
@@ -2412,11 +2180,15 @@ void
TextToolbar::watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec) {
if (SP_IS_TEXT_CONTEXT(ec)) {
// Watch selection
-
// Ensure FontLister is updated here first.................. VVVVV
- c_selection_changed = desktop->getSelection()->connectChangedFirst(sigc::bind(sigc::mem_fun(*this, &TextToolbar::selection_changed), false));
+ c_selection_changed =
+ desktop->getSelection()->connectChangedFirst(sigc::mem_fun(*this, &TextToolbar::selection_changed));
c_selection_modified = desktop->getSelection()->connectModifiedFirst(sigc::mem_fun(*this, &TextToolbar::selection_modified));
c_subselection_changed = desktop->connectToolSubselectionChanged(sigc::mem_fun(*this, &TextToolbar::subselection_changed));
+ selection_changed(desktop->getSelection());
+ } else if (SP_IS_SELECT_CONTEXT(ec)) {
+ c_selection_modified_select_tool = desktop->getSelection()->connectModifiedFirst(
+ sigc::mem_fun(*this, &TextToolbar::selection_modified_select_tool));
} else {
if (c_selection_changed)
c_selection_changed.disconnect();
@@ -2424,21 +2196,144 @@ TextToolbar::watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec) {
c_selection_modified.disconnect();
if (c_subselection_changed)
c_subselection_changed.disconnect();
+ if (c_selection_modified_select_tool)
+ c_selection_modified_select_tool.disconnect();
}
}
void
TextToolbar::selection_modified(Inkscape::Selection *selection, guint /*flags*/)
{
+
selection_changed(selection);
+
}
-void
-TextToolbar::subselection_changed(gpointer /*tc*/)
+void TextToolbar::subselection_wrap_toggle(bool start)
{
- selection_changed(nullptr, true);
+ if (SP_IS_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context)) {
+ Inkscape::UI::Tools::TextTool *const tc = SP_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context);
+ if (tc) {
+ _updating = true;
+ Inkscape::Text::Layout const *layout = te_get_layout(tc->text);
+ if (layout) {
+ int start_selection = layout->iteratorToCharIndex(tc->text_sel_start);
+ int end_selection = layout->iteratorToCharIndex(tc->text_sel_end);
+ tc->text_sel_start = layout->charIndexToIterator(wrap_start);
+ tc->text_sel_end = layout->charIndexToIterator(wrap_end);
+ wrap_start = start_selection;
+ wrap_end = end_selection;
+ }
+ _updating = start;
+ }
+ }
}
+
+void TextToolbar::subselection_changed(gpointer texttool)
+{
+#ifdef DEBUG_TEXT
+ std::cout << std::endl;
+ std::cout << "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" << std::endl;
+ std::cout << "subselection_changed: start " << std::endl;
+#endif
+ // quit if run by the _changed callbacks
+ this->_subselection = true;
+ this->_fullsubselection = false;
+ Inkscape::UI::Tools::TextTool *const tc = SP_TEXT_CONTEXT(SP_EVENT_CONTEXT(texttool));
+ if (tc) {
+ Inkscape::Text::Layout const *layout = te_get_layout(tc->text);
+ if (layout) {
+ if (_updating || tc->_button1on) {
+ // realy it decrease preformance and dont be important live update,
+ return;
+ }
+ Inkscape::Text::Layout::iterator start = layout->begin();
+ Inkscape::Text::Layout::iterator end = layout->end();
+ Inkscape::Text::Layout::iterator start_selection = tc->text_sel_start;
+ Inkscape::Text::Layout::iterator end_selection = tc->text_sel_end;
+
+ if (start_selection > end_selection) {
+ Inkscape::Text::Layout::iterator tmp_selection = start_selection;
+ start_selection = end_selection;
+ end_selection = tmp_selection;
+ }
+#ifdef DEBUG_TEXT
+ std::cout << " GUI: Start of text: " << layout->iteratorToCharIndex(start) << std::endl;
+ std::cout << " GUI: End of text: " << layout->iteratorToCharIndex(end) << std::endl;
+ std::cout << " GUI: Start of selection: " << layout->iteratorToCharIndex(start_selection) << std::endl;
+ std::cout << " GUI: End of selection: " << layout->iteratorToCharIndex(end_selection) << std::endl;
+ std::cout << " GUI: Loop Subelements: " << std::endl;
+ std::cout << " ::::::::::::::::::::::::::::::::::::::::::::: " << std::endl;
+#endif
+ gint startline = layout->paragraphIndex(start_selection);
+ gint endline = layout->paragraphIndex(end_selection);
+ if (start_selection == end_selection) {
+ this->_outer = true;
+ gint counter = 0;
+ for (auto child : tc->text->childList(false)) {
+ SPItem *item = dynamic_cast<SPItem *>(child);
+ if (counter == startline) {
+ this->_sub_active_item = item;
+ break;
+ }
+ ++counter;
+ }
+ selection_changed(nullptr);
+ } else if (start_selection == start && end_selection == end) {
+ // full subselection
+ this->_sub_active_item = nullptr;
+ this->_outer = true;
+ this->_fullsubselection = true;
+ selection_changed(nullptr);
+ } else {
+ this->_sub_active_item = nullptr;
+ this->_outer = false;
+ gint counter = 0;
+ gint pos = -1;
+ gint prevpos = 0;
+ bool started = false;
+ bool finished = false;
+ for (auto child : tc->text->childList(false)) {
+ SPItem *item = dynamic_cast<SPItem *>(child);
+ if (!dynamic_cast<SPFlowpara *>(item) && !dynamic_cast<SPTSpan *>(item)) {
+ pos += sp_text_get_length(child);
+ prevpos = pos;
+ continue;
+ }
+ pos += sp_text_get_length(child);
+ if (counter >= startline && counter < endline) {
+ if (!started) {
+ started = true;
+ wrap_start = prevpos;
+ }
+ if (!finished && startline == endline) {
+ wrap_end = pos;
+ finished = true;
+ }
+ } else {
+ if (started && !finished) {
+ wrap_end = pos;
+ finished = true;
+ }
+ }
+ prevpos = pos;
+ ++counter;
+ }
+ if (!finished) {
+ wrap_end = pos;
+ finished = true;
+ }
+ selection_changed(nullptr);
+ }
+ }
+ }
+#ifdef DEBUG_TEXT
+ std::cout << "subselection_changed: exit " << std::endl;
+ std::cout << "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" << std::endl;
+ std::cout << std::endl;
+#endif
+}
}
}
}
diff --git a/src/ui/toolbar/text-toolbar.h b/src/ui/toolbar/text-toolbar.h
index 00632b663..4faac9e85 100644
--- a/src/ui/toolbar/text-toolbar.h
+++ b/src/ui/toolbar/text-toolbar.h
@@ -28,9 +28,14 @@
* Released under GNU GPL v2+, read the file 'COPYING' for more information.
*/
+#include "object/sp-item.h"
+#include "object/sp-object.h"
#include "toolbar.h"
-
#include <gtkmm/adjustment.h>
+#include <gtkmm/box.h>
+#include <gtkmm/popover.h>
+#include <gtkmm/separatortoolitem.h>
+#include <sigc++/connection.h>
class SPDesktop;
@@ -59,24 +64,23 @@ class TextToolbar : public Toolbar {
private:
bool _freeze;
bool _text_style_from_prefs;
-
UI::Widget::UnitTracker *_tracker;
+ UI::Widget::UnitTracker *_tracker_fs;
UI::Widget::ComboBoxEntryToolItem *_font_family_item;
UI::Widget::ComboBoxEntryToolItem *_font_size_item;
+ UI::Widget::ComboToolItem *_font_size_units_item;
UI::Widget::ComboBoxEntryToolItem *_font_style_item;
+ UI::Widget::ComboToolItem *_line_height_units_item;
+ UI::Widget::SpinButtonToolItem *_line_height_item;
Gtk::ToggleToolButton *_superscript_item;
Gtk::ToggleToolButton *_subscript_item;
- Gtk::ToggleToolButton *_outer_style_item;
- Gtk::ToggleToolButton *_line_height_unset_item;
+
UI::Widget::ComboToolItem *_align_item;
UI::Widget::ComboToolItem *_writing_mode_item;
UI::Widget::ComboToolItem *_orientation_item;
UI::Widget::ComboToolItem *_direction_item;
- UI::Widget::ComboToolItem *_line_height_units_item;
- UI::Widget::ComboToolItem *_line_spacing_item;
- UI::Widget::SpinButtonToolItem *_line_height_item;
UI::Widget::SpinButtonToolItem *_word_spacing_item;
UI::Widget::SpinButtonToolItem *_letter_spacing_item;
UI::Widget::SpinButtonToolItem *_dx_item;
@@ -89,45 +93,49 @@ private:
Glib::RefPtr<Gtk::Adjustment> _dx_adj;
Glib::RefPtr<Gtk::Adjustment> _dy_adj;
Glib::RefPtr<Gtk::Adjustment> _rotation_adj;
-
+ bool _outer;
+ SPItem *_sub_active_item;
int _lineheight_unit;
-
+ int wrap_start;
+ int wrap_end;
+ bool _subselection;
+ bool _fullsubselection;
+ bool _updating;
+ double selection_fontsize;
sigc::connection c_selection_changed;
sigc::connection c_selection_modified;
+ sigc::connection c_selection_modified_select_tool;
sigc::connection c_subselection_changed;
-
void fontfamily_value_changed();
void fontsize_value_changed();
+ void subselection_wrap_toggle(bool start);
void fontstyle_value_changed();
void script_changed(Gtk::ToggleToolButton *btn);
- void lineheight_unset_changed();
- void outer_style_changed();
void align_mode_changed(int mode);
void writing_mode_changed(int mode);
void orientation_changed(int mode);
void direction_changed(int mode);
void lineheight_value_changed();
void lineheight_unit_changed(int not_used);
- void line_spacing_mode_changed(int mode);
void wordspacing_value_changed();
void letterspacing_value_changed();
void dx_value_changed();
void dy_value_changed();
void rotation_value_changed();
- void selection_changed(Inkscape::Selection *selection,
- bool subselection = false);
+ void fontsize_unit_changed(int not_used);
+ void selection_changed(Inkscape::Selection *selection);
void selection_modified(Inkscape::Selection *selection, guint flags);
- void subselection_changed(gpointer tc);
+ void selection_modified_select_tool(Inkscape::Selection *selection, guint flags);
+ void subselection_changed(gpointer texttool);
void watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec);
void set_sizes(int unit);
-protected:
+ protected:
TextToolbar(SPDesktop *desktop);
public:
static GtkWidget * create(SPDesktop *desktop);
};
-
}
}
}
diff --git a/src/ui/tools/text-tool.cpp b/src/ui/tools/text-tool.cpp
index f4a1be76a..37a1fc45a 100644
--- a/src/ui/tools/text-tool.cpp
+++ b/src/ui/tools/text-tool.cpp
@@ -258,13 +258,14 @@ bool TextTool::item_handler(SPItem* item, GdkEvent* event) {
SPItem *item_ungrouped;
gint ret = FALSE;
-
sp_text_context_validate_cursor_iterators(this);
Inkscape::Text::Layout::iterator old_start = this->text_sel_start;
switch (event->type) {
case GDK_BUTTON_PRESS:
if (event->button.button == 1 && !this->space_panning) {
+ // this var allow too much lees subbselection queries
+ // reducing it to cursor iteracion, mouseup and down
// find out clicked item, disregarding groups
item_ungrouped = desktop->getItemAtPoint(Geom::Point(event->button.x, event->button.y), TRUE);
if (SP_IS_TEXT(item_ungrouped) || SP_IS_FLOWTEXT(item_ungrouped)) {
@@ -318,71 +319,10 @@ bool TextTool::item_handler(SPItem* item, GdkEvent* event) {
this->dragging = 0;
sp_event_context_discard_delayed_snap_event(this);
ret = TRUE;
+ desktop->emitToolSubselectionChanged((gpointer)this);
}
break;
case GDK_MOTION_NOTIFY:
- if ((event->motion.state & GDK_BUTTON1_MASK) && this->dragging && !this->space_panning) {
- Inkscape::Text::Layout const *layout = te_get_layout(this->text);
- if (!layout) break;
- // find out click point in document coordinates
- Geom::Point p = desktop->w2d(Geom::Point(event->button.x, event->button.y));
- // set the cursor closest to that point
- Inkscape::Text::Layout::iterator new_end = sp_te_get_position_by_coords(this->text, p);
- if (this->dragging == 2) {
- // double-click dragging: go by word
- if (new_end < this->text_sel_start) {
- if (!layout->isStartOfWord(new_end))
- new_end.prevStartOfWord();
- } else
- if (!layout->isEndOfWord(new_end))
- new_end.nextEndOfWord();
- } else if (this->dragging == 3) {
- // triple-click dragging: go by line
- if (new_end < this->text_sel_start)
- new_end.thisStartOfLine();
- else
- new_end.thisEndOfLine();
- }
- // update display
- if (this->text_sel_end != new_end) {
- this->text_sel_end = new_end;
- sp_text_context_update_cursor(this);
- sp_text_context_update_text_selection(this);
- }
- gobble_motion_events(GDK_BUTTON1_MASK);
- ret = TRUE;
- break;
- }
- // find out item under mouse, disregarding groups
- item_ungrouped = desktop->getItemAtPoint(Geom::Point(event->button.x, event->button.y), TRUE);
- if (SP_IS_TEXT(item_ungrouped) || SP_IS_FLOWTEXT(item_ungrouped)) {
-
- Inkscape::Text::Layout const *layout = te_get_layout(item_ungrouped);
- if (layout->inputTruncated()) {
- SP_CTRLRECT(this->indicator)->setColor(0xff0000ff, false, 0);
- } else {
- SP_CTRLRECT(this->indicator)->setColor(0x0000ff7f, false, 0);
- }
- Geom::OptRect ibbox = item_ungrouped->desktopVisualBounds();
- if (ibbox) {
- SP_CTRLRECT(this->indicator)->setRectangle(*ibbox);
- }
- sp_canvas_item_show(this->indicator);
-
- this->cursor_shape = cursor_text_insert_xpm;
- this->sp_event_context_update_cursor();
- sp_text_context_update_text_selection(this);
-
- if (SP_IS_TEXT (item_ungrouped)) {
- desktop->event_context->defaultMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("<b>Click</b> to edit the text, <b>drag</b> to select part of the text."));
- } else {
- desktop->event_context->defaultMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("<b>Click</b> to edit the flowed text, <b>drag</b> to select part of the text."));
- }
-
- this->over_text = true;
-
- ret = TRUE;
- }
break;
default:
break;
@@ -552,7 +492,7 @@ bool TextTool::root_handler(GdkEvent* event) {
return TRUE;
}
break;
- case GDK_MOTION_NOTIFY:
+ case GDK_MOTION_NOTIFY: {
if (this->over_text) {
this->over_text = false;
// update cursor and statusbar: we are not over a text object now
@@ -560,7 +500,6 @@ bool TextTool::root_handler(GdkEvent* event) {
this->sp_event_context_update_cursor();
desktop->event_context->defaultMessageContext()->clear();
}
-
if (this->creating && (event->motion.state & GDK_BUTTON1_MASK) && !this->space_panning) {
if ( this->within_tolerance
&& ( abs( (gint) event->motion.x - this->xp ) < this->tolerance )
@@ -598,7 +537,67 @@ bool TextTool::root_handler(GdkEvent* event) {
m.preSnap(Inkscape::SnapCandidatePoint(motion_dt, Inkscape::SNAPSOURCE_OTHER_HANDLE));
m.unSetup();
}
+ ToolBase::root_handler(event);
+ if ((event->motion.state & GDK_BUTTON1_MASK) && this->dragging && !this->space_panning) {
+ Inkscape::Text::Layout const *layout = te_get_layout(this->text);
+ if (!layout) break;
+ // find out click point in document coordinates
+ Geom::Point p = desktop->w2d(Geom::Point(event->button.x, event->button.y));
+ // set the cursor closest to that point
+ Inkscape::Text::Layout::iterator new_end = sp_te_get_position_by_coords(this->text, p);
+ if (this->dragging == 2) {
+ // double-click dragging: go by word
+ if (new_end < this->text_sel_start) {
+ if (!layout->isStartOfWord(new_end))
+ new_end.prevStartOfWord();
+ } else
+ if (!layout->isEndOfWord(new_end))
+ new_end.nextEndOfWord();
+ } else if (this->dragging == 3) {
+ // triple-click dragging: go by line
+ if (new_end < this->text_sel_start)
+ new_end.thisStartOfLine();
+ else
+ new_end.thisEndOfLine();
+ }
+ // update display
+ if (this->text_sel_end != new_end) {
+ this->text_sel_end = new_end;
+ sp_text_context_update_cursor(this);
+ sp_text_context_update_text_selection(this);
+ }
+ gobble_motion_events(GDK_BUTTON1_MASK);
+ break;
+ }
+ // find out item under mouse, disregarding groups
+ SPItem *item_ungrouped = desktop->getItemAtPoint(Geom::Point(event->button.x, event->button.y), TRUE, nullptr);
+ if (SP_IS_TEXT(item_ungrouped) || SP_IS_FLOWTEXT(item_ungrouped)) {
+ Inkscape::Text::Layout const *layout = te_get_layout(item_ungrouped);
+ if (layout->inputTruncated()) {
+ SP_CTRLRECT(this->indicator)->setColor(0xff0000ff, false, 0);
+ } else {
+ SP_CTRLRECT(this->indicator)->setColor(0x0000ff7f, false, 0);
+ }
+ Geom::OptRect ibbox = item_ungrouped->desktopVisualBounds();
+ if (ibbox) {
+ SP_CTRLRECT(this->indicator)->setRectangle(*ibbox);
+ }
+ sp_canvas_item_show(this->indicator);
+
+ this->cursor_shape = cursor_text_insert_xpm;
+ this->sp_event_context_update_cursor();
+ sp_text_context_update_text_selection(this);
+ if (SP_IS_TEXT (item_ungrouped)) {
+ desktop->event_context->defaultMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("<b>Click</b> to edit the text, <b>drag</b> to select part of the text."));
+ } else {
+ desktop->event_context->defaultMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("<b>Click</b> to edit the flowed text, <b>drag</b> to select part of the text."));
+ }
+ this->over_text = true;
+ }
+ return TRUE;
+ }
break;
+
case GDK_BUTTON_RELEASE:
if (event->button.button == 1 && !this->space_panning) {
sp_event_context_discard_delayed_snap_event(this);
@@ -690,6 +689,7 @@ bool TextTool::root_handler(GdkEvent* event) {
}
}
this->creating = false;
+ desktop->emitToolSubselectionChanged((gpointer)this);
return TRUE;
}
break;
diff --git a/src/ui/tools/text-tool.h b/src/ui/tools/text-tool.h
index 96c97c418..666a42dd2 100644
--- a/src/ui/tools/text-tool.h
+++ b/src/ui/tools/text-tool.h
@@ -68,7 +68,6 @@ public:
bool over_text; // true if cursor is over a text object
guint dragging : 2; // dragging selection over text
-
bool creating; // dragging rubberband to create flowtext
SPCanvasItem *grabbed; // we grab while we are creating, to get events even if the mouse goes out of the window
Geom::Point p0; // initial point if the flowtext rect
diff --git a/src/ui/widget/unit-tracker.cpp b/src/ui/widget/unit-tracker.cpp
index 0bdd3210a..c51042bac 100644
--- a/src/ui/widget/unit-tracker.cpp
+++ b/src/ui/widget/unit-tracker.cpp
@@ -85,6 +85,12 @@ Inkscape::Util::Unit const * UnitTracker::getActiveUnit() const
return _activeUnit;
}
+void UnitTracker::changeLabel(Glib::ustring new_label, gint pos)
+{
+ ComboToolItemColumns columns;
+ _store->children()[pos][columns.col_label] = new_label;
+}
+
void UnitTracker::setActiveUnit(Inkscape::Util::Unit const *unit)
{
if (unit) {
diff --git a/src/ui/widget/unit-tracker.h b/src/ui/widget/unit-tracker.h
index 1f16292ff..2af8a057f 100644
--- a/src/ui/widget/unit-tracker.h
+++ b/src/ui/widget/unit-tracker.h
@@ -50,6 +50,7 @@ public:
void addAdjustment(GtkAdjustment *adj);
void prependUnit(Inkscape::Util::Unit const *u);
void setFullVal(GtkAdjustment *adj, gdouble val);
+ void changeLabel(Glib::ustring new_label, gint pos);
ComboToolItem *create_tool_item(Glib::ustring const &label,
Glib::ustring const &tooltip);