Commit f47d6140 authored by twanvl's avatar twanvl

Fixed bug in smart_less, strings ending in numbers were compared incorrectly;

Text viewer now doesn't scale when there is a line break inside a word;
Fixed: extra newline was inserted when there was a line break inside a word if there was padding.
parent a2fd7841
...@@ -430,18 +430,12 @@ bool TextValueEditor::onChar(wxKeyEvent& ev) { ...@@ -430,18 +430,12 @@ bool TextValueEditor::onChar(wxKeyEvent& ev) {
} }
break; break;
case WXK_UP: case WXK_UP:
if (field().multi_line) { if ( wordListDropDown(findWordList(selection_end_i)) ) break;
moveSelection(TYPE_INDEX, v.moveLine(selection_end_i, -1), !ev.ShiftDown(), MOVE_LEFT_OPT); moveSelection(TYPE_INDEX, v.moveLine(selection_end_i, -1), !ev.ShiftDown(), MOVE_LEFT_OPT);
} else {
wordListDropDown(findWordList(selection_end_i));
}
break; break;
case WXK_DOWN: case WXK_DOWN:
if (field().multi_line) { if ( wordListDropDown(findWordList(selection_end_i)) ) break;
moveSelection(TYPE_INDEX, v.moveLine(selection_end_i, +1), !ev.ShiftDown(), MOVE_RIGHT_OPT); moveSelection(TYPE_INDEX, v.moveLine(selection_end_i, +1), !ev.ShiftDown(), MOVE_RIGHT_OPT);
} else {
wordListDropDown(findWordList(selection_end_i));
}
break; break;
case WXK_HOME: case WXK_HOME:
// move to begining of line / all (if control) // move to begining of line / all (if control)
...@@ -805,7 +799,7 @@ void TextValueEditor::showCaret() { ...@@ -805,7 +799,7 @@ void TextValueEditor::showCaret() {
// The caret // The caret
wxCaret* caret = editor().GetCaret(); wxCaret* caret = editor().GetCaret();
// cursor rectangle // cursor rectangle
RealRect cursor = v.charRect(selection_end_i); RealRect cursor = v.charRect(selection_end_i, selection_start_i <= selection_end_i);
cursor.width = 0; cursor.width = 0;
// height may be 0 near a <line> // height may be 0 near a <line>
// it is not 0 for empty text, because TextRenderer handles that case // it is not 0 for empty text, because TextRenderer handles that case
...@@ -1312,8 +1306,8 @@ void TextValueEditor::drawWordListIndicators(RotatedDC& dc, bool redrawing) { ...@@ -1312,8 +1306,8 @@ void TextValueEditor::drawWordListIndicators(RotatedDC& dc, bool redrawing) {
RealRect& r = wl->rect; RealRect& r = wl->rect;
if (r.height < 0) { if (r.height < 0) {
// find the rectangle for this indicator // find the rectangle for this indicator
RealRect start = v.charRect(wl->start); RealRect start = v.charRect(wl->start, true);
RealRect end = v.charRect(wl->end > wl->start ? wl->end - 1 : wl->start); RealRect end = v.charRect(wl->end > wl->start ? wl->end - 1 : wl->start, false);
r.x = start.x; r.x = start.x;
r.y = start.y; r.y = start.y;
r.width = end.right() - start.left() + 0.5; r.width = end.right() - start.left() + 0.5;
......
...@@ -182,7 +182,7 @@ class TextValueEditor : public TextValueViewer, public ValueEditor { ...@@ -182,7 +182,7 @@ class TextValueEditor : public TextValueViewer, public ValueEditor {
WordListPosP findWordListBody(const RealPoint& pos) const; WordListPosP findWordListBody(const RealPoint& pos) const;
/// Find a WordListPos for a index position /// Find a WordListPos for a index position
WordListPosP findWordList(size_t index) const; WordListPosP findWordList(size_t index) const;
/// Show a word list drop down menu, if wl /// Show a word list drop down menu, if wl. Returns true if a list is shown
bool wordListDropDown(const WordListPosP& wl); bool wordListDropDown(const WordListPosP& wl);
}; };
......
...@@ -216,11 +216,18 @@ size_t TextViewer::indexAt(const RealPoint& pos) const { ...@@ -216,11 +216,18 @@ size_t TextViewer::indexAt(const RealPoint& pos) const {
return l->posToIndex(pos.x); return l->posToIndex(pos.x);
} }
RealRect TextViewer::charRect(size_t index) const { RealRect TextViewer::charRect(size_t index, bool first) const {
if (lines.empty()) return RealRect(0,0,0,0); if (lines.empty()) return RealRect(0,0,0,0);
const Line& l = findLine(index); const Line& l = findLine(index);
size_t pos = index - l.start; size_t pos = index - l.start;
if (pos + 1 >= l.positions.size()) { if (pos + 1 >= l.positions.size()) {
if (!first && &l < &lines.back()) {
// try the start of the next line
const Line& l2 = *(&l+1);
if (index == l2.start) {
return RealRect(l2.positions.front(), l2.top, 0, l2.line_height);
}
}
return RealRect(l.positions.back(), l.top, 0, l.line_height); return RealRect(l.positions.back(), l.top, 0, l.line_height);
} else { } else {
return RealRect(l.positions[pos], l.top, l.positions[pos + 1] - l.positions[pos], l.line_height); return RealRect(l.positions[pos], l.top, l.positions[pos + 1] - l.positions[pos], l.line_height);
...@@ -420,7 +427,7 @@ void TextViewer::prepareLinesTryScales(RotatedDC& dc, const String& text, const ...@@ -420,7 +427,7 @@ void TextViewer::prepareLinesTryScales(RotatedDC& dc, const String& text, const
// Try the layout at the previous scale, this could give a quick upper bound // Try the layout at the previous scale, this could give a quick upper bound
elements.getCharInfo(dc, scale, 0, text.size(), chars); elements.getCharInfo(dc, scale, 0, text.size(), chars);
bool fits = prepareLinesScale(dc, chars, style, true, lines); bool fits = prepareLinesScale(dc, chars, style, false, lines);
if (fits) { if (fits) {
min_scale = scale; min_scale = scale;
max_scale = min(max_scale, bound_on_max_scale(dc,style,lines,scale)); max_scale = min(max_scale, bound_on_max_scale(dc,style,lines,scale));
...@@ -431,7 +438,7 @@ void TextViewer::prepareLinesTryScales(RotatedDC& dc, const String& text, const ...@@ -431,7 +438,7 @@ void TextViewer::prepareLinesTryScales(RotatedDC& dc, const String& text, const
vector<Line> lines_before; vector<Line> lines_before;
vector<CharInfo> chars_before; vector<CharInfo> chars_before;
elements.getCharInfo(dc, scale, 0, text.size(), chars_before); elements.getCharInfo(dc, scale, 0, text.size(), chars_before);
fits = prepareLinesScale(dc, chars_before, style, true, lines_before); fits = prepareLinesScale(dc, chars_before, style, false, lines_before);
if (fits) { if (fits) {
// too bad // too bad
swap(lines, lines_before); swap(lines, lines_before);
...@@ -542,7 +549,8 @@ bool TextViewer::prepareLinesScale(RotatedDC& dc, const vector<CharInfo>& chars, ...@@ -542,7 +549,8 @@ bool TextViewer::prepareLinesScale(RotatedDC& dc, const vector<CharInfo>& chars,
// Did the word become too long? // Did the word become too long?
if (style.field().multi_line && !break_now) { if (style.field().multi_line && !break_now) {
double max_width = lineRight(dc, style, line.top); double max_width = lineRight(dc, style, line.top);
if (word_start == line.start && word_size.width > max_width) { if (line_size.width + word_size.width > max_width) {
if (word_start == line.start) {
// single word on this line; the word is too long // single word on this line; the word is too long
if (stop_if_too_long) { if (stop_if_too_long) {
return false; // just give up return false; // just give up
...@@ -553,12 +561,13 @@ bool TextViewer::prepareLinesScale(RotatedDC& dc, const vector<CharInfo>& chars, ...@@ -553,12 +561,13 @@ bool TextViewer::prepareLinesScale(RotatedDC& dc, const vector<CharInfo>& chars,
hide_breaker = false; hide_breaker = false;
line.break_after = BREAK_SOFT; line.break_after = BREAK_SOFT;
} }
} else if (line_size.width + word_size.width > max_width) { } else {
// line would become too long, break before the current word // line would become too long, break before the current word
break_now = true; break_now = true;
line.break_after = BREAK_SOFT; line.break_after = BREAK_SOFT;
} }
} }
}
// Ending the current word // Ending the current word
if (accept_word) { if (accept_word) {
// move word pos to line // move word pos to line
...@@ -572,6 +581,14 @@ bool TextViewer::prepareLinesScale(RotatedDC& dc, const vector<CharInfo>& chars, ...@@ -572,6 +581,14 @@ bool TextViewer::prepareLinesScale(RotatedDC& dc, const vector<CharInfo>& chars,
word_start = i + 1; word_start = i + 1;
positions_word.clear(); positions_word.clear();
word_end_or_soft = 0; word_end_or_soft = 0;
// move character that goes outside the box to the next line
if (!hide_breaker && line.positions.size() > 2) {
line.positions.pop_back();
word_start = i;
word_size = add_horizontal(word_size, c.size);
positions_word.push_back(word_size.width);
if (!c.soft) word_end_or_soft = i + 1;
}
} }
// Breaking (ending the current line) // Breaking (ending the current line)
if (break_now) { if (break_now) {
......
...@@ -84,7 +84,8 @@ class TextViewer { ...@@ -84,7 +84,8 @@ class TextViewer {
RealPoint posOf(size_t index) const; RealPoint posOf(size_t index) const;
/// Return the rectangle around a single character /// Return the rectangle around a single character
RealRect charRect(size_t index) const; /** If 'first' prefers earlier lines */
RealRect charRect(size_t index, bool first) const;
/// Is the character at the given index visible? /// Is the character at the given index visible?
bool isVisible(size_t index) const; bool isVisible(size_t index) const;
/// Find the first character index that is at/before/after the given index, and which has a nonzero width /// Find the first character index that is at/before/after the given index, and which has a nonzero width
......
...@@ -300,6 +300,8 @@ bool smart_less(const String& sa, const String& sb) { ...@@ -300,6 +300,8 @@ bool smart_less(const String& sa, const String& sb) {
// two numbers of the same length, but not equal // two numbers of the same length, but not equal
return lt; return lt;
} else if (a != b) { } else if (a != b) {
// not a number
eq = true; lt = false;
if (a >= 0x20 && b >= 0x20) { if (a >= 0x20 && b >= 0x20) {
// compare characters // compare characters
Char la = remove_accents(a), lb = remove_accents(b); Char la = remove_accents(a), lb = remove_accents(b);
...@@ -333,10 +335,18 @@ bool smart_less(const String& sa, const String& sb) { ...@@ -333,10 +335,18 @@ bool smart_less(const String& sa, const String& sb) {
// When we are at the end; shorter strings come first // When we are at the end; shorter strings come first
// This is true for normal string collation // This is true for normal string collation
// and also when both end in a number and another digit follows // and also when both end in a number and another digit follows
if (na - pa != nb - pb) { if (in_num) {
return na - pa < nb - pb; if (na - pa < nb - pb) {
// number b continues?
Char b = sb.GetChar(pb);
if (isDigit(b) || eq) return true; // b is longer
} else if (na - pa > nb - pb) {
Char a = sa.GetChar(pa);
if (isDigit(a) || eq) return false; // a is longer
}
return lt; // compare numbers
} else { } else {
return lt; return na - pa < nb - pb; // outside number, shorter string comes first
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment