[LyX features/breakrows] Improve row flushing
Jean-Marc Lasgouttes
lasgouttes at lyx.org
Fri Sep 24 15:28:35 UTC 2021
The branch, breakrows, has been updated.
discards 4d44f49b52fa9eedb4ee756bcac236f180c7c79c (commit)
discards 708090d8e4d77a4f65c9c5e8506b7d1c0b4c0364 (commit)
discards 53cff168c421fe9bcef814d5b6f563ac550c1cb7 (commit)
discards 85b1a324afc682686983e4792d2daee4184f7143 (commit)
discards 92d6917a897c2668c91f373dde2e3f85fa1a3b3d (commit)
discards 8ab910586808e075f1ec101d1b04585d455c7be7 (commit)
discards e9824398d85f365bc8d3b1d2eef876ecace207f9 (commit)
discards 257db9a5d88a336c9be777a4d4ba2da84012caa5 (commit)
discards fe01f83bbe813f2e37e7be14fc1bb7c6340ede70 (commit)
discards 31e59c17b74e7742490c0cad817c6a2f0bf1a342 (commit)
discards 4323b15b05378fcdeb460842b84fc5002faec080 (commit)
discards 1be84ac684ca27ce2c5b7141af9ac0a50bd531ab (commit)
discards 8a05ecfce19d3c47caf2c4e0205c0e058d9dcbd5 (commit)
discards 1b98b91bc8b1cc7966abfa4b42e68194ee92843d (commit)
discards b2b11baa07669fccd154a65d4cc254d59f4273e6 (commit)
discards d6c2f362de95341ecef5497ab3287f39b26f7ede (commit)
discards 3b378493b7c381d78098d6c0fb4e5c0c0a3f01e7 (commit)
discards 053f1c4934bc77d491e3ea37da4ebfa35cd9f2bf (commit)
discards 920af321c10d351e63c11178ff5d8a50f341a927 (commit)
discards c7719ec52a13322640dbcbf144286f60981bbfad (commit)
This update added new revisions after undoing existing revisions. That is
to say, the old revision is not a strict subset of the new revision. This
situation occurs when you --force push a change and generate a repository
containing something like this:
* -- * -- B -- O -- O -- O (4d44f49b52fa9eedb4ee756bcac236f180c7c79c)
\
N -- N -- N (94adb4facfaeba960a7da8fe1f5eac83af332730)
When this happens we assume that you've already had alert emails for all
of the O revisions, and so we here report only the revisions in the N
branch from the common base, B.
- Log -----------------------------------------------------------------
commit 94adb4facfaeba960a7da8fe1f5eac83af332730
Author: Jean-Marc Lasgouttes <lasgouttes at lyx.org>
Date: Wed Sep 22 15:09:26 2021 +0200
Improve row flushing
Add new row flags Flush and FlushBefore to let insets indicate whether
they cause flushing of current row (eg. newline) or of previous row
(e.g. display insets).
diff --git a/src/RowFlags.h b/src/RowFlags.h
index f94f0c6..01c4dd2 100644
--- a/src/RowFlags.h
+++ b/src/RowFlags.h
@@ -32,22 +32,26 @@ enum RowFlags {
BreakBefore = 1 << 0,
// Avoid breaking row before this element
NoBreakBefore = 1 << 1,
+ // flush the row before this element (useful with BreakBefore)
+ FlushBefore = 1 << 2,
// force new (maybe empty) row after this element
- AlwaysBreakAfter = 1 << 2,
+ AlwaysBreakAfter = 1 << 3,
// break row after this element if there are more elements
- BreakAfter = 1 << 3,
+ BreakAfter = 1 << 4,
// break row whenever needed after this element
- CanBreakAfter = 1 << 4,
+ CanBreakAfter = 1 << 5,
// Avoid breaking row after this element
- NoBreakAfter = 1 << 5,
+ NoBreakAfter = 1 << 6,
// The contents of the row may be broken in two (e.g. string)
- CanBreakInside = 1 << 6,
+ CanBreakInside = 1 << 7,
+ // Flush the row that ends with this element
+ Flush = 1 << 8,
// specify an alignment (left, right) for a display element
// (default is center)
- AlignLeft = 1 << 7,
- AlignRight = 1 << 8,
+ AlignLeft = 1 << 9,
+ AlignRight = 1 << 10,
// A display element breaks row at both ends
- Display = BreakBefore | BreakAfter,
+ Display = FlushBefore | BreakBefore | BreakAfter,
// Flags that concern breaking after element
AfterFlags = AlwaysBreakAfter | BreakAfter | CanBreakAfter | NoBreakAfter
};
diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp
index 3d89aba..9647cad 100644
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@ -1068,7 +1068,6 @@ void cleanupRow(Row & row, bool at_end)
}
row.endpos(row.back().endpos);
- row.flushed(at_end);
// remove trailing spaces on row break
if (!at_end)
row.back().rtrim();
@@ -1118,8 +1117,11 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
int const f2 = (fcit == end) ? (end_label ? Inline : NoBreakBefore)
: fcit->row_flags;
if (rows.empty() || needsRowBreak(f1, f2)) {
- if (!rows.empty())
+ if (!rows.empty()) {
cleanupRow(rows.back(), false);
+ // Flush row as requested by row flags
+ rows.back().flushed((f1 & Flush) || (f2 & FlushBefore));
+ }
pos_type pos = rows.empty() ? 0 : rows.back().endpos();
rows.push_back(newRow(*this, bigrow.pit(), pos, is_rtl));
// the width available for the row.
diff --git a/src/insets/InsetNewline.cpp b/src/insets/InsetNewline.cpp
index f5fcd42..ecfacf4 100644
--- a/src/insets/InsetNewline.cpp
+++ b/src/insets/InsetNewline.cpp
@@ -39,6 +39,15 @@ InsetNewline::InsetNewline() : Inset(nullptr)
{}
+int InsetNewline::rowFlags() const
+{
+ if (params_.kind == InsetNewlineParams::LINEBREAK)
+ return AlwaysBreakAfter;
+ else
+ return AlwaysBreakAfter | Flush;
+}
+
+
void InsetNewlineParams::write(ostream & os) const
{
switch (kind) {
diff --git a/src/insets/InsetNewline.h b/src/insets/InsetNewline.h
index 1ef0ae5..c85a97d 100644
--- a/src/insets/InsetNewline.h
+++ b/src/insets/InsetNewline.h
@@ -47,7 +47,7 @@ public:
explicit InsetNewline(InsetNewlineParams par) : Inset(0)
{ params_.kind = par.kind; }
///
- int rowFlags() const override { return AlwaysBreakAfter; }
+ int rowFlags() const override;
///
static void string2params(std::string const &, InsetNewlineParams &);
///
diff --git a/src/insets/InsetSeparator.h b/src/insets/InsetSeparator.h
index 9352bdf..0c12d95 100644
--- a/src/insets/InsetSeparator.h
+++ b/src/insets/InsetSeparator.h
@@ -65,7 +65,7 @@ public:
return docstring();
}
///
- int rowFlags() const override { return BreakAfter; }
+ int rowFlags() const override { return BreakAfter | Flush; }
private:
///
InsetCode lyxCode() const override { return SEPARATOR_CODE; }
commit 1d0fbca260492ac48f870ae709848c5def91ef51
Author: Jean-Marc Lasgouttes <lasgouttes at lyx.org>
Date: Wed Sep 22 13:17:46 2021 +0200
Simplify setting of RTL in rows
Set RTL status at row creation, which allows to remove a parameter from
cleanupRow.
diff --git a/src/Row.cpp b/src/Row.cpp
index 6b0faa3..4b9836e 100644
--- a/src/Row.cpp
+++ b/src/Row.cpp
@@ -624,7 +624,7 @@ Row::Elements Row::shortenIfNeeded(int const w, int const next_width)
}
-void Row::reverseRTL(bool const rtl_par)
+void Row::reverseRTL()
{
pos_type i = 0;
pos_type const end = elements_.size();
@@ -636,14 +636,13 @@ void Row::reverseRTL(bool const rtl_par)
++j;
// if the direction is not the same as the paragraph
// direction, the sequence has to be reverted.
- if (rtl != rtl_par)
+ if (rtl != rtl_)
reverse(elements_.begin() + i, elements_.begin() + j);
i = j;
}
// If the paragraph itself is RTL, reverse everything
- if (rtl_par)
+ if (rtl_)
reverse(elements_.begin(), elements_.end());
- rtl_ = rtl_par;
}
Row::const_iterator const
diff --git a/src/Row.h b/src/Row.h
index bf49eb1..2c60638 100644
--- a/src/Row.h
+++ b/src/Row.h
@@ -301,10 +301,12 @@ public:
* Find sequences of right-to-left elements and reverse them.
* This should be called once the row is completely built.
*/
- void reverseRTL(bool rtl_par);
+ void reverseRTL();
///
bool isRTL() const { return rtl_; }
///
+ void setRTL(bool rtl) { rtl_ = rtl; }
+ ///
bool needsChangeBar() const { return changebar_; }
///
void needsChangeBar(bool ncb) { changebar_ = ncb; }
diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp
index caa802c..3d89aba 100644
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@ -1050,6 +1050,7 @@ Row newRow(TextMetrics const & tm, pit_type pit, pos_type pos, bool is_rtl)
nrow.pos(pos);
nrow.left_margin = tm.leftMargin(pit, pos);
nrow.right_margin = tm.rightMargin(pit);
+ nrow.setRTL(is_rtl);
if (is_rtl)
swap(nrow.left_margin, nrow.right_margin);
// Remember that the row width takes into account the left_margin
@@ -1059,7 +1060,7 @@ Row newRow(TextMetrics const & tm, pit_type pit, pos_type pos, bool is_rtl)
}
-void cleanupRow(Row & row, bool at_end, bool is_rtl)
+void cleanupRow(Row & row, bool at_end)
{
if (row.empty()) {
row.endpos(0);
@@ -1074,7 +1075,7 @@ void cleanupRow(Row & row, bool at_end, bool is_rtl)
// boundary exists when there was no space at the end of row
row.right_boundary(!at_end && row.back().endpos == row.endpos());
// make sure that the RTL elements are in reverse ordering
- row.reverseRTL(is_rtl);
+ row.reverseRTL();
}
@@ -1118,7 +1119,7 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
: fcit->row_flags;
if (rows.empty() || needsRowBreak(f1, f2)) {
if (!rows.empty())
- cleanupRow(rows.back(), false, is_rtl);
+ cleanupRow(rows.back(), false);
pos_type pos = rows.empty() ? 0 : rows.back().endpos();
rows.push_back(newRow(*this, bigrow.pit(), pos, is_rtl));
// the width available for the row.
@@ -1152,7 +1153,7 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
}
if (!rows.empty()) {
- cleanupRow(rows.back(), true, is_rtl);
+ cleanupRow(rows.back(), true);
// Last row in paragraph is flushed
rows.back().flushed(true);
}
commit 4e9c754bbb097a836220cb80cadb563c9ce48d2d
Author: Jean-Marc Lasgouttes <lasgouttes at lyx.org>
Date: Mon Sep 6 14:52:42 2021 +0200
Break multi-row strings in one pass
Replace FontMetrics::breakAt, which returned the next break point,
with FontMetrics::breakString, which returns a vector of break points.
To this end, an additional parameter gives the available width for
next rows.
Rename various variables and methods accordingly. Factor the code in
breakString_helper to be more manageable.
Adapt Row::Element::splitAt to return a bool on sucess and provide
remaining row elements in a vector. The width noted above has been
added as parameters.
Rename the helper function splitFrom to moveElements and rewrite the
code to be more efficient.
Remove type of row element INVALID, which is not needed anymore.
The code in TextMetrics::breakParagraph is now much simpler.
In Row::finalize, remove the code that computed inconditionnally the
current element size, and make sure that this width will be computed
in all code paths of Row::Element::splitAt.
diff --git a/src/Row.cpp b/src/Row.cpp
index b7e4c07..6b0faa3 100644
--- a/src/Row.cpp
+++ b/src/Row.cpp
@@ -123,41 +123,81 @@ pos_type Row::Element::x2pos(int &x) const
x = 0;
i = isRTL();
}
- break;
- case INVALID:
- LYXERR0("x2pos: INVALID row element !");
}
//lyxerr << "=> p=" << pos + i << " x=" << x << endl;
return pos + i;
}
-Row::Element Row::Element::splitAt(int w, bool force)
+bool Row::Element::splitAt(int const width, int next_width, bool force,
+ Row::Elements & tail)
{
- if (type != STRING || !(row_flags & CanBreakInside))
- return Element();
+ // Not a string or already OK.
+ if (type != STRING || (dim.wid > 0 && dim.wid < width))
+ return false;
FontMetrics const & fm = theFontMetrics(font);
- dim.wid = w;
- int const i = fm.breakAt(str, dim.wid, isRTL(), force);
- if (i != -1) {
- //Create a second row element to return
- Element ret(STRING, pos + i, font, change);
- ret.str = str.substr(i);
- ret.endpos = ret.pos + ret.str.length();
- // Copy the after flags of the original element to the second one.
- ret.row_flags = row_flags & (CanBreakInside | AfterFlags);
-
- // Now update ourselves
- str.erase(i);
- endpos = pos + i;
- // Row should be broken after the original element
- row_flags = (row_flags & ~AfterFlags) | BreakAfter;
- //LYXERR0("breakAt(" << w << ") Row element Broken at " << w << "(w(str)=" << fm.width(str) << "): e=" << *this);
- return ret;
+
+ // A a string that is not breakable
+ if (!(row_flags & CanBreakInside)) {
+ // has width been computed yet?
+ if (dim.wid == 0)
+ dim.wid = fm.width(str);
+ return false;
+ }
+
+ bool const wrap_any = !font.language()->wordWrap();
+ FontMetrics::Breaks breaks = fm.breakString(str, width, next_width,
+ isRTL(), wrap_any | force);
+
+ // if breaking did not really work, give up
+ if (!force && breaks.front().wid > width) {
+ if (dim.wid == 0)
+ dim.wid = fm.width(str);
+ return false;
+ }
+
+ Element first_e(STRING, pos, font, change);
+ // should next element eventually replace *this?
+ bool first = true;
+ docstring::size_type i = 0;
+ for (FontMetrics::Break const & brk : breaks) {
+ Element e(STRING, pos + i, font, change);
+ e.str = str.substr(i, brk.len);
+ e.endpos = e.pos + brk.len;
+ e.dim.wid = brk.wid;
+ e.row_flags = CanBreakInside | BreakAfter;
+ if (first) {
+ // this element eventually goes to *this
+ e.row_flags |= row_flags & ~AfterFlags;
+ first_e = e;
+ first = false;
+ } else
+ tail.push_back(e);
+ i += brk.len;
}
- return Element();
+ if (!tail.empty()) {
+ // Avoid having a last empty element. This happens when
+ // breaking at the trailing space of string
+ if (tail.back().str.empty())
+ tail.pop_back();
+ else {
+ // Copy the after flags of the original element to the last one.
+ tail.back().row_flags &= ~BreakAfter;
+ tail.back().row_flags |= row_flags & AfterFlags;
+ }
+ // first_e row should be broken after the original element
+ first_e.row_flags |= BreakAfter;
+ } else {
+ // Restore the after flags of the original element.
+ first_e.row_flags &= ~BreakAfter;
+ first_e.row_flags |= row_flags & AfterFlags;
+ }
+
+ // update ourselves
+ swap(first_e, *this);
+ return true;
}
@@ -265,10 +305,6 @@ ostream & operator<<(ostream & os, Row::Element const & e)
break;
case Row::SPACE:
os << "SPACE: ";
- break;
- case Row::INVALID:
- os << "INVALID: ";
- break;
}
os << "width=" << e.full_width() << ", row_flags=" << e.row_flags;
return os;
@@ -393,11 +429,6 @@ void Row::finalizeLast()
elt.final = true;
if (elt.change.changed())
changebar_ = true;
-
- if (elt.type == STRING && elt.dim.wid == 0) {
- elt.dim.wid = theFontMetrics(elt.font).width(elt.str);
- dim_.wid += elt.dim.wid;
- }
}
@@ -474,19 +505,14 @@ void Row::pop_back()
namespace {
-// Remove stuff after \c it from \c elts, and return it.
-// if \c init is provided, it will prepended to the rest
-Row::Elements splitFrom(Row::Elements & elts, Row::Elements::iterator const & it,
- Row::Element const & init = Row::Element())
+// Move stuff after \c it from \c from and the end of \c to.
+void moveElements(Row::Elements & from, Row::Elements::iterator const & it,
+ Row::Elements & to)
{
- Row::Elements ret;
- if (init.isValid())
- ret.push_back(init);
- ret.insert(ret.end(), it, elts.end());
- elts.erase(it, elts.end());
- if (!elts.empty())
- elts.back().row_flags = (elts.back().row_flags & ~AfterFlags) | BreakAfter;
- return ret;
+ to.insert(to.end(), it, from.end());
+ from.erase(it, from.end());
+ if (!from.empty())
+ from.back().row_flags = (from.back().row_flags & ~AfterFlags) | BreakAfter;
}
}
@@ -522,6 +548,7 @@ Row::Elements Row::shortenIfNeeded(int const w, int const next_width)
Elements::iterator cit_brk = cit;
int wid_brk = wid + cit_brk->dim.wid;
++cit_brk;
+ Elements tail;
while (cit_brk != beg) {
--cit_brk;
// make a copy of the element to work on it.
@@ -533,28 +560,18 @@ Row::Elements Row::shortenIfNeeded(int const w, int const next_width)
if (wid_brk <= w && brk.row_flags & CanBreakAfter) {
end_ = brk.endpos;
dim_.wid = wid_brk;
- return splitFrom(elements_, cit_brk + 1);
+ moveElements(elements_, cit_brk + 1, tail);
+ return tail;
}
// assume now that the current element is not there
wid_brk -= brk.dim.wid;
- /*
- * Some Asian languages split lines anywhere (no notion of
- * word). It seems that QTextLayout is not aware of this fact.
- * See for reference:
- * https://en.wikipedia.org/wiki/Line_breaking_rules_in_East_Asian_languages
- *
- * FIXME: Something shall be done about characters which are
- * not allowed at the beginning or end of line.
- */
- bool const word_wrap = brk.font.language()->wordWrap();
/* We have found a suitable separable element. This is the common case.
- * Try to break it cleanly (at word boundary) at a length that is both
+ * Try to break it cleanly at a length that is both
* - less than the available space on the row
* - shorter than the natural width of the element, in order to enforce
* break-up.
*/
- Element remainder = brk.splitAt(min(w - wid_brk, brk.dim.wid - 2), !word_wrap);
- if (brk.row_flags & BreakAfter) {
+ if (brk.splitAt(min(w - wid_brk, brk.dim.wid - 2), next_width, false, tail)) {
/* if this element originally did not cause a row overflow
* in itself, and the remainder of the row would still be
* too large after breaking, then we will have issues in
@@ -568,12 +585,10 @@ Row::Elements Row::shortenIfNeeded(int const w, int const next_width)
*cit_brk = brk;
dim_.wid = wid_brk + brk.dim.wid;
// If there are other elements, they should be removed.
- // remainder can be empty when splitting at trailing space
- if (remainder.str.empty())
- return splitFrom(elements_, next(cit_brk, 1));
- else
- return splitFrom(elements_, next(cit_brk, 1), remainder);
+ moveElements(elements_, cit_brk + 1, tail);
+ return tail;
}
+ LATTEST(tail.empty());
}
if (cit != beg && cit->row_flags & NoBreakBefore) {
@@ -588,20 +603,23 @@ Row::Elements Row::shortenIfNeeded(int const w, int const next_width)
// been added. We can cut right here.
end_ = cit->pos;
dim_.wid = wid;
- return splitFrom(elements_, cit);
+ moveElements(elements_, cit, tail);
+ return tail;
}
/* If we are here, it means that we have not found a separator to
- * shorten the row. Let's try to break it again, but not at word
- * boundary this time.
+ * shorten the row. Let's try to break it again, but force
+ * splitting this time.
*/
- Element remainder = cit->splitAt(w - wid, true);
- if (cit->row_flags & BreakAfter) {
+ if (cit->splitAt(w - wid, next_width, true, tail)) {
+ LYXERR0(*cit);
end_ = cit->endpos;
dim_.wid = wid + cit->dim.wid;
// If there are other elements, they should be removed.
- return splitFrom(elements_, next(cit, 1), remainder);
+ moveElements(elements_, cit + 1, tail);
+ return tail;
}
+
return Elements();
}
diff --git a/src/Row.h b/src/Row.h
index 1272a0f..bf49eb1 100644
--- a/src/Row.h
+++ b/src/Row.h
@@ -50,9 +50,7 @@ public:
// An inset
INSET,
// Some spacing described by its width, not a string
- SPACE,
- // Something that should not happen (for error handling)
- INVALID
+ SPACE
};
/**
@@ -61,8 +59,6 @@ public:
*/
struct Element {
//
- Element() = default;
- //
Element(Type const t, pos_type p, Font const & f, Change const & ch)
: type(t), pos(p), endpos(p + 1), font(f), change(ch) {}
@@ -94,13 +90,16 @@ public:
pos_type x2pos(int &x) const;
/** Break the element in two if possible, so that its width is less
* than \param w.
- * \return an element containing the remainder of the text, or
- * an invalid element if nothing happened.
- * \param w: the desired maximum width
- * \param force: if true, the string is cut at any place, otherwise it
- * respects the row breaking rules of characters.
+ * \return a vector of elements containing the remainder of
+ * the text (empty if nothing happened).
+ * \param width maximum width of the row.
+ * \param next_width available width on next row.
+ * \param force: if true, cut string at any place, even for
+ * languages that wrap at word delimiters; if false, do not
+ * break at all if first element would larger than \c width.
*/
- Element splitAt(int w, bool force);
+ // FIXME: ideally last parameter should be Elements&, but it is not possible.
+ bool splitAt(int width, int next_width, bool force, std::vector<Element> & tail);
// remove trailing spaces (useful for end of row)
void rtrim();
@@ -108,8 +107,6 @@ public:
bool isRTL() const { return font.isVisibleRightToLeft(); }
// This is true for virtual elements.
bool isVirtual() const { return type == VIRTUAL; }
- // Invalid element, for error handling
- bool isValid() const { return type !=INVALID; }
// Returns the position on left side of the element.
pos_type left_pos() const { return isRTL() ? endpos : pos; };
@@ -117,11 +114,11 @@ public:
pos_type right_pos() const { return isRTL() ? pos : endpos; };
// The kind of row element
- Type type = INVALID;
+ Type type;
// position of the element in the paragraph
- pos_type pos = 0;
+ pos_type pos;
// first position after the element in the paragraph
- pos_type endpos = 0;
+ pos_type endpos;
// The dimension of the chunk (does not contains the
// separator correction)
Dimension dim;
@@ -289,8 +286,8 @@ public:
* separator and update endpos if necessary. If all that
* remains is a large word, cut it to \param width.
* \param width maximum width of the row.
- * \param available width on next row.
- * \return true if the row has been shortened.
+ * \param next_width available width on next row.
+ * \return list of elements remaining after breaking.
*/
Elements shortenIfNeeded(int const width, int const next_width);
diff --git a/src/RowPainter.cpp b/src/RowPainter.cpp
index 656f89a..400b7b6 100644
--- a/src/RowPainter.cpp
+++ b/src/RowPainter.cpp
@@ -565,10 +565,6 @@ void RowPainter::paintText()
case Row::SPACE:
paintTextDecoration(e);
- break;
-
- case Row::INVALID:
- LYXERR0("Trying to paint INVALID row element.");
}
// The markings of foreign languages
diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp
index 689addc..caa802c 100644
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@ -1059,7 +1059,7 @@ Row newRow(TextMetrics const & tm, pit_type pit, pos_type pos, bool is_rtl)
}
-void cleanupRow(Row & row, pos_type real_endpos, bool is_rtl)
+void cleanupRow(Row & row, bool at_end, bool is_rtl)
{
if (row.empty()) {
row.endpos(0);
@@ -1067,11 +1067,12 @@ void cleanupRow(Row & row, pos_type real_endpos, bool is_rtl)
}
row.endpos(row.back().endpos);
+ row.flushed(at_end);
// remove trailing spaces on row break
- if (row.endpos() < real_endpos)
+ if (!at_end)
row.back().rtrim();
// boundary exists when there was no space at the end of row
- row.right_boundary(row.endpos() < real_endpos && row.back().endpos == row.endpos());
+ row.right_boundary(!at_end && row.back().endpos == row.endpos());
// make sure that the RTL elements are in reverse ordering
row.reverseRTL(is_rtl);
}
@@ -1098,6 +1099,8 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
RowList rows;
bool const is_rtl = text_->isRTL(bigrow.pit());
bool const end_label = text_->getEndLabel(bigrow.pit()) != END_LABEL_NO_LABEL;
+ int const next_width = max_width_ - leftMargin(bigrow.pit(), bigrow.endpos())
+ - rightMargin(bigrow.pit());
int width = 0;
flexible_const_iterator<Row> fcit = flexible_begin(bigrow);
@@ -1115,7 +1118,7 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
: fcit->row_flags;
if (rows.empty() || needsRowBreak(f1, f2)) {
if (!rows.empty())
- cleanupRow(rows.back(), bigrow.endpos(), is_rtl);
+ cleanupRow(rows.back(), false, is_rtl);
pos_type pos = rows.empty() ? 0 : rows.back().endpos();
rows.push_back(newRow(*this, bigrow.pit(), pos, is_rtl));
// the width available for the row.
@@ -1130,45 +1133,26 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
// Next element to consider is either the top of the temporary
// pile, or the place when we were in main row
Row::Element elt = *fcit;
- Row::Element next_elt = elt.splitAt(width - rows.back().width(),
- !elt.font.language()->wordWrap());
- if (elt.dim.wid > width - rows.back().width()) {
- Row & rb = rows.back();
- rb.push_back(*fcit);
- // if the row is too large, try to cut at last separator. In case
- // of success, reset indication that the row was broken abruptly.
- int const next_width = max_width_ - leftMargin(rb.pit(), rb.endpos())
- - rightMargin(rb.pit());
-
- Row::Elements next_elts = rb.shortenIfNeeded(width, next_width);
-
- // Go to next element
- ++fcit;
-
- // Handle later the elements returned by shortenIfNeeded.
- if (!next_elts.empty()) {
- rb.flushed(false);
- fcit.put(next_elts);
- }
- } else {
- // a new element in the row
- rows.back().push_back(elt);
- rows.back().finalizeLast();
-
- // Go to next element
- ++fcit;
-
- // Add a new next element on the pile
- if (next_elt.isValid()) {
- // do as if we inserted this element in the original row
- if (!next_elt.str.empty())
- fcit.put(next_elt);
- }
+ Row::Elements tail;
+ elt.splitAt(width - rows.back().width(), next_width, false, tail);
+ Row & rb = rows.back();
+ rb.push_back(elt);
+ rb.finalizeLast();
+ if (rb.width() > width) {
+ LATTEST(tail.empty());
+ // if the row is too large, try to cut at last separator.
+ tail = rb.shortenIfNeeded(width, next_width);
}
+
+ // Go to next element
+ ++fcit;
+
+ // Handle later the elements returned by splitAt or shortenIfNeeded.
+ fcit.put(tail);
}
if (!rows.empty()) {
- cleanupRow(rows.back(), bigrow.endpos(), is_rtl);
+ cleanupRow(rows.back(), true, is_rtl);
// Last row in paragraph is flushed
rows.back().flushed(true);
}
diff --git a/src/frontends/FontMetrics.h b/src/frontends/FontMetrics.h
index b562ebf..b78bc2d 100644
--- a/src/frontends/FontMetrics.h
+++ b/src/frontends/FontMetrics.h
@@ -16,6 +16,8 @@
#include "support/strfwd.h"
+#include <vector>
+
/**
* A class holding helper functions for determining
* the screen dimensions of fonts.
@@ -121,15 +123,27 @@ public:
* \param ws is the amount of extra inter-word space applied text justification.
*/
virtual int x2pos(docstring const & s, int & x, bool rtl, double ws) const = 0;
+
+ // The places where to break a string and the width of the resulting lines.
+ struct Break {
+ Break(int l, int w) : len(l), wid(w) {}
+ int len = 0;
+ int wid = 0;
+ };
+ typedef std::vector<Break> Breaks;
/**
- * Break string s at width at most x.
- * \return break position (-1 if not successful)
- * \param position x is updated to real width
- * \param rtl is true for right-to-left layout
+ * Break a string in multiple fragments according to width limits.
+ * \return a sequence of Break elements.
+ * \param s is the string to break.
+ * \param first_wid is the available width for first line.
+ * \param wid is the available width for the next lines.
+ * \param rtl is true for right-to-left layout.
* \param force is false for breaking at word separator, true for
* arbitrary position.
*/
- virtual int breakAt(docstring const & s, int & x, bool rtl, bool force) const = 0;
+ virtual Breaks
+ breakString(docstring const & s, int first_wid, int wid, bool rtl, bool force) const = 0;
+
/// return char dimension for the font.
virtual Dimension const dimension(char_type c) const = 0;
/**
diff --git a/src/frontends/qt/GuiFontMetrics.cpp b/src/frontends/qt/GuiFontMetrics.cpp
index 430ea89..daddeae 100644
--- a/src/frontends/qt/GuiFontMetrics.cpp
+++ b/src/frontends/qt/GuiFontMetrics.cpp
@@ -19,6 +19,7 @@
#include "support/convert.h"
#include "support/lassert.h"
+#include "support/lstrings.h"
#include "support/lyxlib.h"
#include "support/debug.h"
@@ -77,14 +78,14 @@ namespace frontend {
/*
- * Limit (strwidth|breakat)_cache_ size to 512kB of string data.
+ * Limit (strwidth|breakstr)_cache_ size to 512kB of string data.
* Limit qtextlayout_cache_ size to 500 elements (we do not know the
* size of the QTextLayout objects anyway).
* Note that all these numbers are arbitrary.
* Also, setting size to 0 is tantamount to disabling the cache.
*/
int cache_metrics_width_size = 1 << 19;
-int cache_metrics_breakat_size = 1 << 19;
+int cache_metrics_breakstr_size = 1 << 19;
// Qt 5.x already has its own caching of QTextLayout objects
// but it does not seem to work well on MacOS X.
#if (QT_VERSION < 0x050000) || defined(Q_OS_MAC)
@@ -119,7 +120,7 @@ inline QChar const ucs4_to_qchar(char_type const ucs4)
GuiFontMetrics::GuiFontMetrics(QFont const & font)
: font_(font), metrics_(font, 0),
strwidth_cache_(cache_metrics_width_size),
- breakat_cache_(cache_metrics_breakat_size),
+ breakstr_cache_(cache_metrics_breakstr_size),
qtextlayout_cache_(cache_metrics_qtextlayout_size)
{
// Determine italic slope
@@ -476,11 +477,13 @@ int GuiFontMetrics::countExpanders(docstring const & str) const
}
-pair<int, int>
-GuiFontMetrics::breakAt_helper(docstring const & s, int const x,
- bool const rtl, bool const force) const
+namespace {
+
+const int brkStrOffset = 1 + BIDI_OFFSET;
+
+
+QString createBreakableString(docstring const & s, bool rtl, QTextLayout & tl)
{
- QTextLayout tl;
/* Qt will not break at a leading or trailing space, and we need
* that sometimes, see http://www.lyx.org/trac/ticket/9921.
*
@@ -509,34 +512,23 @@ GuiFontMetrics::breakAt_helper(docstring const & s, int const x,
// Left-to-right override: forces to draw text left-to-right
qs = QChar(0x202D) + qs;
#endif
- int const offset = 1 + BIDI_OFFSET;
+ return qs;
+}
- tl.setText(qs);
- tl.setFont(font_);
- QTextOption to;
- to.setWrapMode(force ? QTextOption::WrapAtWordBoundaryOrAnywhere
- : QTextOption::WordWrap);
- // Let QTextLine::naturalTextWidth() account for trailing spaces
- // (horizontalAdvance() still does not).
- to.setFlags(QTextOption::IncludeTrailingSpaces);
- tl.setTextOption(to);
- tl.beginLayout();
- QTextLine line = tl.createLine();
- line.setLineWidth(x);
- tl.createLine();
- tl.endLayout();
- int line_wid = iround(line.horizontalAdvance());
- if ((force && line.textLength() == offset) || line_wid > x)
- return {-1, line_wid};
+
+docstring::size_type brkstr2str_pos(QString brkstr, docstring const & str, int pos)
+{
/* Since QString is UTF-16 and docstring is UCS-4, the offsets may
* not be the same when there are high-plan unicode characters
* (bug #10443).
*/
- // The variable `offset' is here to account for the extra leading characters.
+ // The variable `brkStrOffset' is here to account for the extra leading characters.
// The ending character zerow_nbsp has to be ignored if the line is complete.
- int const qlen = line.textLength() - offset - (line.textLength() == qs.length());
+ int const qlen = pos - brkStrOffset - (pos == brkstr.length());
#if QT_VERSION < 0x040801 || QT_VERSION >= 0x050100
- int len = qstring_to_ucs4(qs.mid(offset, qlen)).length();
+ auto const len = qstring_to_ucs4(brkstr.mid(brkStrOffset, qlen)).length();
+ // Avoid warning
+ (void)str;
#else
/* Due to QTBUG-25536 in 4.8.1 <= Qt < 5.1.0, the string returned
* by QString::toUcs4 (used by qstring_to_ucs4) may have wrong
@@ -546,52 +538,108 @@ GuiFontMetrics::breakAt_helper(docstring const & s, int const x,
* worthwhile to implement a dichotomy search if this shows up
* under a profiler.
*/
- int len = min(qlen, static_cast<int>(s.length()));
- while (len >= 0 && toqstr(s.substr(0, len)).length() != qlen)
+ int len = min(qlen, static_cast<int>(str.length()));
+ while (len >= 0 && toqstr(str.substr(0, len)).length() != qlen)
--len;
LASSERT(len > 0 || qlen == 0, /**/);
#endif
- // Do not cut is the string is already short enough. We rely on
- // naturalTextWidth() to catch the case where we cut at the trailing
- // space.
- if (len == static_cast<int>(s.length())
- && line.naturalTextWidth() <= x) {
- len = -1;
-#if QT_VERSION < 0x050000
+ return len;
+}
+
+}
+
+FontMetrics::Breaks
+GuiFontMetrics::breakString_helper(docstring const & s, int first_wid, int wid,
+ bool rtl, bool force) const
+{
+ QTextLayout tl;
+ QString qs = createBreakableString(s, rtl, tl);
+ tl.setText(qs);
+ tl.setFont(font_);
+ QTextOption to;
+ /*
+ * Some Asian languages split lines anywhere (no notion of
+ * word). It seems that QTextLayout is not aware of this fact.
+ * See for reference:
+ * https://en.wikipedia.org/wiki/Line_breaking_rules_in_East_Asian_languages
+ *
+ * FIXME: Something shall be done about characters which are
+ * not allowed at the beginning or end of line.
+ */
+ to.setWrapMode(force ? QTextOption::WrapAtWordBoundaryOrAnywhere
+ : QTextOption::WordWrap);
+ // Let QTextLine::naturalTextWidth() account for trailing spaces
+ // (horizontalAdvance() still does not).
+ to.setFlags(QTextOption::IncludeTrailingSpaces);
+ tl.setTextOption(to);
+
+ bool first = true;
+ tl.beginLayout();
+ while(true) {
+ QTextLine line = tl.createLine();
+ if (!line.isValid())
+ break;
+ line.setLineWidth(first ? first_wid : wid);
+ tl.createLine();
+ first = false;
+ }
+ tl.endLayout();
+
+ Breaks breaks;
+ int pos = 0;
+ for (int i = 0 ; i < tl.lineCount() ; ++i) {
+ QTextLine const & line = tl.lineAt(i);
+ int const epos = brkstr2str_pos(qs, s, line.textStart() + line.textLength());
+#if QT_VERSION >= 0x050000
+ int const wid = i + 1 < tl.lineCount() ? iround(line.horizontalAdvance())
+ : iround(line.naturalTextWidth());
+#else
// With some monospace fonts, the value of horizontalAdvance()
// can be wrong with Qt4. One hypothesis is that the invisible
// characters that we use are given a non-null width.
- line_wid = width(s);
+ // FIXME: this is slower than it could be but we'll get rid of Qt4 anyway
+ int const wid = i + 1 < tl.lineCount() ? width(rtrim(s.substr(pos, epos - pos)))
+ : width(s.substr(pos, epos - pos));
+#endif
+ breaks.emplace_back(epos - pos, wid);
+ pos = epos;
+#if 0
+ // FIXME: should it be kept in some form?
+ if ((force && line.textLength() == brkStrOffset) || line_wid > x)
+ return {-1, line_wid};
#endif
+
}
- return {len, line_wid};
+
+ return breaks;
}
-uint qHash(BreakAtKey const & key)
+uint qHash(BreakStringKey const & key)
{
- int params = key.force + 2 * key.rtl + 4 * key.x;
+ // assume widths are less than 10000. This fits in 32 bits.
+ uint params = key.force + 2 * key.rtl + 4 * key.first_wid + 10000 * key.wid;
return std::qHash(key.s) ^ ::qHash(params);
}
-int GuiFontMetrics::breakAt(docstring const & s, int & x, bool const rtl, bool const force) const
+FontMetrics::Breaks GuiFontMetrics::breakString(docstring const & s, int first_wid, int wid,
+ bool rtl, bool force) const
{
- PROFILE_THIS_BLOCK(breakAt);
+ PROFILE_THIS_BLOCK(breakString);
if (s.empty())
- return false;
+ return Breaks();
- BreakAtKey key{s, x, rtl, force};
- pair<int, int> pp;
- if (auto * pp_ptr = breakat_cache_.object_ptr(key))
- pp = *pp_ptr;
+ BreakStringKey key{s, first_wid, wid, rtl, force};
+ Breaks brks;
+ if (auto * brks_ptr = breakstr_cache_.object_ptr(key))
+ brks = *brks_ptr;
else {
- PROFILE_CACHE_MISS(breakAt);
- pp = breakAt_helper(s, x, rtl, force);
- breakat_cache_.insert(key, pp, sizeof(key) + s.size() * sizeof(char_type));
+ PROFILE_CACHE_MISS(breakString);
+ brks = breakString_helper(s, first_wid, wid, rtl, force);
+ breakstr_cache_.insert(key, brks, sizeof(key) + s.size() * sizeof(char_type));
}
- x = pp.second;
- return pp.first;
+ return brks;
}
diff --git a/src/frontends/qt/GuiFontMetrics.h b/src/frontends/qt/GuiFontMetrics.h
index 40d668b..9501eb8 100644
--- a/src/frontends/qt/GuiFontMetrics.h
+++ b/src/frontends/qt/GuiFontMetrics.h
@@ -27,20 +27,20 @@
namespace lyx {
namespace frontend {
-struct BreakAtKey
+struct BreakStringKey
{
- bool operator==(BreakAtKey const & key) const {
- return key.s == s && key.x == x && key.rtl == rtl && key.force == force;
+ bool operator==(BreakStringKey const & key) const {
+ return key.s == s && key.first_wid == first_wid && key.wid == wid
+ && key.rtl == rtl && key.force == force;
}
docstring s;
- int x;
+ int first_wid;
+ int wid;
bool rtl;
bool force;
};
-static uint qHash(BreakAtKey const &);
-
struct TextLayoutKey
{
bool operator==(TextLayoutKey const & key) const {
@@ -79,7 +79,7 @@ public:
int signedWidth(docstring const & s) const override;
int pos2x(docstring const & s, int pos, bool rtl, double ws) const override;
int x2pos(docstring const & s, int & x, bool rtl, double ws) const override;
- int breakAt(docstring const & s, int & x, bool rtl, bool force) const override;
+ Breaks breakString(docstring const & s, int first_wid, int wid, bool rtl, bool force) const override;
Dimension const dimension(char_type c) const override;
void rectText(docstring const & str,
@@ -103,8 +103,8 @@ public:
private:
- std::pair<int, int> breakAt_helper(docstring const & s, int const x,
- bool const rtl, bool const force) const;
+ Breaks breakString_helper(docstring const & s, int first_wid, int wid,
+ bool rtl, bool force) const;
/// The font
QFont font_;
@@ -119,8 +119,8 @@ private:
mutable QHash<char_type, int> width_cache_;
/// Cache of string widths
mutable Cache<docstring, int> strwidth_cache_;
- /// Cache for breakAt
- mutable Cache<BreakAtKey, std::pair<int, int>> breakat_cache_;
+ /// Cache for breakString
+ mutable Cache<BreakStringKey, Breaks> breakstr_cache_;
/// Cache for QTextLayout
mutable Cache<TextLayoutKey, std::shared_ptr<QTextLayout>> qtextlayout_cache_;
commit 13a905b4a4519ad6aa0990798446dad39f9b82bf
Author: Jean-Marc Lasgouttes <lasgouttes at lyx.org>
Date: Mon Sep 20 17:32:18 2021 +0200
Add operator<< for Row::Elements
This is useful for debugging.
diff --git a/src/Row.cpp b/src/Row.cpp
index 8233a96..b7e4c07 100644
--- a/src/Row.cpp
+++ b/src/Row.cpp
@@ -275,6 +275,17 @@ ostream & operator<<(ostream & os, Row::Element const & e)
}
+ostream & operator<<(ostream & os, Row::Elements const & elts)
+{
+ double x = 0;
+ for (Row::Element const & e : elts) {
+ os << "x=" << x << " => " << e << endl;
+ x += e.full_width();
+ }
+ return os;
+}
+
+
ostream & operator<<(ostream & os, Row const & row)
{
os << " pos: " << row.pos_ << " end: " << row.end_
@@ -286,11 +297,11 @@ ostream & operator<<(ostream & os, Row const & row)
<< " separator: " << row.separator
<< " label_hfill: " << row.label_hfill
<< " row_boundary: " << row.right_boundary() << "\n";
+ // We cannot use the operator above, unfortunately
double x = row.left_margin;
- Row::Elements::const_iterator it = row.elements_.begin();
- for ( ; it != row.elements_.end() ; ++it) {
- os << "x=" << x << " => " << *it << endl;
- x += it->full_width();
+ for (Row::Element const & e : row.elements_) {
+ os << "x=" << x << " => " << e << endl;
+ x += e.full_width();
}
return os;
}
diff --git a/src/Row.h b/src/Row.h
index 7466797..1272a0f 100644
--- a/src/Row.h
+++ b/src/Row.h
@@ -378,6 +378,8 @@ private:
bool changebar_ = false;
};
+std::ostream & operator<<(std::ostream & os, Row::Elements const & elts);
+
/**
* Each paragraph is broken up into a number of rows on the screen.
commit 4ff27953128eb2920f40e63b599fe5dd0315421f
Author: Jean-Marc Lasgouttes <lasgouttes at lyx.org>
Date: Thu Sep 2 15:16:28 2021 +0200
Fix setting of row pos/endpos (overlapping rows)
In TextMetrics::breakParagraph, get rid of the fragile `pos' local
variable, which was not correctly updated. Rely on the endpos of the
last element in row instead.
Rewrite cleanupRow to rely on the endpos of last the row element to
set row endpos, instead of a `pos' parameter.
diff --git a/src/Row.cpp b/src/Row.cpp
index 7b74694..8233a96 100644
--- a/src/Row.cpp
+++ b/src/Row.cpp
@@ -463,8 +463,8 @@ void Row::pop_back()
namespace {
-// Remove stuff after it from elts, and return it.
-// if init is provided, it will be in front of the rest
+// Remove stuff after \c it from \c elts, and return it.
+// if \c init is provided, it will prepended to the rest
Row::Elements splitFrom(Row::Elements & elts, Row::Elements::iterator const & it,
Row::Element const & init = Row::Element())
{
diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp
index d96141c..689addc 100644
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@ -1059,15 +1059,19 @@ Row newRow(TextMetrics const & tm, pit_type pit, pos_type pos, bool is_rtl)
}
-void cleanupRow(Row & row, pos_type pos, pos_type real_endpos, bool is_rtl)
+void cleanupRow(Row & row, pos_type real_endpos, bool is_rtl)
{
- row.endpos(pos);
+ if (row.empty()) {
+ row.endpos(0);
+ return;
+ }
+
+ row.endpos(row.back().endpos);
// remove trailing spaces on row break
- if (pos < real_endpos && !row.empty())
+ if (row.endpos() < real_endpos)
row.back().rtrim();
// boundary exists when there was no space at the end of row
- row.right_boundary(!row.empty() && pos < real_endpos
- && row.back().endpos == pos);
+ row.right_boundary(row.endpos() < real_endpos && row.back().endpos == row.endpos());
// make sure that the RTL elements are in reverse ordering
row.reverseRTL(is_rtl);
}
@@ -1095,7 +1099,6 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
bool const is_rtl = text_->isRTL(bigrow.pit());
bool const end_label = text_->getEndLabel(bigrow.pit()) != END_LABEL_NO_LABEL;
- pos_type pos = 0;
int width = 0;
flexible_const_iterator<Row> fcit = flexible_begin(bigrow);
flexible_const_iterator<Row> const end = flexible_end(bigrow);
@@ -1112,7 +1115,8 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
: fcit->row_flags;
if (rows.empty() || needsRowBreak(f1, f2)) {
if (!rows.empty())
- cleanupRow(rows.back(), pos, bigrow.endpos(), is_rtl);
+ cleanupRow(rows.back(), bigrow.endpos(), is_rtl);
+ pos_type pos = rows.empty() ? 0 : rows.back().endpos();
rows.push_back(newRow(*this, bigrow.pit(), pos, is_rtl));
// the width available for the row.
width = max_width_ - rows.back().right_margin;
@@ -1150,7 +1154,6 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
// a new element in the row
rows.back().push_back(elt);
rows.back().finalizeLast();
- pos = elt.endpos;
// Go to next element
++fcit;
@@ -1165,7 +1168,7 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
}
if (!rows.empty()) {
- cleanupRow(rows.back(), pos, bigrow.endpos(), is_rtl);
+ cleanupRow(rows.back(), bigrow.endpos(), is_rtl);
// Last row in paragraph is flushed
rows.back().flushed(true);
}
commit 0d6ebc9ba679d868a8ad66a24b5346ec6e918942
Author: Jean-Marc Lasgouttes <lasgouttes at lyx.org>
Date: Wed Sep 1 16:54:28 2021 +0200
Get rid of need_new_row boolean in breakParagraph
Instead of having breakParagraph decide when breaking a row is
necessary, let Row::shortenIfNeeded set the row_flag of the last
element to request a row break. This was already done in splitAt.
This is in preparation of splitAt splitting in more than two elements.
diff --git a/src/Row.cpp b/src/Row.cpp
index d3529a3..7b74694 100644
--- a/src/Row.cpp
+++ b/src/Row.cpp
@@ -473,6 +473,8 @@ Row::Elements splitFrom(Row::Elements & elts, Row::Elements::iterator const & it
ret.push_back(init);
ret.insert(ret.end(), it, elts.end());
elts.erase(it, elts.end());
+ if (!elts.empty())
+ elts.back().row_flags = (elts.back().row_flags & ~AfterFlags) | BreakAfter;
return ret;
}
diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp
index 0ffd8d8..d96141c 100644
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@ -1042,6 +1042,7 @@ bool operator==(flexible_const_iterator<T> const & t1,
return t1.cit_ == t2.cit_ && t1.pile_.empty() && t2.pile_.empty();
}
+
Row newRow(TextMetrics const & tm, pit_type pit, pos_type pos, bool is_rtl)
{
Row nrow;
@@ -1071,6 +1072,7 @@ void cleanupRow(Row & row, pos_type pos, pos_type real_endpos, bool is_rtl)
row.reverseRTL(is_rtl);
}
+
// Implement the priorities described in RowFlags.h.
bool needsRowBreak(int f1, int f2)
{
@@ -1093,14 +1095,12 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
bool const is_rtl = text_->isRTL(bigrow.pit());
bool const end_label = text_->getEndLabel(bigrow.pit()) != END_LABEL_NO_LABEL;
- bool need_new_row = true;
pos_type pos = 0;
int width = 0;
flexible_const_iterator<Row> fcit = flexible_begin(bigrow);
flexible_const_iterator<Row> const end = flexible_end(bigrow);
while (true) {
- bool const has_row = !rows.empty();
- bool const row_empty = !has_row || rows.back().empty();
+ bool const row_empty = rows.empty() || rows.back().empty();
// The row flags of previous element, if there is one.
// Otherwise we use NoBreakAfter to avoid an empty row before
// e.g. a displayed equation.
@@ -1110,14 +1110,12 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
// paragraph has an end label (for which an empty row is OK).
int const f2 = (fcit == end) ? (end_label ? Inline : NoBreakBefore)
: fcit->row_flags;
- need_new_row |= needsRowBreak(f1, f2);
- if (need_new_row) {
+ if (rows.empty() || needsRowBreak(f1, f2)) {
if (!rows.empty())
cleanupRow(rows.back(), pos, bigrow.endpos(), is_rtl);
rows.push_back(newRow(*this, bigrow.pit(), pos, is_rtl));
// the width available for the row.
width = max_width_ - rows.back().right_margin;
- need_new_row = false;
}
// The stopping condition is here because we may need a new
@@ -1147,7 +1145,6 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
if (!next_elts.empty()) {
rb.flushed(false);
fcit.put(next_elts);
- need_new_row = true;
}
} else {
// a new element in the row
@@ -1163,7 +1160,6 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
// do as if we inserted this element in the original row
if (!next_elt.str.empty())
fcit.put(next_elt);
- need_new_row = true;
}
}
}
commit 22eead1c271451b09f9cf0b8d3b810385853d043
Author: Jean-Marc Lasgouttes <lasgouttes at lyx.org>
Date: Tue Aug 31 19:23:55 2021 +0200
Centralize the code that removes trailing spaces from end row element.
Move to Row::Element::rtrim the code in Row::shortenIfNeeded that
removes trailing spaces from last element in row, so that it can be
called when actually breaking a row.
Fixes bug found by Kornel.
diff --git a/src/Row.cpp b/src/Row.cpp
index 38dbb85..d3529a3 100644
--- a/src/Row.cpp
+++ b/src/Row.cpp
@@ -35,7 +35,6 @@ using namespace std;
namespace lyx {
-using support::rtrim;
using frontend::FontMetrics;
@@ -162,6 +161,20 @@ Row::Element Row::Element::splitAt(int w, bool force)
}
+void Row::Element::rtrim()
+{
+ if (type != STRING)
+ return;
+ /* This is intended for strings that have been created by splitAt.
+ * They may have trailing spaces, but they are not counted in the
+ * string length (QTextLayout feature, actually). We remove them,
+ * and decrease endpos, since spaces at row break are invisible.
+ */
+ str = support::rtrim(str);
+ endpos = pos + str.length();
+}
+
+
bool Row::isMarginSelected(bool left, DocIterator const & beg,
DocIterator const & end) const
{
@@ -539,14 +552,6 @@ Row::Elements Row::shortenIfNeeded(int const w, int const next_width)
break;
}
end_ = brk.endpos;
- /* after breakAt, there may be spaces at the end of the
- * string, but they are not counted in the string length
- * (QTextLayout feature, actually). We remove them, but do
- * not change the end of the row, since spaces at row
- * break are invisible.
- */
- brk.str = rtrim(brk.str);
- brk.endpos = brk.pos + brk.str.length();
*cit_brk = brk;
dim_.wid = wid_brk + brk.dim.wid;
// If there are other elements, they should be removed.
@@ -578,11 +583,8 @@ Row::Elements Row::shortenIfNeeded(int const w, int const next_width)
* boundary this time.
*/
Element remainder = cit->splitAt(w - wid, true);
- if (remainder.isValid()) {
+ if (cit->row_flags & BreakAfter) {
end_ = cit->endpos;
- // See comment above.
- cit->str = rtrim(cit->str);
- cit->endpos = cit->pos + cit->str.length();
dim_.wid = wid + cit->dim.wid;
// If there are other elements, they should be removed.
return splitFrom(elements_, next(cit, 1), remainder);
diff --git a/src/Row.h b/src/Row.h
index b0b1755..7466797 100644
--- a/src/Row.h
+++ b/src/Row.h
@@ -101,6 +101,8 @@ public:
* respects the row breaking rules of characters.
*/
Element splitAt(int w, bool force);
+ // remove trailing spaces (useful for end of row)
+ void rtrim();
//
bool isRTL() const { return font.isVisibleRightToLeft(); }
diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp
index 3dcacb9..0ffd8d8 100644
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@ -1061,6 +1061,10 @@ Row newRow(TextMetrics const & tm, pit_type pit, pos_type pos, bool is_rtl)
void cleanupRow(Row & row, pos_type pos, pos_type real_endpos, bool is_rtl)
{
row.endpos(pos);
+ // remove trailing spaces on row break
+ if (pos < real_endpos && !row.empty())
+ row.back().rtrim();
+ // boundary exists when there was no space at the end of row
row.right_boundary(!row.empty() && pos < real_endpos
&& row.back().endpos == pos);
// make sure that the RTL elements are in reverse ordering
commit d9a196ffde2f41639a7f24d45a83b97597b3bcdc
Author: Jean-Marc Lasgouttes <lasgouttes at lyx.org>
Date: Tue Aug 31 15:58:56 2021 +0200
Handle the case where breakAt cuts after trailing space
In this case, the extra element returned should empty but valid. The
row flag BreakAfter is set to indicate that we have a break there
(this principle will be used more generally in a forthcoming commit).
To detect that we cut at the trailing space, it is necessary to rely
on the difference between QTextLine::horizontalAdvance() and
QTextLine::naturalTextWidth() when the flag
QTextOption::IncludeTrailingSpaces is used: the trailing space is
taken into account in the later, but not in the former.
Somme comments have been added to make code intent clearer.
diff --git a/src/Row.cpp b/src/Row.cpp
index 6e975a5..38dbb85 100644
--- a/src/Row.cpp
+++ b/src/Row.cpp
@@ -142,13 +142,19 @@ Row::Element Row::Element::splitAt(int w, bool force)
dim.wid = w;
int const i = fm.breakAt(str, dim.wid, isRTL(), force);
if (i != -1) {
+ //Create a second row element to return
Element ret(STRING, pos + i, font, change);
ret.str = str.substr(i);
ret.endpos = ret.pos + ret.str.length();
+ // Copy the after flags of the original element to the second one.
ret.row_flags = row_flags & (CanBreakInside | AfterFlags);
+
+ // Now update ourselves
str.erase(i);
endpos = pos + i;
- //lyxerr << "breakAt(" << w << ") Row element Broken at " << x << "(w(str)=" << fm.width(str) << "): e=" << *this << endl;
+ // Row should be broken after the original element
+ row_flags = (row_flags & ~AfterFlags) | BreakAfter;
+ //LYXERR0("breakAt(" << w << ") Row element Broken at " << w << "(w(str)=" << fm.width(str) << "): e=" << *this);
return ret;
}
@@ -251,7 +257,7 @@ ostream & operator<<(ostream & os, Row::Element const & e)
os << "INVALID: ";
break;
}
- os << "width=" << e.full_width();
+ os << "width=" << e.full_width() << ", row_flags=" << e.row_flags;
return os;
}
@@ -522,7 +528,7 @@ Row::Elements Row::shortenIfNeeded(int const w, int const next_width)
* break-up.
*/
Element remainder = brk.splitAt(min(w - wid_brk, brk.dim.wid - 2), !word_wrap);
- if (remainder.isValid()) {
+ if (brk.row_flags & BreakAfter) {
/* if this element originally did not cause a row overflow
* in itself, and the remainder of the row would still be
* too large after breaking, then we will have issues in
@@ -544,7 +550,11 @@ Row::Elements Row::shortenIfNeeded(int const w, int const next_width)
*cit_brk = brk;
dim_.wid = wid_brk + brk.dim.wid;
// If there are other elements, they should be removed.
- return splitFrom(elements_, next(cit_brk, 1), remainder);
+ // remainder can be empty when splitting at trailing space
+ if (remainder.str.empty())
+ return splitFrom(elements_, next(cit_brk, 1));
+ else
+ return splitFrom(elements_, next(cit_brk, 1), remainder);
}
}
diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp
index 187d0ed..3dcacb9 100644
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@ -1157,7 +1157,8 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
// Add a new next element on the pile
if (next_elt.isValid()) {
// do as if we inserted this element in the original row
- fcit.put(next_elt);
+ if (!next_elt.str.empty())
+ fcit.put(next_elt);
need_new_row = true;
}
}
diff --git a/src/frontends/qt/GuiFontMetrics.cpp b/src/frontends/qt/GuiFontMetrics.cpp
index bafe2d0..430ea89 100644
--- a/src/frontends/qt/GuiFontMetrics.cpp
+++ b/src/frontends/qt/GuiFontMetrics.cpp
@@ -516,6 +516,9 @@ GuiFontMetrics::breakAt_helper(docstring const & s, int const x,
QTextOption to;
to.setWrapMode(force ? QTextOption::WrapAtWordBoundaryOrAnywhere
: QTextOption::WordWrap);
+ // Let QTextLine::naturalTextWidth() account for trailing spaces
+ // (horizontalAdvance() still does not).
+ to.setFlags(QTextOption::IncludeTrailingSpaces);
tl.setTextOption(to);
tl.beginLayout();
QTextLine line = tl.createLine();
@@ -548,8 +551,11 @@ GuiFontMetrics::breakAt_helper(docstring const & s, int const x,
--len;
LASSERT(len > 0 || qlen == 0, /**/);
#endif
- // Do not cut is the string is already short enough
- if (len == static_cast<int>(s.length())) {
+ // Do not cut is the string is already short enough. We rely on
+ // naturalTextWidth() to catch the case where we cut at the trailing
+ // space.
+ if (len == static_cast<int>(s.length())
+ && line.naturalTextWidth() <= x) {
len = -1;
#if QT_VERSION < 0x050000
// With some monospace fonts, the value of horizontalAdvance()
commit a7138ae74a424ec7a8565d1b3edbe3781c6c593a
Author: Jean-Marc Lasgouttes <lasgouttes at lyx.org>
Date: Mon Aug 30 15:48:44 2021 +0200
Workaround for Qt 4
At least with Qt 4.8.7 on Ubuntu 16.04, QTextLine::lineWidth() can
return a bogus value, at least with Courier font. One hypothesis is
that the invisible characters that we use in breakAt_helper are given
a non-null width.
Work around it, although the exact bug has not been pinpointed.
diff --git a/src/frontends/qt/GuiFontMetrics.cpp b/src/frontends/qt/GuiFontMetrics.cpp
index b38bed9..bafe2d0 100644
--- a/src/frontends/qt/GuiFontMetrics.cpp
+++ b/src/frontends/qt/GuiFontMetrics.cpp
@@ -522,7 +522,7 @@ GuiFontMetrics::breakAt_helper(docstring const & s, int const x,
line.setLineWidth(x);
tl.createLine();
tl.endLayout();
- int const line_wid = iround(line.horizontalAdvance());
+ int line_wid = iround(line.horizontalAdvance());
if ((force && line.textLength() == offset) || line_wid > x)
return {-1, line_wid};
/* Since QString is UTF-16 and docstring is UCS-4, the offsets may
@@ -548,9 +548,16 @@ GuiFontMetrics::breakAt_helper(docstring const & s, int const x,
--len;
LASSERT(len > 0 || qlen == 0, /**/);
#endif
- // si la chaîne est déjà trop courte, on ne coupe pas
- if (len == static_cast<int>(s.length()))
+ // Do not cut is the string is already short enough
+ if (len == static_cast<int>(s.length())) {
len = -1;
+#if QT_VERSION < 0x050000
+ // With some monospace fonts, the value of horizontalAdvance()
+ // can be wrong with Qt4. One hypothesis is that the invisible
+ // characters that we use are given a non-null width.
+ line_wid = width(s);
+#endif
+ }
return {len, line_wid};
}
commit cc4b822abe80598e9ac5418e857b018bb7c48169
Author: Jean-Marc Lasgouttes <lasgouttes at lyx.org>
Date: Tue Jul 20 00:07:13 2021 +0200
Last step of transition: use sortenIfNeeded again.
Change semantics of Row::shortenIfNeeded: instead of breaking the row
and returning a boolean, it returns the list of row elements that have
been removed (or broken) from the row. The logic of the method remains
the same.
Use shortenIfNeeded in breakParagraph. This was the last missing block.
Remove Row::breakAt and the old breakRow. Only bugs remain now :)
diff --git a/src/Row.cpp b/src/Row.cpp
index 3bc8ef0..6e975a5 100644
--- a/src/Row.cpp
+++ b/src/Row.cpp
@@ -156,12 +156,6 @@ Row::Element Row::Element::splitAt(int w, bool force)
}
-bool Row::Element::breakAt(int w, bool force)
-{
- return splitAt(w, force).isValid();
-}
-
-
bool Row::isMarginSelected(bool left, DocIterator const & beg,
DocIterator const & end) const
{
@@ -448,10 +442,31 @@ void Row::pop_back()
}
-bool Row::shortenIfNeeded(int const w, int const next_width)
+namespace {
+
+// Remove stuff after it from elts, and return it.
+// if init is provided, it will be in front of the rest
+Row::Elements splitFrom(Row::Elements & elts, Row::Elements::iterator const & it,
+ Row::Element const & init = Row::Element())
+{
+ Row::Elements ret;
+ if (init.isValid())
+ ret.push_back(init);
+ ret.insert(ret.end(), it, elts.end());
+ elts.erase(it, elts.end());
+ return ret;
+}
+
+}
+
+
+Row::Elements Row::shortenIfNeeded(int const w, int const next_width)
{
+ // FIXME: performance: if the last element is a string, we would
+ // like to avoid computing its length.
+ finalizeLast();
if (empty() || width() <= w)
- return false;
+ return Elements();
Elements::iterator const beg = elements_.begin();
Elements::iterator const end = elements_.end();
@@ -467,8 +482,8 @@ bool Row::shortenIfNeeded(int const w, int const next_width)
if (cit == end) {
// This should not happen since the row is too long.
- LYXERR0("Something is wrong cannot shorten row: " << *this);
- return false;
+ LYXERR0("Something is wrong, cannot shorten row: " << *this);
+ return Elements();
}
// Iterate backwards over breakable elements and try to break them
@@ -486,8 +501,7 @@ bool Row::shortenIfNeeded(int const w, int const next_width)
if (wid_brk <= w && brk.row_flags & CanBreakAfter) {
end_ = brk.endpos;
dim_.wid = wid_brk;
- elements_.erase(cit_brk + 1, end);
- return true;
+ return splitFrom(elements_, cit_brk + 1);
}
// assume now that the current element is not there
wid_brk -= brk.dim.wid;
@@ -507,7 +521,8 @@ bool Row::shortenIfNeeded(int const w, int const next_width)
* - shorter than the natural width of the element, in order to enforce
* break-up.
*/
- if (brk.breakAt(min(w - wid_brk, brk.dim.wid - 2), !word_wrap)) {
+ Element remainder = brk.splitAt(min(w - wid_brk, brk.dim.wid - 2), !word_wrap);
+ if (remainder.isValid()) {
/* if this element originally did not cause a row overflow
* in itself, and the remainder of the row would still be
* too large after breaking, then we will have issues in
@@ -529,14 +544,13 @@ bool Row::shortenIfNeeded(int const w, int const next_width)
*cit_brk = brk;
dim_.wid = wid_brk + brk.dim.wid;
// If there are other elements, they should be removed.
- elements_.erase(cit_brk + 1, end);
- return true;
+ return splitFrom(elements_, next(cit_brk, 1), remainder);
}
}
- if (cit != beg && cit->type == VIRTUAL) {
- // It is not possible to separate a virtual element from the
- // previous one.
+ if (cit != beg && cit->row_flags & NoBreakBefore) {
+ // It is not possible to separate this element from the
+ // previous one. (e.g. VIRTUAL)
--cit;
wid -= cit->dim.wid;
}
@@ -546,25 +560,24 @@ bool Row::shortenIfNeeded(int const w, int const next_width)
// been added. We can cut right here.
end_ = cit->pos;
dim_.wid = wid;
- elements_.erase(cit, end);
- return true;
+ return splitFrom(elements_, cit);
}
/* If we are here, it means that we have not found a separator to
* shorten the row. Let's try to break it again, but not at word
* boundary this time.
*/
- if (cit->breakAt(w - wid, true)) {
+ Element remainder = cit->splitAt(w - wid, true);
+ if (remainder.isValid()) {
end_ = cit->endpos;
// See comment above.
cit->str = rtrim(cit->str);
cit->endpos = cit->pos + cit->str.length();
dim_.wid = wid + cit->dim.wid;
// If there are other elements, they should be removed.
- elements_.erase(next(cit, 1), end);
- return true;
+ return splitFrom(elements_, next(cit, 1), remainder);
}
- return false;
+ return Elements();
}
diff --git a/src/Row.h b/src/Row.h
index 72d7a86..b0b1755 100644
--- a/src/Row.h
+++ b/src/Row.h
@@ -101,12 +101,6 @@ public:
* respects the row breaking rules of characters.
*/
Element splitAt(int w, bool force);
- /** Break the element if possible, so that its width is less
- * than \param w. Returns true on success. When \param force
- * is true, the string is cut at any place, otherwise it
- * respects the row breaking rules of characters.
- */
- bool breakAt(int w, bool force);
//
bool isRTL() const { return font.isVisibleRightToLeft(); }
@@ -296,7 +290,7 @@ public:
* \param available width on next row.
* \return true if the row has been shortened.
*/
- bool shortenIfNeeded(int const width, int const next_width);
+ Elements shortenIfNeeded(int const width, int const next_width);
/**
* If last element of the row is a string, compute its width
diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp
index c829d94..187d0ed 100644
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@ -491,7 +491,7 @@ bool TextMetrics::redoParagraph(pit_type const pit, bool const align_rows)
// If there is an end of paragraph marker, its size should be
// substracted to the available width. The logic here is
- // almost the same as in breakRow, remember keep them in sync.
+ // almost the same as in tokenizeParagraph, remember keep them in sync.
int eop = 0;
if (e.pos + 1 == par.size()
&& (lyxrc.paragraph_markers || par.lookupChange(par.size()).changed())
@@ -1006,6 +1006,11 @@ public:
void put(value_type const & e) { pile_.push_back(e); }
+ // Put a sequence of elements on the pile (in reverse order!)
+ void put(vector<value_type> const & elts) {
+ pile_.insert(pile_.end(), elts.rbegin(), elts.rend());
+ }
+
// This should be private, but declaring the friend functions is too much work
//private:
typename T::const_iterator cit_;
@@ -1121,19 +1126,40 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
Row::Element elt = *fcit;
Row::Element next_elt = elt.splitAt(width - rows.back().width(),
!elt.font.language()->wordWrap());
- // a new element in the row
- rows.back().push_back(elt);
- rows.back().finalizeLast();
- pos = elt.endpos;
-
- // Go to next element
- ++fcit;
-
- // Add a new next element on the pile
- if (next_elt.isValid()) {
- // do as if we inserted this element in the original row
- fcit.put(next_elt);
- need_new_row = true;
+ if (elt.dim.wid > width - rows.back().width()) {
+ Row & rb = rows.back();
+ rb.push_back(*fcit);
+ // if the row is too large, try to cut at last separator. In case
+ // of success, reset indication that the row was broken abruptly.
+ int const next_width = max_width_ - leftMargin(rb.pit(), rb.endpos())
+ - rightMargin(rb.pit());
+
+ Row::Elements next_elts = rb.shortenIfNeeded(width, next_width);
+
+ // Go to next element
+ ++fcit;
+
+ // Handle later the elements returned by shortenIfNeeded.
+ if (!next_elts.empty()) {
+ rb.flushed(false);
+ fcit.put(next_elts);
+ need_new_row = true;
+ }
+ } else {
+ // a new element in the row
+ rows.back().push_back(elt);
+ rows.back().finalizeLast();
+ pos = elt.endpos;
+
+ // Go to next element
+ ++fcit;
+
+ // Add a new next element on the pile
+ if (next_elt.isValid()) {
+ // do as if we inserted this element in the original row
+ fcit.put(next_elt);
+ need_new_row = true;
+ }
}
}
@@ -1146,185 +1172,6 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
return rows;
}
-/** This is the function where the hard work is done. The code here is
- * very sensitive to small changes :) Note that part of the
- * intelligence is also in Row::shortenIfNeeded.
- */
-bool TextMetrics::breakRow(Row & row, int const right_margin) const
-{
- LATTEST(row.empty());//
- Paragraph const & par = text_->getPar(row.pit());//
- Buffer const & buf = text_->inset().buffer();//
- BookmarksSection::BookmarkPosList bpl =//
- theSession().bookmarks().bookmarksInPar(buf.fileName(), par.id());//
-
- pos_type const end = par.size();//
- pos_type const pos = row.pos();//
- pos_type const body_pos = par.beginOfBody();//
- bool const is_rtl = text_->isRTL(row.pit());//
- bool need_new_row = false;//
-
- row.left_margin = leftMargin(row.pit(), pos);//
- row.right_margin = right_margin;//
- if (is_rtl)//
- swap(row.left_margin, row.right_margin);//
- // Remember that the row width takes into account the left_margin
- // but not the right_margin.
- row.dim().wid = row.left_margin;//
- // the width available for the row.
- int const width = max_width_ - row.right_margin;//
-
- // check for possible inline completion
- DocIterator const & ic_it = bv_->inlineCompletionPos();//
- pos_type ic_pos = -1;//
- if (ic_it.inTexted() && ic_it.text() == text_ && ic_it.pit() == row.pit())//
- ic_pos = ic_it.pos();//
-
- // Now we iterate through until we reach the right margin
- // or the end of the par, then build a representation of the row.
- pos_type i = pos;//---------------------------------------------------vvv
- FontIterator fi = FontIterator(*this, par, row.pit(), pos);
- // The real stopping condition is a few lines below.
- while (true) {
- // Firstly, check whether there is a bookmark here.
- if (lyxrc.bookmarks_visibility == LyXRC::BMK_INLINE)
- for (auto const & bp_p : bpl)
- if (bp_p.second == i) {
- Font f = *fi;
- f.fontInfo().setColor(Color_bookmark);
- // â¶ U+2776 DINGBAT NEGATIVE CIRCLED DIGIT ONE
- char_type const ch = 0x2775 + bp_p.first;
- row.addVirtual(i, docstring(1, ch), f, Change());
- }
-
- // The stopping condition is here so that the display of a
- // bookmark can take place at paragraph start too.
- if (i >= end || (i != pos && row.width() > width))//^width
- break;
-
- char_type c = par.getChar(i);
- // The most special cases are handled first.
- if (par.isInset(i)) {
- Inset const * ins = par.getInset(i);
- Dimension dim = bv_->coordCache().insets().dim(ins);
- row.add(i, ins, dim, *fi, par.lookupChange(i));
- } else if (c == ' ' && i + 1 == body_pos) {
- // There is a space at i, but it should not be
- // added as a separator, because it is just
- // before body_pos. Instead, insert some spacing to
- // align text
- FontMetrics const & fm = theFontMetrics(text_->labelFont(par));
- // this is needed to make sure that the row width is correct
- row.finalizeLast();
- int const add = max(fm.width(par.layout().labelsep),
- labelEnd(row.pit()) - row.width());
- row.addSpace(i, add, *fi, par.lookupChange(i));
- } else if (c == '\t')
- row.addSpace(i, theFontMetrics(*fi).width(from_ascii(" ")),
- *fi, par.lookupChange(i));
- else if (c == 0x2028 || c == 0x2029) {
- /**
- * U+2028 LINE SEPARATOR
- * U+2029 PARAGRAPH SEPARATOR
-
- * These are special unicode characters that break
- * lines/pragraphs. Not handling them lead to trouble wrt
- * Qt QTextLayout formatting. We add a visible character
- * on screen so that the user can see that something is
- * happening.
- */
- row.finalizeLast();
- // ⤶ U+2936 ARROW POINTING DOWNWARDS THEN CURVING LEFTWARDS
- // ¶ U+00B6 PILCROW SIGN
- char_type const screen_char = (c == 0x2028) ? 0x2936 : 0x00B6;
- row.add(i, screen_char, *fi, par.lookupChange(i), i >= body_pos);
- } else
- row.add(i, c, *fi, par.lookupChange(i), i >= body_pos);
-
- // add inline completion width
- // draw logically behind the previous character
- if (ic_pos == i + 1 && !bv_->inlineCompletion().empty()) {
- docstring const comp = bv_->inlineCompletion();
- size_t const uniqueTo =bv_->inlineCompletionUniqueChars();
- Font f = *fi;
-
- if (uniqueTo > 0) {
- f.fontInfo().setColor(Color_inlinecompletion);
- row.addVirtual(i + 1, comp.substr(0, uniqueTo), f, Change());
- }
- f.fontInfo().setColor(Color_nonunique_inlinecompletion);
- row.addVirtual(i + 1, comp.substr(uniqueTo), f, Change());
- }
-
- // Handle some situations that abruptly terminate the row
- // - Before an inset with BreakBefore
- // - After an inset with BreakAfter
- Inset const * prevInset = !row.empty() ? row.back().inset : 0;
- Inset const * nextInset = (i + 1 < end) ? par.getInset(i + 1) : 0;
- if ((nextInset && nextInset->rowFlags() & BreakBefore)
- || (prevInset && prevInset->rowFlags() & BreakAfter)) {
- row.flushed(true);
- // Force a row creation after this one if it is ended by
- // an inset that either
- // - has row flag RowAfter that enforces that;
- // - or (1) did force the row breaking, (2) is at end of
- // paragraph and (3) the said paragraph has an end label.
- need_new_row = prevInset &&
- (prevInset->rowFlags() & AlwaysBreakAfter
- || (prevInset->rowFlags() & BreakAfter && i + 1 == end
- && text_->getEndLabel(row.pit()) != END_LABEL_NO_LABEL));
- ++i;
- break;
- }
-
- ++i;
- ++fi;
- }
- row.finalizeLast();
- row.endpos(i);
-
- // End of paragraph marker. The logic here is almost the
- // same as in redoParagraph, remember keep them in sync.
- ParagraphList const & pars = text_->paragraphs();
- Change const & change = par.lookupChange(i);
- if ((lyxrc.paragraph_markers || change.changed())
- && !need_new_row // not this
- && i == end && size_type(row.pit() + 1) < pars.size()) {
- // add a virtual element for the end-of-paragraph
- // marker; it is shown on screen, but does not exist
- // in the paragraph.
- Font f(text_->layoutFont(row.pit()));
- f.fontInfo().setColor(Color_paragraphmarker);
- f.setLanguage(par.getParLanguage(buf.params()));
- // ¶ U+00B6 PILCROW SIGN
- row.addVirtual(end, docstring(1, char_type(0x00B6)), f, change);
- }
-
- // Is there a end-of-paragaph change?
- if (i == end && par.lookupChange(end).changed() && !need_new_row)
- row.needsChangeBar(true);
- //--------------------------------------------------------------------^^^
- // FIXME : nothing below this
-
- // if the row is too large, try to cut at last separator. In case
- // of success, reset indication that the row was broken abruptly.
- int const next_width = max_width_ - leftMargin(row.pit(), row.endpos())
- - rightMargin(row.pit());
-
- if (row.shortenIfNeeded(width, next_width))
- row.flushed(false);
- row.right_boundary(!row.empty() && row.endpos() < end//
- && row.back().endpos == row.endpos());//
- // Last row in paragraph is flushed
- if (row.endpos() == end)//
- row.flushed(true);//
-
- // make sure that the RTL elements are in reverse ordering
- row.reverseRTL(is_rtl);//
- //LYXERR0("breakrow: row is " << row);
-
- return need_new_row;
-}
int TextMetrics::parTopSpacing(pit_type const pit) const
{
diff --git a/src/TextMetrics.h b/src/TextMetrics.h
index 3ff1161..e38ba71 100644
--- a/src/TextMetrics.h
+++ b/src/TextMetrics.h
@@ -151,15 +151,12 @@ private:
/// FIXME??
int labelEnd(pit_type const pit) const;
+ // Turn paragraph oh index \c pit into a single row
Row tokenizeParagraph(pit_type pit) const;
+ // Break the row produced by tokenizeParagraph() into a list of rows.
RowList breakParagraph(Row const & row) const;
- /// sets row.end to the pos value *after* which a row should break.
- /// for example, the pos after which isNewLine(pos) == true
- /// \return true when another row is required (after a newline)
- bool breakRow(Row & row, int right_margin) const;
-
// Expands the alignment of row \param row in paragraph \param par
LyXAlignment getAlign(Paragraph const & par, Row const & row) const;
/// Aligns properly the row contents (computes spaces and fills)
commit 5e251d8e6983f024e53bd71f769955b7ad85f942
Author: Jean-Marc Lasgouttes <lasgouttes at lyx.org>
Date: Sun Jul 18 01:09:33 2021 +0200
Implement handling of row_flags for row breaking
To this end, add the helper function needsRowBreak which computes the
effect of two consecutive row flags. This function implements the
priorities described in RowFlags.h.
This function is called with the relevant flags, or NoBreak* when at
boundaries and updates need_new_row.
Some common code is factored in a new cleanupRow() helper.
diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp
index 051d050..c829d94 100644
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@ -980,22 +980,6 @@ Row TextMetrics::tokenizeParagraph(pit_type const pit) const
namespace {
-Row newRow(TextMetrics const & tm, pit_type pit, pos_type pos, bool is_rtl)
-{
- Row nrow;
- nrow.pit(pit);
- nrow.pos(pos);
- nrow.left_margin = tm.leftMargin(pit, pos);
- nrow.right_margin = tm.rightMargin(pit);
- if (is_rtl)
- swap(nrow.left_margin, nrow.right_margin);
- // Remember that the row width takes into account the left_margin
- // but not the right_margin.
- nrow.dim().wid = nrow.left_margin;
- return nrow;
-}
-
-
/** Helper template flexible_const_iterator<T>
* A way to iterate over a const container, but insert fake elements in it.
* In the case of a row, we will have to break some elements, which
@@ -1018,6 +1002,8 @@ public:
value_type operator*() const { return pile_.empty() ? *cit_ : pile_.back(); }
+ value_type const * operator->() const { return pile_.empty() ? &*cit_ : &pile_.back(); }
+
void put(value_type const & e) { pile_.push_back(e); }
// This should be private, but declaring the friend functions is too much work
@@ -1051,6 +1037,44 @@ bool operator==(flexible_const_iterator<T> const & t1,
return t1.cit_ == t2.cit_ && t1.pile_.empty() && t2.pile_.empty();
}
+Row newRow(TextMetrics const & tm, pit_type pit, pos_type pos, bool is_rtl)
+{
+ Row nrow;
+ nrow.pit(pit);
+ nrow.pos(pos);
+ nrow.left_margin = tm.leftMargin(pit, pos);
+ nrow.right_margin = tm.rightMargin(pit);
+ if (is_rtl)
+ swap(nrow.left_margin, nrow.right_margin);
+ // Remember that the row width takes into account the left_margin
+ // but not the right_margin.
+ nrow.dim().wid = nrow.left_margin;
+ return nrow;
+}
+
+
+void cleanupRow(Row & row, pos_type pos, pos_type real_endpos, bool is_rtl)
+{
+ row.endpos(pos);
+ row.right_boundary(!row.empty() && pos < real_endpos
+ && row.back().endpos == pos);
+ // make sure that the RTL elements are in reverse ordering
+ row.reverseRTL(is_rtl);
+}
+
+// Implement the priorities described in RowFlags.h.
+bool needsRowBreak(int f1, int f2)
+{
+ if (f1 & AlwaysBreakAfter /*|| f2 & AlwaysBreakBefore*/)
+ return true;
+ if (f1 & NoBreakAfter || f2 & NoBreakBefore)
+ return false;
+ if (f1 & BreakAfter || f2 & BreakBefore)
+ return true;
+ return false;
+}
+
+
}
@@ -1058,6 +1082,7 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
{
RowList rows;
bool const is_rtl = text_->isRTL(bigrow.pit());
+ bool const end_label = text_->getEndLabel(bigrow.pit()) != END_LABEL_NO_LABEL;
bool need_new_row = true;
pos_type pos = 0;
@@ -1065,15 +1090,21 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
flexible_const_iterator<Row> fcit = flexible_begin(bigrow);
flexible_const_iterator<Row> const end = flexible_end(bigrow);
while (true) {
+ bool const has_row = !rows.empty();
+ bool const row_empty = !has_row || rows.back().empty();
+ // The row flags of previous element, if there is one.
+ // Otherwise we use NoBreakAfter to avoid an empty row before
+ // e.g. a displayed equation.
+ int const f1 = row_empty ? NoBreakAfter : rows.back().back().row_flags;
+ // The row flags of next element, if there is one.
+ // Otherwise we use NoBreakBefore (see above), unless the
+ // paragraph has an end label (for which an empty row is OK).
+ int const f2 = (fcit == end) ? (end_label ? Inline : NoBreakBefore)
+ : fcit->row_flags;
+ need_new_row |= needsRowBreak(f1, f2);
if (need_new_row) {
- if (!rows.empty()) {
- Row & rb = rows.back();
- rb.endpos(pos);
- rb.right_boundary(!rb.empty() && rb.endpos() < bigrow.endpos()
- && rb.back().endpos == rb.endpos());
- // make sure that the RTL elements are in reverse ordering
- rb.reverseRTL(is_rtl);
- }
+ if (!rows.empty())
+ cleanupRow(rows.back(), pos, bigrow.endpos(), is_rtl);
rows.push_back(newRow(*this, bigrow.pit(), pos, is_rtl));
// the width available for the row.
width = max_width_ - rows.back().right_margin;
@@ -1107,13 +1138,9 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
}
if (!rows.empty()) {
- Row & rb = rows.back();
+ cleanupRow(rows.back(), pos, bigrow.endpos(), is_rtl);
// Last row in paragraph is flushed
- rb.flushed(true);
- rb.endpos(bigrow.endpos());
- rb.right_boundary(false);
- // make sure that the RTL elements are in reverse ordering
- rb.reverseRTL(is_rtl);
+ rows.back().flushed(true);
}
return rows;
@@ -1227,9 +1254,8 @@ bool TextMetrics::breakRow(Row & row, int const right_margin) const
}
f.fontInfo().setColor(Color_nonunique_inlinecompletion);
row.addVirtual(i + 1, comp.substr(uniqueTo), f, Change());
- }//---------------------------------------------------------------^^^
+ }
- // FIXME: Handle when breaking the rows
// Handle some situations that abruptly terminate the row
// - Before an inset with BreakBefore
// - After an inset with BreakAfter
@@ -1254,7 +1280,6 @@ bool TextMetrics::breakRow(Row & row, int const right_margin) const
++i;
++fi;
}
- //--------------------------------------------------------------------vvv
row.finalizeLast();
row.endpos(i);
commit 6a195673db223be1016b01a254561b26d3312b59
Author: Jean-Marc Lasgouttes <lasgouttes at lyx.org>
Date: Sat Jul 17 23:16:15 2021 +0200
Change the way the element's width is updated.
Remove the code that computed the width every 30 characters (yay!).
Make sure that finalizeLast() is called after inserting a row element in
a row in breakParagraph.
diff --git a/src/Row.cpp b/src/Row.cpp
index 705a147..3bc8ef0 100644
--- a/src/Row.cpp
+++ b/src/Row.cpp
@@ -370,8 +370,7 @@ void Row::finalizeLast()
if (elt.change.changed())
changebar_ = true;
- if (elt.type == STRING) {
- dim_.wid -= elt.dim.wid;
+ if (elt.type == STRING && elt.dim.wid == 0) {
elt.dim.wid = theFontMetrics(elt.font).width(elt.str);
dim_.wid += elt.dim.wid;
}
@@ -401,16 +400,8 @@ void Row::add(pos_type const pos, char_type const c,
e.row_flags = can_break ? CanBreakInside : Inline;
elements_.push_back(e);
}
- if (back().str.length() % 30 == 0) {
- dim_.wid -= back().dim.wid;
- back().str += c;
- back().endpos = pos + 1;
- back().dim.wid = theFontMetrics(back().font).width(back().str);
- dim_.wid += back().dim.wid;
- } else {
- back().str += c;
- back().endpos = pos + 1;
- }
+ back().str += c;
+ back().endpos = pos + 1;
}
diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp
index eaaafee..051d050 100644
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@ -1092,6 +1092,7 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
!elt.font.language()->wordWrap());
// a new element in the row
rows.back().push_back(elt);
+ rows.back().finalizeLast();
pos = elt.endpos;
// Go to next element
commit 3d9988b6e65bca3368f8ab2206a6811761d4db7a
Author: Jean-Marc Lasgouttes <lasgouttes at lyx.org>
Date: Sat Jul 17 02:31:49 2021 +0200
Introduce helper template to simplify breakParagraph code
This is a semi-generic iterator for iterating over a container and
pretend that we add elements to it along the way.
diff --git a/src/Row.h b/src/Row.h
index 4fdcee4..72d7a86 100644
--- a/src/Row.h
+++ b/src/Row.h
@@ -150,6 +150,8 @@ public:
friend std::ostream & operator<<(std::ostream & os, Element const & row);
};
+ ///
+ typedef Element value_type;
///
Row() {}
diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp
index 3734520..eaaafee 100644
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@ -995,6 +995,62 @@ Row newRow(TextMetrics const & tm, pit_type pit, pos_type pos, bool is_rtl)
return nrow;
}
+
+/** Helper template flexible_const_iterator<T>
+ * A way to iterate over a const container, but insert fake elements in it.
+ * In the case of a row, we will have to break some elements, which
+ * create new ones. This class allows to abstract this.
+ * Only the required parts are implemented for now.
+ */
+template<class T>
+class flexible_const_iterator {
+ typedef typename T::value_type value_type;
+public:
+
+ //
+ flexible_const_iterator operator++() {
+ if (pile_.empty())
+ ++cit_;
+ else
+ pile_.pop_back();
+ return *this;
+ }
+
+ value_type operator*() const { return pile_.empty() ? *cit_ : pile_.back(); }
+
+ void put(value_type const & e) { pile_.push_back(e); }
+
+// This should be private, but declaring the friend functions is too much work
+//private:
+ typename T::const_iterator cit_;
+ // A vector that is used as like a pile to store the elements to
+ // consider before incrementing the underlying iterator.
+ vector<value_type> pile_;
+};
+
+
+template<class T>
+flexible_const_iterator<T> flexible_begin(T const & t)
+{
+ return { t.begin(), vector<typename T::value_type>() };
+}
+
+
+template<class T>
+flexible_const_iterator<T> flexible_end(T const & t)
+{
+ return { t.end(), vector<typename T::value_type>() };
+}
+
+
+// Equality is only possible if respective piles are empty
+template<class T>
+bool operator==(flexible_const_iterator<T> const & t1,
+ flexible_const_iterator<T> const & t2)
+{
+ return t1.cit_ == t2.cit_ && t1.pile_.empty() && t2.pile_.empty();
+}
+
}
@@ -1006,11 +1062,8 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
bool need_new_row = true;
pos_type pos = 0;
int width = 0;
- Row::const_iterator cit = bigrow.begin();
- Row::const_iterator const end = bigrow.end();
- // This is a vector, but we use it like a pile putting and taking
- // stuff at the back.
- Row::Elements pile;
+ flexible_const_iterator<Row> fcit = flexible_begin(bigrow);
+ flexible_const_iterator<Row> const end = flexible_end(bigrow);
while (true) {
if (need_new_row) {
if (!rows.empty()) {
@@ -1029,27 +1082,25 @@ RowList TextMetrics::breakParagraph(Row const & bigrow) const
// The stopping condition is here because we may need a new
// empty row at the end.
- if (cit == end && pile.empty())
+ if (fcit == end)
break;
// Next element to consider is either the top of the temporary
// pile, or the place when we were in main row
- Row::Element elt = pile.empty() ? *cit : pile.back();
- //LYXERR0("elt=" << elt);
+ Row::Element elt = *fcit;
Row::Element next_elt = elt.splitAt(width - rows.back().width(),
!elt.font.language()->wordWrap());
- //LYXERR0("next_elt=" << next_elt);
// a new element in the row
rows.back().push_back(elt);
pos = elt.endpos;
+
// Go to next element
- if (pile.empty())
- ++cit;
- else
- pile.pop_back();
+ ++fcit;
+
// Add a new next element on the pile
if (next_elt.isValid()) {
- pile.push_back(next_elt);
+ // do as if we inserted this element in the original row
+ fcit.put(next_elt);
need_new_row = true;
}
}
commit 2a81a4393409340f9d2ef01d9a8e5b9e42ec7623
Author: Jean-Marc Lasgouttes <lasgouttes at lyx.org>
Date: Fri Jul 16 00:10:25 2021 +0200
A set of easy fixes and missing features
* show changebar when end of paragraph is changed.
* when row is finished, set endpos and right_boundary
* handle bidi.
diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp
index aed277c..3734520 100644
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@ -955,12 +955,15 @@ Row TextMetrics::tokenizeParagraph(pit_type const pit) const
row.finalizeLast();
row.endpos(end);
- // End of paragraph marker. The logic here is almost the
+ // End of paragraph marker, either if LyXRc requires it, or there
+ // is an end of paragraph change. The logic here is almost the
// same as in redoParagraph, remember keep them in sync.
ParagraphList const & pars = text_->paragraphs();
- Change const & change = par.lookupChange(i);
- if ((lyxrc.paragraph_markers || change.changed())
- && i == end && size_type(pit + 1) < pars.size()) {
+ Change const & endchange = par.lookupChange(end);
+ if (endchange.changed())
+ row.needsChangeBar(true);
+ if ((lyxrc.paragraph_markers || endchange.changed())
+ && size_type(pit + 1) < pars.size()) {
// add a virtual element for the end-of-paragraph
// marker; it is shown on screen, but does not exist
// in the paragraph.
@@ -968,7 +971,7 @@ Row TextMetrics::tokenizeParagraph(pit_type const pit) const
f.fontInfo().setColor(Color_paragraphmarker);
f.setLanguage(par.getParLanguage(buf.params()));
// ¶ U+00B6 PILCROW SIGN
- row.addVirtual(end, docstring(1, char_type(0x00B6)), f, change);
+ row.addVirtual(end, docstring(1, char_type(0x00B6)), f, endchange);
}
return row;
@@ -995,24 +998,30 @@ Row newRow(TextMetrics const & tm, pit_type pit, pos_type pos, bool is_rtl)
}
-RowList TextMetrics::breakParagraph(Row const & row) const
+RowList TextMetrics::breakParagraph(Row const & bigrow) const
{
RowList rows;
- bool const is_rtl = text_->isRTL(row.pit());
+ bool const is_rtl = text_->isRTL(bigrow.pit());
bool need_new_row = true;
pos_type pos = 0;
int width = 0;
- Row::const_iterator cit = row.begin();
- Row::const_iterator const end = row.end();
+ Row::const_iterator cit = bigrow.begin();
+ Row::const_iterator const end = bigrow.end();
// This is a vector, but we use it like a pile putting and taking
// stuff at the back.
Row::Elements pile;
while (true) {
if (need_new_row) {
- if (!rows.empty())
- rows.back().endpos(pos);
- rows.push_back(newRow(*this, row.pit(), pos, is_rtl));
+ if (!rows.empty()) {
+ Row & rb = rows.back();
+ rb.endpos(pos);
+ rb.right_boundary(!rb.empty() && rb.endpos() < bigrow.endpos()
+ && rb.back().endpos == rb.endpos());
+ // make sure that the RTL elements are in reverse ordering
+ rb.reverseRTL(is_rtl);
+ }
+ rows.push_back(newRow(*this, bigrow.pit(), pos, is_rtl));
// the width available for the row.
width = max_width_ - rows.back().right_margin;
need_new_row = false;
@@ -1045,6 +1054,16 @@ RowList TextMetrics::breakParagraph(Row const & row) const
}
}
+ if (!rows.empty()) {
+ Row & rb = rows.back();
+ // Last row in paragraph is flushed
+ rb.flushed(true);
+ rb.endpos(bigrow.endpos());
+ rb.right_boundary(false);
+ // make sure that the RTL elements are in reverse ordering
+ rb.reverseRTL(is_rtl);
+ }
+
return rows;
}
@@ -1217,14 +1236,14 @@ bool TextMetrics::breakRow(Row & row, int const right_margin) const
if (row.shortenIfNeeded(width, next_width))
row.flushed(false);
- row.right_boundary(!row.empty() && row.endpos() < end
- && row.back().endpos == row.endpos());
+ row.right_boundary(!row.empty() && row.endpos() < end//
+ && row.back().endpos == row.endpos());//
// Last row in paragraph is flushed
- if (row.endpos() == end)
- row.flushed(true);
+ if (row.endpos() == end)//
+ row.flushed(true);//
// make sure that the RTL elements are in reverse ordering
- row.reverseRTL(is_rtl);
+ row.reverseRTL(is_rtl);//
//LYXERR0("breakrow: row is " << row);
return need_new_row;
commit 52309a9097d4106494312ae3ac392a6060ca9a7b
Author: Jean-Marc Lasgouttes <lasgouttes at lyx.org>
Date: Wed Jul 14 00:48:03 2021 +0200
Use the new tokenizing and breaking code instead of breakRow.
diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp
index 0578913..aed277c 100644
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@ -516,43 +516,28 @@ bool TextMetrics::redoParagraph(pit_type const pit, bool const align_rows)
}
}
- pos_type first = 0;
- size_t row_index = 0;
- bool need_new_row = false;
- // maximum pixel width of a row
- do {
- if (row_index == pm.rows().size())
- pm.rows().push_back(Row());
- else
- pm.rows()[row_index] = Row();
- Row & row = pm.rows()[row_index];
- row.pit(pit);
- row.pos(first);
- need_new_row = breakRow(row, right_margin);
+ // Transform the paragraph into a single row containing all the elements.
+ Row const bigrow = tokenizeParagraph(pit);
+ // Split the row in several rows fitting in available width
+ pm.rows() = breakParagraph(bigrow);
+
+ /* If there is more than one row, expand the text to the full
+ * allowable width. This setting here is needed for the
+ * setRowAlignment() below. We do nothing when tight insets are
+ * requested.
+ */
+ if (pm.rows().size() > 1 && !tight_ && dim_.wid < max_width_)
+ dim_.wid = max_width_;
+
+ // Compute height and alignment of the rows.
+ for (Row & row : pm.rows()) {
setRowHeight(row);
- row.changed(true);
- if ((row_index || row.endpos() < par.size() || row.right_boundary())
- && !tight_) {
- /* If there is more than one row or the row has been
- * broken by a display inset or a newline, expand the text
- * to the full allowable width. This setting here is
- * needed for the setRowAlignment() below.
- * We do nothing when tight insets are requested.
- */
- if (dim_.wid < max_width_)
- dim_.wid = max_width_;
- }
if (align_rows)
setRowAlignment(row, max(dim_.wid, row.width()));
- first = row.endpos();
- ++row_index;
pm.dim().wid = max(pm.dim().wid, row.width() + row.right_margin);
pm.dim().des += row.height();
- } while (first < par.size() || need_new_row);
-
- if (row_index < pm.rows().size())
- pm.rows().resize(row_index);
+ }
// This type of margin can only be handled at the global paragraph level
if (par.layout().margintype == MARGIN_RIGHT_ADDRESS_BOX) {
commit 30d23f2350d1252c5ef2d923a011cc5ff5d743b5
Author: Jean-Marc Lasgouttes <lasgouttes at lyx.org>
Date: Wed Jul 14 00:47:42 2021 +0200
Break the paragraph's big row according to margins
Still many features missing:
- handle insets that break rows (display math, newline, ...)
- handle rows that are too long by replacing the single call to
breakAt with a call to a reworked Row::shortenIfNeeded.
- some easy things at the end of breakRow (bidi text, etc.).
diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp
index ffd3df4..0578913 100644
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@ -990,6 +990,79 @@ Row TextMetrics::tokenizeParagraph(pit_type const pit) const
}
+namespace {
+
+Row newRow(TextMetrics const & tm, pit_type pit, pos_type pos, bool is_rtl)
+{
+ Row nrow;
+ nrow.pit(pit);
+ nrow.pos(pos);
+ nrow.left_margin = tm.leftMargin(pit, pos);
+ nrow.right_margin = tm.rightMargin(pit);
+ if (is_rtl)
+ swap(nrow.left_margin, nrow.right_margin);
+ // Remember that the row width takes into account the left_margin
+ // but not the right_margin.
+ nrow.dim().wid = nrow.left_margin;
+ return nrow;
+}
+
+}
+
+
+RowList TextMetrics::breakParagraph(Row const & row) const
+{
+ RowList rows;
+ bool const is_rtl = text_->isRTL(row.pit());
+
+ bool need_new_row = true;
+ pos_type pos = 0;
+ int width = 0;
+ Row::const_iterator cit = row.begin();
+ Row::const_iterator const end = row.end();
+ // This is a vector, but we use it like a pile putting and taking
+ // stuff at the back.
+ Row::Elements pile;
+ while (true) {
+ if (need_new_row) {
+ if (!rows.empty())
+ rows.back().endpos(pos);
+ rows.push_back(newRow(*this, row.pit(), pos, is_rtl));
+ // the width available for the row.
+ width = max_width_ - rows.back().right_margin;
+ need_new_row = false;
+ }
+
+ // The stopping condition is here because we may need a new
+ // empty row at the end.
+ if (cit == end && pile.empty())
+ break;
+
+ // Next element to consider is either the top of the temporary
+ // pile, or the place when we were in main row
+ Row::Element elt = pile.empty() ? *cit : pile.back();
+ //LYXERR0("elt=" << elt);
+ Row::Element next_elt = elt.splitAt(width - rows.back().width(),
+ !elt.font.language()->wordWrap());
+ //LYXERR0("next_elt=" << next_elt);
+ // a new element in the row
+ rows.back().push_back(elt);
+ pos = elt.endpos;
+ // Go to next element
+ if (pile.empty())
+ ++cit;
+ else
+ pile.pop_back();
+ // Add a new next element on the pile
+ if (next_elt.isValid()) {
+ pile.push_back(next_elt);
+ need_new_row = true;
+ }
+ }
+
+ return rows;
+}
+
/** This is the function where the hard work is done. The code here is
* very sensitive to small changes :) Note that part of the
* intelligence is also in Row::shortenIfNeeded.
@@ -1003,20 +1076,20 @@ bool TextMetrics::breakRow(Row & row, int const right_margin) const
theSession().bookmarks().bookmarksInPar(buf.fileName(), par.id());//
pos_type const end = par.size();//
- pos_type const pos = row.pos();
+ pos_type const pos = row.pos();//
pos_type const body_pos = par.beginOfBody();//
- bool const is_rtl = text_->isRTL(row.pit());
- bool need_new_row = false;
+ bool const is_rtl = text_->isRTL(row.pit());//
+ bool need_new_row = false;//
- row.left_margin = leftMargin(row.pit(), pos);
- row.right_margin = right_margin;
- if (is_rtl)
- swap(row.left_margin, row.right_margin);
+ row.left_margin = leftMargin(row.pit(), pos);//
+ row.right_margin = right_margin;//
+ if (is_rtl)//
+ swap(row.left_margin, row.right_margin);//
// Remember that the row width takes into account the left_margin
// but not the right_margin.
- row.dim().wid = row.left_margin;
+ row.dim().wid = row.left_margin;//
// the width available for the row.
- int const width = max_width_ - row.right_margin;
+ int const width = max_width_ - row.right_margin;//
// check for possible inline completion
DocIterator const & ic_it = bv_->inlineCompletionPos();//
diff --git a/src/TextMetrics.h b/src/TextMetrics.h
index 1666cd0..3ff1161 100644
--- a/src/TextMetrics.h
+++ b/src/TextMetrics.h
@@ -153,6 +153,8 @@ private:
Row tokenizeParagraph(pit_type pit) const;
+ RowList breakParagraph(Row const & row) const;
+
/// sets row.end to the pos value *after* which a row should break.
/// for example, the pos after which isNewLine(pos) == true
/// \return true when another row is required (after a newline)
commit 729d2fac569544837ec9bb3b2885c58ee4f419a1
Author: Jean-Marc Lasgouttes <lasgouttes at lyx.org>
Date: Mon Jul 12 00:07:59 2021 +0200
Implement Row::Element::row_flags
Move the enum definition RowFlags in its own include file, to avoid
loading Inset.h. Document it more thoroughly.
Rename RowAfter to AlwaysBreakAfter.
Add CanBreakInside (rows that can be themselves broken). This allow to
differentiate elements before bodyPos() and allows to remove a
parameter to shortenIfNeeded().
Make the Inset::rowFlags() method return int instead of RowFlags, as
should be done for all the bitwise flags. Remove the hand-made bitwise
operators.
Set R::E::row_flags when creating elements.
* INSET elements use the inset's rowFLags();
* virtual element forbid breaking before them, and inherit the *After
flags from the previous element of the row;
* STRING elements usr CanBreakInside, except before bodyPos.
More stuff may be added later.
diff --git a/src/Makefile.am b/src/Makefile.am
index 31701f2..99a0f98 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -273,6 +273,7 @@ HEADERFILESCORE = \
ParIterator.h \
PDFOptions.h \
Row.h \
+ RowFlags.h \
RowPainter.h \
Server.h \
ServerSocket.h \
diff --git a/src/Row.cpp b/src/Row.cpp
index da2d885..705a147 100644
--- a/src/Row.cpp
+++ b/src/Row.cpp
@@ -135,7 +135,7 @@ pos_type Row::Element::x2pos(int &x) const
Row::Element Row::Element::splitAt(int w, bool force)
{
- if (type != STRING)
+ if (type != STRING || !(row_flags & CanBreakInside))
return Element();
FontMetrics const & fm = theFontMetrics(font);
@@ -145,6 +145,7 @@ Row::Element Row::Element::splitAt(int w, bool force)
Element ret(STRING, pos + i, font, change);
ret.str = str.substr(i);
ret.endpos = ret.pos + ret.str.length();
+ ret.row_flags = row_flags & (CanBreakInside | AfterFlags);
str.erase(i);
endpos = pos + i;
//lyxerr << "breakAt(" << w << ") Row element Broken at " << x << "(w(str)=" << fm.width(str) << "): e=" << *this << endl;
@@ -378,12 +379,13 @@ void Row::finalizeLast()
void Row::add(pos_type const pos, Inset const * ins, Dimension const & dim,
- Font const & f, Change const & ch)
+ Font const & f, Change const & ch)
{
finalizeLast();
Element e(INSET, pos, f, ch);
e.inset = ins;
e.dim = dim;
+ e.row_flags = ins->rowFlags();
elements_.push_back(e);
dim_.wid += dim.wid;
changebar_ |= ins->isChanged();
@@ -391,11 +393,12 @@ void Row::add(pos_type const pos, Inset const * ins, Dimension const & dim,
void Row::add(pos_type const pos, char_type const c,
- Font const & f, Change const & ch)
+ Font const & f, Change const & ch, bool can_break)
{
if (!sameString(f, ch)) {
finalizeLast();
Element e(STRING, pos, f, ch);
+ e.row_flags = can_break ? CanBreakInside : Inline;
elements_.push_back(e);
}
if (back().str.length() % 30 == 0) {
@@ -420,6 +423,10 @@ void Row::addVirtual(pos_type const pos, docstring const & s,
e.dim.wid = theFontMetrics(f).width(s);
dim_.wid += e.dim.wid;
e.endpos = pos;
+ // Copy after* flags from previous elements, forbid break before element
+ int const prev_row_flags = elements_.empty() ? Inline : elements_.back().row_flags;
+ int const can_inherit = AfterFlags & ~AlwaysBreakAfter;
+ e.row_flags = (prev_row_flags & can_inherit) | NoBreakBefore;
elements_.push_back(e);
finalizeLast();
}
@@ -450,7 +457,7 @@ void Row::pop_back()
}
-bool Row::shortenIfNeeded(pos_type const keep, int const w, int const next_width)
+bool Row::shortenIfNeeded(int const w, int const next_width)
{
if (empty() || width() <= w)
return false;
@@ -482,11 +489,10 @@ bool Row::shortenIfNeeded(pos_type const keep, int const w, int const next_width
// make a copy of the element to work on it.
Element brk = *cit_brk;
/* If the current element is an inset that allows breaking row
- * after itself, and it the row is already short enough after
+ * after itself, and if the row is already short enough after
* this inset, then cut right after this element.
*/
- if (wid_brk <= w && brk.type == INSET
- && brk.inset->rowFlags() & Inset::CanBreakAfter) {
+ if (wid_brk <= w && brk.row_flags & CanBreakAfter) {
end_ = brk.endpos;
dim_.wid = wid_brk;
elements_.erase(cit_brk + 1, end);
@@ -504,10 +510,6 @@ bool Row::shortenIfNeeded(pos_type const keep, int const w, int const next_width
* not allowed at the beginning or end of line.
*/
bool const word_wrap = brk.font.language()->wordWrap();
- // When there is text before the body part (think description
- // environment), do not try to break.
- if (brk.pos < keep)
- continue;
/* We have found a suitable separable element. This is the common case.
* Try to break it cleanly (at word boundary) at a length that is both
* - less than the available space on the row
diff --git a/src/Row.h b/src/Row.h
index 3048cf1..4fdcee4 100644
--- a/src/Row.h
+++ b/src/Row.h
@@ -18,6 +18,7 @@
#include "Changes.h"
#include "Dimension.h"
#include "Font.h"
+#include "RowFlags.h"
#include "support/docstring.h"
#include "support/types.h"
@@ -143,6 +144,8 @@ public:
Change change;
// is it possible to add contents to this element?
bool final = false;
+ // properties with respect to row breaking (made of RowFlag enums)
+ int row_flags = Inline;
friend std::ostream & operator<<(std::ostream & os, Element const & row);
};
@@ -247,7 +250,7 @@ public:
Font const & f, Change const & ch);
///
void add(pos_type pos, char_type const c,
- Font const & f, Change const & ch);
+ Font const & f, Change const & ch, bool can_break);
///
void addVirtual(pos_type pos, docstring const & s,
Font const & f, Change const & ch);
@@ -287,12 +290,11 @@ public:
* if row width is too large, remove all elements after last
* separator and update endpos if necessary. If all that
* remains is a large word, cut it to \param width.
- * \param body_pos minimum amount of text to keep.
* \param width maximum width of the row.
* \param available width on next row.
* \return true if the row has been shortened.
*/
- bool shortenIfNeeded(pos_type const body_pos, int const width, int const next_width);
+ bool shortenIfNeeded(int const width, int const next_width);
/**
* If last element of the row is a string, compute its width
diff --git a/src/RowFlags.h b/src/RowFlags.h
new file mode 100644
index 0000000..f94f0c6
--- /dev/null
+++ b/src/RowFlags.h
@@ -0,0 +1,57 @@
+// -*- C++ -*-
+/**
+ * \file RowFlags.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Jean-Marc Lasgouttes
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#ifndef ROWFLAGS_H
+#define ROWFLAGS_H
+
+// Do not include anything here
+
+namespace lyx {
+
+/* The list of possible flags, that can be combined.
+ * Some flags that should logically be here (e.g.,
+ * CanBreakBefore), do not exist. This is because the need has not
+ * been identitfied yet.
+ *
+ * Priorities when before/after disagree:
+ * AlwaysBreak* > NoBreak* > Break* or CanBreak*.
+ */
+enum RowFlags {
+ // Do not break before or after this element, except if really
+ // needed (between NoBreak* and CanBreak*).
+ Inline = 0,
+ // break row before this element if the row is not empty
+ BreakBefore = 1 << 0,
+ // Avoid breaking row before this element
+ NoBreakBefore = 1 << 1,
+ // force new (maybe empty) row after this element
+ AlwaysBreakAfter = 1 << 2,
+ // break row after this element if there are more elements
+ BreakAfter = 1 << 3,
+ // break row whenever needed after this element
+ CanBreakAfter = 1 << 4,
+ // Avoid breaking row after this element
+ NoBreakAfter = 1 << 5,
+ // The contents of the row may be broken in two (e.g. string)
+ CanBreakInside = 1 << 6,
+ // specify an alignment (left, right) for a display element
+ // (default is center)
+ AlignLeft = 1 << 7,
+ AlignRight = 1 << 8,
+ // A display element breaks row at both ends
+ Display = BreakBefore | BreakAfter,
+ // Flags that concern breaking after element
+ AfterFlags = AlwaysBreakAfter | BreakAfter | CanBreakAfter | NoBreakAfter
+};
+
+} // namespace lyx
+
+#endif
diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp
index 1036066..ffd3df4 100644
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@ -634,10 +634,10 @@ LyXAlignment TextMetrics::getAlign(Paragraph const & par, Row const & row) const
// Display-style insets should always be on a centered row
if (Inset const * inset = par.getInset(row.pos())) {
- if (inset->rowFlags() & Inset::Display) {
- if (inset->rowFlags() & Inset::AlignLeft)
+ if (inset->rowFlags() & Display) {
+ if (inset->rowFlags() & AlignLeft)
align = LYX_ALIGN_BLOCK;
- else if (inset->rowFlags() & Inset::AlignRight)
+ else if (inset->rowFlags() & AlignRight)
align = LYX_ALIGN_RIGHT;
else
align = LYX_ALIGN_CENTER;
@@ -928,7 +928,7 @@ Row TextMetrics::tokenizeParagraph(pit_type const pit) const
row.addSpace(i, add, *fi, par.lookupChange(i));
} else if (c == '\t')
row.addSpace(i, theFontMetrics(*fi).width(from_ascii(" ")),
- *fi, par.lookupChange(i));
+ *fi, par.lookupChange(i));
else if (c == 0x2028 || c == 0x2029) {
/**
* U+2028 LINE SEPARATOR
@@ -944,9 +944,10 @@ Row TextMetrics::tokenizeParagraph(pit_type const pit) const
// ⤶ U+2936 ARROW POINTING DOWNWARDS THEN CURVING LEFTWARDS
// ¶ U+00B6 PILCROW SIGN
char_type const screen_char = (c == 0x2028) ? 0x2936 : 0x00B6;
- row.add(i, screen_char, *fi, par.lookupChange(i));
+ row.add(i, screen_char, *fi, par.lookupChange(i), i >= body_pos);
} else
- row.add(i, c, *fi, par.lookupChange(i));
+ // row elements before body are unbreakable
+ row.add(i, c, *fi, par.lookupChange(i), i >= body_pos);
// add inline completion width
// draw logically behind the previous character
@@ -1080,9 +1081,9 @@ bool TextMetrics::breakRow(Row & row, int const right_margin) const
// ⤶ U+2936 ARROW POINTING DOWNWARDS THEN CURVING LEFTWARDS
// ¶ U+00B6 PILCROW SIGN
char_type const screen_char = (c == 0x2028) ? 0x2936 : 0x00B6;
- row.add(i, screen_char, *fi, par.lookupChange(i));
+ row.add(i, screen_char, *fi, par.lookupChange(i), i >= body_pos);
} else
- row.add(i, c, *fi, par.lookupChange(i));
+ row.add(i, c, *fi, par.lookupChange(i), i >= body_pos);
// add inline completion width
// draw logically behind the previous character
@@ -1105,8 +1106,8 @@ bool TextMetrics::breakRow(Row & row, int const right_margin) const
// - After an inset with BreakAfter
Inset const * prevInset = !row.empty() ? row.back().inset : 0;
Inset const * nextInset = (i + 1 < end) ? par.getInset(i + 1) : 0;
- if ((nextInset && nextInset->rowFlags() & Inset::BreakBefore)
- || (prevInset && prevInset->rowFlags() & Inset::BreakAfter)) {
+ if ((nextInset && nextInset->rowFlags() & BreakBefore)
+ || (prevInset && prevInset->rowFlags() & BreakAfter)) {
row.flushed(true);
// Force a row creation after this one if it is ended by
// an inset that either
@@ -1114,8 +1115,8 @@ bool TextMetrics::breakRow(Row & row, int const right_margin) const
// - or (1) did force the row breaking, (2) is at end of
// paragraph and (3) the said paragraph has an end label.
need_new_row = prevInset &&
- (prevInset->rowFlags() & Inset::RowAfter
- || (prevInset->rowFlags() & Inset::BreakAfter && i + 1 == end
+ (prevInset->rowFlags() & AlwaysBreakAfter
+ || (prevInset->rowFlags() & BreakAfter && i + 1 == end
&& text_->getEndLabel(row.pit()) != END_LABEL_NO_LABEL));
++i;
break;
@@ -1156,7 +1157,7 @@ bool TextMetrics::breakRow(Row & row, int const right_margin) const
int const next_width = max_width_ - leftMargin(row.pit(), row.endpos())
- rightMargin(row.pit());
- if (row.shortenIfNeeded(body_pos, width, next_width))
+ if (row.shortenIfNeeded(width, next_width))
row.flushed(false);
row.right_boundary(!row.empty() && row.endpos() < end
&& row.back().endpos == row.endpos());
@@ -1900,7 +1901,7 @@ int TextMetrics::leftMargin(pit_type const pit, pos_type const pos) const
// display style insets do not need indentation
&& !(!par.empty()
&& par.isInset(0)
- && par.getInset(0)->rowFlags() & Inset::Display)
+ && par.getInset(0)->rowFlags() & Display)
&& (!(tclass.isDefaultLayout(par.layout())
|| tclass.isPlainLayout(par.layout()))
|| buffer.params().paragraph_separation
diff --git a/src/insets/Inset.h b/src/insets/Inset.h
index af24423..372b95a 100644
--- a/src/insets/Inset.h
+++ b/src/insets/Inset.h
@@ -20,6 +20,7 @@
#include "LayoutEnums.h"
#include "OutputEnums.h"
#include "OutputParams.h"
+#include "RowFlags.h"
#include "support/docstring.h"
#include "support/strfwd.h"
@@ -478,26 +479,8 @@ public:
virtual CtObject getCtObject(OutputParams const &) const;
- enum RowFlags {
- Inline = 0,
- // break row before this inset
- BreakBefore = 1 << 0,
- // break row after this inset
- BreakAfter = 1 << 1,
- // it is possible to break after this inset
- CanBreakAfter = 1 << 2,
- // force new (maybe empty) row after this inset
- RowAfter = 1 << 3,
- // specify an alignment (left, right) for a display inset
- // (default is center)
- AlignLeft = 1 << 4,
- AlignRight = 1 << 5,
- // A display inset breaks row at both ends
- Display = BreakBefore | BreakAfter
- };
-
- /// How should this inset be displayed in its row?
- virtual RowFlags rowFlags() const { return Inline; }
+ // properties with respect to row breaking (made of RowFLag enums)
+ virtual int rowFlags() const { return Inline; }
/// indentation before this inset (only needed for displayed hull insets with fleqn option)
virtual int indent(BufferView const &) const { return 0; }
///
@@ -655,20 +638,6 @@ protected:
};
-inline Inset::RowFlags operator|(Inset::RowFlags const d1,
- Inset::RowFlags const d2)
-{
- return static_cast<Inset::RowFlags>(int(d1) | int(d2));
-}
-
-
-inline Inset::RowFlags operator&(Inset::RowFlags const d1,
- Inset::RowFlags const d2)
-{
- return static_cast<Inset::RowFlags>(int(d1) & int(d2));
-}
-
-
} // namespace lyx
#endif
diff --git a/src/insets/InsetBibtex.h b/src/insets/InsetBibtex.h
index be7659f..55451f5 100644
--- a/src/insets/InsetBibtex.h
+++ b/src/insets/InsetBibtex.h
@@ -47,7 +47,7 @@ public:
///
InsetCode lyxCode() const override { return BIBTEX_CODE; }
///
- RowFlags rowFlags() const override { return Display; }
+ int rowFlags() const override { return Display; }
///
void latex(otexstream &, OutputParams const &) const override;
///
diff --git a/src/insets/InsetCaption.h b/src/insets/InsetCaption.h
index ed6dbbb..c1bcd17 100644
--- a/src/insets/InsetCaption.h
+++ b/src/insets/InsetCaption.h
@@ -40,7 +40,7 @@ private:
///
void write(std::ostream & os) const override;
///
- RowFlags rowFlags() const override { return Display; }
+ int rowFlags() const override { return Display; }
///
bool neverIndent() const override { return true; }
///
diff --git a/src/insets/InsetFloatList.h b/src/insets/InsetFloatList.h
index 489b0fe..ce6caa5 100644
--- a/src/insets/InsetFloatList.h
+++ b/src/insets/InsetFloatList.h
@@ -32,7 +32,7 @@ public:
///
InsetCode lyxCode() const override { return FLOAT_LIST_CODE; }
///
- RowFlags rowFlags() const override { return Display; }
+ int rowFlags() const override { return Display; }
///
void write(std::ostream &) const override;
///
diff --git a/src/insets/InsetInclude.cpp b/src/insets/InsetInclude.cpp
index aeae2fb..10ea52b 100644
--- a/src/insets/InsetInclude.cpp
+++ b/src/insets/InsetInclude.cpp
@@ -1251,7 +1251,7 @@ string InsetInclude::contextMenuName() const
}
-Inset::RowFlags InsetInclude::rowFlags() const
+int InsetInclude::rowFlags() const
{
return type(params()) == INPUT ? Inline : Display;
}
diff --git a/src/insets/InsetInclude.h b/src/insets/InsetInclude.h
index 8585222..d62c751 100644
--- a/src/insets/InsetInclude.h
+++ b/src/insets/InsetInclude.h
@@ -75,7 +75,7 @@ public:
///
void draw(PainterInfo & pi, int x, int y) const override;
///
- RowFlags rowFlags() const override;
+ int rowFlags() const override;
///
InsetCode lyxCode() const override { return INCLUDE_CODE; }
///
diff --git a/src/insets/InsetIndex.h b/src/insets/InsetIndex.h
index bddb8ba..b064cc7 100644
--- a/src/insets/InsetIndex.h
+++ b/src/insets/InsetIndex.h
@@ -119,7 +119,7 @@ public:
///
bool hasSettings() const override;
///
- RowFlags rowFlags() const override { return Display; }
+ int rowFlags() const override { return Display; }
//@}
/// \name Static public methods obligated for InsetCommand derived classes
diff --git a/src/insets/InsetListings.cpp b/src/insets/InsetListings.cpp
index e8fe8b1..57df06e 100644
--- a/src/insets/InsetListings.cpp
+++ b/src/insets/InsetListings.cpp
@@ -64,7 +64,7 @@ InsetListings::~InsetListings()
}
-Inset::RowFlags InsetListings::rowFlags() const
+int InsetListings::rowFlags() const
{
return params().isInline() || params().isFloat() ? Inline : Display | AlignLeft;
}
diff --git a/src/insets/InsetListings.h b/src/insets/InsetListings.h
index 41be439..9d4eeb1 100644
--- a/src/insets/InsetListings.h
+++ b/src/insets/InsetListings.h
@@ -46,7 +46,7 @@ private:
///
InsetCode lyxCode() const override { return LISTINGS_CODE; }
/// lstinline is inlined, normal listing is displayed
- RowFlags rowFlags() const override;
+ int rowFlags() const override;
///
docstring layoutName() const override;
///
diff --git a/src/insets/InsetNewline.h b/src/insets/InsetNewline.h
index 3d540a8..1ef0ae5 100644
--- a/src/insets/InsetNewline.h
+++ b/src/insets/InsetNewline.h
@@ -47,7 +47,7 @@ public:
explicit InsetNewline(InsetNewlineParams par) : Inset(0)
{ params_.kind = par.kind; }
///
- RowFlags rowFlags() const override { return BreakAfter | RowAfter; }
+ int rowFlags() const override { return AlwaysBreakAfter; }
///
static void string2params(std::string const &, InsetNewlineParams &);
///
diff --git a/src/insets/InsetNewpage.h b/src/insets/InsetNewpage.h
index f020488..d086276 100644
--- a/src/insets/InsetNewpage.h
+++ b/src/insets/InsetNewpage.h
@@ -76,7 +76,7 @@ private:
///
void write(std::ostream & os) const override;
///
- RowFlags rowFlags() const override { return (params_.kind == InsetNewpageParams::NOPAGEBREAK) ? Inline : Display; }
+ int rowFlags() const override { return (params_.kind == InsetNewpageParams::NOPAGEBREAK) ? Inline : Display; }
///
docstring insetLabel() const;
///
diff --git a/src/insets/InsetNomencl.h b/src/insets/InsetNomencl.h
index 1778e01..362cd46 100644
--- a/src/insets/InsetNomencl.h
+++ b/src/insets/InsetNomencl.h
@@ -94,7 +94,7 @@ public:
///
bool hasSettings() const override { return true; }
///
- RowFlags rowFlags() const override { return Display; }
+ int rowFlags() const override { return Display; }
///
void latex(otexstream &, OutputParams const &) const override;
///
diff --git a/src/insets/InsetSeparator.h b/src/insets/InsetSeparator.h
index f7e0ab9..9352bdf 100644
--- a/src/insets/InsetSeparator.h
+++ b/src/insets/InsetSeparator.h
@@ -65,7 +65,7 @@ public:
return docstring();
}
///
- RowFlags rowFlags() const override { return BreakAfter; }
+ int rowFlags() const override { return BreakAfter; }
private:
///
InsetCode lyxCode() const override { return SEPARATOR_CODE; }
diff --git a/src/insets/InsetSpace.cpp b/src/insets/InsetSpace.cpp
index 9585596..1a2eb09 100644
--- a/src/insets/InsetSpace.cpp
+++ b/src/insets/InsetSpace.cpp
@@ -192,7 +192,7 @@ bool InsetSpace::getStatus(Cursor & cur, FuncRequest const & cmd,
}
-Inset::RowFlags InsetSpace::rowFlags() const
+int InsetSpace::rowFlags() const
{
switch (params_.kind) {
case InsetSpaceParams::PROTECTED:
diff --git a/src/insets/InsetSpace.h b/src/insets/InsetSpace.h
index 5cf7aa7..e401d6d 100644
--- a/src/insets/InsetSpace.h
+++ b/src/insets/InsetSpace.h
@@ -115,7 +115,7 @@ public:
///
docstring toolTip(BufferView const & bv, int x, int y) const override;
/// unprotected spaces allow line breaking after them
- RowFlags rowFlags() const override;
+ int rowFlags() const override;
///
void metrics(MetricsInfo &, Dimension &) const override;
///
diff --git a/src/insets/InsetSpecialChar.cpp b/src/insets/InsetSpecialChar.cpp
index 3ecdaf1..88af653 100644
--- a/src/insets/InsetSpecialChar.cpp
+++ b/src/insets/InsetSpecialChar.cpp
@@ -83,7 +83,7 @@ docstring InsetSpecialChar::toolTip(BufferView const &, int, int) const
}
-Inset::RowFlags InsetSpecialChar::rowFlags() const
+int InsetSpecialChar::rowFlags() const
{
switch (kind_) {
case ALLOWBREAK:
diff --git a/src/insets/InsetSpecialChar.h b/src/insets/InsetSpecialChar.h
index 3056b10..0c8cc36 100644
--- a/src/insets/InsetSpecialChar.h
+++ b/src/insets/InsetSpecialChar.h
@@ -63,7 +63,7 @@ public:
///
docstring toolTip(BufferView const & bv, int x, int y) const override;
/// some special chars allow line breaking after them
- RowFlags rowFlags() const override;
+ int rowFlags() const override;
///
void metrics(MetricsInfo &, Dimension &) const override;
///
diff --git a/src/insets/InsetTOC.h b/src/insets/InsetTOC.h
index 045ae07..ca3f463 100644
--- a/src/insets/InsetTOC.h
+++ b/src/insets/InsetTOC.h
@@ -37,7 +37,7 @@ public:
///
docstring layoutName() const override;
///
- RowFlags rowFlags() const override { return Display; }
+ int rowFlags() const override { return Display; }
///
void validate(LaTeXFeatures &) const override;
///
diff --git a/src/insets/InsetTabular.cpp b/src/insets/InsetTabular.cpp
index d6d9c57..9b22e38 100644
--- a/src/insets/InsetTabular.cpp
+++ b/src/insets/InsetTabular.cpp
@@ -6139,21 +6139,21 @@ bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd,
}
-Inset::RowFlags InsetTabular::rowFlags() const
-{
- if (tabular.is_long_tabular) {
- switch (tabular.longtabular_alignment) {
- case Tabular::LYX_LONGTABULAR_ALIGN_LEFT:
- return Display | AlignLeft;
- case Tabular::LYX_LONGTABULAR_ALIGN_CENTER:
- return Display;
- case Tabular::LYX_LONGTABULAR_ALIGN_RIGHT:
- return Display | AlignRight;
- default:
- return Display;
- }
- } else
- return Inline;
+int InsetTabular::rowFlags() const
+{
+ if (tabular.is_long_tabular) {
+ switch (tabular.longtabular_alignment) {
+ case Tabular::LYX_LONGTABULAR_ALIGN_LEFT:
+ return Display | AlignLeft;
+ case Tabular::LYX_LONGTABULAR_ALIGN_CENTER:
+ return Display;
+ case Tabular::LYX_LONGTABULAR_ALIGN_RIGHT:
+ return Display | AlignRight;
+ default:
+ return Display;
+ }
+ } else
+ return Inline;
}
diff --git a/src/insets/InsetTabular.h b/src/insets/InsetTabular.h
index 8d1be1b..0d4e7af 100644
--- a/src/insets/InsetTabular.h
+++ b/src/insets/InsetTabular.h
@@ -989,7 +989,7 @@ public:
//
bool isTable() const override { return true; }
///
- RowFlags rowFlags() const override;
+ int rowFlags() const override;
///
void latex(otexstream &, OutputParams const &) const override;
///
diff --git a/src/insets/InsetVSpace.h b/src/insets/InsetVSpace.h
index 9b95f00..51c2b5b 100644
--- a/src/insets/InsetVSpace.h
+++ b/src/insets/InsetVSpace.h
@@ -62,7 +62,7 @@ private:
///
void write(std::ostream & os) const override;
///
- RowFlags rowFlags() const override { return Display; }
+ int rowFlags() const override { return Display; }
///
void doDispatch(Cursor & cur, FuncRequest & cmd) override;
///
diff --git a/src/mathed/InsetMathHull.cpp b/src/mathed/InsetMathHull.cpp
index 97d95da..26ac40b 100644
--- a/src/mathed/InsetMathHull.cpp
+++ b/src/mathed/InsetMathHull.cpp
@@ -988,7 +988,7 @@ bool InsetMathHull::outerDisplay() const
}
-Inset::RowFlags InsetMathHull::rowFlags() const
+int InsetMathHull::rowFlags() const
{
switch (type_) {
case hullUnknown:
diff --git a/src/mathed/InsetMathHull.h b/src/mathed/InsetMathHull.h
index 0b865be..b019188 100644
--- a/src/mathed/InsetMathHull.h
+++ b/src/mathed/InsetMathHull.h
@@ -288,7 +288,7 @@ public:
///
Inset * editXY(Cursor & cur, int x, int y) override;
///
- RowFlags rowFlags() const override;
+ int rowFlags() const override;
/// helper function
bool display() const { return rowFlags() & Display; }
commit dfff28800d34fa1dacdb4d90d8d704ef18c9a1d0
Author: Jean-Marc Lasgouttes <lasgouttes at lyx.org>
Date: Sun Jul 11 15:19:37 2021 +0200
Create new method TM::tokenizeParagraph
This contains large parts of breakRow, but creates a unique row for the paragraph.
The parts taken or not in redoParagraph are annotated.
The new method is not used yet.
diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp
index 57c7715..1036066 100644
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@ -868,21 +868,142 @@ private:
} // namespace
+
+Row TextMetrics::tokenizeParagraph(pit_type const pit) const
+{
+ Row row;
+ row.pit(pit);
+ Paragraph const & par = text_->getPar(pit);
+ Buffer const & buf = text_->inset().buffer();
+ BookmarksSection::BookmarkPosList bpl =
+ theSession().bookmarks().bookmarksInPar(buf.fileName(), par.id());
+
+ pos_type const end = par.size();
+ pos_type const body_pos = par.beginOfBody();
+
+ // check for possible inline completion
+ DocIterator const & ic_it = bv_->inlineCompletionPos();
+ pos_type ic_pos = -1;
+ if (ic_it.inTexted() && ic_it.text() == text_ && ic_it.pit() == pit)
+ ic_pos = ic_it.pos();
+
+ // Now we iterate through until we reach the right margin
+ // or the end of the par, then build a representation of the row.
+ pos_type i = 0;
+ FontIterator fi = FontIterator(*this, par, pit, 0);
+ // The real stopping condition is a few lines below.
+ while (true) {
+ // Firstly, check whether there is a bookmark here.
+ if (lyxrc.bookmarks_visibility == LyXRC::BMK_INLINE)
+ for (auto const & bp_p : bpl)
+ if (bp_p.second == i) {
+ Font f = *fi;
+ f.fontInfo().setColor(Color_bookmark);
+ // â¶ U+2776 DINGBAT NEGATIVE CIRCLED DIGIT ONE
+ char_type const ch = 0x2775 + bp_p.first;
+ row.addVirtual(i, docstring(1, ch), f, Change());
+ }
+
+ // The stopping condition is here so that the display of a
+ // bookmark can take place at paragraph start too.
+ if (i >= end)
+ break;
+
+ char_type c = par.getChar(i);
+ // The most special cases are handled first.
+ if (par.isInset(i)) {
+ Inset const * ins = par.getInset(i);
+ Dimension dim = bv_->coordCache().insets().dim(ins);
+ row.add(i, ins, dim, *fi, par.lookupChange(i));
+ } else if (c == ' ' && i + 1 == body_pos) {
+ // There is a space at i, but it should not be
+ // added as a separator, because it is just
+ // before body_pos. Instead, insert some spacing to
+ // align text
+ FontMetrics const & fm = theFontMetrics(text_->labelFont(par));
+ // this is needed to make sure that the row width is correct
+ row.finalizeLast();
+ int const add = max(fm.width(par.layout().labelsep),
+ labelEnd(pit) - row.width());
+ row.addSpace(i, add, *fi, par.lookupChange(i));
+ } else if (c == '\t')
+ row.addSpace(i, theFontMetrics(*fi).width(from_ascii(" ")),
+ *fi, par.lookupChange(i));
+ else if (c == 0x2028 || c == 0x2029) {
+ /**
+ * U+2028 LINE SEPARATOR
+ * U+2029 PARAGRAPH SEPARATOR
+
+ * These are special unicode characters that break
+ * lines/pragraphs. Not handling them lead to trouble wrt
+ * Qt QTextLayout formatting. We add a visible character
+ * on screen so that the user can see that something is
+ * happening.
+ */
+ row.finalizeLast();
+ // ⤶ U+2936 ARROW POINTING DOWNWARDS THEN CURVING LEFTWARDS
+ // ¶ U+00B6 PILCROW SIGN
+ char_type const screen_char = (c == 0x2028) ? 0x2936 : 0x00B6;
+ row.add(i, screen_char, *fi, par.lookupChange(i));
+ } else
+ row.add(i, c, *fi, par.lookupChange(i));
+
+ // add inline completion width
+ // draw logically behind the previous character
+ if (ic_pos == i + 1 && !bv_->inlineCompletion().empty()) {
+ docstring const comp = bv_->inlineCompletion();
+ size_t const uniqueTo =bv_->inlineCompletionUniqueChars();
+ Font f = *fi;
+
+ if (uniqueTo > 0) {
+ f.fontInfo().setColor(Color_inlinecompletion);
+ row.addVirtual(i + 1, comp.substr(0, uniqueTo), f, Change());
+ }
+ f.fontInfo().setColor(Color_nonunique_inlinecompletion);
+ row.addVirtual(i + 1, comp.substr(uniqueTo), f, Change());
+ }
+
+ ++i;
+ ++fi;
+ }
+ row.finalizeLast();
+ row.endpos(end);
+
+ // End of paragraph marker. The logic here is almost the
+ // same as in redoParagraph, remember keep them in sync.
+ ParagraphList const & pars = text_->paragraphs();
+ Change const & change = par.lookupChange(i);
+ if ((lyxrc.paragraph_markers || change.changed())
+ && i == end && size_type(pit + 1) < pars.size()) {
+ // add a virtual element for the end-of-paragraph
+ // marker; it is shown on screen, but does not exist
+ // in the paragraph.
+ Font f(text_->layoutFont(pit));
+ f.fontInfo().setColor(Color_paragraphmarker);
+ f.setLanguage(par.getParLanguage(buf.params()));
+ // ¶ U+00B6 PILCROW SIGN
+ row.addVirtual(end, docstring(1, char_type(0x00B6)), f, change);
+ }
+
+ return row;
+}
+
+
/** This is the function where the hard work is done. The code here is
* very sensitive to small changes :) Note that part of the
* intelligence is also in Row::shortenIfNeeded.
*/
bool TextMetrics::breakRow(Row & row, int const right_margin) const
{
- LATTEST(row.empty());
- Paragraph const & par = text_->getPar(row.pit());
- Buffer const & buf = text_->inset().buffer();
- BookmarksSection::BookmarkPosList bpl =
- theSession().bookmarks().bookmarksInPar(buf.fileName(), par.id());
+ LATTEST(row.empty());//
+ Paragraph const & par = text_->getPar(row.pit());//
+ Buffer const & buf = text_->inset().buffer();//
+ BookmarksSection::BookmarkPosList bpl =//
+ theSession().bookmarks().bookmarksInPar(buf.fileName(), par.id());//
- pos_type const end = par.size();
+ pos_type const end = par.size();//
pos_type const pos = row.pos();
- pos_type const body_pos = par.beginOfBody();
+ pos_type const body_pos = par.beginOfBody();//
bool const is_rtl = text_->isRTL(row.pit());
bool need_new_row = false;
@@ -897,14 +1018,14 @@ bool TextMetrics::breakRow(Row & row, int const right_margin) const
int const width = max_width_ - row.right_margin;
// check for possible inline completion
- DocIterator const & ic_it = bv_->inlineCompletionPos();
- pos_type ic_pos = -1;
- if (ic_it.inTexted() && ic_it.text() == text_ && ic_it.pit() == row.pit())
- ic_pos = ic_it.pos();
+ DocIterator const & ic_it = bv_->inlineCompletionPos();//
+ pos_type ic_pos = -1;//
+ if (ic_it.inTexted() && ic_it.text() == text_ && ic_it.pit() == row.pit())//
+ ic_pos = ic_it.pos();//
// Now we iterate through until we reach the right margin
// or the end of the par, then build a representation of the row.
- pos_type i = pos;
+ pos_type i = pos;//---------------------------------------------------vvv
FontIterator fi = FontIterator(*this, par, row.pit(), pos);
// The real stopping condition is a few lines below.
while (true) {
@@ -921,7 +1042,7 @@ bool TextMetrics::breakRow(Row & row, int const right_margin) const
// The stopping condition is here so that the display of a
// bookmark can take place at paragraph start too.
- if (i >= end || (i != pos && row.width() > width))
+ if (i >= end || (i != pos && row.width() > width))//^width
break;
char_type c = par.getChar(i);
@@ -976,8 +1097,9 @@ bool TextMetrics::breakRow(Row & row, int const right_margin) const
}
f.fontInfo().setColor(Color_nonunique_inlinecompletion);
row.addVirtual(i + 1, comp.substr(uniqueTo), f, Change());
- }
+ }//---------------------------------------------------------------^^^
+ // FIXME: Handle when breaking the rows
// Handle some situations that abruptly terminate the row
// - Before an inset with BreakBefore
// - After an inset with BreakAfter
@@ -1002,6 +1124,7 @@ bool TextMetrics::breakRow(Row & row, int const right_margin) const
++i;
++fi;
}
+ //--------------------------------------------------------------------vvv
row.finalizeLast();
row.endpos(i);
@@ -1010,7 +1133,7 @@ bool TextMetrics::breakRow(Row & row, int const right_margin) const
ParagraphList const & pars = text_->paragraphs();
Change const & change = par.lookupChange(i);
if ((lyxrc.paragraph_markers || change.changed())
- && !need_new_row
+ && !need_new_row // not this
&& i == end && size_type(row.pit() + 1) < pars.size()) {
// add a virtual element for the end-of-paragraph
// marker; it is shown on screen, but does not exist
@@ -1025,6 +1148,8 @@ bool TextMetrics::breakRow(Row & row, int const right_margin) const
// Is there a end-of-paragaph change?
if (i == end && par.lookupChange(end).changed() && !need_new_row)
row.needsChangeBar(true);
+ //--------------------------------------------------------------------^^^
+ // FIXME : nothing below this
// if the row is too large, try to cut at last separator. In case
// of success, reset indication that the row was broken abruptly.
diff --git a/src/TextMetrics.h b/src/TextMetrics.h
index 1501250..1666cd0 100644
--- a/src/TextMetrics.h
+++ b/src/TextMetrics.h
@@ -151,6 +151,8 @@ private:
/// FIXME??
int labelEnd(pit_type const pit) const;
+ Row tokenizeParagraph(pit_type pit) const;
+
/// sets row.end to the pos value *after* which a row should break.
/// for example, the pos after which isNewLine(pos) == true
/// \return true when another row is required (after a newline)
commit ad55a82992866067ae245da73d55e63aafbfd693
Author: Jean-Marc Lasgouttes <lasgouttes at lyx.org>
Date: Sun Jul 11 15:33:33 2021 +0200
Small Row cleanups
Move declaration of RowList to Row.h
Move initialization of POD members of Row and Row::Element to declaration.
Make method isVirtual() depend on type.
Add new row element type INVALID and method isValid()
Make methods R::E::left/right_pos inline.
Add method R::E::splitAt() that returns an element containing the
remaining stuff, or an invalid element if nothing was split. breakAt
is now a simple wrapper around this function.
Add method R::push_back().
diff --git a/src/ParagraphMetrics.h b/src/ParagraphMetrics.h
index 9889473..1d690aa 100644
--- a/src/ParagraphMetrics.h
+++ b/src/ParagraphMetrics.h
@@ -20,17 +20,8 @@
#include "Dimension.h"
#include "Row.h"
-#include <vector>
-
namespace lyx {
-/**
- * Each paragraph is broken up into a number of rows on the screen.
- * This is a list of such on-screen rows, ordered from the top row
- * downwards.
- */
-typedef std::vector<Row> RowList;
-
class BufferView;
class Paragraph;
diff --git a/src/Row.cpp b/src/Row.cpp
index 2f6db3d..da2d885 100644
--- a/src/Row.cpp
+++ b/src/Row.cpp
@@ -124,53 +124,43 @@ pos_type Row::Element::x2pos(int &x) const
x = 0;
i = isRTL();
}
+ break;
+ case INVALID:
+ LYXERR0("x2pos: INVALID row element !");
}
//lyxerr << "=> p=" << pos + i << " x=" << x << endl;
return pos + i;
}
-bool Row::Element::breakAt(int w, bool force)
+Row::Element Row::Element::splitAt(int w, bool force)
{
if (type != STRING)
- return false;
+ return Element();
FontMetrics const & fm = theFontMetrics(font);
dim.wid = w;
int const i = fm.breakAt(str, dim.wid, isRTL(), force);
if (i != -1) {
+ Element ret(STRING, pos + i, font, change);
+ ret.str = str.substr(i);
+ ret.endpos = ret.pos + ret.str.length();
str.erase(i);
endpos = pos + i;
//lyxerr << "breakAt(" << w << ") Row element Broken at " << x << "(w(str)=" << fm.width(str) << "): e=" << *this << endl;
+ return ret;
}
- return i != - 1;
+ return Element();
}
-pos_type Row::Element::left_pos() const
-{
- return isRTL() ? endpos : pos;
-}
-
-
-pos_type Row::Element::right_pos() const
+bool Row::Element::breakAt(int w, bool force)
{
- return isRTL() ? pos : endpos;
+ return splitAt(w, force).isValid();
}
-Row::Row()
- : separator(0), label_hfill(0), left_margin(0), right_margin(0),
- sel_beg(-1), sel_end(-1),
- begin_margin_sel(false), end_margin_sel(false),
- changed_(true),
- pit_(0), pos_(0), end_(0),
- right_boundary_(false), flushed_(false), rtl_(false),
- changebar_(false)
-{}
-
-
bool Row::isMarginSelected(bool left, DocIterator const & beg,
DocIterator const & end) const
{
@@ -262,6 +252,9 @@ ostream & operator<<(ostream & os, Row::Element const & e)
case Row::SPACE:
os << "SPACE: ";
break;
+ case Row::INVALID:
+ os << "INVALID: ";
+ break;
}
os << "width=" << e.full_width();
return os;
@@ -443,6 +436,13 @@ void Row::addSpace(pos_type const pos, int const width,
}
+void Row::push_back(Row::Element const & e)
+{
+ dim_.wid += e.dim.wid;
+ elements_.push_back(e);
+}
+
+
void Row::pop_back()
{
dim_.wid -= elements_.back().dim.wid;
diff --git a/src/Row.h b/src/Row.h
index b54a233..3048cf1 100644
--- a/src/Row.h
+++ b/src/Row.h
@@ -49,7 +49,9 @@ public:
// An inset
INSET,
// Some spacing described by its width, not a string
- SPACE
+ SPACE,
+ // Something that should not happen (for error handling)
+ INVALID
};
/**
@@ -57,9 +59,12 @@ public:
* by other methods that need to parse the Row contents.
*/
struct Element {
+ //
+ Element() = default;
+ //
Element(Type const t, pos_type p, Font const & f, Change const & ch)
- : type(t), pos(p), endpos(p + 1), inset(0),
- extra(0), font(f), change(ch), final(false) {}
+ : type(t), pos(p), endpos(p + 1), font(f), change(ch) {}
+
// Return the number of separator in the element (only STRING type)
int countSeparators() const;
@@ -86,40 +91,49 @@ public:
* adjusted to the actual pixel position.
*/
pos_type x2pos(int &x) const;
+ /** Break the element in two if possible, so that its width is less
+ * than \param w.
+ * \return an element containing the remainder of the text, or
+ * an invalid element if nothing happened.
+ * \param w: the desired maximum width
+ * \param force: if true, the string is cut at any place, otherwise it
+ * respects the row breaking rules of characters.
+ */
+ Element splitAt(int w, bool force);
/** Break the element if possible, so that its width is less
* than \param w. Returns true on success. When \param force
- * is true, the string is cut at any place, other wise it
+ * is true, the string is cut at any place, otherwise it
* respects the row breaking rules of characters.
*/
bool breakAt(int w, bool force);
- // Returns the position on left side of the element.
- pos_type left_pos() const;
- // Returns the position on right side of the element.
- pos_type right_pos() const;
-
//
bool isRTL() const { return font.isVisibleRightToLeft(); }
// This is true for virtual elements.
- // Note that we do not use the type here. The two definitions
- // should be equivalent
- bool isVirtual() const { return pos == endpos; }
+ bool isVirtual() const { return type == VIRTUAL; }
+ // Invalid element, for error handling
+ bool isValid() const { return type !=INVALID; }
+
+ // Returns the position on left side of the element.
+ pos_type left_pos() const { return isRTL() ? endpos : pos; };
+ // Returns the position on right side of the element.
+ pos_type right_pos() const { return isRTL() ? pos : endpos; };
// The kind of row element
- Type type;
+ Type type = INVALID;
// position of the element in the paragraph
- pos_type pos;
+ pos_type pos = 0;
// first position after the element in the paragraph
- pos_type endpos;
+ pos_type endpos = 0;
// The dimension of the chunk (does not contains the
// separator correction)
Dimension dim;
// Non-zero only if element is an inset
- Inset const * inset;
+ Inset const * inset = nullptr;
// Only non-null for justified rows
- double extra;
+ double extra = 0;
// Non-empty if element is a string or is virtual
docstring str;
@@ -128,14 +142,15 @@ public:
//
Change change;
// is it possible to add contents to this element?
- bool final;
+ bool final = false;
friend std::ostream & operator<<(std::ostream & os, Element const & row);
};
///
- Row();
+ Row() {}
+
/**
* Helper function: set variable \c var to value \c val, and mark
* row as changed is the values were different. This is intended
@@ -264,7 +279,9 @@ public:
Element & back() { return elements_.back(); }
///
Element const & back() const { return elements_.back(); }
- /// remove last element
+ /// add element at the end and update width
+ void push_back(Element const &);
+ /// remove last element and update width
void pop_back();
/**
* if row width is too large, remove all elements after last
@@ -301,21 +318,21 @@ public:
friend std::ostream & operator<<(std::ostream & os, Row const & row);
/// additional width for separators in justified rows (i.e. space)
- double separator;
+ double separator = 0;
/// width of hfills in the label
- double label_hfill;
+ double label_hfill = 0;
/// the left margin position of the row
- int left_margin;
+ int left_margin = 0;
/// the right margin of the row
- int right_margin;
+ int right_margin = 0;
///
- mutable pos_type sel_beg;
+ mutable pos_type sel_beg = -1;
///
- mutable pos_type sel_end;
+ mutable pos_type sel_end = -1;
///
- mutable bool begin_margin_sel;
+ mutable bool begin_margin_sel = false;
///
- mutable bool end_margin_sel;
+ mutable bool end_margin_sel = false;
private:
/// Decides whether the margin is selected.
@@ -340,28 +357,35 @@ private:
Elements elements_;
/// has the Row appearance changed since last drawing?
- mutable bool changed_;
+ mutable bool changed_ = true;
/// Index of the paragraph that contains this row
- pit_type pit_;
+ pit_type pit_ = 0;
/// first pos covered by this row
- pos_type pos_;
+ pos_type pos_ = 0;
/// one behind last pos covered by this row
- pos_type end_;
+ pos_type end_ = 0;
// Is there a boundary at the end of the row (display inset...)
- bool right_boundary_;
+ bool right_boundary_ = false;
// Shall the row be flushed when it is supposed to be justified?
- bool flushed_;
+ bool flushed_ = false;
/// Row dimension.
Dimension dim_;
/// Row contents dimension. Does not contain the space above/below row.
Dimension contents_dim_;
/// true when this row lives in a right-to-left paragraph
- bool rtl_;
+ bool rtl_ = false;
/// true when a changebar should be drawn in the margin
- bool changebar_;
+ bool changebar_ = false;
};
+/**
+ * Each paragraph is broken up into a number of rows on the screen.
+ * This is a list of such on-screen rows, ordered from the top row
+ * downwards.
+ */
+typedef std::vector<Row> RowList;
+
} // namespace lyx
#endif
diff --git a/src/RowPainter.cpp b/src/RowPainter.cpp
index 400b7b6..656f89a 100644
--- a/src/RowPainter.cpp
+++ b/src/RowPainter.cpp
@@ -565,6 +565,10 @@ void RowPainter::paintText()
case Row::SPACE:
paintTextDecoration(e);
+ break;
+
+ case Row::INVALID:
+ LYXERR0("Trying to paint INVALID row element.");
}
// The markings of foreign languages
commit 7e07630120614e2561a023c1a7ae92f447eedee0
Author: Jean-Marc Lasgouttes <lasgouttes at lyx.org>
Date: Sat Jul 10 23:21:27 2021 +0200
Change FontMetrics::breakAt to return a position
Since we intend to break the row element in two, it is not good to
truncate the string too early.
Moreover, the row element width is now set at this point, even if no
breaking occurs.
diff --git a/src/Row.cpp b/src/Row.cpp
index 16ae9ae..2f6db3d 100644
--- a/src/Row.cpp
+++ b/src/Row.cpp
@@ -132,19 +132,19 @@ pos_type Row::Element::x2pos(int &x) const
bool Row::Element::breakAt(int w, bool force)
{
- if (type != STRING || dim.wid <= w)
+ if (type != STRING)
return false;
FontMetrics const & fm = theFontMetrics(font);
- int x = w;
- if(fm.breakAt(str, x, isRTL(), force)) {
- dim.wid = x;
- endpos = pos + str.length();
+ dim.wid = w;
+ int const i = fm.breakAt(str, dim.wid, isRTL(), force);
+ if (i != -1) {
+ str.erase(i);
+ endpos = pos + i;
//lyxerr << "breakAt(" << w << ") Row element Broken at " << x << "(w(str)=" << fm.width(str) << "): e=" << *this << endl;
- return true;
}
- return false;
+ return i != - 1;
}
diff --git a/src/frontends/FontMetrics.h b/src/frontends/FontMetrics.h
index 2a6ffea..b562ebf 100644
--- a/src/frontends/FontMetrics.h
+++ b/src/frontends/FontMetrics.h
@@ -122,13 +122,14 @@ public:
*/
virtual int x2pos(docstring const & s, int & x, bool rtl, double ws) const = 0;
/**
- * Break string at width at most x.
- * \return true if successful
+ * Break string s at width at most x.
+ * \return break position (-1 if not successful)
+ * \param position x is updated to real width
* \param rtl is true for right-to-left layout
* \param force is false for breaking at word separator, true for
* arbitrary position.
*/
- virtual bool breakAt(docstring & s, int & x, bool rtl, bool force) const = 0;
+ virtual int breakAt(docstring const & s, int & x, bool rtl, bool force) const = 0;
/// return char dimension for the font.
virtual Dimension const dimension(char_type c) const = 0;
/**
diff --git a/src/frontends/qt/GuiFontMetrics.cpp b/src/frontends/qt/GuiFontMetrics.cpp
index 8273ed8..b38bed9 100644
--- a/src/frontends/qt/GuiFontMetrics.cpp
+++ b/src/frontends/qt/GuiFontMetrics.cpp
@@ -524,7 +524,7 @@ GuiFontMetrics::breakAt_helper(docstring const & s, int const x,
tl.endLayout();
int const line_wid = iround(line.horizontalAdvance());
if ((force && line.textLength() == offset) || line_wid > x)
- return {-1, -1};
+ return {-1, line_wid};
/* Since QString is UTF-16 and docstring is UCS-4, the offsets may
* not be the same when there are high-plan unicode characters
* (bug #10443).
@@ -548,6 +548,9 @@ GuiFontMetrics::breakAt_helper(docstring const & s, int const x,
--len;
LASSERT(len > 0 || qlen == 0, /**/);
#endif
+ // si la chaîne est déjà trop courte, on ne coupe pas
+ if (len == static_cast<int>(s.length()))
+ len = -1;
return {len, line_wid};
}
@@ -559,7 +562,7 @@ uint qHash(BreakAtKey const & key)
}
-bool GuiFontMetrics::breakAt(docstring & s, int & x, bool const rtl, bool const force) const
+int GuiFontMetrics::breakAt(docstring const & s, int & x, bool const rtl, bool const force) const
{
PROFILE_THIS_BLOCK(breakAt);
if (s.empty())
@@ -574,11 +577,8 @@ bool GuiFontMetrics::breakAt(docstring & s, int & x, bool const rtl, bool const
pp = breakAt_helper(s, x, rtl, force);
breakat_cache_.insert(key, pp, sizeof(key) + s.size() * sizeof(char_type));
}
- if (pp.first == -1)
- return false;
- s = s.substr(0, pp.first);
x = pp.second;
- return true;
+ return pp.first;
}
diff --git a/src/frontends/qt/GuiFontMetrics.h b/src/frontends/qt/GuiFontMetrics.h
index 95b577c..40d668b 100644
--- a/src/frontends/qt/GuiFontMetrics.h
+++ b/src/frontends/qt/GuiFontMetrics.h
@@ -79,7 +79,7 @@ public:
int signedWidth(docstring const & s) const override;
int pos2x(docstring const & s, int pos, bool rtl, double ws) const override;
int x2pos(docstring const & s, int & x, bool rtl, double ws) const override;
- bool breakAt(docstring & s, int & x, bool rtl, bool force) const override;
+ int breakAt(docstring const & s, int & x, bool rtl, bool force) const override;
Dimension const dimension(char_type c) const override;
void rectText(docstring const & str,
commit 6bbd88accfb76248d00346f308ba1f67f186e094
Author: Jean-Marc Lasgouttes <lasgouttes at lyx.org>
Date: Fri Sep 24 16:57:05 2021 +0200
Improve (modestly) the performance of font metrics caches
This fixes two performance issues and improves the performance of
TextMetrics::redoParagraph by 15% in a workload that uses the cache a
lot. The difference will be much less when the cache is not used much.
1/ repetion of the hash code computation
The code
if (cache.contains(key))
result = cache[key]:
is not efficient, since qHash(key) has to be computed twice.
To fix this a new Cache::object_str() method is added, which allows
if (auto * obj = cache.object(key))
result = *obj;
2/ code of has code computation
Instead of using a verbose string that is complicated to build as
key, new key structs BreakAtKey and TextLayoutKey are introduced,
along with the relevant qHash() implementation.
diff --git a/src/frontends/qt/GuiFontMetrics.cpp b/src/frontends/qt/GuiFontMetrics.cpp
index 7d72820..8273ed8 100644
--- a/src/frontends/qt/GuiFontMetrics.cpp
+++ b/src/frontends/qt/GuiFontMetrics.cpp
@@ -253,8 +253,8 @@ int GuiFontMetrics::rbearing(char_type c) const
int GuiFontMetrics::width(docstring const & s) const
{
PROFILE_THIS_BLOCK(width);
- if (strwidth_cache_.contains(s))
- return strwidth_cache_[s];
+ if (int * wid_p = strwidth_cache_.object_ptr(s))
+ return *wid_p;
PROFILE_CACHE_MISS(width);
/* Several problems have to be taken into account:
* * QFontMetrics::width does not returns a wrong value with Qt5 with
@@ -328,14 +328,19 @@ int GuiFontMetrics::signedWidth(docstring const & s) const
}
+uint qHash(TextLayoutKey const & key)
+{
+ double params = (2 * key.rtl - 1) * key.ws;
+ return std::qHash(key.s) ^ ::qHash(params);
+}
+
shared_ptr<QTextLayout const>
GuiFontMetrics::getTextLayout(docstring const & s, bool const rtl,
double const wordspacing) const
{
PROFILE_THIS_BLOCK(getTextLayout);
- docstring const s_cache =
- s + (rtl ? "r" : "l") + convert<docstring>(wordspacing);
- if (auto ptl = qtextlayout_cache_[s_cache])
+ TextLayoutKey key{s, rtl, wordspacing};
+ if (auto ptl = qtextlayout_cache_[key])
return ptl;
PROFILE_CACHE_MISS(getTextLayout);
auto const ptl = make_shared<QTextLayout>();
@@ -368,7 +373,7 @@ GuiFontMetrics::getTextLayout(docstring const & s, bool const rtl,
ptl->beginLayout();
ptl->createLine();
ptl->endLayout();
- qtextlayout_cache_.insert(s_cache, ptl);
+ qtextlayout_cache_.insert(key, ptl);
return ptl;
}
@@ -547,22 +552,27 @@ GuiFontMetrics::breakAt_helper(docstring const & s, int const x,
}
+uint qHash(BreakAtKey const & key)
+{
+ int params = key.force + 2 * key.rtl + 4 * key.x;
+ return std::qHash(key.s) ^ ::qHash(params);
+}
+
+
bool GuiFontMetrics::breakAt(docstring & s, int & x, bool const rtl, bool const force) const
{
PROFILE_THIS_BLOCK(breakAt);
if (s.empty())
return false;
- docstring const s_cache =
- s + convert<docstring>(x) + (rtl ? "r" : "l") + (force ? "f" : "w");
+ BreakAtKey key{s, x, rtl, force};
pair<int, int> pp;
-
- if (breakat_cache_.contains(s_cache))
- pp = breakat_cache_[s_cache];
+ if (auto * pp_ptr = breakat_cache_.object_ptr(key))
+ pp = *pp_ptr;
else {
PROFILE_CACHE_MISS(breakAt);
pp = breakAt_helper(s, x, rtl, force);
- breakat_cache_.insert(s_cache, pp, s_cache.size() * sizeof(char_type));
+ breakat_cache_.insert(key, pp, sizeof(key) + s.size() * sizeof(char_type));
}
if (pp.first == -1)
return false;
diff --git a/src/frontends/qt/GuiFontMetrics.h b/src/frontends/qt/GuiFontMetrics.h
index e9af0dd..95b577c 100644
--- a/src/frontends/qt/GuiFontMetrics.h
+++ b/src/frontends/qt/GuiFontMetrics.h
@@ -27,6 +27,32 @@
namespace lyx {
namespace frontend {
+struct BreakAtKey
+{
+ bool operator==(BreakAtKey const & key) const {
+ return key.s == s && key.x == x && key.rtl == rtl && key.force == force;
+ }
+
+ docstring s;
+ int x;
+ bool rtl;
+ bool force;
+};
+
+static uint qHash(BreakAtKey const &);
+
+struct TextLayoutKey
+{
+ bool operator==(TextLayoutKey const & key) const {
+ return key.s == s && key.rtl == rtl && key.ws == ws;
+ }
+
+ docstring s;
+ bool rtl;
+ double ws;
+};
+
+
class GuiFontMetrics : public FontMetrics
{
public:
@@ -94,9 +120,9 @@ private:
/// Cache of string widths
mutable Cache<docstring, int> strwidth_cache_;
/// Cache for breakAt
- mutable Cache<docstring, std::pair<int, int>> breakat_cache_;
+ mutable Cache<BreakAtKey, std::pair<int, int>> breakat_cache_;
/// Cache for QTextLayout
- mutable Cache<docstring, std::shared_ptr<QTextLayout>> qtextlayout_cache_;
+ mutable Cache<TextLayoutKey, std::shared_ptr<QTextLayout>> qtextlayout_cache_;
struct AscendDescend {
int ascent;
diff --git a/src/support/Cache.h b/src/support/Cache.h
index 2b97f6e..1e44ff2 100644
--- a/src/support/Cache.h
+++ b/src/support/Cache.h
@@ -56,6 +56,8 @@ public:
return *obj;
return Val();
}
+ // Version that returns a pointer, and nullptr if the object is not present
+ Val * object_ptr(Key const & key) const { return Q::object(key); }
/// Synonymous for object, same remark as above.
Val operator[](Key const & key) const { return object(key); }
/// Everything from QCache except QCache::take.
commit 9ae002b69f5ae140448b71f8b41ce8797f328468
Author: Enrico Forestieri <forenr at lyx.org>
Date: Fri Sep 24 10:15:58 2021 +0200
Fix bug #12373
Do not perform any autocorrection in the presence of a selection.
diff --git a/src/mathed/InsetMathNest.cpp b/src/mathed/InsetMathNest.cpp
index 01719e5..9210886 100644
--- a/src/mathed/InsetMathNest.cpp
+++ b/src/mathed/InsetMathNest.cpp
@@ -1666,7 +1666,7 @@ void InsetMathNest::lfunMouseRelease(Cursor & cur, FuncRequest & cmd)
bool InsetMathNest::interpretChar(Cursor & cur, char_type const c)
{
// try auto-correction
- if (lyxrc.autocorrection_math && cur.pos() != 0
+ if (lyxrc.autocorrection_math && cur.pos() != 0 && !cur.selection()
&& math_autocorrect(cur, c))
return true;
commit dd947300bc6365650ed61a7aa3e7c1be2245ed41
Author: Kornel Benko <kornel at lyx.org>
Date: Fri Sep 24 10:08:02 2021 +0200
Amend dca39815: Fix a few warnings in Floating.
diff --git a/src/Floating.cpp b/src/Floating.cpp
index d396e8a..6a532aa 100644
--- a/src/Floating.cpp
+++ b/src/Floating.cpp
@@ -42,8 +42,8 @@ Floating::Floating(string const & type, string const & placement,
usesfloatpkg_(usesfloat), ispredefined_(ispredefined),
allowswide_(allowswide), allowssideways_(allowssideways),
html_tag_(htmlTag), html_attrib_(htmlAttrib), html_style_(htmlStyle),
- docbook_tag_(docbookTag), docbook_tag_type_(docbookTagType),
- docbook_caption_(docbookCaption)
+ docbook_caption_(docbookCaption), docbook_tag_(docbookTag),
+ docbook_tag_type_(docbookTagType)
{
// Implement some edge cases for DocBook. Both docbook_float_type_ and docbook_attr_ must be computed
// based on the given value of docbookFloatType; docbook_tag_ can still be guessed without correlation.
commit dca39815d3e3e753e310ed53fe6007fb41f7a32b
Author: Thibaut Cuvelier <tcuvelier at lyx.org>
Date: Fri Sep 24 01:19:28 2021 +0200
Fix a few warnings in Floating.
diff --git a/src/Floating.cpp b/src/Floating.cpp
index ecd325f..d396e8a 100644
--- a/src/Floating.cpp
+++ b/src/Floating.cpp
@@ -85,6 +85,10 @@ Floating::Floating(string const & type, string const & placement,
// Specific floats for achemso.
else if (docbook_float_type_ == "figure" && achemso.find(floattype_) != achemso.end())
docbook_attr_ += " type='" + floattype_ + "'";
+
+ // Finally, merge in the attributes given in argument.
+ if (!docbookAttr.empty())
+ docbook_attr_ += " " + docbookAttr;
}
}
diff --git a/src/Floating.h b/src/Floating.h
index 7461e96..7af2334 100644
--- a/src/Floating.h
+++ b/src/Floating.h
@@ -143,7 +143,7 @@ private:
/// DocBook tag type (block, paragraph, inline)
mutable std::string docbook_tag_type_;
/// DocBook float type, to override float_type_ (figure, table, algorithm, video)
- mutable std::string docbook_float_type_;
+ std::string docbook_float_type_;
};
commit e53af9e67749cd20db1035560c6f7a6abe7232b3
Author: Thibaut Cuvelier <tcuvelier at lyx.org>
Date: Fri Sep 24 00:43:32 2021 +0200
DocBook: add a LilyPond test.
diff --git a/autotests/export/docbook/LilyPond_Book.lyx b/autotests/export/docbook/LilyPond_Book.lyx
new file mode 100644
index 0000000..8f40f2b
--- /dev/null
+++ b/autotests/export/docbook/LilyPond_Book.lyx
@@ -0,0 +1,154 @@
+#LyX 2.4 created this file. For more info see https://www.lyx.org/
+\lyxformat 608
+\begin_document
+\begin_header
+\save_transient_properties true
+\origin unavailable
+\textclass article
+\use_default_options true
+\begin_modules
+lilypond
+\end_modules
+\maintain_unincluded_children no
+\language english
+\language_package default
+\inputencoding utf8
+\fontencoding auto
+\font_roman "lmodern" "default"
+\font_sans "lmss" "default"
+\font_typewriter "lmtt" "default"
+\font_math "auto" "auto"
+\font_default_family default
+\use_non_tex_fonts false
+\font_sc false
+\font_roman_osf false
+\font_sans_osf false
+\font_typewriter_osf false
+\font_sf_scale 100 100
+\font_tt_scale 100 100
+\use_microtype false
+\use_dash_ligatures false
+\graphics default
+\default_output_format default
+\output_sync 0
+\bibtex_command default
+\index_command default
+\paperfontsize default
+\spacing single
+\use_hyperref true
+\pdf_title "LilyPond-book and LyX"
+\pdf_author "The LyX Team"
+\pdf_bookmarks true
+\pdf_bookmarksnumbered true
+\pdf_bookmarksopen true
+\pdf_bookmarksopenlevel 1
+\pdf_breaklinks false
+\pdf_pdfborder false
+\pdf_colorlinks true
+\pdf_backref false
+\pdf_pdfusetitle false
+\pdf_quoted_options "linkcolor=blue,urlcolor=blue,pdfstartview=XYZ"
+\papersize default
+\use_geometry true
+\use_package amsmath 1
+\use_package amssymb 1
+\use_package cancel 1
+\use_package esint 1
+\use_package mathdots 1
+\use_package mathtools 1
+\use_package mhchem 1
+\use_package stackrel 1
+\use_package stmaryrd 1
+\use_package undertilde 1
+\cite_engine basic
+\cite_engine_type default
+\biblio_style plain
+\use_bibtopic false
+\use_indices false
+\paperorientation portrait
+\suppress_date true
+\justification true
+\use_refstyle 0
+\use_minted 0
+\use_lineno 0
+\index Index
+\shortcut idx
+\color #008000
+\end_index
+\leftmargin 2cm
+\topmargin 2cm
+\rightmargin 2cm
+\bottommargin 2cm
+\secnumdepth 3
+\tocdepth 3
+\paragraph_separation indent
+\paragraph_indentation default
+\is_math_indent 0
+\math_numbering_side default
+\quotes_style english
+\dynamic_quotes 0
+\papercolumns 1
+\papersides 1
+\paperpagestyle default
+\tablestyle default
+\tracking_changes false
+\output_changes false
+\change_bars false
+\postpone_fragile_content false
+\html_math_output 0
+\html_css_as_file 0
+\html_be_strict true
+\docbook_table_output 0
+\docbook_mathml_prefix 1
+\end_header
+
+\begin_body
+
+\begin_layout Title
+LilyPond-book and \SpecialChar LyX
+
+\end_layout
+
+\begin_layout Standard
+\begin_inset Flex LilyPond
+status open
+
+\begin_layout Plain Layout
+
+\begin_inset Argument 1
+status open
+
+\begin_layout Plain Layout
+
+staffsize=28
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Plain Layout
+
+
+\backslash
+relative c'' {
+\end_layout
+
+\begin_layout Plain Layout
+
+ g a b c
+\end_layout
+
+\begin_layout Plain Layout
+
+}
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\end_body
+\end_document
diff --git a/autotests/export/docbook/LilyPond_Book.xml b/autotests/export/docbook/LilyPond_Book.xml
new file mode 100644
index 0000000..109e112
--- /dev/null
+++ b/autotests/export/docbook/LilyPond_Book.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- This DocBook file was created by LyX 2.4.0dev
+ See https://www.lyx.org/ for more information -->
+<article xml:lang="en_US" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:xi="http://www.w3.org/2001/XInclude" version="5.2">
+<title>LilyPond-book and LyX</title>
+<mediaobject>
+<textobject>
+<programlisting language='lilypond' role='fragment verbatim staffsize=16 ragged-right relative=2'>
+\relative c'' { g a b c}
+</programlisting>
+</textobject>
+</mediaobject>
+</article>
\ No newline at end of file
commit db3efe45490a2cf4f90af075bd6da232c6ebea1e
Author: Thibaut Cuvelier <tcuvelier at lyx.org>
Date: Thu Sep 23 23:40:21 2021 +0200
Amend 4fd6edf3
Escape paths in the generated RC file.
diff --git a/lib/configure.py b/lib/configure.py
index b204012..d13b314 100644
--- a/lib/configure.py
+++ b/lib/configure.py
@@ -1311,6 +1311,7 @@ def checkConverterEntries():
# even when requested with --pdf. This is a problem if a user
# clicks View PDF after having done a View DVI. To circumvent
# this, use different output folders for eps and pdf outputs.
+ cmd = cmd.replace('"', '\\"')
addToRC(r'\converter lilypond-book latex "' + cmd + ' --safe --lily-output-dir=ly-eps $$i" ""')
addToRC(r'\converter lilypond-book pdflatex "' + cmd + ' --safe --pdf --latex-program=pdflatex --lily-output-dir=ly-pdf $$i" ""')
addToRC(r'\converter lilypond-book-ja platex "' + cmd + ' --safe --pdf --latex-program=platex --lily-output-dir=ly-pdf $$i" ""')
commit 4fd6edf330a5aa160d9c25562278dc43c6e102da
Author: Thibaut Cuvelier <tcuvelier at lyx.org>
Date: Thu Sep 23 02:59:39 2021 +0200
Find LilyPond on Windows too.
The main problem is that, while lilypond.exe exists, there is not lilypond-book.exe: the previous calls always failed, even though the file was there, just not called the right way.
diff --git a/lib/configure.py b/lib/configure.py
index 0a71889..b204012 100644
--- a/lib/configure.py
+++ b/lib/configure.py
@@ -1290,30 +1290,37 @@ def checkConverterEntries():
logger.info('+ found LilyPond, but could not extract version number.')
#
path, lilypond_book = checkProg('a LilyPond book (LaTeX) -> LaTeX converter', ['lilypond-book'])
- if (lilypond_book):
- version_string = cmdOutput("lilypond-book --version")
- match = re.match('(\S+)$', version_string)
- if match:
- version_number = match.groups()[0]
- version = version_number.split('.')
- if int(version[0]) > 2 or (len(version) > 1 and int(version[0]) == 2 and int(version[1]) >= 13):
- # Note: The --lily-output-dir flag is required because lilypond-book
- # does not process input again unless the input has changed,
- # even if the output format being requested is different. So
- # once a .eps file exists, lilypond-book won't create a .pdf
- # even when requested with --pdf. This is a problem if a user
- # clicks View PDF after having done a View DVI. To circumvent
- # this, use different output folders for eps and pdf outputs.
- addToRC(r'\converter lilypond-book latex "lilypond-book --safe --lily-output-dir=ly-eps $$i" ""')
- addToRC(r'\converter lilypond-book pdflatex "lilypond-book --safe --pdf --latex-program=pdflatex --lily-output-dir=ly-pdf $$i" ""')
- addToRC(r'\converter lilypond-book-ja platex "lilypond-book --safe --pdf --latex-program=platex --lily-output-dir=ly-pdf $$i" ""')
- addToRC(r'\converter lilypond-book xetex "lilypond-book --safe --pdf --latex-program=xelatex --lily-output-dir=ly-pdf $$i" ""')
- addToRC(r'\converter lilypond-book luatex "lilypond-book --safe --pdf --latex-program=lualatex --lily-output-dir=ly-pdf $$i" ""')
- addToRC(r'\converter lilypond-book dviluatex "lilypond-book --safe --latex-program=dvilualatex --lily-output-dir=ly-eps $$i" ""')
- logger.info('+ found LilyPond-book version %s.' % version_number)
- else:
- logger.info('+ found LilyPond-book, but version %s is too old.' % version_number)
- else:
+ if lilypond_book:
+ found_lilypond_book = False
+ # On Windows, the file lilypond-book is not directly callable, it must be passed as argument to python.
+ for cmd in ["lilypond-book", "python \"" + path + "/lilypond-book\""]:
+ version_string = cmdOutput(cmd + " --version")
+ if len(version_string) == 0:
+ continue
+ found_lilypond_book = True
+
+ match = re.match('(\S+)$', version_string)
+ if match:
+ version_number = match.groups()[0]
+ version = version_number.split('.')
+ if int(version[0]) > 2 or (len(version) > 1 and int(version[0]) == 2 and int(version[1]) >= 13):
+ # Note: The --lily-output-dir flag is required because lilypond-book
+ # does not process input again unless the input has changed,
+ # even if the output format being requested is different. So
+ # once a .eps file exists, lilypond-book won't create a .pdf
+ # even when requested with --pdf. This is a problem if a user
+ # clicks View PDF after having done a View DVI. To circumvent
+ # this, use different output folders for eps and pdf outputs.
+ addToRC(r'\converter lilypond-book latex "' + cmd + ' --safe --lily-output-dir=ly-eps $$i" ""')
+ addToRC(r'\converter lilypond-book pdflatex "' + cmd + ' --safe --pdf --latex-program=pdflatex --lily-output-dir=ly-pdf $$i" ""')
+ addToRC(r'\converter lilypond-book-ja platex "' + cmd + ' --safe --pdf --latex-program=platex --lily-output-dir=ly-pdf $$i" ""')
+ addToRC(r'\converter lilypond-book xetex "' + cmd + ' --safe --pdf --latex-program=xelatex --lily-output-dir=ly-pdf $$i" ""')
+ addToRC(r'\converter lilypond-book luatex "' + cmd + ' --safe --pdf --latex-program=lualatex --lily-output-dir=ly-pdf $$i" ""')
+ addToRC(r'\converter lilypond-book dviluatex "' + cmd + ' --safe --latex-program=dvilualatex --lily-output-dir=ly-eps $$i" ""')
+ logger.info('+ found LilyPond-book version %s.' % version_number)
+ else:
+ logger.info('+ found LilyPond-book, but version %s is too old.' % version_number)
+ if not found_lilypond_book:
logger.info('+ found LilyPond-book, but could not extract version number.')
#
checkProg('a Noteedit -> LilyPond converter', ['noteedit --export-lilypond $$i'],
commit 4f46c22d034b22ca80e906b97a4f0a8021f37611
Author: Kornel Benko <kornel at lyx.org>
Date: Tue Sep 21 11:27:13 2021 +0200
Cmake build: Unify use of sanitizer
The configuration variable is LYX_DEBUG_SANITIZE
which can have following values:
"NONE"
"ADDRESS" Use address sanitizer (previously used with the variable LYX_ASAN)
"UNSPECIFIED" Use unspecified sanitizer
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f36784a..ecebdc9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -217,7 +217,7 @@ else()
unset(LYX_ENABLE_VALGRIND_TESTS CACHE)
endif()
endif()
-LYX_OPTION(ASAN "Use address sanitizer" OFF ALL)
+LYX_COMBO(DEBUG_SANITIZE "Use sanitize check" NONE ADDRESS UNSPECIFIED)
#LYX_COMBO(USE_FILEDIALOG "Use native or QT file dialog" QT NATIVE)
LYX_COMBO(USE_QT "Use Qt version as frontend" AUTO QT4 QT5 QT6)
LYX_COMBO(USE_IPO "Interprocedural optimization" OFF AUTO ON)
@@ -674,6 +674,19 @@ else()
set(LYX_CXX_FLAGS "")
endif()
+if (LYX_DEBUG_SANITIZE MATCHES "ADDRESS")
+ set(LYX_CXX_FLAGS "${LYX_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
+ message(STATUS)
+ message(STATUS "Address sanitizer enabled. Usage:")
+ message(STATUS " wget https://llvm.org/svn/llvm-project/compiler-rt/trunk/lib/asan/scripts/asan_symbolize.py")
+ message(STATUS " chmod +x ./asan_symbolize.py")
+ message(STATUS " ./bin/${_lyx} 2>&1 | ./asan_symbolize.py | c++filt ")
+ message(STATUS)
+elseif (LYX_DEBUG_SANITIZE MATCHES "UNSPECIFIED")
+ set(LYX_CXX_FLAGS "${LYX_CXX_FLAGS} -fsanitize=undefined -fno-omit-frame-pointer")
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined -fno-omit-frame-pointer")
+endif()
+
if(MSVC)
if (CXX11_FLAG MATCHES "\\+\\+([0-9]+)")
set(CMAKE_CXX_STANDARD ${CMAKE_MATCH_1})
@@ -726,16 +739,6 @@ else()
endif()
endif()
-if(LYX_ASAN)
- set(CMAKE_CXX_FLAGS "-fsanitize=address -fno-omit-frame-pointer -g ${CMAKE_CXX_FLAGS}")
- message(STATUS)
- message(STATUS "Address sanitizer enabled. Usage:")
- message(STATUS " wget https://llvm.org/svn/llvm-project/compiler-rt/trunk/lib/asan/scripts/asan_symbolize.py")
- message(STATUS " chmod +x ./asan_symbolize.py")
- message(STATUS " ./bin/${_lyx} 2>&1 | ./asan_symbolize.py | c++filt ")
- message(STATUS)
-endif()
-
set(LYX_CXX_FLAGS_EXTRA "" CACHE STRING "Desired semicolon separated list of extra cxx compile flags, like '-Werror'")
mark_as_advanced(LYX_CXX_FLAGS_EXTRA)
if(LYX_CXX_FLAGS_EXTRA)
commit ffa1b1dcc7f526247ef3fa2f7a3a49dd8605d53f
Author: Thibaut Cuvelier <tcuvelier at lyx.org>
Date: Tue Sep 21 01:21:13 2021 +0200
DocBook: add inner tags for layouts.
This makes it possible to implement LilyPond as prescribed in https://lilypond.org/doc/v2.22/Documentation/usage/docbook.
diff --git a/lib/layouts/lilypond.module b/lib/layouts/lilypond.module
index b4978bd..6c98f14 100644
--- a/lib/layouts/lilypond.module
+++ b/lib/layouts/lilypond.module
@@ -45,6 +45,7 @@ InsetLayout "Flex:LilyPond"
LabelFont
Color foreground
EndFont
+ DocBookTag IGNORE
EndArgument
DocBookNotInPara true
DocBookWrapperTag mediaobject
diff --git a/src/insets/InsetLayout.cpp b/src/insets/InsetLayout.cpp
index b6056cd..769a774 100644
--- a/src/insets/InsetLayout.cpp
+++ b/src/insets/InsetLayout.cpp
@@ -107,6 +107,9 @@ bool InsetLayout::read(Lexer & lex, TextClass const & tclass,
IL_DOCBOOKITEMWRAPPERTAG,
IL_DOCBOOKITEMWRAPPERTAGTYPE,
IL_DOCBOOKITEMWRAPPERATTR,
+ IL_DOCBOOKINNERTAG,
+ IL_DOCBOOKINNERTAGTYPE,
+ IL_DOCBOOKINNERATTR,
IL_DOCBOOKNOFONTINSIDE,
IL_INTOC,
IL_ISTOCCAPTION,
@@ -156,6 +159,9 @@ bool InsetLayout::read(Lexer & lex, TextClass const & tclass,
{ "docbookargumentbeforemaintag", IL_DOCBOOKARGUMENTBEFOREMAINTAG },
{ "docbookattr", IL_DOCBOOKATTR },
{ "docbookininfo", IL_DOCBOOKININFO },
+ { "docbookinnerattr", IL_DOCBOOKINNERATTR },
+ { "docbookinnertag", IL_DOCBOOKINNERTAG },
+ { "docbookinnertagtype", IL_DOCBOOKINNERTAGTYPE },
{ "docbookitemattr", IL_DOCBOOKITEMATTR },
{ "docbookitemtag", IL_DOCBOOKITEMTAG },
{ "docbookitemtagtype", IL_DOCBOOKITEMTAGTYPE },
@@ -521,6 +527,15 @@ bool InsetLayout::read(Lexer & lex, TextClass const & tclass,
case IL_DOCBOOKTAGTYPE:
lex >> docbooktagtype_;
break;
+ case IL_DOCBOOKINNERTAG:
+ lex >> docbookinnertag_;
+ break;
+ case IL_DOCBOOKINNERATTR:
+ lex >> docbookinnerattr_;
+ break;
+ case IL_DOCBOOKINNERTAGTYPE:
+ lex >> docbookinnertagtype_;
+ break;
case IL_DOCBOOKININFO:
lex >> docbookininfo_;
break;
@@ -714,6 +729,14 @@ std::string InsetLayout::docbooktagtype() const
}
+std::string InsetLayout::docbookinnertagtype() const
+{
+ if (docbookinnertagtype_ != "block" && docbookinnertagtype_ != "paragraph" && docbookinnertagtype_ != "inline")
+ docbookinnertagtype_ = "block";
+ return docbookinnertagtype_;
+}
+
+
std::string InsetLayout::docbookwrappertagtype() const
{
if (docbookwrappertagtype_ != "block" && docbookwrappertagtype_ != "paragraph" && docbookwrappertagtype_ != "inline")
diff --git a/src/insets/InsetLayout.h b/src/insets/InsetLayout.h
index b48fde7..da003a9 100644
--- a/src/insets/InsetLayout.h
+++ b/src/insets/InsetLayout.h
@@ -156,6 +156,12 @@ public:
///
std::string docbookattr() const { return docbookattr_; }
///
+ std::string docbookinnertag() const { return docbookinnertag_; }
+ ///
+ std::string docbookinnertagtype() const;
+ ///
+ std::string docbookinnerattr() const { return docbookinnerattr_; }
+ ///
std::string const & docbookininfo() const;
///
bool docbooksection() const { return docbooksection_; }
@@ -319,6 +325,12 @@ private:
///
std::string docbookattr_;
///
+ std::string docbookinnertag_;
+ ///
+ mutable std::string docbookinnertagtype_;
+ ///
+ std::string docbookinnerattr_;
+ ///
mutable std::string docbookininfo_;
///
bool docbooknotinpara_ = false;
diff --git a/src/insets/InsetText.cpp b/src/insets/InsetText.cpp
index 95d55b7..635a83f 100644
--- a/src/insets/InsetText.cpp
+++ b/src/insets/InsetText.cpp
@@ -686,6 +686,9 @@ void InsetText::docbook(XMLStream & xs, OutputParams const & rp, XHTMLOptions op
attrs += from_ascii(" xlink:href=\"") + text_.asString() + from_ascii("\"");
xml::openTag(xs, il.docbooktag(), attrs, il.docbooktagtype());
}
+
+ if (!il.docbookinnertag().empty() && il.docbookinnertag() != "NONE" && il.docbookinnertag() != "IGNORE")
+ xml::openTag(xs, il.docbookinnertag(), il.docbookinnerattr(), il.docbookinnertagtype());
}
// - Think about the arguments before the paragraph.
@@ -733,6 +736,9 @@ void InsetText::docbook(XMLStream & xs, OutputParams const & rp, XHTMLOptions op
if (!il.docbookitemwrappertag().empty() && il.docbookitemwrappertag() != "NONE" && il.docbookitemwrappertag() != "IGNORE")
xml::closeTag(xs, il.docbookitemwrappertag(), il.docbookitemwrappertagtype());
+ if (!il.docbookinnertag().empty() && il.docbookinnertag() != "NONE" && il.docbookinnertag() != "IGNORE")
+ xml::closeTag(xs, il.docbookinnertag(), il.docbookinnertagtype());
+
if (!il.docbooktag().empty() && il.docbooktag() != "NONE" && il.docbooktag() != "IGNORE")
xml::closeTag(xs, il.docbooktag(), il.docbooktagtype());
commit 7ee23ca885e80ad014c00999584b239d703de2e4
Author: Thibaut Cuvelier <tcuvelier at lyx.org>
Date: Tue Sep 21 01:18:10 2021 +0200
XML: add a check for a typical case in the xml name space.
IGNORE is a typical placeholder for tags that should not be output, along with NONE. At some point, we should check if both are required, or if NONE is enoughâ¦
diff --git a/src/xml.cpp b/src/xml.cpp
index 2f54feb..7c614da 100644
--- a/src/xml.cpp
+++ b/src/xml.cpp
@@ -836,7 +836,7 @@ void xml::openTag(XMLStream & xs, const std::string & tag, const docstring & att
void xml::closeTag(XMLStream & xs, const docstring & tag, const std::string & tagtype)
{
- if (tag.empty() || tag == "NONE")
+ if (tag.empty() || tag == "NONE" || tag == "IGNORE")
return;
if (tag == "para" || tagtype == "paragraph") // Special case for <para>: always considered as a paragraph.
commit 14ed5b205021f57140dcfb603c4869edc352b60a
Author: Thibaut Cuvelier <tcuvelier at lyx.org>
Date: Mon Sep 20 03:19:20 2021 +0200
DocBook: start implementing LilyPond.
All the changes that can be achieved without C++ code changes.
diff --git a/lib/examples/Modules/LilyPond_Book.lyx b/lib/examples/Modules/LilyPond_Book.lyx
index 05ee970..9e65968 100644
--- a/lib/examples/Modules/LilyPond_Book.lyx
+++ b/lib/examples/Modules/LilyPond_Book.lyx
@@ -1,5 +1,5 @@
#LyX 2.4 created this file. For more info see https://www.lyx.org/
-\lyxformat 600
+\lyxformat 608
\begin_document
\begin_header
\save_transient_properties true
@@ -21,9 +21,9 @@ lilypond
\font_default_family default
\use_non_tex_fonts false
\font_sc false
+\font_roman_osf false
\font_sans_osf false
\font_typewriter_osf false
-\font_roman_osf false
\font_sf_scale 100 100
\font_tt_scale 100 100
\use_microtype false
@@ -90,12 +90,16 @@ lilypond
\papercolumns 1
\papersides 1
\paperpagestyle default
+\tablestyle default
\tracking_changes false
-\postpone_fragile_content false
\output_changes false
+\change_bars false
+\postpone_fragile_content false
\html_math_output 0
\html_css_as_file 0
\html_be_strict true
+\docbook_table_output 0
+\docbook_mathml_prefix 1
\end_header
\begin_body
diff --git a/lib/layouts/lilypond.module b/lib/layouts/lilypond.module
index 5df45f6..b4978bd 100644
--- a/lib/layouts/lilypond.module
+++ b/lib/layouts/lilypond.module
@@ -46,4 +46,9 @@ InsetLayout "Flex:LilyPond"
Color foreground
EndFont
EndArgument
+ DocBookNotInPara true
+ DocBookWrapperTag mediaobject
+ DocBookTag textobject
+ DocBookInnerTag programlisting
+ DocBookInnerAttr "language='lilypond' role='fragment verbatim staffsize=16 ragged-right relative=2'"
End
diff --git a/src/output_docbook.cpp b/src/output_docbook.cpp
index 582fab0..114c258 100644
--- a/src/output_docbook.cpp
+++ b/src/output_docbook.cpp
@@ -343,7 +343,7 @@ void makeParagraph(
// We do not really want to wrap that whole thing in a <div>...</div>.
bool special_case = false;
Inset const *specinset = par->size() == 1 ? par->getInset(0) : nullptr;
- if (specinset && !specinset->getLayout().htmlisblock()) { // TODO: Convert htmlisblock to a DocBook parameter?
+ if (specinset && !specinset->getLayout().htmlisblock()) { // TODO: Convert htmlisblock to a DocBook parameter? docbooknotinpara should be enough in most cases.
Layout const &style = par->layout();
FontInfo const first_font = style.labeltype == LABEL_MANUAL ?
style.labelfont : style.font;
commit 687ccdbb3241f26a0875dcf9906d7609a8b56ddc
Author: Kornel Benko <kornel at lyx.org>
Date: Mon Sep 20 11:52:16 2021 +0200
Complete the FontTag typeinfo
diff --git a/src/tests/dummy_functions.cpp b/src/tests/dummy_functions.cpp
index f570616..2698351 100644
--- a/src/tests/dummy_functions.cpp
+++ b/src/tests/dummy_functions.cpp
@@ -54,6 +54,7 @@ namespace xml {
docstring StartTag::writeTag() const { return docstring(); }
docstring StartTag::writeEndTag() const { return docstring(); }
bool StartTag::operator==(FontTag const & rhs) const { return rhs == *this; }
+ bool FontTag::operator==(StartTag const & tag) const { FontTag const * const ftag = tag.asFontTag(); if (!ftag) return false; return (font_type_ == ftag->font_type_); }
}
} // namespace lyx
diff --git a/src/tex2lyx/dummy_impl.cpp b/src/tex2lyx/dummy_impl.cpp
index 961eb9a..eb44567 100644
--- a/src/tex2lyx/dummy_impl.cpp
+++ b/src/tex2lyx/dummy_impl.cpp
@@ -22,6 +22,7 @@
#include "LaTeXFeatures.h"
#include "LyXRC.h"
#include "output_xhtml.h"
+#include "xml.h"
#include "support/Messages.h"
@@ -117,6 +118,7 @@ namespace xml {
docstring StartTag::writeTag() const { return docstring(); }
docstring StartTag::writeEndTag() const { return docstring(); }
bool StartTag::operator==(FontTag const & rhs) const { return rhs == *this; }
+bool FontTag::operator==(StartTag const & tag) const { FontTag const * const ftag = tag.asFontTag(); if (!ftag) return false; return (font_type_ == ftag->font_type_); }
}
} // namespace lyx
commit 8b6e3d374996cc124a9830c71bc2bb744097a7a2
Author: Thibaut Cuvelier <tcuvelier at lyx.org>
Date: Mon Sep 20 00:06:20 2021 +0200
DocBook: add more flexibility for floats.
Intended to fix #12371.
diff --git a/lib/scripts/layout2layout.py b/lib/scripts/layout2layout.py
index eb04f45..e7eb307 100644
--- a/lib/scripts/layout2layout.py
+++ b/lib/scripts/layout2layout.py
@@ -11,7 +11,7 @@
# This script will update a .layout file to current format
# The latest layout format is also defined in src/TextClass.cpp
-currentFormat = 93
+currentFormat = 94
# Incremented to format 4, 6 April 2007, lasgouttes
@@ -316,6 +316,9 @@ currentFormat = 93
# Incremented to format 93, 13 February 2021 by spitz
# Add DocBookNoFontInside
+# Incremented to format 94, 19 September 2021 by tcuvelier
+# Add DocBookFloatType, DocBookCaption
+
# Do not forget to document format change in Customization
# Manual (section "Declaring a new text class").
@@ -566,7 +569,7 @@ def convert(lines, end_format):
i += 1
continue
- if 87 <= format <= 93:
+ if 87 <= format <= 94:
# nothing to do.
i += 1
continue
diff --git a/src/Floating.cpp b/src/Floating.cpp
index fa93b97..ecd325f 100644
--- a/src/Floating.cpp
+++ b/src/Floating.cpp
@@ -31,8 +31,9 @@ Floating::Floating(string const & type, string const & placement,
string const & listName, std::string const & listCmd,
string const & refPrefix, std::string const & allowedplacement,
string const & htmlTag, string const & htmlAttrib,
- docstring const & htmlStyle,
+ docstring const & htmlStyle, std::string const & docbookTag,
string const & docbookAttr, string const & docbookTagType,
+ std::string const & docbookFloatType, std::string const & docbookCaption,
string const & required, bool usesfloat, bool ispredefined,
bool allowswide, bool allowssideways)
: floattype_(type), placement_(placement), ext_(ext), within_(within),
@@ -41,26 +42,49 @@ Floating::Floating(string const & type, string const & placement,
usesfloatpkg_(usesfloat), ispredefined_(ispredefined),
allowswide_(allowswide), allowssideways_(allowssideways),
html_tag_(htmlTag), html_attrib_(htmlAttrib), html_style_(htmlStyle),
- docbook_attr_(docbookAttr), docbook_tag_type_(docbookTagType)
-{}
-
-
-std::string Floating::docbookFloatType() const
+ docbook_tag_(docbookTag), docbook_tag_type_(docbookTagType),
+ docbook_caption_(docbookCaption)
{
- // TODO: configure this in the layouts?
- if (floattype_ == "figure" || floattype_ == "graph" ||
- floattype_ == "chart" || floattype_ == "scheme") {
- return "figure";
- } else if (floattype_ == "table" || floattype_ == "tableau") {
- return "table";
- } else if (floattype_ == "algorithm") {
- return "algorithm";
- } else if (floattype_ == "video") {
- return "video";
- } else {
- // If nothing matches, return something that will not be valid.
- LYXERR0("Unrecognised float type: " + floattype_);
- return "unknown";
+ // Implement some edge cases for DocBook. Both docbook_float_type_ and docbook_attr_ must be computed
+ // based on the given value of docbookFloatType; docbook_tag_ can still be guessed without correlation.
+
+ // Determine the value of docbook_float_type_.
+ {
+ // These are the allowed values for docbook_float_type_. Both docbook_attr_ and docbook_tag_type_
+ // depend on this list.
+ static std::set<std::string> allowedFloatTypes{"figure", "table", "algorithm", "video", "example"};
+
+ // If some type is predetermined in the layout, use it.
+ if (!docbookFloatType.empty() && allowedFloatTypes.find(docbookFloatType) != allowedFloatTypes.end())
+ docbook_float_type_ = docbookFloatType;
+ // Otherwise, try to guess the type.
+ else if (floattype_ == "figure" || floattype_ == "graph" ||
+ floattype_ == "chart" || floattype_ == "scheme") {
+ docbook_float_type_ = "figure";
+ } else if (floattype_ == "table" || floattype_ == "tableau") {
+ docbook_float_type_ = "table";
+ } else if (floattype_ == "algorithm") {
+ docbook_float_type_ = "algorithm";
+ } else if (floattype_ == "video") {
+ docbook_float_type_ = "video";
+ } else {
+ // If nothing matches, return something that will not be valid.
+ LYXERR0("Unrecognised float type: " + floattype_);
+ docbook_float_type_ = "unknown";
+ }
+ }
+
+ // Determine the value of docbook_attr_.
+ {
+ std::set<std::string> achemso = {"chart", "graph", "scheme"};
+ bool hasType = docbook_attr_.find("type=") != std::string::npos;
+
+ // For algorithms, a type attribute must be mentioned, if not already present in docbook_attr_.
+ if (docbook_float_type_ == "algorithm" && !hasType)
+ docbook_attr_ += " type='algorithm'";
+ // Specific floats for achemso.
+ else if (docbook_float_type_ == "figure" && achemso.find(floattype_) != achemso.end())
+ docbook_attr_ += " type='" + floattype_ + "'";
}
}
@@ -103,25 +127,30 @@ string Floating::defaultCSSClass() const
}
+std::string Floating::docbookFloatType() const
+{
+ // All the work is done in the constructor.
+ return docbook_float_type_;
+}
+
+
string Floating::docbookAttr() const
{
- std::set<std::string> achemso = { "chart", "graph", "scheme" };
- // For algorithms, a type attribute must be mentioned, if not already present in docbook_attr_.
- if (docbookFloatType() == "algorithm" && docbook_attr_.find("type=") != std::string::npos)
- return docbook_attr_ + " type='algorithm'";
- // Specific floats for achemso.
- else if (docbookFloatType() == "figure" && achemso.find(floattype_) != achemso.end())
- return docbook_attr_ + " type='" + floattype_ + "'";
- else
- return docbook_attr_;
+ return docbook_attr_;
}
string Floating::docbookTag(bool hasTitle) const
{
- // TODO: configure this in the layouts?
+ // If there is a preconfigured tag, use it.
+ if (!docbook_tag_.empty())
+ return docbook_tag_;
+
+ // Otherwise, guess it.
if (docbookFloatType() == "figure" || docbookFloatType() == "algorithm" || docbookFloatType() == "video") {
return hasTitle ? "figure" : "informalfigure";
+ } else if (docbookFloatType() == "example") {
+ return hasTitle ? "example" : "informalexample";
} else if (docbookFloatType() == "table") {
return hasTitle ? "table" : "informaltable";
} else {
@@ -142,8 +171,11 @@ string const & Floating::docbookTagType() const
string const & Floating::docbookCaption() const
{
- docbook_caption_ = "";
- if (floattype_ == "figure" || floattype_ == "algorithm")
+ if (!docbook_caption_.empty())
+ return docbook_caption_;
+
+ if (docbook_float_type_ == "figure" || docbook_float_type_ == "video" ||
+ docbook_float_type_ == "algorithm" || docbook_float_type_ == "example")
docbook_caption_ = "title";
else if (floattype_ == "table" || floattype_ == "tableau")
docbook_caption_ = "caption";
diff --git a/src/Floating.h b/src/Floating.h
index 4672d9a..7461e96 100644
--- a/src/Floating.h
+++ b/src/Floating.h
@@ -37,8 +37,9 @@ public:
std::string const & listName, std::string const & listCmd,
std::string const & refPrefix, std::string const & allowedplacement,
std::string const & htmlTag, std::string const & htmlAttrib,
- docstring const & htmlStyle,
- std::string const & docbookAttr, std::string const & docbookTagType,
+ docstring const & htmlStyle, std::string const & docbookTag,
+ std::string const & docbookAttr, std::string const & docbookTagType,
+ std::string const & docbookFloatType, std::string const & docbookCaption,
std::string const & required, bool usesfloat, bool ispredefined,
bool allowswide, bool allowssideways);
///
@@ -135,10 +136,14 @@ private:
// has a title or not, an information that is not available in the layouts.
/// attribute (mostly, role)
mutable std::string docbook_caption_;
- /// caption tag (mostly, either caption or title)
+ /// float tag
+ std::string docbook_tag_;
+ /// attributes for the float tag
std::string docbook_attr_;
/// DocBook tag type (block, paragraph, inline)
mutable std::string docbook_tag_type_;
+ /// DocBook float type, to override float_type_ (figure, table, algorithm, video)
+ mutable std::string docbook_float_type_;
};
diff --git a/src/TextClass.cpp b/src/TextClass.cpp
index 1b72706..9546cee 100644
--- a/src/TextClass.cpp
+++ b/src/TextClass.cpp
@@ -59,7 +59,7 @@ namespace lyx {
// You should also run the development/tools/updatelayouts.py script,
// to update the format of all of our layout files.
//
-int const LAYOUT_FORMAT = 93; // tcuvelier: DocBookNoFontInside
+int const LAYOUT_FORMAT = 94; // tcuvelier: DocBookFloatType, DocBookCaption
// Layout format for the current lyx file format. Controls which format is
@@ -1402,8 +1402,10 @@ bool TextClass::readFloat(Lexer & lexrc)
FT_HTMLATTR,
FT_HTMLTAG,
FT_DOCBOOKATTR,
+ FT_DOCBOOKFLOATTYPE,
FT_DOCBOOKTAG,
FT_DOCBOOKTAGTYPE,
+ FT_DOCBOOKCAPTION,
FT_LISTCOMMAND,
FT_REFPREFIX,
FT_ALLOWED_PLACEMENT,
@@ -1418,6 +1420,8 @@ bool TextClass::readFloat(Lexer & lexrc)
{ "allowssideways", FT_ALLOWS_SIDEWAYS },
{ "allowswide", FT_ALLOWS_WIDE },
{ "docbookattr", FT_DOCBOOKATTR },
+ { "docbookcaption", FT_DOCBOOKCAPTION },
+ { "docbookfloattype", FT_DOCBOOKFLOATTYPE },
{ "docbooktag", FT_DOCBOOKTAG },
{ "docbooktagtype", FT_DOCBOOKTAGTYPE },
{ "end", FT_END },
@@ -1445,8 +1449,10 @@ bool TextClass::readFloat(Lexer & lexrc)
docstring htmlstyle;
string htmltag;
string docbookattr;
+ string docbookcaption;
string docbooktag;
string docbooktagtype;
+ string docbookfloattype;
string listname;
string listcommand;
string name;
@@ -1564,6 +1570,10 @@ bool TextClass::readFloat(Lexer & lexrc)
lexrc.next();
docbookattr = lexrc.getString();
break;
+ case FT_DOCBOOKCAPTION:
+ lexrc.next();
+ docbookcaption = lexrc.getString();
+ break;
case FT_DOCBOOKTAG:
lexrc.next();
docbooktag = lexrc.getString();
@@ -1572,6 +1582,10 @@ bool TextClass::readFloat(Lexer & lexrc)
lexrc.next();
docbooktagtype = lexrc.getString();
break;
+ case FT_DOCBOOKFLOATTYPE:
+ lexrc.next();
+ docbookfloattype = lexrc.getString();
+ break;
case FT_END:
getout = true;
break;
@@ -1602,8 +1616,9 @@ bool TextClass::readFloat(Lexer & lexrc)
}
Floating fl(type, placement, ext, within, style, name,
listname, listcommand, refprefix, allowed_placement,
- htmltag, htmlattr, htmlstyle, docbookattr,
- docbooktagtype, required, usesfloat, ispredefined,
+ htmltag, htmlattr, htmlstyle, docbooktag, docbookattr,
+ docbooktagtype, docbookfloattype, docbookcaption,
+ required, usesfloat, ispredefined,
allowswide, allowssideways);
floatlist_.newFloat(fl);
// each float has its own counter
commit bde9b7afa0f3dad4a92cce2fbe61ef1381cf195a
Author: Thibaut Cuvelier <tcuvelier at lyx.org>
Date: Sun Sep 19 20:10:51 2021 +0200
Kill warning for uncovered code path.
diff --git a/src/TextClass.cpp b/src/TextClass.cpp
index 57a9f74..1b72706 100644
--- a/src/TextClass.cpp
+++ b/src/TextClass.cpp
@@ -1575,6 +1575,9 @@ bool TextClass::readFloat(Lexer & lexrc)
case FT_END:
getout = true;
break;
+ default:
+ LYXERR0("Unhandled value " << le << " in TextClass::readFloat.");
+ break;
}
}
commit c5262f04a266cc2e499a4a341daf9528feaa8dd3
Author: Stephan Witt <switt at lyx.org>
Date: Mon Aug 23 14:44:36 2021 +0200
#12247 disable Qt5 modifier hack for Qt-5.12 version or newer
Initially Qt5 modifier handling was broken. Therefore a workaround was introduced.
This workaround broke the LyX modifier handling with swap of Command-Control-key disabled.
The change disables the hack to get the correct behavior in LyX.
diff --git a/src/frontends/qt/GuiKeySymbol.cpp b/src/frontends/qt/GuiKeySymbol.cpp
index c1882f7..77e3dc3 100644
--- a/src/frontends/qt/GuiKeySymbol.cpp
+++ b/src/frontends/qt/GuiKeySymbol.cpp
@@ -859,10 +859,11 @@ bool KeySymbol::operator==(KeySymbol const & ks) const
KeyModifier q_key_state(Qt::KeyboardModifiers state)
{
KeyModifier k = NoModifier;
-#if defined(Q_OS_MAC) && QT_VERSION > 0x050000
+#if defined(Q_OS_MAC) && (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) && (QT_VERSION < QT_VERSION_CHECK(5, 12, 0))
/// Additional check for Control and Meta modifier swap state.
/// Starting with Qt 5 the modifiers aren't reported correctly.
/// Until this is fixed a correction is required.
+ /// AFAIK it is fixed at least with Qt 5.12.0
const bool dontSwapCtrlAndMeta =
frontend::theGuiApp()->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta);
#else
commit 874ae71f95f18f8a5e82b4b6a68769843eb7c54b
Author: Kornel Benko <kornel at lyx.org>
Date: Sat Aug 21 21:29:25 2021 +0200
Update sk.po
diff --git a/po/sk.po b/po/sk.po
index c268d68..9ce73ab 100644
--- a/po/sk.po
+++ b/po/sk.po
@@ -8,8 +8,8 @@ msgid ""
msgstr ""
"Project-Id-Version: LyX-2.4\n"
"Report-Msgid-Bugs-To: lyx-devel at lists.lyx.org\n"
-"POT-Creation-Date: 2021-07-22 16:55+0200\n"
-"PO-Revision-Date: 2021-07-22 15:02+0000\n"
+"POT-Creation-Date: 2021-08-21 21:24+0200\n"
+"PO-Revision-Date: 2021-08-21 19:27+0000\n"
"Last-Translator: Kornel Benko <kornel at lyx.org>\n"
"Language-Team: Slovak <kornel at lyx.org>\n"
"Language: sk\n"
@@ -5341,7 +5341,7 @@ msgstr "Ign&orovať"
#: src/frontends/qt/ui/SpellcheckerUi.ui:175
msgid ""
-"Ignore all occurrences of this word within this document. This is perdurant "
+"Ignore all occurrences of this word within this document. This persists "
"beyond the current session."
msgstr ""
"Ignorovať výskyt tohto slova v tomto dokumente. Platà aj pre každé neskoršie "
commit 5af2107aa12a6dd2dbe1b5627b6a6638c7418a4a
Author: Juergen Spitzmueller <spitz at lyx.org>
Date: Sat Aug 21 15:28:16 2021 +0200
de.po
diff --git a/po/de.gmo b/po/de.gmo
index 51f1be8..cecfdd7 100644
Binary files a/po/de.gmo and b/po/de.gmo differ
diff --git a/po/de.po b/po/de.po
index d43fe30..8d42e8a 100644
--- a/po/de.po
+++ b/po/de.po
@@ -94,15 +94,15 @@ msgid ""
msgstr ""
"Project-Id-Version: LyX 2.4git\n"
"Report-Msgid-Bugs-To: lyx-devel at lists.lyx.org\n"
-"POT-Creation-Date: 2021-05-12 09:06+0200\n"
-"PO-Revision-Date: 2021-05-12 09:16+0200\n"
+"POT-Creation-Date: 2021-08-21 15:21+0200\n"
+"PO-Revision-Date: 2021-08-21 15:27+0200\n"
"Last-Translator: Jürgen Spitzmüller <spitz at lyx.org>\n"
"Language-Team: Deutsch <lyx-docs at lists.lyx.org>\n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Gtranslator 3.38.0\n"
+"X-Generator: Gtranslator 40.0\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
#: src/frontends/qt/ui/AboutUi.ui:27
@@ -668,7 +668,7 @@ msgstr "Dehnen"
#: src/frontends/qt/ui/BoxUi.ui:265 src/frontends/qt/ui/ListingsUi.ui:110
#: src/frontends/qt/ui/TabularUi.ui:344 src/frontends/qt/ui/TabularUi.ui:1553
-#: src/frontends/qt/ui/WrapUi.ui:47 src/frontends/qt/GuiDocument.cpp:1542
+#: src/frontends/qt/ui/WrapUi.ui:47 src/frontends/qt/GuiDocument.cpp:1544
#: src/frontends/qt/GuiParagraph.cpp:115 src/frontends/qt/GuiTabular.cpp:1040
msgid "Left"
msgstr "Links"
@@ -681,7 +681,7 @@ msgstr "Zentriert"
#: src/frontends/qt/ui/BoxUi.ui:275 src/frontends/qt/ui/ListingsUi.ui:115
#: src/frontends/qt/ui/TabularUi.ui:354 src/frontends/qt/ui/WrapUi.ui:52
-#: src/frontends/qt/GuiDocument.cpp:1544 src/frontends/qt/GuiParagraph.cpp:116
+#: src/frontends/qt/GuiDocument.cpp:1546 src/frontends/qt/GuiParagraph.cpp:116
#: src/frontends/qt/GuiTabular.cpp:1042
msgid "Right"
msgstr "Rechts"
@@ -767,7 +767,7 @@ msgid "Remove the selected branch"
msgstr "Den ausgewählten Zweig entfernen"
#: src/frontends/qt/ui/BranchesUi.ui:74 src/frontends/qt/ui/IndicesUi.ui:165
-#: src/Buffer.cpp:4723 src/Buffer.cpp:4736
+#: src/Buffer.cpp:4734 src/Buffer.cpp:4747
msgid "&Remove"
msgstr "&Entfernen"
@@ -842,17 +842,17 @@ msgid "Add A&ll"
msgstr "A&lle hinzufügen"
#: src/frontends/qt/ui/BranchesUnknownUi.ui:58 src/Buffer.cpp:1458
-#: src/Buffer.cpp:4697 src/Buffer.cpp:4807 src/LyXVC.cpp:114 src/LyXVC.cpp:310
+#: src/Buffer.cpp:4708 src/Buffer.cpp:4818 src/LyXVC.cpp:114 src/LyXVC.cpp:310
#: src/buffer_funcs.cpp:56 src/frontends/qt/GuiBranches.cpp:226
-#: src/frontends/qt/GuiClipboard.cpp:252 src/frontends/qt/GuiDocument.cpp:2834
+#: src/frontends/qt/GuiClipboard.cpp:252 src/frontends/qt/GuiDocument.cpp:2836
#: src/frontends/qt/GuiParagraph.cpp:177 src/frontends/qt/GuiPrefs.cpp:3410
-#: src/frontends/qt/GuiView.cpp:2807 src/frontends/qt/GuiView.cpp:3039
-#: src/frontends/qt/GuiView.cpp:3063 src/frontends/qt/GuiView.cpp:3077
-#: src/frontends/qt/GuiView.cpp:3179 src/frontends/qt/GuiView.cpp:3224
-#: src/frontends/qt/GuiView.cpp:3279 src/frontends/qt/GuiView.cpp:3513
-#: src/frontends/qt/GuiView.cpp:3527 src/frontends/qt/GuiView.cpp:3629
-#: src/frontends/qt/GuiView.cpp:3654 src/frontends/qt/GuiView.cpp:4358
-#: src/frontends/qt/GuiView.cpp:4365 src/insets/InsetBibtex.cpp:153
+#: src/frontends/qt/GuiView.cpp:2811 src/frontends/qt/GuiView.cpp:3043
+#: src/frontends/qt/GuiView.cpp:3067 src/frontends/qt/GuiView.cpp:3081
+#: src/frontends/qt/GuiView.cpp:3183 src/frontends/qt/GuiView.cpp:3228
+#: src/frontends/qt/GuiView.cpp:3283 src/frontends/qt/GuiView.cpp:3517
+#: src/frontends/qt/GuiView.cpp:3531 src/frontends/qt/GuiView.cpp:3633
+#: src/frontends/qt/GuiView.cpp:3658 src/frontends/qt/GuiView.cpp:4362
+#: src/frontends/qt/GuiView.cpp:4369 src/insets/InsetBibtex.cpp:153
msgid "&Cancel"
msgstr "&Abbrechen"
@@ -891,15 +891,15 @@ msgstr "&GröÃe:"
#: src/frontends/qt/GuiCharacter.cpp:136 src/frontends/qt/GuiCharacter.cpp:147
#: src/frontends/qt/GuiCharacter.cpp:190 src/frontends/qt/GuiCharacter.cpp:241
#: src/frontends/qt/GuiDocument.cpp:120 src/frontends/qt/GuiDocument.cpp:858
-#: src/frontends/qt/GuiDocument.cpp:878 src/frontends/qt/GuiDocument.cpp:1048
-#: src/frontends/qt/GuiDocument.cpp:1133 src/frontends/qt/GuiDocument.cpp:1179
-#: src/frontends/qt/GuiDocument.cpp:1190 src/frontends/qt/GuiDocument.cpp:1418
-#: src/frontends/qt/GuiDocument.cpp:1536 src/frontends/qt/GuiDocument.cpp:1543
-#: src/frontends/qt/GuiDocument.cpp:2576 src/frontends/qt/GuiDocument.cpp:2663
-#: src/frontends/qt/GuiDocument.cpp:2664 src/frontends/qt/GuiDocument.cpp:2665
-#: src/frontends/qt/GuiDocument.cpp:2685 src/frontends/qt/GuiDocument.cpp:2692
-#: src/frontends/qt/GuiDocument.cpp:2699 src/frontends/qt/GuiDocument.cpp:2789
-#: src/frontends/qt/GuiDocument.cpp:3398 src/frontends/qt/GuiDocument.cpp:4894
+#: src/frontends/qt/GuiDocument.cpp:878 src/frontends/qt/GuiDocument.cpp:1050
+#: src/frontends/qt/GuiDocument.cpp:1135 src/frontends/qt/GuiDocument.cpp:1181
+#: src/frontends/qt/GuiDocument.cpp:1192 src/frontends/qt/GuiDocument.cpp:1420
+#: src/frontends/qt/GuiDocument.cpp:1538 src/frontends/qt/GuiDocument.cpp:1545
+#: src/frontends/qt/GuiDocument.cpp:2578 src/frontends/qt/GuiDocument.cpp:2665
+#: src/frontends/qt/GuiDocument.cpp:2666 src/frontends/qt/GuiDocument.cpp:2667
+#: src/frontends/qt/GuiDocument.cpp:2687 src/frontends/qt/GuiDocument.cpp:2694
+#: src/frontends/qt/GuiDocument.cpp:2701 src/frontends/qt/GuiDocument.cpp:2791
+#: src/frontends/qt/GuiDocument.cpp:3400 src/frontends/qt/GuiDocument.cpp:4896
#: src/frontends/qt/GuiExternal.cpp:76 src/frontends/qt/GuiGraphics.cpp:71
#: src/frontends/qt/GuiIndices.cpp:58 src/frontends/qt/GuiListings.cpp:160
#: src/frontends/qt/GuiListings.cpp:167 src/frontends/qt/GuiPrefs.cpp:2479
@@ -1097,7 +1097,7 @@ msgstr "S&prache:"
#: lib/layouts/bicaption.module:16 lib/layouts/europasscv.layout:440
#: lib/layouts/europasscv.layout:475 lib/layouts/europasscv.layout:482
#: lib/layouts/europecv.layout:321 lib/layouts/europecv.layout:327
-#: lib/layouts/moderncv.layout:580 src/frontends/qt/GuiDocument.cpp:1767
+#: lib/layouts/moderncv.layout:580 src/frontends/qt/GuiDocument.cpp:1769
#: src/frontends/qt/GuiPrefs.cpp:2426 src/frontends/qt/Menus.cpp:938
msgid "Language"
msgstr "Sprache"
@@ -1291,7 +1291,7 @@ msgid "Greyed-out notes:"
msgstr "Grauschrift-Notizen:"
#: src/frontends/qt/ui/ColorUi.ui:118 src/frontends/qt/ui/ColorUi.ui:256
-#: src/frontends/qt/GuiDocument.cpp:2205 src/frontends/qt/GuiDocument.cpp:2235
+#: src/frontends/qt/GuiDocument.cpp:2207 src/frontends/qt/GuiDocument.cpp:2237
msgid "&Change..."
msgstr "&Ãnderung..."
@@ -3421,7 +3421,7 @@ msgstr "Bilder"
#: src/frontends/qt/ui/OutputUi.ui:279 lib/layouts/aapaper.layout:63
#: lib/layouts/egs.layout:712 lib/languages:146
-#: src/frontends/qt/GuiDocument.cpp:1597 src/frontends/qt/GuiErrorList.cpp:50
+#: src/frontends/qt/GuiDocument.cpp:1599 src/frontends/qt/GuiErrorList.cpp:50
#: src/frontends/qt/GuiLog.cpp:282 src/frontends/qt/GuiPrefs.cpp:642
msgid "LaTeX"
msgstr "LaTeX"
@@ -3631,7 +3631,7 @@ msgstr "&Querformat"
#: src/frontends/qt/ui/PageLayoutUi.ui:162
#: lib/layouts/customHeadersFooters.module:3 lib/layouts/landscape.module:3
-#: lib/layouts/multicol.module:3 src/frontends/qt/GuiDocument.cpp:1765
+#: lib/layouts/multicol.module:3 src/frontends/qt/GuiDocument.cpp:1767
msgid "Page Layout"
msgstr "Seitenlayout"
@@ -3676,9 +3676,9 @@ msgstr "Doppelt"
#: src/frontends/qt/ui/TabularUi.ui:1277 src/frontends/qt/ui/VSpaceUi.ui:118
#: lib/layouts/stdcustom.inc:8 src/frontends/qt/FloatPlacement.cpp:185
#: src/frontends/qt/GuiDocument.cpp:859 src/frontends/qt/GuiDocument.cpp:865
-#: src/frontends/qt/GuiDocument.cpp:873 src/frontends/qt/GuiDocument.cpp:987
-#: src/frontends/qt/GuiDocument.cpp:1054 src/frontends/qt/GuiDocument.cpp:1140
-#: src/frontends/qt/GuiDocument.cpp:1191 src/frontends/qt/GuiDocument.cpp:1537
+#: src/frontends/qt/GuiDocument.cpp:873 src/frontends/qt/GuiDocument.cpp:989
+#: src/frontends/qt/GuiDocument.cpp:1056 src/frontends/qt/GuiDocument.cpp:1142
+#: src/frontends/qt/GuiDocument.cpp:1193 src/frontends/qt/GuiDocument.cpp:1539
#: src/frontends/qt/GuiHSpace.cpp:57 src/frontends/qt/GuiPrefs.cpp:816
#: src/frontends/qt/GuiPrefs.cpp:844 src/frontends/qt/GuiPrefs.cpp:871
#: src/frontends/qt/GuiPrefs.cpp:2325 src/frontends/qt/GuiPrefs.cpp:2348
@@ -4489,18 +4489,18 @@ msgstr ""
"soll"
#: src/frontends/qt/ui/PrefLanguageUi.ui:77
-#: src/frontends/qt/GuiDocument.cpp:1050 src/frontends/qt/GuiDocument.cpp:2706
+#: src/frontends/qt/GuiDocument.cpp:1052 src/frontends/qt/GuiDocument.cpp:2708
#: src/frontends/qt/GuiPrefs.cpp:815 src/frontends/qt/GuiPrefs.cpp:843
msgid "Automatic"
msgstr "Automatisch"
#: src/frontends/qt/ui/PrefLanguageUi.ui:82
-#: src/frontends/qt/GuiDocument.cpp:1052
+#: src/frontends/qt/GuiDocument.cpp:1054
msgid "Always Babel"
msgstr "Immer Babel"
#: src/frontends/qt/ui/PrefLanguageUi.ui:92
-#: src/frontends/qt/GuiDocument.cpp:1056
+#: src/frontends/qt/GuiDocument.cpp:1058
msgid "None[[language package]]"
msgstr "Keines"
@@ -4675,7 +4675,7 @@ msgid "Default length &unit:"
msgstr "Standard-Längene&inheit:"
#: src/frontends/qt/ui/PrefLanguageUi.ui:348
-#: src/frontends/qt/GuiDocument.cpp:1013
+#: src/frontends/qt/GuiDocument.cpp:1015
msgid "Language Default"
msgstr "Sprachvoreinstellung"
@@ -5527,7 +5527,7 @@ msgstr "I&gnorieren"
#: src/frontends/qt/ui/SpellcheckerUi.ui:175
msgid ""
-"Ignore all occurrences of this word within this document. This is perdurant "
+"Ignore all occurrences of this word within this document. This persists "
"beyond the current session."
msgstr ""
"Ignoriere alle Vorkommen dieses Wortes in diesem Dokument (über die aktuelle "
@@ -6116,7 +6116,7 @@ msgstr ""
"Filtere Elemente, die nicht ausgegeben werden (in Notizen, inaktiven "
"Zweigen, im Ãnderungsmodus gelöscht, usw.)"
-#: src/frontends/qt/ui/TocUi.ui:317
+#: src/frontends/qt/ui/TocUi.ui:317 src/frontends/qt/TocWidget.cpp:88
msgid "All items"
msgstr "Alle Elemente"
@@ -6226,8 +6226,8 @@ msgstr "Nur Haupttext"
msgid "Select the output format"
msgstr "Ausgabeformat wählen"
-#: src/frontends/qt/ui/WorkAreaUi.ui:82 src/frontends/qt/GuiView.cpp:3654
-#: src/frontends/qt/GuiView.cpp:4358
+#: src/frontends/qt/ui/WorkAreaUi.ui:82 src/frontends/qt/GuiView.cpp:3658
+#: src/frontends/qt/GuiView.cpp:4362
msgid "&Reload"
msgstr "Ne&u laden"
@@ -7106,7 +7106,7 @@ msgstr "Definition"
#: lib/layouts/theorems-without-preamble.inc:240
#: lib/layouts/theorems-without-preamble.inc:243 lib/layouts/theorems.inc:204
#: lib/layouts/theorems.inc:213 lib/layouts/theorems.inc:216
-#: src/frontends/qt/GuiDocument.cpp:1344
+#: src/frontends/qt/GuiDocument.cpp:1346
msgid "Example"
msgstr "Beispiel"
@@ -7613,7 +7613,7 @@ msgstr "Peer-Review-Titel"
#: lib/layouts/ijmpc.layout:496 lib/layouts/ijmpc.layout:498
#: lib/layouts/ijmpd.layout:520 lib/layouts/ijmpd.layout:522
#: lib/layouts/kluwer.layout:364 lib/layouts/kluwer.layout:377
-#: lib/examples/Articles:0 src/RowPainter.cpp:369
+#: lib/examples/Articles:0 src/RowPainter.cpp:373
msgid "Appendix"
msgstr "Anhang"
@@ -7650,7 +7650,7 @@ msgstr "Kurztitel für den Anhang"
#: lib/layouts/stdstruct.inc:59 lib/layouts/svcommon.inc:657
#: lib/layouts/tufte-book.layout:292 lib/layouts/tufte-book.layout:294
#: lib/layouts/tufte-handout.layout:77 lib/examples/Articles:0
-#: src/frontends/qt/GuiDocument.cpp:1771 src/insets/InsetBibtex.cpp:957
+#: src/frontends/qt/GuiDocument.cpp:1773 src/insets/InsetBibtex.cpp:957
msgid "Bibliography"
msgstr "Literaturverzeichnis"
@@ -8208,7 +8208,7 @@ msgid "Altaffilation"
msgstr "Alt. Zugehörigkeit"
#: lib/layouts/aastex.layout:201 lib/layouts/agutex.layout:132
-#: src/mathed/InsetMathHull.cpp:1856 src/mathed/InsetMathHull.cpp:1865
+#: src/mathed/InsetMathHull.cpp:1866 src/mathed/InsetMathHull.cpp:1875
msgid "Number"
msgstr "Nummer"
@@ -8224,9 +8224,9 @@ msgstr "Alternative Zugehörigkeit:"
msgid "And"
msgstr "Und"
-#: lib/layouts/aastex.layout:256 src/frontends/qt/GuiDocument.cpp:3137
-#: src/frontends/qt/GuiDocument.cpp:3149 src/frontends/qt/GuiDocument.cpp:3275
-#: src/frontends/qt/GuiDocument.cpp:3294
+#: lib/layouts/aastex.layout:256 src/frontends/qt/GuiDocument.cpp:3139
+#: src/frontends/qt/GuiDocument.cpp:3151 src/frontends/qt/GuiDocument.cpp:3277
+#: src/frontends/qt/GuiDocument.cpp:3296
msgid "and"
msgstr "und"
@@ -12689,8 +12689,8 @@ msgid "Fixme Error"
msgstr "Fixme-Fehler"
#: lib/layouts/fixme.module:83 src/frontends/qt/GuiCompare.cpp:199
-#: src/frontends/qt/GuiDocument.cpp:2847 src/frontends/qt/GuiDocument.cpp:2921
-#: src/frontends/qt/GuiDocument.cpp:4837
+#: src/frontends/qt/GuiDocument.cpp:2849 src/frontends/qt/GuiDocument.cpp:2923
+#: src/frontends/qt/GuiDocument.cpp:4839
msgid "Error"
msgstr "Fehler"
@@ -17046,7 +17046,7 @@ msgstr "FuÃnoten"
msgid "Notes"
msgstr "Notizen"
-#: lib/layouts/stdinsets.inc:14 src/frontends/qt/GuiDocument.cpp:1778
+#: lib/layouts/stdinsets.inc:14 src/frontends/qt/GuiDocument.cpp:1780
msgid "Branches"
msgstr "Zweige"
@@ -17084,7 +17084,7 @@ msgstr "Programmlistings"
msgid "List of Listings"
msgstr "Verzeichnis der Programmlistings"
-#: lib/layouts/stdinsets.inc:350 src/frontends/qt/GuiDocument.cpp:1776
+#: lib/layouts/stdinsets.inc:350 src/frontends/qt/GuiDocument.cpp:1778
msgid "Listings[[inset]]"
msgstr "Programmlistings"
@@ -17143,12 +17143,11 @@ msgstr "Untergleichungen"
#: lib/layouts/subequations.module:6
msgid ""
-"Provide a straightforward way to segregate subequations in LyX. See the "
-"subequations.lyx example file."
+"Provide a straightforward way to segregate subequations in LyX. See the Math "
+"manual."
msgstr ""
"Bietet eine elegante Möglichkeit, Untergleichungen zu erstellen. Bitte "
-"konsultieren Sie das Beispieldokument 'subequations.lyx' für weitere "
-"Informationen."
+"konsultieren Sie das Mathe-Handbuch für weitere Informationen."
#: lib/layouts/svcommon.inc:72
msgid "Front Matter"
@@ -19629,7 +19628,7 @@ msgid "Copy as Reference|R"
msgstr "Als Querverweis kopieren|k"
#: lib/ui/stdcontext.inc:61 lib/ui/stdcontext.inc:375 lib/ui/stdmenus.inc:108
-#: lib/ui/stdtoolbars.inc:86 src/Text3.cpp:1556
+#: lib/ui/stdtoolbars.inc:86 src/Text3.cpp:1561
#: src/mathed/InsetMathNest.cpp:555
msgid "Cut"
msgstr "Ausschneiden"
@@ -19640,7 +19639,7 @@ msgid "Copy"
msgstr "Kopieren"
#: lib/ui/stdcontext.inc:63 lib/ui/stdcontext.inc:377 lib/ui/stdmenus.inc:110
-#: lib/ui/stdtoolbars.inc:88 src/Text3.cpp:1501
+#: lib/ui/stdtoolbars.inc:88 src/Text3.cpp:1506
#: src/frontends/qt/GuiToolbar.cpp:441 src/mathed/InsetMathGrid.cpp:1560
#: src/mathed/InsetMathNest.cpp:533
msgid "Paste"
@@ -21952,7 +21951,7 @@ msgid "Fractions"
msgstr "Brüche"
#: lib/ui/stdtoolbars.inc:219 lib/ui/stdtoolbars.inc:442
-#: src/frontends/qt/GuiDocument.cpp:1763
+#: src/frontends/qt/GuiDocument.cpp:1765
msgid "Fonts"
msgstr "Schriften"
@@ -21969,7 +21968,7 @@ msgid "Big operators"
msgstr "GroÃe Operatoren"
#: lib/ui/stdtoolbars.inc:223 lib/ui/stdtoolbars.inc:690
-#: src/frontends/qt/GuiDocument.cpp:5169
+#: src/frontends/qt/GuiDocument.cpp:5171
msgid "Miscellaneous"
msgstr "Verschiedenes"
@@ -26960,10 +26959,6 @@ msgid "Feynman Diagrams"
msgstr "Feynman-Diagramme"
#: lib/examples/Articles:0
-msgid "Instant Preview"
-msgstr "Eingebettete Vorschau"
-
-#: lib/examples/Articles:0
msgid "Itemize Bullets"
msgstr "Auflistungszeichen"
@@ -26984,6 +26979,10 @@ msgid "XY-Pic"
msgstr "XY-Pic"
#: lib/examples/Articles:0
+msgid "Instant Preview"
+msgstr "Eingebettete Vorschau"
+
+#: lib/examples/Articles:0
msgid "Graphics and Insets"
msgstr "Grafiken und Einfügungen"
@@ -27023,7 +27022,7 @@ msgstr "Noweb2LyX"
msgid "Noweb Listerrors"
msgstr "Noweb-Fehlerbericht"
-#: lib/examples/Articles:0 src/frontends/qt/GuiDocument.cpp:1761
+#: lib/examples/Articles:0 src/frontends/qt/GuiDocument.cpp:1763
msgid "Modules"
msgstr "Module"
@@ -27256,11 +27255,11 @@ msgstr "\\begin_header fehlt"
msgid "\\begin_document is missing"
msgstr "\\begin_document fehlt"
-#: src/Buffer.cpp:1043 src/Buffer.cpp:3016
+#: src/Buffer.cpp:1043 src/Buffer.cpp:3027
msgid "Changes not shown in LaTeX output"
msgstr "Ãnderungen nicht in der LaTeX-Ausgabe angezeigt"
-#: src/Buffer.cpp:1044 src/Buffer.cpp:3017
+#: src/Buffer.cpp:1044 src/Buffer.cpp:3028
msgid ""
"Changes will not be highlighted in LaTeX output, because xcolor and ulem are "
"not installed.\n"
@@ -27349,7 +27348,7 @@ msgstr ""
"%1$s stammt von einer neueren LyX-Version, aber das lyx2lyx-Skript konnte "
"das Dokument nicht konvertieren."
-#: src/Buffer.cpp:1445 src/Buffer.cpp:4707 src/Buffer.cpp:4816
+#: src/Buffer.cpp:1445 src/Buffer.cpp:4718 src/Buffer.cpp:4827
msgid "File is read-only"
msgstr "Datei ist schreibgeschützt"
@@ -27373,8 +27372,8 @@ msgid "Overwrite modified file?"
msgstr "Modifizierte Datei überschreiben?"
#: src/Buffer.cpp:1458 src/Exporter.cpp:50
-#: src/frontends/qt/GuiClipboard.cpp:252 src/frontends/qt/GuiView.cpp:2807
-#: src/frontends/qt/GuiView.cpp:3076 src/frontends/qt/GuiView.cpp:3179
+#: src/frontends/qt/GuiClipboard.cpp:252 src/frontends/qt/GuiView.cpp:2811
+#: src/frontends/qt/GuiView.cpp:3080 src/frontends/qt/GuiView.cpp:3183
msgid "&Overwrite"
msgstr "&Ãberschreiben"
@@ -27574,53 +27573,53 @@ msgstr ""
"kombinieren, weil sie inkompatible Sprachpakete erfordern:\n"
"%1$s%2$s"
-#: src/Buffer.cpp:2324
+#: src/Buffer.cpp:2335
msgid "Running chktex..."
msgstr "ChkTeX wird ausgeführt..."
-#: src/Buffer.cpp:2343
+#: src/Buffer.cpp:2354
msgid "chktex failure"
msgstr "ChkTeX ist fehlgeschlagen"
-#: src/Buffer.cpp:2344
+#: src/Buffer.cpp:2355
msgid "Could not run chktex successfully."
msgstr "Chktex konnte nicht erfolgreich ausgeführt werden."
-#: src/Buffer.cpp:2719
+#: src/Buffer.cpp:2730
#, c-format
msgid "Don't know how to export to format: %1$s"
msgstr "Keine Informationen vorhanden, um in das Format %1$s zu exportieren"
-#: src/Buffer.cpp:2823
+#: src/Buffer.cpp:2834
#, c-format
msgid "Error exporting to format: %1$s."
msgstr "Keine Informationen vorhanden, um in das Format %1$s zu exportieren."
-#: src/Buffer.cpp:2832
+#: src/Buffer.cpp:2843
msgid "Error generating literate programming code."
msgstr "Fehler bei der Erzeugung des Codes für literarische Programmierung."
-#: src/Buffer.cpp:2908
+#: src/Buffer.cpp:2919
#, c-format
msgid "Branch \"%1$s\" does not exist."
msgstr "Zweig \"%1$s\" existiert nicht."
-#: src/Buffer.cpp:2941
+#: src/Buffer.cpp:2952
#, c-format
msgid "Branch \"%1$s\" already exists."
msgstr "Zweig \"%1$s\" existiert bereits."
-#: src/Buffer.cpp:2998
+#: src/Buffer.cpp:3009
msgid "Error viewing the output file."
msgstr "Fehler bei der Ansicht der Ausgabedatei."
-#: src/Buffer.cpp:3360 src/frontends/qt/GuiView.cpp:2638
+#: src/Buffer.cpp:3371 src/frontends/qt/GuiView.cpp:2642
#: src/frontends/qt/Validator.cpp:241 src/insets/ExternalSupport.cpp:394
#: src/insets/InsetGraphics.cpp:692 src/insets/InsetInclude.cpp:606
msgid "Invalid filename"
msgstr "Ungültiger Dateiname"
-#: src/Buffer.cpp:3361 src/insets/ExternalSupport.cpp:395
+#: src/Buffer.cpp:3372 src/insets/ExternalSupport.cpp:395
#: src/insets/InsetGraphics.cpp:693 src/insets/InsetInclude.cpp:607
msgid ""
"The following filename will cause troubles when running the exported file "
@@ -27629,12 +27628,12 @@ msgstr ""
"Der folgende Dateiname wird Probleme bereiten, wenn LaTeX mit der "
"exportierten Datei ausgeführt wird: "
-#: src/Buffer.cpp:3366 src/insets/ExternalSupport.cpp:400
+#: src/Buffer.cpp:3377 src/insets/ExternalSupport.cpp:400
#: src/insets/InsetGraphics.cpp:700 src/insets/InsetInclude.cpp:611
msgid "Problematic filename for DVI"
msgstr "Problematischer Dateiname für DVI"
-#: src/Buffer.cpp:3367 src/insets/ExternalSupport.cpp:401
+#: src/Buffer.cpp:3378 src/insets/ExternalSupport.cpp:401
#: src/insets/InsetGraphics.cpp:701 src/insets/InsetInclude.cpp:612
msgid ""
"The following filename can cause troubles when running the exported file "
@@ -27643,11 +27642,11 @@ msgstr ""
"Der folgende Dateiname könnte Probleme bereiten, wenn LaTeX mit der "
"exportierten Datei ausgeführt und die erzeugte DVI-Datei geöffnet wird: "
-#: src/Buffer.cpp:3406 src/insets/InsetBibtex.cpp:349
+#: src/Buffer.cpp:3417 src/insets/InsetBibtex.cpp:349
msgid "Export Warning!"
msgstr "Export-Warnung!"
-#: src/Buffer.cpp:3407
+#: src/Buffer.cpp:3418
msgid ""
"There are spaces in the paths to your BibTeX databases.\n"
"BibTeX will be unable to find them."
@@ -27655,57 +27654,57 @@ msgstr ""
"Die Pfade zu Ihren BibTeX-Datenbanken enthalten Leerzeichen.\n"
"BiBTeX wird die Datenbanken nicht finden."
-#: src/Buffer.cpp:4081
+#: src/Buffer.cpp:4092
#, c-format
msgid "Preview source code for paragraph %1$d"
msgstr "Quellcode für Absatz %1$d vorschauen"
-#: src/Buffer.cpp:4086
+#: src/Buffer.cpp:4097
#, c-format
msgid "Preview source code from paragraph %1$s to %2$s"
msgstr "Quellcode von Absatz %1$s bis %2$s vorschauen"
-#: src/Buffer.cpp:4141
+#: src/Buffer.cpp:4152
msgid "Preview source code"
msgstr "Quellcode vorschauen"
-#: src/Buffer.cpp:4143
+#: src/Buffer.cpp:4154
msgid "Preview preamble"
msgstr "Vorschau des Vorspanns"
-#: src/Buffer.cpp:4145
+#: src/Buffer.cpp:4156
msgid "Preview body"
msgstr "Vorschau des Haupttextes"
-#: src/Buffer.cpp:4161
+#: src/Buffer.cpp:4172
msgid "Plain text does not have a preamble."
msgstr "Einfacher Text hat keinen Vorspann."
-#: src/Buffer.cpp:4298
+#: src/Buffer.cpp:4309
msgid "Autosaving current document..."
msgstr "Automatisches Speichern des aktuellen Dokuments..."
-#: src/Buffer.cpp:4420
+#: src/Buffer.cpp:4431
#, c-format
msgid "No information for exporting the format %1$s."
msgstr "Keine Informationen vorhanden, um das Format %1$s zu exportieren."
-#: src/Buffer.cpp:4424
+#: src/Buffer.cpp:4435
#, c-format
msgid "Hint: use non-TeX fonts or set input encoding to '%1$s'"
msgstr ""
"Tipp: Verwenden Sie keine TeX-Schriften oder stellen Sie als Kodierung "
"'%1$s' ein."
-#: src/Buffer.cpp:4426
+#: src/Buffer.cpp:4437
msgid "Couldn't export file"
msgstr "Die Datei konnte nicht exportiert werden"
-#: src/Buffer.cpp:4494 src/frontends/qt/GuiView.cpp:2780
+#: src/Buffer.cpp:4505 src/frontends/qt/GuiView.cpp:2784
msgid "File name error"
msgstr "Fehler im Dateinamen"
-#: src/Buffer.cpp:4495
+#: src/Buffer.cpp:4506
#, c-format
msgid ""
"The directory path to the document\n"
@@ -27718,21 +27717,21 @@ msgstr ""
"enthält Leerzeichen, aber Ihre TeX-Installation erlaubt dies nicht. Bitte "
"speichern Sie Ihr Dokument in einem Verzeichnis ohne Leerzeichen."
-#: src/Buffer.cpp:4584 src/Buffer.cpp:4614 src/frontends/qt/GuiView.cpp:850
+#: src/Buffer.cpp:4595 src/Buffer.cpp:4625 src/frontends/qt/GuiView.cpp:850
msgid "Document export cancelled."
msgstr "Der Export des Dokuments wurde abgebrochen."
-#: src/Buffer.cpp:4617
+#: src/Buffer.cpp:4628
#, c-format
msgid "Document exported as %1$s to file `%2$s'"
msgstr "Dokument wurde als %1$s in die Datei ,%2$s` exportiert."
-#: src/Buffer.cpp:4624
+#: src/Buffer.cpp:4635
#, c-format
msgid "Document exported as %1$s"
msgstr "Dokument als %1$s exportiert"
-#: src/Buffer.cpp:4693
+#: src/Buffer.cpp:4704
#, c-format
msgid ""
"An emergency save of the document %1$s exists.\n"
@@ -27743,23 +27742,23 @@ msgstr ""
"\n"
"Soll die Notspeicherung wiederhergestellt werden?"
-#: src/Buffer.cpp:4696
+#: src/Buffer.cpp:4707
msgid "Load emergency save?"
msgstr "Notspeicherung laden?"
-#: src/Buffer.cpp:4697
+#: src/Buffer.cpp:4708
msgid "&Recover"
msgstr "&Wiederherstellen"
-#: src/Buffer.cpp:4697
+#: src/Buffer.cpp:4708
msgid "&Load Original"
msgstr "&Original laden"
-#: src/Buffer.cpp:4697
+#: src/Buffer.cpp:4708
msgid "&Only show difference"
msgstr "Nur &Unterschiede zeigen"
-#: src/Buffer.cpp:4708
+#: src/Buffer.cpp:4719
#, c-format
msgid ""
"An emergency file is successfully loaded, but the original file %1$s is "
@@ -27769,15 +27768,15 @@ msgstr ""
"%1$s ist schreibgeschützt.\n"
"Bitte speichern Sie die Datei unter einem neuen Namen."
-#: src/Buffer.cpp:4715
+#: src/Buffer.cpp:4726
msgid "Document was successfully recovered."
msgstr "Dokument wurde erfolgreich wiederhergestellt."
-#: src/Buffer.cpp:4717
+#: src/Buffer.cpp:4728
msgid "Document was NOT successfully recovered."
msgstr "Dokument wurde NICHT erfolgreich wiederhergestellt."
-#: src/Buffer.cpp:4718
+#: src/Buffer.cpp:4729
#, c-format
msgid ""
"Remove emergency file now?\n"
@@ -27787,31 +27786,31 @@ msgstr ""
"%1$s\n"
"jetzt löschen?"
-#: src/Buffer.cpp:4722 src/Buffer.cpp:4734
+#: src/Buffer.cpp:4733 src/Buffer.cpp:4745
msgid "Delete emergency file?"
msgstr "Notspeicherung löschen?"
-#: src/Buffer.cpp:4723 src/Buffer.cpp:4736
+#: src/Buffer.cpp:4734 src/Buffer.cpp:4747
msgid "&Keep"
msgstr "&Behalten"
-#: src/Buffer.cpp:4727
+#: src/Buffer.cpp:4738
msgid "Emergency file deleted"
msgstr "Notspeicherung gelöscht"
-#: src/Buffer.cpp:4728
+#: src/Buffer.cpp:4739
msgid "Do not forget to save your file now!"
msgstr "Vergessen Sie nicht, ihre Datei jetzt zu speichern!"
-#: src/Buffer.cpp:4735
+#: src/Buffer.cpp:4746
msgid "Remove emergency file now?"
msgstr "Notspeicherungsdatei jetzt löschen?"
-#: src/Buffer.cpp:4758
+#: src/Buffer.cpp:4769
msgid "Can't rename emergency file!"
msgstr "Notspeicherungsdatei kann nicht umbenannt werden!"
-#: src/Buffer.cpp:4759
+#: src/Buffer.cpp:4770
msgid ""
"LyX was unable to rename the emergency file. You should do so manually. "
"Otherwise, you will be asked about it again the next time you try to load "
@@ -27822,11 +27821,11 @@ msgstr ""
"wieder danach gefragt, und Ihre Datei könnte mit einer dann nicht mehr "
"aktuellen Notspeicherung überschrieben werden."
-#: src/Buffer.cpp:4764
+#: src/Buffer.cpp:4775
msgid "Emergency File Renames"
msgstr "Umbenennung der Notspeicherung"
-#: src/Buffer.cpp:4765
+#: src/Buffer.cpp:4776
#, c-format
msgid ""
"Emergency file renamed as:\n"
@@ -27835,7 +27834,7 @@ msgstr ""
"Notspeicherung umbenannt als:\n"
" %1$s"
-#: src/Buffer.cpp:4804
+#: src/Buffer.cpp:4815
#, c-format
msgid ""
"The backup of the document %1$s is newer.\n"
@@ -27846,19 +27845,19 @@ msgstr ""
"\n"
"Stattdessen die Sicherung laden?"
-#: src/Buffer.cpp:4806
+#: src/Buffer.cpp:4817
msgid "Load backup?"
msgstr "Sicherung laden?"
-#: src/Buffer.cpp:4807
+#: src/Buffer.cpp:4818
msgid "&Load backup"
msgstr "&Sicherung laden"
-#: src/Buffer.cpp:4807
+#: src/Buffer.cpp:4818
msgid "Load &original"
msgstr "&Original laden"
-#: src/Buffer.cpp:4817
+#: src/Buffer.cpp:4828
#, c-format
msgid ""
"A backup file is successfully loaded, but the original file %1$s is marked "
@@ -27868,16 +27867,16 @@ msgstr ""
"%1$s ist schreibgeschützt.\n"
"Bitte speichern Sie die Datei unter einem neuen Namen."
-#: src/Buffer.cpp:5219 src/insets/InsetCaption.cpp:404
+#: src/Buffer.cpp:5230 src/insets/InsetCaption.cpp:404
msgid "Senseless!!! "
msgstr "Sinnlos!!! "
-#: src/Buffer.cpp:5474
+#: src/Buffer.cpp:5485
#, c-format
msgid "Document %1$s reloaded."
msgstr "Dokument %1$s neu geladen."
-#: src/Buffer.cpp:5477
+#: src/Buffer.cpp:5488
#, c-format
msgid "Could not reload document %1$s."
msgstr "Kann Dokument %1$s nicht neu laden."
@@ -27962,7 +27961,7 @@ msgstr ""
"Das LaTeX-Paket undertilde wird nur verwendet, wenn die Mathe Rahmen-"
"Verzierung 'utilde' verwendet wird"
-#: src/BufferParams.cpp:787
+#: src/BufferParams.cpp:784
#, c-format
msgid ""
"The selected document class\n"
@@ -27985,16 +27984,16 @@ msgstr ""
"In Abschnitt 3.1.2.2 des Benutzerhandbuchs\n"
"finden Sie weitere Hilfe."
-#: src/BufferParams.cpp:796
+#: src/BufferParams.cpp:793
msgid "Document class not available"
msgstr "Die Dokumentklasse ist nicht verfügbar"
-#: src/BufferParams.cpp:1101 src/Color.cpp:281
-#: src/frontends/qt/GuiDocument.cpp:3527
+#: src/BufferParams.cpp:1098 src/Color.cpp:281
+#: src/frontends/qt/GuiDocument.cpp:3529
msgid "greyedout inset text"
msgstr "Grauschrift-Einfügungstext"
-#: src/BufferParams.cpp:1814 src/BufferParams.cpp:2256 src/Encoding.cpp:253
+#: src/BufferParams.cpp:1811 src/BufferParams.cpp:2253 src/Encoding.cpp:253
#: src/Paragraph.cpp:2972 src/frontends/qt/LaTeXHighlighter.cpp:123
#: src/frontends/qt/LaTeXHighlighter.cpp:216
#: src/insets/InsetCommandParams.cpp:508 src/insets/InsetCommandParams.cpp:516
@@ -28005,7 +28004,7 @@ msgstr "Grauschrift-Einfügungstext"
msgid "LyX Warning: "
msgstr "LyX-Warnung: "
-#: src/BufferParams.cpp:1815 src/BufferParams.cpp:2257 src/Encoding.cpp:254
+#: src/BufferParams.cpp:1812 src/BufferParams.cpp:2254 src/Encoding.cpp:254
#: src/Paragraph.cpp:2973 src/insets/InsetCommandParams.cpp:509
#: src/insets/InsetCommandParams.cpp:517 src/insets/InsetGraphics.cpp:887
#: src/insets/InsetGraphics.cpp:895 src/insets/InsetListings.cpp:299
@@ -28014,11 +28013,11 @@ msgstr "LyX-Warnung: "
msgid "uncodable character"
msgstr "unkodierbares Zeichen"
-#: src/BufferParams.cpp:1828
+#: src/BufferParams.cpp:1825
msgid "Uncodable character in class options"
msgstr "Unkodierbare Zeichen in den Klassenoptionen"
-#: src/BufferParams.cpp:1830
+#: src/BufferParams.cpp:1827
#, c-format
msgid ""
"The class options of your document contain glyphs that are unknown in the "
@@ -28036,11 +28035,11 @@ msgstr ""
"Wählen Sie eine passende Kodierung (bspw. utf8)\n"
"oder ändern Sie den LaTeX-Code im Vorspann."
-#: src/BufferParams.cpp:2270
+#: src/BufferParams.cpp:2267
msgid "Uncodable character in user preamble"
msgstr "Unkodierbares Zeichen im Benutzervorspann"
-#: src/BufferParams.cpp:2272
+#: src/BufferParams.cpp:2269
#, c-format
msgid ""
"The user preamble of your document contains glyphs that are unknown in the "
@@ -28058,7 +28057,7 @@ msgstr ""
"Wählen Sie eine passende Kodierung (bspw. utf8)\n"
"oder ändern Sie den LaTeX-Code im Vorspann."
-#: src/BufferParams.cpp:2587
+#: src/BufferParams.cpp:2584
#, c-format
msgid ""
"The layout file:\n"
@@ -28073,11 +28072,11 @@ msgstr ""
"Formaten wird benutzt werden. LyX wird nicht in der Lage sein eine korrekte\n"
"Ausgabe zu erzeugen."
-#: src/BufferParams.cpp:2593
+#: src/BufferParams.cpp:2590
msgid "Document class not found"
msgstr "Dokumentklasse nicht gefunden"
-#: src/BufferParams.cpp:2600
+#: src/BufferParams.cpp:2597
#, c-format
msgid ""
"Due to some error in it, the layout file:\n"
@@ -28092,15 +28091,15 @@ msgstr ""
"korrekte\n"
"Ausgabe erzeugen können."
-#: src/BufferParams.cpp:2606 src/BufferView.cpp:1431 src/BufferView.cpp:1463
+#: src/BufferParams.cpp:2603 src/BufferView.cpp:1431 src/BufferView.cpp:1463
msgid "Could not load class"
msgstr "Konnte Klasse nicht laden"
-#: src/BufferParams.cpp:2651
+#: src/BufferParams.cpp:2648
msgid "Error reading internal layout information"
msgstr "Fehler beim Einlesen interner Format-Informationen"
-#: src/BufferParams.cpp:2652 src/TextClass.cpp:1934 src/TextClass.cpp:1967
+#: src/BufferParams.cpp:2649 src/TextClass.cpp:1934 src/TextClass.cpp:1967
msgid "Read Error"
msgstr "Lesefehler"
@@ -28129,7 +28128,7 @@ msgid "This portion of the document is deleted."
msgstr "Dieser Teil des Dokuments wird gelöscht."
#: src/BufferView.cpp:1198 src/BufferView.cpp:2264
-#: src/frontends/qt/GuiView.cpp:4228 src/frontends/qt/GuiView.cpp:4316
+#: src/frontends/qt/GuiView.cpp:4232 src/frontends/qt/GuiView.cpp:4320
msgid "Absolute filename expected."
msgstr "Ein absoluter Dateipfad wird erwartet."
@@ -28890,11 +28889,11 @@ msgstr ""
"konvertieren.\n"
"Definieren Sie einen Konverter in den Einstellungen."
-#: src/Converter.cpp:567 src/frontends/qt/GuiDocument.cpp:1990
+#: src/Converter.cpp:567 src/frontends/qt/GuiDocument.cpp:1992
msgid "Pygments driver command not found!"
msgstr "Pygments-Treiberbefehl nicht gefunden!"
-#: src/Converter.cpp:568 src/frontends/qt/GuiDocument.cpp:1991
+#: src/Converter.cpp:568 src/frontends/qt/GuiDocument.cpp:1993
msgid ""
"The driver command necessary to use the minted package\n"
"(pygmentize) has not been found. Make sure you have\n"
@@ -29170,17 +29169,17 @@ msgid "Number %1$s"
msgstr "Nummer %1$s"
#: src/FontInfo.cpp:43 src/frontends/qt/GuiCharacter.cpp:148
-#: src/frontends/qt/GuiDocument.cpp:4894 src/frontends/qt/GuiListings.cpp:167
+#: src/frontends/qt/GuiDocument.cpp:4896 src/frontends/qt/GuiListings.cpp:167
msgid "Roman"
msgstr "Serifenschrift"
#: src/FontInfo.cpp:43 src/frontends/qt/GuiCharacter.cpp:149
-#: src/frontends/qt/GuiDocument.cpp:4894 src/frontends/qt/GuiListings.cpp:167
+#: src/frontends/qt/GuiDocument.cpp:4896 src/frontends/qt/GuiListings.cpp:167
msgid "Sans Serif"
msgstr "Serifenlos"
#: src/FontInfo.cpp:43 src/frontends/qt/GuiCharacter.cpp:150
-#: src/frontends/qt/GuiDocument.cpp:4894 src/frontends/qt/GuiListings.cpp:167
+#: src/frontends/qt/GuiDocument.cpp:4896 src/frontends/qt/GuiListings.cpp:167
msgid "Typewriter"
msgstr "Schreibmaschine"
@@ -29264,7 +29263,7 @@ msgstr "Eigenname %1$s, "
msgid "Cannot view file"
msgstr "Datei kann nicht betrachtet werden"
-#: src/Format.cpp:633 src/frontends/qt/GuiView.cpp:3918
+#: src/Format.cpp:633 src/frontends/qt/GuiView.cpp:3922
#, c-format
msgid "File does not exist: %1$s"
msgstr "Die Datei existiert nicht: %1$s"
@@ -30325,7 +30324,7 @@ msgstr "LyX-VK: Protokollmeldung"
msgid "(no log message)"
msgstr "(keine Protokollmeldung)"
-#: src/LyXVC.cpp:252 src/frontends/qt/GuiView.cpp:3781
+#: src/LyXVC.cpp:252 src/frontends/qt/GuiView.cpp:3785
msgid "LyX VC: Log Message"
msgstr "LyX VK: Protokollmeldung"
@@ -30346,7 +30345,7 @@ msgstr ""
msgid "Revert to stored version of document?"
msgstr "Zur gespeicherten Version des Dokuments zurückkehren?"
-#: src/LyXVC.cpp:310 src/frontends/qt/GuiView.cpp:4365
+#: src/LyXVC.cpp:310 src/frontends/qt/GuiView.cpp:4369
msgid "&Revert"
msgstr "&Wiederherstellen"
@@ -30370,11 +30369,11 @@ msgstr ""
msgid "Unknown Inset"
msgstr "Unbekannte Einfügung"
-#: src/Text.cpp:554 src/insets/InsetTabular.cpp:472
+#: src/Text.cpp:554 src/insets/InsetTabular.cpp:473
msgid "Change tracking author index missing"
msgstr "Autorindex für die Ãnderungsverfolgung fehlt"
-#: src/Text.cpp:555 src/insets/InsetTabular.cpp:473
+#: src/Text.cpp:555 src/insets/InsetTabular.cpp:474
#, c-format
msgid ""
"A change tracking author information for index %1$d is missing. This can "
@@ -30483,40 +30482,40 @@ msgstr "Bereits im Regexp-Modus"
msgid "Regexp editor mode"
msgstr "Regexp-Editor-Modus"
-#: src/Text3.cpp:1590
+#: src/Text3.cpp:1595
msgid "Layout "
msgstr "Format "
-#: src/Text3.cpp:1591 src/Text3.cpp:2161
+#: src/Text3.cpp:1596 src/Text3.cpp:2166
msgid " not known"
msgstr " unbekannt"
-#: src/Text3.cpp:2160
+#: src/Text3.cpp:2165
msgid "Table Style "
msgstr "Tabellenstil"
-#: src/Text3.cpp:2353 src/frontends/qt/GuiApplication.cpp:1843
+#: src/Text3.cpp:2358 src/frontends/qt/GuiApplication.cpp:1848
msgid "Missing argument"
msgstr "Fehlendes Argument"
-#: src/Text3.cpp:2522
+#: src/Text3.cpp:2527
msgid "Invalid argument (number exceeds stack size)!"
msgstr "Ungültiges Argument (Zahl gröÃer als Zwischenspeicher)!"
-#: src/Text3.cpp:2526
+#: src/Text3.cpp:2531
msgid "Invalid argument (must be a non-negative number)!"
msgstr "Ungültiges Argument (muss eine nicht-negative Zahl sein)!"
-#: src/Text3.cpp:2531 src/Text3.cpp:2549
+#: src/Text3.cpp:2536 src/Text3.cpp:2554
#, c-format
msgid "Text properties applied: %1$s"
msgstr "Angewendete Texteigenschaften: %1$s"
-#: src/Text3.cpp:2708
+#: src/Text3.cpp:2713
msgid "Path to thesaurus directory not set!"
msgstr "Pfad zum Thesaurus-Wörterbuch nicht festlegt!"
-#: src/Text3.cpp:2709
+#: src/Text3.cpp:2714
msgid ""
"The path to the thesaurus directory has not been specified.\n"
"The thesaurus is not functional.\n"
@@ -30528,7 +30527,7 @@ msgstr ""
"Im Benutzerhandbuch, Abschnitt 6.15.11, finden Sie Hinweise,\n"
"um den Thesaurus einzurichten."
-#: src/Text3.cpp:2845 src/Text3.cpp:2856
+#: src/Text3.cpp:2848 src/Text3.cpp:2859
msgid "Paragraph layout set"
msgstr "Absatzformat festgelegt"
@@ -30686,7 +30685,7 @@ msgstr "Marken und Querverweise"
msgid "Broken References and Citations"
msgstr "Ungültige Literatur- und Querverweise"
-#: src/TocBackend.cpp:296 src/frontends/qt/GuiDocument.cpp:1760
+#: src/TocBackend.cpp:296 src/frontends/qt/GuiDocument.cpp:1762
msgid "Child Documents"
msgstr "Unterdokumente"
@@ -30710,7 +30709,7 @@ msgstr "Ist das RCS-Paket auf Ihrem System installiert?"
#: src/VCBackend.cpp:934 src/VCBackend.cpp:993 src/VCBackend.cpp:1052
#: src/VCBackend.cpp:1060 src/VCBackend.cpp:1348 src/VCBackend.cpp:1450
#: src/VCBackend.cpp:1456 src/VCBackend.cpp:1479 src/VCBackend.cpp:1964
-#: src/frontends/qt/GuiView.cpp:3697 src/frontends/qt/GuiView.cpp:3740
+#: src/frontends/qt/GuiView.cpp:3701 src/frontends/qt/GuiView.cpp:3744
msgid "Revision control error."
msgstr "Fehler der Versionskontrolle."
@@ -30911,15 +30910,15 @@ msgstr ""
#: src/VCBackend.cpp:1522 src/VCBackend.cpp:1526
#: src/frontends/qt/FindAndReplace.cpp:381 src/frontends/qt/GuiPrefs.cpp:1891
-#: src/lyxfind.cpp:303 src/lyxfind.cpp:330 src/lyxfind.cpp:350
-#: src/lyxfind.cpp:687 src/lyxfind.cpp:715
+#: src/lyxfind.cpp:303 src/lyxfind.cpp:330 src/lyxfind.cpp:351
+#: src/lyxfind.cpp:694 src/lyxfind.cpp:722
msgid "&Yes"
msgstr "&Ja"
#: src/VCBackend.cpp:1522 src/VCBackend.cpp:1526
#: src/frontends/qt/FindAndReplace.cpp:381 src/frontends/qt/GuiPrefs.cpp:1891
-#: src/lyxfind.cpp:303 src/lyxfind.cpp:330 src/lyxfind.cpp:350
-#: src/lyxfind.cpp:687 src/lyxfind.cpp:715
+#: src/lyxfind.cpp:303 src/lyxfind.cpp:330 src/lyxfind.cpp:351
+#: src/lyxfind.cpp:694 src/lyxfind.cpp:722
msgid "&No"
msgstr "&Nein"
@@ -30975,7 +30974,7 @@ msgstr ""
"Möchten Sie die Ãnderungen verwerfen und zur gespeicherten Version "
"zurückkehren?"
-#: src/buffer_funcs.cpp:55 src/frontends/qt/GuiView.cpp:4356
+#: src/buffer_funcs.cpp:55 src/frontends/qt/GuiView.cpp:4360
msgid "Reload saved document?"
msgstr "Gespeichertes Dokument neu laden?"
@@ -31056,7 +31055,7 @@ msgid "Dings 4"
msgstr "Dings 4"
#: src/frontends/qt/ButtonController.cpp:222
-#: src/frontends/qt/GuiApplication.cpp:1967 src/frontends/qt/GuiCompare.cpp:193
+#: src/frontends/qt/GuiApplication.cpp:1972 src/frontends/qt/GuiCompare.cpp:193
#: src/frontends/qt/GuiSymbols.cpp:346
msgid "Cancel"
msgstr "Abbrechen"
@@ -31128,8 +31127,8 @@ msgstr "Erweiterte Suche läuft (drücken Sie ESC, um abzubrechen) ..."
msgid "Advanced search cancelled by user"
msgstr "Erweiterte Suche durch den Benutzer abgebrochen"
-#: src/frontends/qt/FindAndReplace.cpp:380 src/lyxfind.cpp:349
-#: src/lyxfind.cpp:686 src/lyxfind.cpp:714
+#: src/frontends/qt/FindAndReplace.cpp:380 src/lyxfind.cpp:350
+#: src/lyxfind.cpp:693 src/lyxfind.cpp:721
msgid "Wrap search?"
msgstr "Von vorne suchen?"
@@ -31161,8 +31160,8 @@ msgstr ""
"Eingabetaste)"
#: src/frontends/qt/FloatPlacement.cpp:182
-#: src/frontends/qt/GuiDocument.cpp:1139 src/frontends/qt/GuiDocument.cpp:2707
-#: src/frontends/qt/GuiDocument.cpp:2734
+#: src/frontends/qt/GuiDocument.cpp:1141 src/frontends/qt/GuiDocument.cpp:2709
+#: src/frontends/qt/GuiDocument.cpp:2736
msgid "Class Default"
msgstr "Klassenvoreinstellungen"
@@ -31170,7 +31169,7 @@ msgstr "Klassenvoreinstellungen"
msgid "Document Default"
msgstr "Dokumentvoreinstellung"
-#: src/frontends/qt/FloatPlacement.h:38 src/frontends/qt/GuiDocument.cpp:1775
+#: src/frontends/qt/FloatPlacement.h:38 src/frontends/qt/GuiDocument.cpp:1777
msgid "Float Settings"
msgstr "Gleitobjekt-Einstellungen"
@@ -31356,15 +31355,15 @@ msgstr "Fokusfehler!"
msgid "Running configure..."
msgstr "Neukonfiguration wird durchgeführt..."
-#: src/frontends/qt/GuiApplication.cpp:1664
+#: src/frontends/qt/GuiApplication.cpp:1666
msgid "Reloading configuration..."
msgstr "Konfiguration wird neu geladen..."
-#: src/frontends/qt/GuiApplication.cpp:1671
+#: src/frontends/qt/GuiApplication.cpp:1676
msgid "System reconfiguration failed"
msgstr "Neukonfiguration des Systems fehlgeschlagen"
-#: src/frontends/qt/GuiApplication.cpp:1672
+#: src/frontends/qt/GuiApplication.cpp:1677
msgid ""
"The system reconfiguration has failed.\n"
"Default textclass is used but LyX may\n"
@@ -31376,11 +31375,11 @@ msgstr ""
"der Lage, korrekt zu arbeiten.\n"
"Bitte rekonfigurieren Sie nochmals, wenn nötig."
-#: src/frontends/qt/GuiApplication.cpp:1677
+#: src/frontends/qt/GuiApplication.cpp:1682
msgid "System reconfigured"
msgstr "Das System wurde neu konfiguriert"
-#: src/frontends/qt/GuiApplication.cpp:1678
+#: src/frontends/qt/GuiApplication.cpp:1683
msgid ""
"The system has been reconfigured.\n"
"You need to restart LyX to make use of any\n"
@@ -31390,59 +31389,59 @@ msgstr ""
"Sie müssen LyX neu starten, um die aktualisierten\n"
"Spezifikationen für die Dokumentklassen zu nutzen."
-#: src/frontends/qt/GuiApplication.cpp:1759
+#: src/frontends/qt/GuiApplication.cpp:1764
msgid "Exiting."
msgstr "LyX wird beendet."
-#: src/frontends/qt/GuiApplication.cpp:1855
+#: src/frontends/qt/GuiApplication.cpp:1860
#, c-format
msgid "Opening help file %1$s..."
msgstr "Hilfe-Datei %1$s wird geöffnet..."
-#: src/frontends/qt/GuiApplication.cpp:1875
+#: src/frontends/qt/GuiApplication.cpp:1880
msgid "Wrong argument. Must be 'examples' or 'templates'."
msgstr "Falsches Argument: muss 'examples' oder 'templates' sein."
-#: src/frontends/qt/GuiApplication.cpp:1889
+#: src/frontends/qt/GuiApplication.cpp:1894
msgid "Syntax: set-color <lyx_name> <x11_name> <x11_darkname>"
msgstr "Syntax: set-color <lyx_name> <x11_name> <x11_darkname>"
-#: src/frontends/qt/GuiApplication.cpp:1909
+#: src/frontends/qt/GuiApplication.cpp:1914
#, c-format
msgid "Set-color \"%1$s\" failed - color is undefined or may not be redefined"
msgstr ""
"Set-color \"%1$s\" ist fehlgeschlagen -- die Farbe ist nicht definiert oder "
"darf nicht umdefiniert werden."
-#: src/frontends/qt/GuiApplication.cpp:2014
+#: src/frontends/qt/GuiApplication.cpp:2019
#, c-format
msgid "Cannot iterate more than %1$d times"
msgstr "Mehr als %1$d Wiederholungen sind nicht möglich."
-#: src/frontends/qt/GuiApplication.cpp:2114
+#: src/frontends/qt/GuiApplication.cpp:2119
#, c-format
msgid "Applied \"%1$s\" to %2$d buffer(s)"
msgstr "Der Befehl \"%1$s\" wurde auf %2$d Dateien (Pufferspeicher) angewandt"
-#: src/frontends/qt/GuiApplication.cpp:2200
+#: src/frontends/qt/GuiApplication.cpp:2205
#, c-format
msgid "Document defaults saved in %1$s"
msgstr "Dokument-Standardeinstellungen gespeichert in %1$s"
-#: src/frontends/qt/GuiApplication.cpp:2204
+#: src/frontends/qt/GuiApplication.cpp:2209
msgid "Unable to save document defaults"
msgstr "Die Dokument-Standardeinstellungen können nicht gespeichert werden"
-#: src/frontends/qt/GuiApplication.cpp:2438
-#: src/frontends/qt/GuiApplication.cpp:2453
+#: src/frontends/qt/GuiApplication.cpp:2443
+#: src/frontends/qt/GuiApplication.cpp:2458
msgid "Unknown function."
msgstr "Unbekannte Funktion."
-#: src/frontends/qt/GuiApplication.cpp:2971
+#: src/frontends/qt/GuiApplication.cpp:2976
msgid "The current document was closed."
msgstr "Das aktuelle Dokument wurde geschlossen."
-#: src/frontends/qt/GuiApplication.cpp:2981
+#: src/frontends/qt/GuiApplication.cpp:2986
msgid ""
"LyX has caught an exception, it will now attempt to save all unsaved "
"documents and exit.\n"
@@ -31454,12 +31453,12 @@ msgstr ""
"\n"
"Exception: "
-#: src/frontends/qt/GuiApplication.cpp:2985
-#: src/frontends/qt/GuiApplication.cpp:2991
+#: src/frontends/qt/GuiApplication.cpp:2990
+#: src/frontends/qt/GuiApplication.cpp:2996
msgid "Software exception Detected"
msgstr "Softwareausnahme erkannt"
-#: src/frontends/qt/GuiApplication.cpp:2989
+#: src/frontends/qt/GuiApplication.cpp:2994
msgid ""
"LyX has caught some really weird exception, it will now attempt to save all "
"unsaved documents and exit."
@@ -31467,12 +31466,12 @@ msgstr ""
"LyX hat einen ziemlich seltsamen Fehler entdeckt. Das Programm wird jetzt "
"versuchen, alle ungespeicherten Dateien zu speichern, und dann beendet."
-#: src/frontends/qt/GuiApplication.cpp:3295
-#: src/frontends/qt/GuiApplication.cpp:3307
+#: src/frontends/qt/GuiApplication.cpp:3300
+#: src/frontends/qt/GuiApplication.cpp:3312
msgid "Could not find UI definition file"
msgstr "Die Benutzeroberflächen-Definitionsdatei konnte nicht gefunden werden"
-#: src/frontends/qt/GuiApplication.cpp:3296
+#: src/frontends/qt/GuiApplication.cpp:3301
#, c-format
msgid ""
"Error while reading the included file\n"
@@ -31483,13 +31482,13 @@ msgstr ""
"%1$s.\n"
"Bitte überprüfen Sie Ihre Installation."
-#: src/frontends/qt/GuiApplication.cpp:3302
+#: src/frontends/qt/GuiApplication.cpp:3307
msgid "Could not find default UI file"
msgstr ""
"Die Standard-Benutzeroberflächen-Definitionsdatei konnte nicht gefunden "
"werden"
-#: src/frontends/qt/GuiApplication.cpp:3303
+#: src/frontends/qt/GuiApplication.cpp:3308
msgid ""
"LyX could not find the default UI file!\n"
"Please check your installation."
@@ -31498,7 +31497,7 @@ msgstr ""
"für die Benutzeroberfläche!\n"
"Bitte überprüfen Sie Ihre Installation."
-#: src/frontends/qt/GuiApplication.cpp:3308
+#: src/frontends/qt/GuiApplication.cpp:3313
#, c-format
msgid ""
"Error while reading the configuration file\n"
@@ -31609,12 +31608,12 @@ msgstr "alle Literaturverzeichnisse"
#: src/frontends/qt/GuiBibtex.cpp:456 src/frontends/qt/GuiBibtex.cpp:466
#: src/frontends/qt/GuiCompare.cpp:163 src/frontends/qt/GuiCompare.cpp:167
-#: src/frontends/qt/GuiDocument.cpp:2885 src/frontends/qt/GuiExternal.cpp:677
+#: src/frontends/qt/GuiDocument.cpp:2887 src/frontends/qt/GuiExternal.cpp:677
#: src/frontends/qt/GuiGraphics.cpp:789 src/frontends/qt/GuiInclude.cpp:380
#: src/frontends/qt/GuiLyXFiles.cpp:362 src/frontends/qt/GuiLyXFiles.cpp:368
#: src/frontends/qt/GuiView.cpp:2551 src/frontends/qt/GuiView.cpp:2610
-#: src/frontends/qt/GuiView.cpp:2746 src/frontends/qt/GuiView.cpp:2880
-#: src/frontends/qt/GuiView.cpp:3000 src/frontends/qt/GuiView.cpp:3122
+#: src/frontends/qt/GuiView.cpp:2750 src/frontends/qt/GuiView.cpp:2884
+#: src/frontends/qt/GuiView.cpp:3004 src/frontends/qt/GuiView.cpp:3126
msgid "D&ocuments"
msgstr "Do&kumente"
@@ -31696,7 +31695,7 @@ msgid "Filename Suffix"
msgstr "Erweitere Dateinamen"
#: src/frontends/qt/GuiBranches.cpp:135 src/frontends/qt/GuiBranches.cpp:149
-#: src/frontends/qt/GuiDocument.cpp:3324 src/frontends/qt/GuiDocument.cpp:4635
+#: src/frontends/qt/GuiDocument.cpp:3326 src/frontends/qt/GuiDocument.cpp:4637
#: src/frontends/qt/GuiProgressView.cpp:144
#: src/frontends/qt/GuiProgressView.cpp:158
#: src/frontends/qt/GuiProgressView.cpp:179
@@ -31704,8 +31703,8 @@ msgid "Yes"
msgstr "Ja"
#: src/frontends/qt/GuiBranches.cpp:135 src/frontends/qt/GuiBranches.cpp:149
-#: src/frontends/qt/GuiDocument.cpp:3323 src/frontends/qt/GuiDocument.cpp:3966
-#: src/frontends/qt/GuiDocument.cpp:4634
+#: src/frontends/qt/GuiDocument.cpp:3325 src/frontends/qt/GuiDocument.cpp:3968
+#: src/frontends/qt/GuiDocument.cpp:4636
#: src/frontends/qt/GuiProgressView.cpp:110
#: src/frontends/qt/GuiProgressView.cpp:143
#: src/frontends/qt/GuiProgressView.cpp:179
@@ -31975,10 +31974,10 @@ msgstr "%1$s Dateien"
msgid "Choose a filename to save the pasted graphic as"
msgstr "Wählen Sie einen Dateinamen, um die eingefügte Grafik zu speichern als"
-#: src/frontends/qt/GuiClipboard.cpp:220 src/frontends/qt/GuiView.cpp:2624
-#: src/frontends/qt/GuiView.cpp:2765 src/frontends/qt/GuiView.cpp:2781
-#: src/frontends/qt/GuiView.cpp:2793 src/frontends/qt/GuiView.cpp:2810
-#: src/frontends/qt/GuiView.cpp:2895 src/frontends/qt/GuiView.cpp:4328
+#: src/frontends/qt/GuiClipboard.cpp:220 src/frontends/qt/GuiView.cpp:2628
+#: src/frontends/qt/GuiView.cpp:2769 src/frontends/qt/GuiView.cpp:2785
+#: src/frontends/qt/GuiView.cpp:2797 src/frontends/qt/GuiView.cpp:2814
+#: src/frontends/qt/GuiView.cpp:2899 src/frontends/qt/GuiView.cpp:4332
msgid "Canceled."
msgstr "Abgebrochen."
@@ -32008,8 +32007,8 @@ msgid "Select document"
msgstr "Dokument wählen"
#: src/frontends/qt/GuiCompare.cpp:157 src/frontends/qt/GuiLyXFiles.cpp:361
-#: src/frontends/qt/GuiView.cpp:2555 src/frontends/qt/GuiView.cpp:2613
-#: src/frontends/qt/GuiView.cpp:2884 src/frontends/qt/GuiView.cpp:3011
+#: src/frontends/qt/GuiView.cpp:2555 src/frontends/qt/GuiView.cpp:2614
+#: src/frontends/qt/GuiView.cpp:2888 src/frontends/qt/GuiView.cpp:3015
msgid "LyX Documents (*.lyx)"
msgstr "LyX-Dokumente (*.lyx)"
@@ -32113,32 +32112,32 @@ msgstr "Unterdokument"
msgid "Include to Output"
msgstr "In Ausgabe einbinden"
-#: src/frontends/qt/GuiDocument.cpp:985
+#: src/frontends/qt/GuiDocument.cpp:987
msgid "Unicode (utf8)"
msgstr "Unicode (utf8)"
-#: src/frontends/qt/GuiDocument.cpp:986
+#: src/frontends/qt/GuiDocument.cpp:988
msgid "Traditional (auto-selected)"
msgstr "Traditionell (automatisch gewählt)"
-#: src/frontends/qt/GuiDocument.cpp:989
+#: src/frontends/qt/GuiDocument.cpp:991
msgid "Select Unicode (utf8) encoding."
msgstr "Wählen Sie die passende Unicode-Kodierung"
-#: src/frontends/qt/GuiDocument.cpp:991
+#: src/frontends/qt/GuiDocument.cpp:993
msgid "Use language-dependent traditional encodings."
msgstr "Verwendet sprachspezifische traditionelle Kodierungen."
-#: src/frontends/qt/GuiDocument.cpp:993
+#: src/frontends/qt/GuiDocument.cpp:995
msgid "Select a custom, document-wide encoding."
msgstr ""
"Hiermit können Sie eine benutzerdefinierte dokumentweite Kodierung wählen"
-#: src/frontends/qt/GuiDocument.cpp:1002
+#: src/frontends/qt/GuiDocument.cpp:1004
msgid "Standard Unicode support by the ``inputenc'' package."
msgstr "Standard-Unicode-Unterstützung durch das Paket ,,inputenc``."
-#: src/frontends/qt/GuiDocument.cpp:1005
+#: src/frontends/qt/GuiDocument.cpp:1007
msgid ""
"Use UTF-8 'as-is': do not load any supporting packages, do not convert any "
"characters to LaTeX macros. For use with non-TeX fonts (XeTeX/LuaTeX) or "
@@ -32149,7 +32148,7 @@ msgstr ""
"Nicht-TeX-Schriften (XeTeX/LuaTeX) verwendet. Er kann auch bei manuellen "
"Konfigurationen nützlich sein."
-#: src/frontends/qt/GuiDocument.cpp:1010
+#: src/frontends/qt/GuiDocument.cpp:1012
msgid ""
"Load ``inputenc'' with option 'utf8x' for extended Unicode support by the "
"``ucs'' package."
@@ -32157,11 +32156,11 @@ msgstr ""
"Lade ,,inputenc`` mit der Option ,utf8x` für erweiterte Unicode-"
"Unterstützung (über das Paket ,,ucs``)."
-#: src/frontends/qt/GuiDocument.cpp:1014
+#: src/frontends/qt/GuiDocument.cpp:1016
msgid "Language Default (no inputenc)"
msgstr "Sprachvoreinstellung (ohne inputenc)"
-#: src/frontends/qt/GuiDocument.cpp:1016
+#: src/frontends/qt/GuiDocument.cpp:1018
msgid ""
"Use the traditional default encoding of the text language. Switch encoding "
"if a text part is set to a language with different default."
@@ -32170,7 +32169,7 @@ msgstr ""
"Textes. Die Kodierung wird der jeweiligen Sprache angepasst, auch bei "
"Sprachwechseln im Dokument."
-#: src/frontends/qt/GuiDocument.cpp:1020
+#: src/frontends/qt/GuiDocument.cpp:1022
msgid ""
"Do not load the 'inputenc' package. Switch encoding if required but do not "
"write input encoding switch commands to the source."
@@ -32178,23 +32177,23 @@ msgstr ""
"Lädt das Paket ,,inputenc`` nicht. Die Kodierung wird zwar, falls nötig, "
"angepasst, aber es werden keine entsprechenden LaTeX-Makros ausgegeben."
-#: src/frontends/qt/GuiDocument.cpp:1134
+#: src/frontends/qt/GuiDocument.cpp:1136
msgid "10"
msgstr "10"
-#: src/frontends/qt/GuiDocument.cpp:1135
+#: src/frontends/qt/GuiDocument.cpp:1137
msgid "11"
msgstr "11"
-#: src/frontends/qt/GuiDocument.cpp:1136
+#: src/frontends/qt/GuiDocument.cpp:1138
msgid "12"
msgstr "12"
-#: src/frontends/qt/GuiDocument.cpp:1138
+#: src/frontends/qt/GuiDocument.cpp:1140
msgid "Automatic[[encoding]]"
msgstr "Automatisch"
-#: src/frontends/qt/GuiDocument.cpp:1148
+#: src/frontends/qt/GuiDocument.cpp:1150
msgid ""
"Use OpenType and TrueType fonts directly (requires XeTeX or LuaTeX)\n"
"You need to install the package \"fontspec\" to use this feature"
@@ -32203,194 +32202,194 @@ msgstr ""
"LuaTeX)\n"
"Um dieses Feature zu nutzen, müssen Sie das Paket \"fontspec\" installieren."
-#: src/frontends/qt/GuiDocument.cpp:1180
+#: src/frontends/qt/GuiDocument.cpp:1182
msgid "empty"
msgstr "leer"
-#: src/frontends/qt/GuiDocument.cpp:1181
+#: src/frontends/qt/GuiDocument.cpp:1183
msgid "plain"
msgstr "einfach"
-#: src/frontends/qt/GuiDocument.cpp:1182
+#: src/frontends/qt/GuiDocument.cpp:1184
msgid "headings"
msgstr "mit Ãberschriften"
-#: src/frontends/qt/GuiDocument.cpp:1183
+#: src/frontends/qt/GuiDocument.cpp:1185
msgid "fancy"
msgstr "ausgefallen"
-#: src/frontends/qt/GuiDocument.cpp:1192
+#: src/frontends/qt/GuiDocument.cpp:1194
msgid "US letter"
msgstr "US letter"
-#: src/frontends/qt/GuiDocument.cpp:1193
+#: src/frontends/qt/GuiDocument.cpp:1195
msgid "US legal"
msgstr "US legal"
-#: src/frontends/qt/GuiDocument.cpp:1194
+#: src/frontends/qt/GuiDocument.cpp:1196
msgid "US executive"
msgstr "US executive"
-#: src/frontends/qt/GuiDocument.cpp:1195
+#: src/frontends/qt/GuiDocument.cpp:1197
msgid "A0"
msgstr "A0"
-#: src/frontends/qt/GuiDocument.cpp:1196
+#: src/frontends/qt/GuiDocument.cpp:1198
msgid "A1"
msgstr "A1"
-#: src/frontends/qt/GuiDocument.cpp:1197
+#: src/frontends/qt/GuiDocument.cpp:1199
msgid "A2"
msgstr "A2"
-#: src/frontends/qt/GuiDocument.cpp:1198
+#: src/frontends/qt/GuiDocument.cpp:1200
msgid "A3"
msgstr "A3"
-#: src/frontends/qt/GuiDocument.cpp:1199
+#: src/frontends/qt/GuiDocument.cpp:1201
msgid "A4"
msgstr "A4"
-#: src/frontends/qt/GuiDocument.cpp:1200
+#: src/frontends/qt/GuiDocument.cpp:1202
msgid "A5"
msgstr "A5"
-#: src/frontends/qt/GuiDocument.cpp:1201
+#: src/frontends/qt/GuiDocument.cpp:1203
msgid "A6"
msgstr "A6"
-#: src/frontends/qt/GuiDocument.cpp:1202
+#: src/frontends/qt/GuiDocument.cpp:1204
msgid "B0"
msgstr "B0"
-#: src/frontends/qt/GuiDocument.cpp:1203
+#: src/frontends/qt/GuiDocument.cpp:1205
msgid "B1"
msgstr "B1"
-#: src/frontends/qt/GuiDocument.cpp:1204
+#: src/frontends/qt/GuiDocument.cpp:1206
msgid "B2"
msgstr "B2"
-#: src/frontends/qt/GuiDocument.cpp:1205
+#: src/frontends/qt/GuiDocument.cpp:1207
msgid "B3"
msgstr "B3"
-#: src/frontends/qt/GuiDocument.cpp:1206
+#: src/frontends/qt/GuiDocument.cpp:1208
msgid "B4"
msgstr "B4"
-#: src/frontends/qt/GuiDocument.cpp:1207
+#: src/frontends/qt/GuiDocument.cpp:1209
msgid "B5"
msgstr "B5"
-#: src/frontends/qt/GuiDocument.cpp:1208
+#: src/frontends/qt/GuiDocument.cpp:1210
msgid "B6"
msgstr "B6"
-#: src/frontends/qt/GuiDocument.cpp:1209
+#: src/frontends/qt/GuiDocument.cpp:1211
msgid "C0"
msgstr "C0"
-#: src/frontends/qt/GuiDocument.cpp:1210
+#: src/frontends/qt/GuiDocument.cpp:1212
msgid "C1"
msgstr "C1"
-#: src/frontends/qt/GuiDocument.cpp:1211
+#: src/frontends/qt/GuiDocument.cpp:1213
msgid "C2"
msgstr "C2"
-#: src/frontends/qt/GuiDocument.cpp:1212
+#: src/frontends/qt/GuiDocument.cpp:1214
msgid "C3"
msgstr "C3"
-#: src/frontends/qt/GuiDocument.cpp:1213
+#: src/frontends/qt/GuiDocument.cpp:1215
msgid "C4"
msgstr "C4"
-#: src/frontends/qt/GuiDocument.cpp:1214
+#: src/frontends/qt/GuiDocument.cpp:1216
msgid "C5"
msgstr "C5"
-#: src/frontends/qt/GuiDocument.cpp:1215
+#: src/frontends/qt/GuiDocument.cpp:1217
msgid "C6"
msgstr "C6"
-#: src/frontends/qt/GuiDocument.cpp:1216
+#: src/frontends/qt/GuiDocument.cpp:1218
msgid "JIS B0"
msgstr "JIS B0"
-#: src/frontends/qt/GuiDocument.cpp:1217
+#: src/frontends/qt/GuiDocument.cpp:1219
msgid "JIS B1"
msgstr "JIS B1"
-#: src/frontends/qt/GuiDocument.cpp:1218
+#: src/frontends/qt/GuiDocument.cpp:1220
msgid "JIS B2"
msgstr "JIS B2"
-#: src/frontends/qt/GuiDocument.cpp:1219
+#: src/frontends/qt/GuiDocument.cpp:1221
msgid "JIS B3"
msgstr "JIS B3"
-#: src/frontends/qt/GuiDocument.cpp:1220
+#: src/frontends/qt/GuiDocument.cpp:1222
msgid "JIS B4"
msgstr "JIS B4"
-#: src/frontends/qt/GuiDocument.cpp:1221
+#: src/frontends/qt/GuiDocument.cpp:1223
msgid "JIS B5"
msgstr "JIS B5"
-#: src/frontends/qt/GuiDocument.cpp:1222
+#: src/frontends/qt/GuiDocument.cpp:1224
msgid "JIS B6"
msgstr "JIS B6"
-#: src/frontends/qt/GuiDocument.cpp:1345
+#: src/frontends/qt/GuiDocument.cpp:1347
msgid "Numbered"
msgstr "Nummeriert"
-#: src/frontends/qt/GuiDocument.cpp:1346
+#: src/frontends/qt/GuiDocument.cpp:1348
msgid "Appears in TOC"
msgstr "Erscheint im Inhaltsverzeichnis"
-#: src/frontends/qt/GuiDocument.cpp:1434
+#: src/frontends/qt/GuiDocument.cpp:1436
msgid "Package"
msgstr "Paket"
-#: src/frontends/qt/GuiDocument.cpp:1434
+#: src/frontends/qt/GuiDocument.cpp:1436
msgid "Load automatically"
msgstr "Automatisch laden"
-#: src/frontends/qt/GuiDocument.cpp:1435
+#: src/frontends/qt/GuiDocument.cpp:1437
msgid "Load always"
msgstr "Immer laden"
-#: src/frontends/qt/GuiDocument.cpp:1435
+#: src/frontends/qt/GuiDocument.cpp:1437
msgid "Do not load"
msgstr "Nicht laden"
-#: src/frontends/qt/GuiDocument.cpp:1447
+#: src/frontends/qt/GuiDocument.cpp:1449
msgid "The AMS LaTeX packages are always used"
msgstr "Die AMS-LaTeX-Pakete werden immer verwendet"
-#: src/frontends/qt/GuiDocument.cpp:1450
+#: src/frontends/qt/GuiDocument.cpp:1452
#, c-format
msgid "The LaTeX package %1$s is always used"
msgstr "Das LaTeX-Paket %1$s wird immer verwendet"
-#: src/frontends/qt/GuiDocument.cpp:1455
+#: src/frontends/qt/GuiDocument.cpp:1457
msgid "The AMS LaTeX packages are never used"
msgstr "Die AMS-LaTeX-Pakete werden nie verwendet"
-#: src/frontends/qt/GuiDocument.cpp:1458
+#: src/frontends/qt/GuiDocument.cpp:1460
#, c-format
msgid "The LaTeX package %1$s is never used"
msgstr "Das LaTeX-Paket %1$s wird nie verwendet"
-#: src/frontends/qt/GuiDocument.cpp:1595 src/frontends/qt/GuiDocument.cpp:2864
+#: src/frontends/qt/GuiDocument.cpp:1597 src/frontends/qt/GuiDocument.cpp:2866
#, c-format
msgid "%1$s [Class '%2$s']"
msgstr "%1$s [Klasse '%2$s']"
-#: src/frontends/qt/GuiDocument.cpp:1598
+#: src/frontends/qt/GuiDocument.cpp:1600
#, c-format
msgid ""
"Class not found by LyX. Please check if you have the matching %1$s class and "
@@ -32399,83 +32398,83 @@ msgstr ""
"Klasse wurde von LyX nicht gefunden. Bitte prüfen Sie, ob Sie die "
"entsprechende %1$s-Klasse und alle nötigen Pakete (%2$s) installiert haben."
-#: src/frontends/qt/GuiDocument.cpp:1660
+#: src/frontends/qt/GuiDocument.cpp:1662
msgid "All avail. modules"
msgstr "Alle verf. Module"
-#: src/frontends/qt/GuiDocument.cpp:1752 src/frontends/qt/GuiDocument.cpp:1976
+#: src/frontends/qt/GuiDocument.cpp:1754 src/frontends/qt/GuiDocument.cpp:1978
msgid "Input listings parameters below. Enter ? for a list of parameters."
msgstr ""
"Geben Sie unten Listing-Parameter ein. Geben Sie '?' für eine Liste gültiger "
"Parameter ein."
-#: src/frontends/qt/GuiDocument.cpp:1759
+#: src/frontends/qt/GuiDocument.cpp:1761
msgid "Document Class"
msgstr "Dokumentklasse"
-#: src/frontends/qt/GuiDocument.cpp:1762
+#: src/frontends/qt/GuiDocument.cpp:1764
msgid "Local Layout"
msgstr "Lokales Format"
-#: src/frontends/qt/GuiDocument.cpp:1764
+#: src/frontends/qt/GuiDocument.cpp:1766
msgid "Text Layout"
msgstr "Textformat"
-#: src/frontends/qt/GuiDocument.cpp:1766
+#: src/frontends/qt/GuiDocument.cpp:1768
msgid "Page Margins"
msgstr "Seitenränder"
-#: src/frontends/qt/GuiDocument.cpp:1768 src/frontends/qt/GuiPrefs.cpp:1076
+#: src/frontends/qt/GuiDocument.cpp:1770 src/frontends/qt/GuiPrefs.cpp:1076
msgid "Colors"
msgstr "Farben"
-#: src/frontends/qt/GuiDocument.cpp:1769
+#: src/frontends/qt/GuiDocument.cpp:1771
msgid "Change Tracking"
msgstr "Ãnderungsverfolgung"
-#: src/frontends/qt/GuiDocument.cpp:1770
+#: src/frontends/qt/GuiDocument.cpp:1772
msgid "Numbering & TOC"
msgstr "Nummerierung & Inhaltsverzeichnis"
-#: src/frontends/qt/GuiDocument.cpp:1772
+#: src/frontends/qt/GuiDocument.cpp:1774
msgid "Indexes"
msgstr "Stichwortverzeichnis"
-#: src/frontends/qt/GuiDocument.cpp:1773
+#: src/frontends/qt/GuiDocument.cpp:1775
msgid "PDF Properties"
msgstr "PDF-Eigenschaften"
-#: src/frontends/qt/GuiDocument.cpp:1774
+#: src/frontends/qt/GuiDocument.cpp:1776
msgid "Math Options"
msgstr "Mathe-Optionen"
-#: src/frontends/qt/GuiDocument.cpp:1777
+#: src/frontends/qt/GuiDocument.cpp:1779
msgid "Bullets"
msgstr "Auflistungszeichen"
-#: src/frontends/qt/GuiDocument.cpp:1779
+#: src/frontends/qt/GuiDocument.cpp:1781
msgid "Formats[[output]]"
msgstr "Formate"
-#: src/frontends/qt/GuiDocument.cpp:1780
+#: src/frontends/qt/GuiDocument.cpp:1782
msgid "LaTeX Preamble"
msgstr "LaTeX-Vorspann"
-#: src/frontends/qt/GuiDocument.cpp:2085 src/frontends/qt/GuiDocument.cpp:2171
+#: src/frontends/qt/GuiDocument.cpp:2087 src/frontends/qt/GuiDocument.cpp:2173
msgid "Class defaults"
msgstr "Klassenvoreinstellung"
-#: src/frontends/qt/GuiDocument.cpp:2085 src/frontends/qt/GuiDocument.cpp:2171
+#: src/frontends/qt/GuiDocument.cpp:2087 src/frontends/qt/GuiDocument.cpp:2173
msgid "Package defaults"
msgstr "Paketvoreinstellung"
-#: src/frontends/qt/GuiDocument.cpp:2088 src/frontends/qt/GuiDocument.cpp:2174
+#: src/frontends/qt/GuiDocument.cpp:2090 src/frontends/qt/GuiDocument.cpp:2176
msgid "If no value is given, the defaults as set by the class are used."
msgstr ""
"Wenn kein Wert angegeben wird, werden die Voreinstellungen der Klasse "
"verwendet."
-#: src/frontends/qt/GuiDocument.cpp:2089 src/frontends/qt/GuiDocument.cpp:2175
+#: src/frontends/qt/GuiDocument.cpp:2091 src/frontends/qt/GuiDocument.cpp:2177
msgid ""
"If no value is given, the defaults as set by the geometry package or a "
"package/class overriding geometry's defaults are used."
@@ -32484,49 +32483,49 @@ msgstr ""
"Pakets oder eines Pakets bzw. der Klasse verwendet, falls diese die Geometry-"
"Voreinstellungen überschreiben."
-#: src/frontends/qt/GuiDocument.cpp:2218 src/frontends/qt/GuiDocument.cpp:2248
+#: src/frontends/qt/GuiDocument.cpp:2220 src/frontends/qt/GuiDocument.cpp:2250
msgid "&Default..."
msgstr "Stan&dard..."
-#: src/frontends/qt/GuiDocument.cpp:2449
+#: src/frontends/qt/GuiDocument.cpp:2451
msgid "Direct (No inputenc)"
msgstr "Direkt (ohne inputenc)"
-#: src/frontends/qt/GuiDocument.cpp:2451
+#: src/frontends/qt/GuiDocument.cpp:2453
msgid "Direct (XeTeX/LuaTeX)"
msgstr "Direkt (XeTeX/LuaTeX)"
-#: src/frontends/qt/GuiDocument.cpp:2637 src/frontends/qt/GuiDocument.cpp:4310
-#: src/frontends/qt/GuiDocument.cpp:4319 src/frontends/qt/GuiDocument.cpp:4328
-#: src/frontends/qt/GuiDocument.cpp:4337
+#: src/frontends/qt/GuiDocument.cpp:2639 src/frontends/qt/GuiDocument.cpp:4312
+#: src/frontends/qt/GuiDocument.cpp:4321 src/frontends/qt/GuiDocument.cpp:4330
+#: src/frontends/qt/GuiDocument.cpp:4339
msgid " (not installed)"
msgstr " (nicht installiert)"
-#: src/frontends/qt/GuiDocument.cpp:2666
+#: src/frontends/qt/GuiDocument.cpp:2668
msgid "Non-TeX Fonts Default"
msgstr "Voreinstellung Nicht-TeX Schriften"
-#: src/frontends/qt/GuiDocument.cpp:2668
+#: src/frontends/qt/GuiDocument.cpp:2670
msgid " (not available)"
msgstr " (nicht verfügbar)"
-#: src/frontends/qt/GuiDocument.cpp:2669
+#: src/frontends/qt/GuiDocument.cpp:2671
msgid "Class Default (TeX Fonts)"
msgstr "Klassenvoreinstellungen (TeX-Schriften)"
-#: src/frontends/qt/GuiDocument.cpp:2816
+#: src/frontends/qt/GuiDocument.cpp:2818
msgid "Lay&outs"
msgstr "F&ormatdateien"
-#: src/frontends/qt/GuiDocument.cpp:2818
+#: src/frontends/qt/GuiDocument.cpp:2820
msgid "LyX Layout (*.layout)"
msgstr "LyX-Formatdatei (*.layout)"
-#: src/frontends/qt/GuiDocument.cpp:2820 src/frontends/qt/GuiDocument.cpp:2829
+#: src/frontends/qt/GuiDocument.cpp:2822 src/frontends/qt/GuiDocument.cpp:2831
msgid "Local layout file"
msgstr "Lokale Formatdatei"
-#: src/frontends/qt/GuiDocument.cpp:2830
+#: src/frontends/qt/GuiDocument.cpp:2832
msgid ""
"The layout file you have selected is a local layout\n"
"file, not one in the system or user directory.\n"
@@ -32539,35 +32538,35 @@ msgstr ""
"kann, müssen Sie sicherstellen, dass die Formatdatei\n"
"nicht verschoben wird."
-#: src/frontends/qt/GuiDocument.cpp:2834
+#: src/frontends/qt/GuiDocument.cpp:2836
msgid "&Set Layout"
msgstr "&Layout übernehmen"
-#: src/frontends/qt/GuiDocument.cpp:2848
+#: src/frontends/qt/GuiDocument.cpp:2850
msgid "Unable to read local layout file."
msgstr "Lokale Formatdatei kann nicht gelesen werden."
-#: src/frontends/qt/GuiDocument.cpp:2865
+#: src/frontends/qt/GuiDocument.cpp:2867
msgid "This is a local layout file."
msgstr "Dies ist eine lokale Formatdatei."
-#: src/frontends/qt/GuiDocument.cpp:2879
+#: src/frontends/qt/GuiDocument.cpp:2881
msgid "Select master document"
msgstr "Hauptdokument wählen"
-#: src/frontends/qt/GuiDocument.cpp:2883
+#: src/frontends/qt/GuiDocument.cpp:2885
msgid "LyX Files (*.lyx)"
msgstr "LyX-Dokumente (*.lyx)"
# , c-format
# , c-format
-#: src/frontends/qt/GuiDocument.cpp:2907 src/frontends/qt/GuiDocument.cpp:3211
-#: src/frontends/qt/GuiDocument.cpp:4826
+#: src/frontends/qt/GuiDocument.cpp:2909 src/frontends/qt/GuiDocument.cpp:3213
+#: src/frontends/qt/GuiDocument.cpp:4828
msgid "Unapplied changes"
msgstr "Nicht übernommene Ãnderungen"
-#: src/frontends/qt/GuiDocument.cpp:2908 src/frontends/qt/GuiDocument.cpp:3212
-#: src/frontends/qt/GuiDocument.cpp:4827
+#: src/frontends/qt/GuiDocument.cpp:2910 src/frontends/qt/GuiDocument.cpp:3214
+#: src/frontends/qt/GuiDocument.cpp:4829
msgid ""
"Some changes in the dialog were not yet applied.\n"
"If you do not apply now, they will be lost after this action."
@@ -32576,86 +32575,86 @@ msgstr ""
"Wenn Sie sie jetzt nicht anwenden, werden sie nach dieser\n"
"Aktion verlorengehen."
-#: src/frontends/qt/GuiDocument.cpp:2910 src/frontends/qt/GuiDocument.cpp:3214
-#: src/frontends/qt/GuiDocument.cpp:4829
+#: src/frontends/qt/GuiDocument.cpp:2912 src/frontends/qt/GuiDocument.cpp:3216
+#: src/frontends/qt/GuiDocument.cpp:4831
msgid "&Apply"
msgstr "&Anwenden"
-#: src/frontends/qt/GuiDocument.cpp:2910 src/frontends/qt/GuiDocument.cpp:3214
-#: src/frontends/qt/GuiDocument.cpp:4829
+#: src/frontends/qt/GuiDocument.cpp:2912 src/frontends/qt/GuiDocument.cpp:3216
+#: src/frontends/qt/GuiDocument.cpp:4831
msgid "&Dismiss"
msgstr "&Ablehnen"
-#: src/frontends/qt/GuiDocument.cpp:2921 src/frontends/qt/GuiDocument.cpp:4837
+#: src/frontends/qt/GuiDocument.cpp:2923 src/frontends/qt/GuiDocument.cpp:4839
msgid "Unable to set document class."
msgstr "Kann Dokumentklasse nicht einstellen."
-#: src/frontends/qt/GuiDocument.cpp:3087
+#: src/frontends/qt/GuiDocument.cpp:3089
msgid "Basic numerical"
msgstr "Einfach nummerisch"
-#: src/frontends/qt/GuiDocument.cpp:3090
+#: src/frontends/qt/GuiDocument.cpp:3092
msgid "Author-year"
msgstr "Autor-Jahr"
-#: src/frontends/qt/GuiDocument.cpp:3093
+#: src/frontends/qt/GuiDocument.cpp:3095
msgid "Author-number"
msgstr "Autor-Nummer"
-#: src/frontends/qt/GuiDocument.cpp:3136
+#: src/frontends/qt/GuiDocument.cpp:3138
#, c-format
msgid "%1$s and %2$s"
msgstr "%1$s und %2$s"
-#: src/frontends/qt/GuiDocument.cpp:3143
+#: src/frontends/qt/GuiDocument.cpp:3145
#, c-format
msgid "%1$s, %2$s"
msgstr "%1$s, %2$s"
-#: src/frontends/qt/GuiDocument.cpp:3148
+#: src/frontends/qt/GuiDocument.cpp:3150
#, c-format
msgid "%1$s, %2$s, and %3$s"
msgstr "%1$s, %2$s und %3$s"
-#: src/frontends/qt/GuiDocument.cpp:3162
+#: src/frontends/qt/GuiDocument.cpp:3164
#, c-format
msgid "%1$s (unavailable)"
msgstr "%1$s (nicht verfügbar)"
-#: src/frontends/qt/GuiDocument.cpp:3261
+#: src/frontends/qt/GuiDocument.cpp:3263
msgid "Module provided by document class."
msgstr "Von der Dokumentklasse bereitgestelltes Modul."
-#: src/frontends/qt/GuiDocument.cpp:3269
+#: src/frontends/qt/GuiDocument.cpp:3271
#, c-format
msgid "<p><b>Category:</b> %1$s.</p>"
msgstr "<p><b>Kategorie:</b> %1$s.</p>"
-#: src/frontends/qt/GuiDocument.cpp:3279
+#: src/frontends/qt/GuiDocument.cpp:3281
#, c-format
msgid "<p><b>Package(s) required:</b> %1$s.</p>"
msgstr "<p><b>Benötigte Pakete:</b> %1$s.</p>"
-#: src/frontends/qt/GuiDocument.cpp:3285
+#: src/frontends/qt/GuiDocument.cpp:3287
msgid "or"
msgstr "oder"
-#: src/frontends/qt/GuiDocument.cpp:3288
+#: src/frontends/qt/GuiDocument.cpp:3290
#, c-format
msgid "<p><b>Modules required:</b> %1$s.</p>"
msgstr "<p><b>Benötigte Module:</b> %1$s.</p>"
-#: src/frontends/qt/GuiDocument.cpp:3297
+#: src/frontends/qt/GuiDocument.cpp:3299
#, c-format
msgid "<p><b>Modules excluded:</b> %1$s.</p>"
msgstr "<p><b>Ausgeschlossene Module:</b> %1$s.</p>"
-#: src/frontends/qt/GuiDocument.cpp:3302
+#: src/frontends/qt/GuiDocument.cpp:3304
#, c-format
msgid "<p><b>Filename:</b> <tt>%1$s.module</tt>.</p>"
msgstr "<p><b>Dateiname:</b> <tt>%1$s.module</tt>.</p>"
-#: src/frontends/qt/GuiDocument.cpp:3307
+#: src/frontends/qt/GuiDocument.cpp:3309
msgid ""
"<p><font color=red><b>WARNING: Some required packages are unavailable!</b></"
"font></p>"
@@ -32663,56 +32662,56 @@ msgstr ""
"<p><font color=red><b>WARNUNG: Einige benötigte Pakete sind nicht verfügbar!"
"</b></font></p>"
-#: src/frontends/qt/GuiDocument.cpp:3968
+#: src/frontends/qt/GuiDocument.cpp:3970
msgid "per part"
msgstr "pro Teil"
-#: src/frontends/qt/GuiDocument.cpp:3970
+#: src/frontends/qt/GuiDocument.cpp:3972
msgid "per chapter"
msgstr "pro Kapitel"
-#: src/frontends/qt/GuiDocument.cpp:3972
+#: src/frontends/qt/GuiDocument.cpp:3974
msgid "per section"
msgstr "pro Abschnitt"
-#: src/frontends/qt/GuiDocument.cpp:3974
+#: src/frontends/qt/GuiDocument.cpp:3976
msgid "per subsection"
msgstr "pro Unterabschnitt"
-#: src/frontends/qt/GuiDocument.cpp:3975
+#: src/frontends/qt/GuiDocument.cpp:3977
msgid "per child document"
msgstr "pro Unterdokument"
-#: src/frontends/qt/GuiDocument.cpp:4230
+#: src/frontends/qt/GuiDocument.cpp:4232
msgid "[No options predefined]"
msgstr "[Keine Optionen vordefiniert]"
-#: src/frontends/qt/GuiDocument.cpp:4497
+#: src/frontends/qt/GuiDocument.cpp:4499
msgid "C&ustomize Hyperref Options"
msgstr "H&yperref-Optionen anpassen"
-#: src/frontends/qt/GuiDocument.cpp:4499
+#: src/frontends/qt/GuiDocument.cpp:4501
msgid "&Use Hyperref Support"
msgstr "Hyperref-Unterstützung &verwenden"
-#: src/frontends/qt/GuiDocument.cpp:4849
+#: src/frontends/qt/GuiDocument.cpp:4851
msgid "Can't set layout!"
msgstr "Kann Format nicht verwenden!"
-#: src/frontends/qt/GuiDocument.cpp:4850
+#: src/frontends/qt/GuiDocument.cpp:4852
#, c-format
msgid "Unable to set layout for ID: %1$s"
msgstr "Kann Format für ID '%1$s' nicht verwenden"
-#: src/frontends/qt/GuiDocument.cpp:4948
+#: src/frontends/qt/GuiDocument.cpp:4950
msgid "Not Found"
msgstr "Nicht gefunden"
-#: src/frontends/qt/GuiDocument.cpp:5010
+#: src/frontends/qt/GuiDocument.cpp:5012
msgid "Assigned master does not include this file"
msgstr "Zugewiesenes Hauptdokument bettet diese Datei nicht ein"
-#: src/frontends/qt/GuiDocument.cpp:5011
+#: src/frontends/qt/GuiDocument.cpp:5013
#, c-format
msgid ""
"You must include this file in the document\n"
@@ -32723,11 +32722,11 @@ msgstr ""
"'%1$s' einbetten, sonst bleibt die\n"
"vorgenommene Zuordnung des Hauptdokuments wirkungslos."
-#: src/frontends/qt/GuiDocument.cpp:5015
+#: src/frontends/qt/GuiDocument.cpp:5017
msgid "Could not load master"
msgstr "Konnte das Hauptdokument nicht laden"
-#: src/frontends/qt/GuiDocument.cpp:5016
+#: src/frontends/qt/GuiDocument.cpp:5018
#, c-format
msgid ""
"The master document '%1$s'\n"
@@ -32736,23 +32735,23 @@ msgstr ""
"Das Hauptdokument '%1$s'\n"
"konnte nicht geladen werden."
-#: src/frontends/qt/GuiDocument.cpp:5166
+#: src/frontends/qt/GuiDocument.cpp:5168
msgid "%1 (missing req.)"
msgstr "%1 (fehlende Vor.)"
-#: src/frontends/qt/GuiDocument.cpp:5178
+#: src/frontends/qt/GuiDocument.cpp:5180
msgid "personal module"
msgstr "persönliches Modul"
-#: src/frontends/qt/GuiDocument.cpp:5178
+#: src/frontends/qt/GuiDocument.cpp:5180
msgid "distributed module"
msgstr "mitgeliefertes Modul"
-#: src/frontends/qt/GuiDocument.cpp:5179
+#: src/frontends/qt/GuiDocument.cpp:5181
msgid "<b>Module name:</b> <i>%1</i> (%2)"
msgstr "<b>Modulname:</b> <i>%1</i> (%2)"
-#: src/frontends/qt/GuiDocument.cpp:5185
+#: src/frontends/qt/GuiDocument.cpp:5187
msgid "<b>Note:</b> Some requirements for this module are missing!"
msgstr ""
"<b>Achtung:</b> Einige Voraussetzungen für dieses Modul sind nicht gegeben!"
@@ -33431,7 +33430,7 @@ msgid "Select example file"
msgstr "Wählen Sie eine Beispieldatei"
#: src/frontends/qt/GuiLyXFiles.cpp:363 src/frontends/qt/GuiView.cpp:2611
-#: src/frontends/qt/GuiView.cpp:2747 src/frontends/qt/GuiView.cpp:2881
+#: src/frontends/qt/GuiView.cpp:2751 src/frontends/qt/GuiView.cpp:2885
msgid "&Examples"
msgstr "&Beispiele"
@@ -33440,7 +33439,7 @@ msgid "Select template file"
msgstr "Wählen Sie eine Vorlagendatei"
#: src/frontends/qt/GuiLyXFiles.cpp:369 src/frontends/qt/GuiView.cpp:2552
-#: src/frontends/qt/GuiView.cpp:3001
+#: src/frontends/qt/GuiView.cpp:3005
msgid "&Templates"
msgstr "&Vorlagen"
@@ -33567,7 +33566,7 @@ msgstr ""
"Normalerweise müssen Sie diese Breite nicht festlegen, da die maximale "
"Breite aller Punkte verwendet wird."
-#: src/frontends/qt/GuiParagraph.cpp:175 src/frontends/qt/GuiView.cpp:3279
+#: src/frontends/qt/GuiParagraph.cpp:175 src/frontends/qt/GuiView.cpp:3283
msgid "&Close"
msgstr "&SchlieÃen"
@@ -34479,7 +34478,15 @@ msgstr "Dokument nicht geladen."
msgid "Select document to open"
msgstr "Wählen Sie das zu öffnende Dokument"
-#: src/frontends/qt/GuiView.cpp:2639
+#: src/frontends/qt/GuiView.cpp:2615
+msgid "LyX Document Backups (*.lyx~)"
+msgstr "LyX-Dokument-Backups (*.lyx~)"
+
+#: src/frontends/qt/GuiView.cpp:2616
+msgid "All Files (*.*)"
+msgstr "Alle Dateien (*.*)"
+
+#: src/frontends/qt/GuiView.cpp:2643
#, c-format
msgid ""
"The directory in the given path\n"
@@ -34490,40 +34497,40 @@ msgstr ""
"%1$s\n"
"existiert nicht."
-#: src/frontends/qt/GuiView.cpp:2656
+#: src/frontends/qt/GuiView.cpp:2660
#, c-format
msgid "Opening document %1$s..."
msgstr "Ãffne Dokument %1$s..."
-#: src/frontends/qt/GuiView.cpp:2661
+#: src/frontends/qt/GuiView.cpp:2665
#, c-format
msgid "Document %1$s opened."
msgstr "Dokument %1$s ist geöffnet."
-#: src/frontends/qt/GuiView.cpp:2664
+#: src/frontends/qt/GuiView.cpp:2668
msgid "Version control detected."
msgstr "Versionskontrolle erkannt."
-#: src/frontends/qt/GuiView.cpp:2666
+#: src/frontends/qt/GuiView.cpp:2670
#, c-format
msgid "Could not open document %1$s"
msgstr "Das Dokument %1$s konnte nicht geöffnet werden"
-#: src/frontends/qt/GuiView.cpp:2694
+#: src/frontends/qt/GuiView.cpp:2698
msgid "Couldn't import file"
msgstr "Die Datei konnte nicht importiert werden"
-#: src/frontends/qt/GuiView.cpp:2695
+#: src/frontends/qt/GuiView.cpp:2699
#, c-format
msgid "No information for importing the format %1$s."
msgstr "Keine Informationen vorhanden, um das Format %1$s zu importieren."
-#: src/frontends/qt/GuiView.cpp:2742
+#: src/frontends/qt/GuiView.cpp:2746
#, c-format
msgid "Select %1$s file to import"
msgstr "Wählen Sie die einzufügende %1$s-Datei"
-#: src/frontends/qt/GuiView.cpp:2777
+#: src/frontends/qt/GuiView.cpp:2781
#, c-format
msgid ""
"The file name '%1$s' is invalid!\n"
@@ -34532,8 +34539,8 @@ msgstr ""
"Der Dateiname '%1$s' ist ungültig!\n"
"Import wird abgebrochen."
-#: src/frontends/qt/GuiView.cpp:2804 src/frontends/qt/GuiView.cpp:3071
-#: src/frontends/qt/GuiView.cpp:3174
+#: src/frontends/qt/GuiView.cpp:2808 src/frontends/qt/GuiView.cpp:3075
+#: src/frontends/qt/GuiView.cpp:3178
#, c-format
msgid ""
"The document %1$s already exists.\n"
@@ -34544,33 +34551,33 @@ msgstr ""
"\n"
"Möchten Sie dieses Dokument überschreiben?"
-#: src/frontends/qt/GuiView.cpp:2806 src/frontends/qt/GuiView.cpp:3075
-#: src/frontends/qt/GuiView.cpp:3178
+#: src/frontends/qt/GuiView.cpp:2810 src/frontends/qt/GuiView.cpp:3079
+#: src/frontends/qt/GuiView.cpp:3182
msgid "Overwrite document?"
msgstr "Dokument überschreiben?"
-#: src/frontends/qt/GuiView.cpp:2815
+#: src/frontends/qt/GuiView.cpp:2819
#, c-format
msgid "Importing %1$s..."
msgstr "Importiere %1$s..."
-#: src/frontends/qt/GuiView.cpp:2818
+#: src/frontends/qt/GuiView.cpp:2822
msgid "imported."
msgstr "wurde eingefügt."
-#: src/frontends/qt/GuiView.cpp:2820
+#: src/frontends/qt/GuiView.cpp:2824
msgid "file not imported!"
msgstr "Datei wurde nicht importiert!"
-#: src/frontends/qt/GuiView.cpp:2846
+#: src/frontends/qt/GuiView.cpp:2850
msgid "newfile"
msgstr "Neues_Dokument"
-#: src/frontends/qt/GuiView.cpp:2879
+#: src/frontends/qt/GuiView.cpp:2883
msgid "Select LyX document to insert"
msgstr "Wählen Sie das einzufügende LyX-Dokument"
-#: src/frontends/qt/GuiView.cpp:2926
+#: src/frontends/qt/GuiView.cpp:2930
#, c-format
msgid ""
"It is suggested to save the template in a subdirectory\n"
@@ -34583,23 +34590,23 @@ msgstr ""
"Dieser Unterordner existiert aber noch nicht.\n"
"Soll er angelegt werden?"
-#: src/frontends/qt/GuiView.cpp:2931
+#: src/frontends/qt/GuiView.cpp:2935
msgid "Create Language Directory?"
msgstr "Sprach-Unterorder erstellen?"
-#: src/frontends/qt/GuiView.cpp:2932 src/frontends/qt/GuiView.cpp:2963
+#: src/frontends/qt/GuiView.cpp:2936 src/frontends/qt/GuiView.cpp:2967
msgid "&Yes, Create"
msgstr "&Ja, erstellen"
-#: src/frontends/qt/GuiView.cpp:2932 src/frontends/qt/GuiView.cpp:2963
+#: src/frontends/qt/GuiView.cpp:2936 src/frontends/qt/GuiView.cpp:2967
msgid "&No, Save Template in Parent Directory"
msgstr "&Nein, speichere Vorlage im Hauptordner"
-#: src/frontends/qt/GuiView.cpp:2935 src/frontends/qt/GuiView.cpp:2966
+#: src/frontends/qt/GuiView.cpp:2939 src/frontends/qt/GuiView.cpp:2970
msgid "Subdirectory creation failed!"
msgstr "Erstellung des Unterordners fehlgeschlagen!"
-#: src/frontends/qt/GuiView.cpp:2936 src/frontends/qt/GuiView.cpp:2967
+#: src/frontends/qt/GuiView.cpp:2940 src/frontends/qt/GuiView.cpp:2971
msgid ""
"Could not create subdirectory.\n"
"The template will be saved in the parent directory."
@@ -34607,7 +34614,7 @@ msgstr ""
"Der Unterordner konnte leider nicht erstellt werden\n"
"Die Vorlage wird im Hauptordner gespeichert."
-#: src/frontends/qt/GuiView.cpp:2957
+#: src/frontends/qt/GuiView.cpp:2961
#, c-format
msgid ""
"It is suggested to save the template in a subdirectory\n"
@@ -34620,19 +34627,19 @@ msgstr ""
"Dieser Unterordner existiert aber noch nicht.\n"
"Soll er angelegt werden?"
-#: src/frontends/qt/GuiView.cpp:2962
+#: src/frontends/qt/GuiView.cpp:2966
msgid "Create Category Directory?"
msgstr "Kategorien-Ordner erstellen?"
-#: src/frontends/qt/GuiView.cpp:2997
+#: src/frontends/qt/GuiView.cpp:3001
msgid "Choose a filename to save template as"
msgstr "Wählen Sie einen Dateinamen für die Vorlage"
-#: src/frontends/qt/GuiView.cpp:2998
+#: src/frontends/qt/GuiView.cpp:3002
msgid "Choose a filename to save document as"
msgstr "Wählen Sie einen Dateinamen für das Dokument"
-#: src/frontends/qt/GuiView.cpp:3034
+#: src/frontends/qt/GuiView.cpp:3038
#, c-format
msgid ""
"The file\n"
@@ -34647,17 +34654,17 @@ msgstr ""
"Bitte schlieÃen Sie sie, wenn Sie sie überschreiben möchten.\n"
"Möchten Sie statt dessen einen neuen Dateinamen wählen?"
-#: src/frontends/qt/GuiView.cpp:3038
+#: src/frontends/qt/GuiView.cpp:3042
msgid "Chosen File Already Open"
msgstr "Ausgewählte Datei bereits geöffnet"
-#: src/frontends/qt/GuiView.cpp:3039 src/frontends/qt/GuiView.cpp:3061
-#: src/frontends/qt/GuiView.cpp:3077 src/frontends/qt/GuiView.cpp:3179
-#: src/frontends/qt/GuiView.cpp:3224
+#: src/frontends/qt/GuiView.cpp:3043 src/frontends/qt/GuiView.cpp:3065
+#: src/frontends/qt/GuiView.cpp:3081 src/frontends/qt/GuiView.cpp:3183
+#: src/frontends/qt/GuiView.cpp:3228
msgid "&Rename"
msgstr "&Umbenennen"
-#: src/frontends/qt/GuiView.cpp:3054
+#: src/frontends/qt/GuiView.cpp:3058
#, c-format
msgid ""
"The document %1$s is already registered.\n"
@@ -34668,27 +34675,27 @@ msgstr ""
"\n"
"Möchten Sie einen anderen Namen wählen?"
-#: src/frontends/qt/GuiView.cpp:3059
+#: src/frontends/qt/GuiView.cpp:3063
msgid "Rename document?"
msgstr "Dokument umbenennen?"
-#: src/frontends/qt/GuiView.cpp:3059
+#: src/frontends/qt/GuiView.cpp:3063
msgid "Copy document?"
msgstr "Dokument kopieren?"
-#: src/frontends/qt/GuiView.cpp:3061
+#: src/frontends/qt/GuiView.cpp:3065
msgid "&Copy"
msgstr "&Kopieren"
-#: src/frontends/qt/GuiView.cpp:3121
+#: src/frontends/qt/GuiView.cpp:3125
msgid "Choose a filename to export the document as"
msgstr "Wählen Sie einen Dateinamen für das exportierte Dokument"
-#: src/frontends/qt/GuiView.cpp:3125
+#: src/frontends/qt/GuiView.cpp:3129
msgid "Guess from extension (*.*)"
msgstr "Von der Dateierweiterung ableiten (*.*)"
-#: src/frontends/qt/GuiView.cpp:3220
+#: src/frontends/qt/GuiView.cpp:3224
#, c-format
msgid ""
"The document %1$s could not be saved.\n"
@@ -34699,15 +34706,15 @@ msgstr ""
"\n"
"Möchten Sie das Dokument umbenennen und erneut versuchen?"
-#: src/frontends/qt/GuiView.cpp:3223
+#: src/frontends/qt/GuiView.cpp:3227
msgid "Rename and save?"
msgstr "Umbenennen und speichern?"
-#: src/frontends/qt/GuiView.cpp:3224
+#: src/frontends/qt/GuiView.cpp:3228
msgid "&Retry"
msgstr "&Wiederholen"
-#: src/frontends/qt/GuiView.cpp:3269
+#: src/frontends/qt/GuiView.cpp:3273
#, c-format
msgid ""
"Last view on document %1$s is being closed.\n"
@@ -34729,25 +34736,25 @@ msgstr ""
"die Voreinstellung in Werkzeuge > Einstellungen ... >\n"
"Aussehen & Handhabung > Benutzeroberfläche.\n"
-#: src/frontends/qt/GuiView.cpp:3278
+#: src/frontends/qt/GuiView.cpp:3282
msgid "Close or hide document?"
msgstr "Dokument schlieÃen oder verbergen?"
-#: src/frontends/qt/GuiView.cpp:3279
+#: src/frontends/qt/GuiView.cpp:3283
msgid "&Hide"
msgstr "&Verbergen"
-#: src/frontends/qt/GuiView.cpp:3376
+#: src/frontends/qt/GuiView.cpp:3380
msgid "Close document"
msgstr "Dokument schlieÃen"
-#: src/frontends/qt/GuiView.cpp:3377
+#: src/frontends/qt/GuiView.cpp:3381
msgid "Document could not be closed because it is being processed by LyX."
msgstr ""
"Dokument konnte nicht geschlossen werden, da es gerade von LyX verarbeitet "
"wird."
-#: src/frontends/qt/GuiView.cpp:3509 src/frontends/qt/GuiView.cpp:3624
+#: src/frontends/qt/GuiView.cpp:3513 src/frontends/qt/GuiView.cpp:3628
#, c-format
msgid ""
"The document %1$s has not been saved yet.\n"
@@ -34758,16 +34765,16 @@ msgstr ""
"\n"
"Möchten Sie das Dokument speichern?"
-#: src/frontends/qt/GuiView.cpp:3512 src/frontends/qt/GuiView.cpp:3627
+#: src/frontends/qt/GuiView.cpp:3516 src/frontends/qt/GuiView.cpp:3631
msgid "Save new document?"
msgstr "Neues Dokument speichern?"
-#: src/frontends/qt/GuiView.cpp:3513 src/frontends/qt/GuiView.cpp:3527
-#: src/frontends/qt/GuiView.cpp:3629
+#: src/frontends/qt/GuiView.cpp:3517 src/frontends/qt/GuiView.cpp:3531
+#: src/frontends/qt/GuiView.cpp:3633
msgid "&Save"
msgstr "&Speichern"
-#: src/frontends/qt/GuiView.cpp:3518
+#: src/frontends/qt/GuiView.cpp:3522
#, c-format
msgid ""
"The document %1$s has unsaved changes.\n"
@@ -34778,7 +34785,7 @@ msgstr ""
"sind nicht gespeichert.\n"
"Möchten Sie das Dokument speichern oder die Ãnderungen verwerfen?"
-#: src/frontends/qt/GuiView.cpp:3521
+#: src/frontends/qt/GuiView.cpp:3525
#, c-format
msgid ""
"The document %1$s has not been saved yet.\n"
@@ -34789,19 +34796,19 @@ msgstr ""
"\n"
"Möchten Sie das Dokument speichern oder es endgültig verwerfen?"
-#: src/frontends/qt/GuiView.cpp:3525 src/frontends/qt/GuiView.cpp:3621
+#: src/frontends/qt/GuiView.cpp:3529 src/frontends/qt/GuiView.cpp:3625
msgid "Save changed document?"
msgstr "Geändertes Dokument speichern?"
-#: src/frontends/qt/GuiView.cpp:3525
+#: src/frontends/qt/GuiView.cpp:3529
msgid "Save document?"
msgstr "Dokument speichern?"
-#: src/frontends/qt/GuiView.cpp:3527
+#: src/frontends/qt/GuiView.cpp:3531
msgid "&Discard"
msgstr "&Verwerfen"
-#: src/frontends/qt/GuiView.cpp:3618
+#: src/frontends/qt/GuiView.cpp:3622
#, c-format
msgid ""
"The document %1$s has unsaved changes.\n"
@@ -34812,7 +34819,7 @@ msgstr ""
"\n"
"Möchten Sie das Dokument speichern?"
-#: src/frontends/qt/GuiView.cpp:3650
+#: src/frontends/qt/GuiView.cpp:3654
#, c-format
msgid ""
"Document \n"
@@ -34824,37 +34831,37 @@ msgstr ""
"wurde extern verändert. Wollen Sie es erneut laden?\n"
"Alle lokalen Veränderungen werden dann verworfen."
-#: src/frontends/qt/GuiView.cpp:3653
+#: src/frontends/qt/GuiView.cpp:3657
msgid "Reload externally changed document?"
msgstr "Extern geändertes Dokument neu laden?"
-#: src/frontends/qt/GuiView.cpp:3698
+#: src/frontends/qt/GuiView.cpp:3702
msgid "Document could not be checked in."
msgstr "Das Dokument konnte nicht eingecheckt werden."
-#: src/frontends/qt/GuiView.cpp:3741
+#: src/frontends/qt/GuiView.cpp:3745
msgid "Error when setting the locking property."
msgstr "Fehler beim Setzen der Dateisperrung."
-#: src/frontends/qt/GuiView.cpp:3790
+#: src/frontends/qt/GuiView.cpp:3794
msgid "Directory is not accessible."
msgstr "Das Verzeichnis ist nicht lesbar."
-#: src/frontends/qt/GuiView.cpp:3867
+#: src/frontends/qt/GuiView.cpp:3871
#, c-format
msgid "Opening child document %1$s..."
msgstr "Ãffne Unterdokument %1$s..."
-#: src/frontends/qt/GuiView.cpp:3925
+#: src/frontends/qt/GuiView.cpp:3929
#, c-format
msgid "No buffer for file: %1$s."
msgstr "Kein Pufferspeicher für Datei: %1$s."
-#: src/frontends/qt/GuiView.cpp:3935
+#: src/frontends/qt/GuiView.cpp:3939
msgid "Inverse Search Failed"
msgstr "Rückwärtssuche gescheitert"
-#: src/frontends/qt/GuiView.cpp:3936
+#: src/frontends/qt/GuiView.cpp:3940
msgid ""
"Invalid position requested by inverse search.\n"
"You may need to update the viewed document."
@@ -34862,35 +34869,35 @@ msgstr ""
"Die Rückwärtssuche wollte eine ungültige Position anspringen.\n"
"Bitte aktualisieren Sie das ausgegebene Dokument."
-#: src/frontends/qt/GuiView.cpp:4016
+#: src/frontends/qt/GuiView.cpp:4020
msgid "Export Error"
msgstr "Exportfehler"
-#: src/frontends/qt/GuiView.cpp:4017
+#: src/frontends/qt/GuiView.cpp:4021
msgid "Error cloning the Buffer."
msgstr "Fehler beim Klonen des Pufferspeichers."
-#: src/frontends/qt/GuiView.cpp:4168 src/frontends/qt/GuiView.cpp:4188
+#: src/frontends/qt/GuiView.cpp:4172 src/frontends/qt/GuiView.cpp:4192
msgid "Exporting ..."
msgstr "Exportiere ..."
-#: src/frontends/qt/GuiView.cpp:4197
+#: src/frontends/qt/GuiView.cpp:4201
msgid "Previewing ..."
msgstr "Generiere Vorschau ..."
-#: src/frontends/qt/GuiView.cpp:4235
+#: src/frontends/qt/GuiView.cpp:4239
msgid "Document not loaded"
msgstr "Dokument nicht geladen"
-#: src/frontends/qt/GuiView.cpp:4322
+#: src/frontends/qt/GuiView.cpp:4326
msgid "Select file to insert"
msgstr "Wählen Sie das einzufügende Dokument"
-#: src/frontends/qt/GuiView.cpp:4325
+#: src/frontends/qt/GuiView.cpp:4329
msgid "All Files (*)"
msgstr "Alle Dateien (*)"
-#: src/frontends/qt/GuiView.cpp:4353
+#: src/frontends/qt/GuiView.cpp:4357
#, c-format
msgid ""
"The current version will be lost. Are you sure you want to load the version "
@@ -34900,7 +34907,7 @@ msgstr ""
"dass Sie die auf der Festplatte gespeicherte Version des Dokuments %1$s "
"laden möchten?"
-#: src/frontends/qt/GuiView.cpp:4360
+#: src/frontends/qt/GuiView.cpp:4364
#, c-format
msgid ""
"Any changes will be lost. Are you sure you want to revert to the saved "
@@ -34909,61 +34916,61 @@ msgstr ""
"Alle Ãnderungen gehen verloren. Sind Sie sicher, dass Sie zur gespeicherten "
"Version des Dokuments %1$s zurückkehren möchten?"
-#: src/frontends/qt/GuiView.cpp:4363
+#: src/frontends/qt/GuiView.cpp:4367
msgid "Revert to saved document?"
msgstr "Gespeichertes Dokument neu laden?"
-#: src/frontends/qt/GuiView.cpp:4380
+#: src/frontends/qt/GuiView.cpp:4384
msgid "Buffer export reset."
msgstr "Export zurückgesetzt."
-#: src/frontends/qt/GuiView.cpp:4403
+#: src/frontends/qt/GuiView.cpp:4407
msgid "Saving all documents..."
msgstr "Speichere alle Dokumente..."
-#: src/frontends/qt/GuiView.cpp:4413
+#: src/frontends/qt/GuiView.cpp:4417
msgid "All documents saved."
msgstr "Alle Dokumente wurden gespeichert."
-#: src/frontends/qt/GuiView.cpp:4452
+#: src/frontends/qt/GuiView.cpp:4456
msgid "Developer mode is now enabled."
msgstr "Der Entwicklermodus ist nun aktiviert."
-#: src/frontends/qt/GuiView.cpp:4454
+#: src/frontends/qt/GuiView.cpp:4458
msgid "Developer mode is now disabled."
msgstr "Der Entwicklermodus ist nun deaktiviert."
-#: src/frontends/qt/GuiView.cpp:4486
+#: src/frontends/qt/GuiView.cpp:4490
msgid "Toolbars unlocked."
msgstr "Werkzeugleisten nicht verankert."
-#: src/frontends/qt/GuiView.cpp:4488
+#: src/frontends/qt/GuiView.cpp:4492
msgid "Toolbars locked."
msgstr "Werkzeugleisten verankert."
-#: src/frontends/qt/GuiView.cpp:4501
+#: src/frontends/qt/GuiView.cpp:4505
#, c-format
msgid "Icon size set to %1$dx%2$d."
msgstr "Eingestellte SymbolgröÃe: %1$dx%2$d."
-#: src/frontends/qt/GuiView.cpp:4590
+#: src/frontends/qt/GuiView.cpp:4594
#, c-format
msgid "%1$s unknown command!"
msgstr "LFUN_UI_TOGGLE %1$s unbekannter Befehl!"
-#: src/frontends/qt/GuiView.cpp:4694
+#: src/frontends/qt/GuiView.cpp:4698
msgid "Zoom level is now %1$d% (default value: %2$d%)"
msgstr "Aktueller Skalierungsfaktor: %1$d% (Standardwert: %2$d%)"
-#: src/frontends/qt/GuiView.cpp:4753
+#: src/frontends/qt/GuiView.cpp:4757
msgid "Please, preview the document first."
msgstr "Bitte geben Sie das Dokument zunächst aus."
-#: src/frontends/qt/GuiView.cpp:4769
+#: src/frontends/qt/GuiView.cpp:4773
msgid "Couldn't proceed."
msgstr "Konnte nicht fortfahren."
-#: src/frontends/qt/GuiView.cpp:5124
+#: src/frontends/qt/GuiView.cpp:5128
msgid "Disable Shell Escape"
msgstr "Erlaubnis zum Aufruf externer Programme widerrufen"
@@ -36854,11 +36861,11 @@ msgstr "Geschützter horizontaler Abstand (%1$s)"
msgid "Unknown TOC type"
msgstr "Unbekannter Inhaltsverzeichnis-Typ"
-#: src/insets/InsetTabular.cpp:463
+#: src/insets/InsetTabular.cpp:464
msgid "Change tracking data incomplete"
msgstr "Unvollständige Daten für Ãnderungsmarkierung"
-#: src/insets/InsetTabular.cpp:464
+#: src/insets/InsetTabular.cpp:465
msgid ""
"Change tracking information for tabular row/column is incomplete. I will "
"ignore this."
@@ -36866,15 +36873,15 @@ msgstr ""
"Die Informationen für die Ãnderungen von Tabellenzeilen- oder -spalten sind "
"unvollständig. Sie werden ignoriert."
-#: src/insets/InsetTabular.cpp:5600
+#: src/insets/InsetTabular.cpp:5602
msgid "Column movement not supported with multi-columns."
msgstr "Verschieben von Spalten mit Mehrfachspalten leider nicht möglich."
-#: src/insets/InsetTabular.cpp:5618
+#: src/insets/InsetTabular.cpp:5620
msgid "Row movement not supported with multi-rows."
msgstr "Verschieben von Zeilen mit Mehrfachzeilen leider nicht möglich."
-#: src/insets/InsetTabular.cpp:6120
+#: src/insets/InsetTabular.cpp:6122
msgid "Selection size should match clipboard content."
msgstr ""
"Die Anzahl der ausgewählten Zellen stimmt nicht mit dem Inhalt der "
@@ -36980,7 +36987,7 @@ msgstr ""
"Der gesuchte Ausdruck wurde innerhalb der Auswahl nicht gefunden.\n"
"AuÃerhalb weitersuchen?"
-#: src/lyxfind.cpp:344 src/lyxfind.cpp:684
+#: src/lyxfind.cpp:345 src/lyxfind.cpp:691
msgid ""
"End of file reached while searching forward.\n"
"Continue searching from the beginning?"
@@ -36988,7 +36995,7 @@ msgstr ""
"Das Ende des Dokuments wurde bei der Vorwärtssuche erreicht.\n"
"Suche am Anfang fortsetzen?"
-#: src/lyxfind.cpp:347 src/lyxfind.cpp:712
+#: src/lyxfind.cpp:348 src/lyxfind.cpp:719
msgid ""
"Beginning of file reached while searching backward.\n"
"Continue searching from the end?"
@@ -36996,58 +37003,66 @@ msgstr ""
"Der Anfang des Dokuments wurde bei der Rückwärtssuche erreicht.\n"
"Suche am Ende fortsetzen?"
-#: src/lyxfind.cpp:657
+#: src/lyxfind.cpp:364
+msgid "Search reached end of document, continuing from beginning."
+msgstr "Das Ende des Dokuments wurde erreicht, suche vom Anfang ab weiter."
+
+#: src/lyxfind.cpp:365
+msgid "Search reached beginning of document, continuing from end."
+msgstr "Der Anfang des Dokuments wurde erreicht, suche vom Ende ab weiter."
+
+#: src/lyxfind.cpp:664
msgid "String not found in selection."
msgstr "Der gesuchte Ausdruck wurde in der Auswahl nicht gefunden."
-#: src/lyxfind.cpp:659
+#: src/lyxfind.cpp:666
msgid "String not found."
msgstr "Die Zeichenkette wurde nicht gefunden."
-#: src/lyxfind.cpp:662
+#: src/lyxfind.cpp:669
msgid "String found."
msgstr "Zeichenkette gefunden."
-#: src/lyxfind.cpp:664
+#: src/lyxfind.cpp:671
msgid "String has been replaced."
msgstr "Die Zeichenkette wurde ersetzt."
-#: src/lyxfind.cpp:667
+#: src/lyxfind.cpp:674
#, c-format
msgid "%1$d strings have been replaced in the selection."
msgstr "%1$d Zeichenketten wurden in der Auswahl ersetzt."
-#: src/lyxfind.cpp:668
+#: src/lyxfind.cpp:675
#, c-format
msgid "%1$d strings have been replaced."
msgstr "%1$d Zeichenketten wurden ersetzt."
-#: src/lyxfind.cpp:4388
+#: src/lyxfind.cpp:4483
msgid "One match has been replaced."
msgstr "Ein Treffer wurde ersetzt."
-#: src/lyxfind.cpp:4391
+#: src/lyxfind.cpp:4486
msgid "Two matches have been replaced."
msgstr "Zwei Treffer wurden ersetzt."
-#: src/lyxfind.cpp:4394
+#: src/lyxfind.cpp:4489
#, c-format
msgid "%1$d matches have been replaced."
msgstr "%1$d Treffer wurden ersetzt."
-#: src/lyxfind.cpp:4400
+#: src/lyxfind.cpp:4495
msgid "Match not found."
msgstr "Die Zeichenkette wurde nicht gefunden!"
-#: src/lyxfind.cpp:4406
+#: src/lyxfind.cpp:4501
msgid "Match has been replaced."
msgstr "Die Zeichenkette wurde ersetzt."
-#: src/lyxfind.cpp:4408
+#: src/lyxfind.cpp:4503
msgid "Match found."
msgstr "Die Zeichenkette wurde gefunden!"
-#: src/mathed/InsetMathAMSArray.cpp:135 src/mathed/InsetMathHull.cpp:2153
+#: src/mathed/InsetMathAMSArray.cpp:135 src/mathed/InsetMathHull.cpp:2163
#: src/mathed/InsetMathSplit.cpp:127 src/mathed/InsetMathSubstack.cpp:70
#, c-format
msgid "Can't add vertical grid lines in '%1$s'"
@@ -37110,16 +37125,16 @@ msgstr "Keine vertikale Linie zu löschen"
msgid "Unknown tabular feature '%1$s'"
msgstr "Unbekanntes Tabellenmerkmal '%1$s'"
-#: src/mathed/InsetMathHull.cpp:1716
+#: src/mathed/InsetMathHull.cpp:1726
#, c-format
msgid "Type: %1$s"
msgstr "Typ: %1$s"
-#: src/mathed/InsetMathHull.cpp:1752
+#: src/mathed/InsetMathHull.cpp:1762
msgid "Bad math environment"
msgstr "Ungeeignete Matheumgebung"
-#: src/mathed/InsetMathHull.cpp:1753
+#: src/mathed/InsetMathHull.cpp:1763
msgid ""
"Computation cannot be performed for AMS math environments.\n"
"Change the math formula type and try again."
@@ -37127,16 +37142,16 @@ msgstr ""
"In AMS-Matheumgebungen kann keine Berechnung durchgeführt werden.\n"
"Bitte ändern Sie die Formelart und versuchen Sie es noch einmal."
-#: src/mathed/InsetMathHull.cpp:1856 src/mathed/InsetMathHull.cpp:1865
+#: src/mathed/InsetMathHull.cpp:1866 src/mathed/InsetMathHull.cpp:1875
msgid "No number"
msgstr "Keine Nummer"
-#: src/mathed/InsetMathHull.cpp:2136
+#: src/mathed/InsetMathHull.cpp:2146
#, c-format
msgid "Can't change number of rows in '%1$s'"
msgstr "Die Anzahl der Zeilen in '%1$s' kann nicht geändert werden."
-#: src/mathed/InsetMathHull.cpp:2146
+#: src/mathed/InsetMathHull.cpp:2156
#, c-format
msgid "Can't change number of columns in '%1$s'"
msgstr "Die Anzahl der Spalten in '%1$s' kann nicht geändert werden."
@@ -37332,7 +37347,7 @@ msgstr ""
msgid "Directory not found"
msgstr "Verzeichnis nicht gefunden"
-#: src/support/Systemcall.cpp:433
+#: src/support/Systemcall.cpp:441
#, c-format
msgid ""
"The command\n"
@@ -37347,15 +37362,15 @@ msgstr ""
"\n"
"Möchten Sie ihn beenden?"
-#: src/support/Systemcall.cpp:435
+#: src/support/Systemcall.cpp:443
msgid "Stop command?"
msgstr "Befehl stoppen?"
-#: src/support/Systemcall.cpp:436
+#: src/support/Systemcall.cpp:444
msgid "&Stop it"
msgstr "&Beenden"
-#: src/support/Systemcall.cpp:436
+#: src/support/Systemcall.cpp:444
msgid "Let it &run"
msgstr "&Fortfahren"
commit 489549c9b4152381ff338fcc23976555bd40570f
Author: Juergen Spitzmueller <spitz at lyx.org>
Date: Sat Aug 21 15:19:30 2021 +0200
Fix debug output
diff --git a/src/frontends/qt/GuiSpellchecker.cpp b/src/frontends/qt/GuiSpellchecker.cpp
index 7e4c3d7..8adf132 100644
--- a/src/frontends/qt/GuiSpellchecker.cpp
+++ b/src/frontends/qt/GuiSpellchecker.cpp
@@ -433,7 +433,7 @@ void SpellcheckerWidget::on_skipAllPB_clicked()
/// ignore all occurrences of word
if (d->disabled())
return;
- LYXERR(Debug::GUI, "Spellchecker: ignore all button");
+ LYXERR(Debug::GUI, "Spellchecker: skip all button");
if (d->word_.lang() && !d->word_.word().empty())
theSpellChecker()->accept(d->word_);
d->forward();
commit e8bf83e42bba5d6c8b1fb2c686deb68e2e2584f2
Author: Juergen Spitzmueller <spitz at lyx.org>
Date: Sat Aug 21 15:19:07 2021 +0200
Correct tooltip
as advised by Scott
diff --git a/src/frontends/qt/ui/SpellcheckerUi.ui b/src/frontends/qt/ui/SpellcheckerUi.ui
index 953b3f0..3bc0346 100644
--- a/src/frontends/qt/ui/SpellcheckerUi.ui
+++ b/src/frontends/qt/ui/SpellcheckerUi.ui
@@ -172,7 +172,7 @@
<item row="8" column="1">
<widget class="QPushButton" name="ignoreAllPB">
<property name="toolTip">
- <string>Ignore all occurrences of this word within this document. This is perdurant beyond the current session.</string>
+ <string>Ignore all occurrences of this word within this document. This persists beyond the current session.</string>
</property>
<property name="text">
<string>I&gnore All</string>
commit 3f2510991d230224161309d0198bf0d905cdad75
Author: Juergen Spitzmueller <spitz at lyx.org>
Date: Sat Aug 21 15:18:30 2021 +0200
Recheck whole buffer after word has been added to/removed from document dic.
diff --git a/src/Text3.cpp b/src/Text3.cpp
index fcccdd3..b1bf879 100644
--- a/src/Text3.cpp
+++ b/src/Text3.cpp
@@ -2755,13 +2755,12 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
cur.recordUndoBufferParams();
bv->buffer().params().spellignore().push_back(wl);
cur.recordUndo();
- // trigger re-check
- WordLangTuple wl;
- docstring_list suggestions;
- Paragraph const & par = cur.paragraph();
- pos_type from = cur.pos();
- pos_type to = from;
- par.spellCheck(from, to, wl, suggestions, true, true);
+ // trigger re-check of whole buffer
+ ParagraphList & pars = bv->buffer().paragraphs();
+ ParagraphList::iterator pit = pars.begin();
+ ParagraphList::iterator pend = pars.end();
+ for (; pit != pend; ++pit)
+ pit->requestSpellCheck();
}
break;
}
@@ -2794,13 +2793,12 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
cur.recordUndoBufferParams();
bv->buffer().params().spellignore().erase(it);
cur.recordUndo();
- // trigger re-check
- WordLangTuple wl;
- docstring_list suggestions;
- Paragraph const & par = cur.paragraph();
- pos_type from = cur.pos();
- pos_type to = from;
- par.spellCheck(from, to, wl, suggestions, true, true);
+ // trigger re-check of whole buffer
+ ParagraphList & pars = bv->buffer().paragraphs();
+ ParagraphList::iterator pit = pars.begin();
+ ParagraphList::iterator pend = pars.end();
+ for (; pit != pend; ++pit)
+ pit->requestSpellCheck();
}
break;
}
commit 5a9c6ce69b8368351db10121f0a20ccfa8585150
Author: Pavel Sanda <sanda at lyx.org>
Date: Mon Aug 2 15:25:36 2021 +0200
xhtml Toc rendering seems bit too dense now.
diff --git a/lib/layouts/stdinsets.inc b/lib/layouts/stdinsets.inc
index 2331d48..2b562c2 100644
--- a/lib/layouts/stdinsets.inc
+++ b/lib/layouts/stdinsets.inc
@@ -267,11 +267,11 @@ InsetLayout TOC
font-weight: bold;
}
div.lyxtoc-2 {
- margin: 0em 0.1em 0em 1em;
+ margin: 0.5em 0.1em 0em 1em;
font-size: large;
font-weight: normal;
}
- div.lyxtoc-3 { margin: 0em 0.1em 0em 0.5em; font-size: medium; }
+ div.lyxtoc-3 { margin: 0.2em 0.1em 0em 0.5em; font-size: medium; }
div.lyxtoc-4 { margin: 0em 0.1em 0em 0.5em; }
div.lyxtoc-5 { margin: 0em 0.1em 0em 0.5em; }
div.lyxtoc-6 { margin: 0em 0.1em 0em 0.5em; }
commit 6d3a2218636010672ab6723956966162d5dbc541
Author: Kornel Benko <kornel at lyx.org>
Date: Thu Jul 22 17:04:25 2021 +0200
Update sk.po
diff --git a/po/sk.po b/po/sk.po
index 284b663..c268d68 100644
--- a/po/sk.po
+++ b/po/sk.po
@@ -8,8 +8,8 @@ msgid ""
msgstr ""
"Project-Id-Version: LyX-2.4\n"
"Report-Msgid-Bugs-To: lyx-devel at lists.lyx.org\n"
-"POT-Creation-Date: 2021-05-23 09:44+0200\n"
-"PO-Revision-Date: 2021-05-23 08:19+0000\n"
+"POT-Creation-Date: 2021-07-22 16:55+0200\n"
+"PO-Revision-Date: 2021-07-22 15:02+0000\n"
"Last-Translator: Kornel Benko <kornel at lyx.org>\n"
"Language-Team: Slovak <kornel at lyx.org>\n"
"Language: sk\n"
@@ -16903,11 +16903,10 @@ msgstr "Pod-rovnice"
#: lib/layouts/subequations.module:6
msgid ""
-"Provide a straightforward way to segregate subequations in LyX. See the "
-"subequations.lyx example file."
+"Provide a straightforward way to segregate subequations in LyX. See the Math "
+"manual."
msgstr ""
-"UmožniÅ¥ priamy spôsob na oddelenie pod-rovnÃc v LyXe. ViÄte prÃkladný súbor "
-"subequations.lyx."
+"UmožniÅ¥ priamy spôsob na oddelenie pod-rovnÃc v LyXe. ViÄte manuál Math."
#: lib/layouts/svcommon.inc:72
msgid "Front Matter"
@@ -36543,6 +36542,14 @@ msgstr ""
"DoÅ¡lo k zaÄiatku súboru hľadajúc spätne.\n"
"PokraÄovaÅ¥ hľadanÃm od konca?"
+#: src/lyxfind.cpp:364
+msgid "Search reached end of document, continuing from beginning."
+msgstr "Hľadanie doÅ¡lo na koniec dokumentu, pokraÄuje od zaÄiatku."
+
+#: src/lyxfind.cpp:365
+msgid "Search reached beginning of document, continuing from end."
+msgstr "Hľadanie doÅ¡lo na zaÄiatok dokumentu, pokraÄuje od konca."
+
#: src/lyxfind.cpp:657
msgid "String not found in selection."
msgstr "Reťazec vo výbere nenájdený."
commit 20cee1593752df09b6c1d47794eb9971404fa448
Author: Pavel Sanda <sanda at lyx.org>
Date: Thu Jul 22 14:30:08 2021 +0200
Give the user visible feedback when reconfiguring.
diff --git a/src/frontends/qt/GuiApplication.cpp b/src/frontends/qt/GuiApplication.cpp
index 1f03997..01a646d 100644
--- a/src/frontends/qt/GuiApplication.cpp
+++ b/src/frontends/qt/GuiApplication.cpp
@@ -1652,8 +1652,10 @@ void GuiApplication::gotoBookmark(unsigned int idx, bool openFile,
void GuiApplication::reconfigure(string const & option)
{
// emit message signal.
- if (current_view_)
+ if (current_view_) {
current_view_->message(_("Running configure..."));
+ current_view_->setCursor(Qt::WaitCursor);
+ }
// Run configure in user lyx directory
string const lock_file = package().getConfigureLockName();
@@ -1667,6 +1669,9 @@ void GuiApplication::reconfigure(string const & option)
LaTeXPackages::getAvailable();
fileUnlock(fd, lock_file.c_str());
+ if (current_view_)
+ current_view_->unsetCursor();
+
if (ret)
Alert::information(_("System reconfiguration failed"),
_("The system reconfiguration has failed.\n"
commit b0a74fa41075a35f26106050140aa637d5b41d1d
Author: Jean-Marc Lasgouttes <lasgouttes at lyx.org>
Date: Wed Jul 21 11:24:45 2021 +0200
Count the width of pilcrows indicating changed end-of-par
This is related to #10357. The case of real end-of-par markers is
taken into account, but not "change" markers, which have been
introduced in 2.4.
diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp
index b0d1ff0..57c7715 100644
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@ -493,8 +493,9 @@ bool TextMetrics::redoParagraph(pit_type const pit, bool const align_rows)
// substracted to the available width. The logic here is
// almost the same as in breakRow, remember keep them in sync.
int eop = 0;
- if (lyxrc.paragraph_markers && e.pos + 1 == par.size()
- && size_type(pit + 1) < text_->paragraphs().size()) {
+ if (e.pos + 1 == par.size()
+ && (lyxrc.paragraph_markers || par.lookupChange(par.size()).changed())
+ && size_type(pit + 1) < text_->paragraphs().size()) {
Font f(text_->layoutFont(pit));
// ¶ U+00B6 PILCROW SIGN
eop = theFontMetrics(f).width(char_type(0x00B6));
-----------------------------------------------------------------------
Summary of changes:
CMakeLists.txt | 25 +-
.../export/docbook/LilyPond_Book.lyx | 89 +-
...32_charstyles-docbook.xml => LilyPond_Book.xml} | 12 +-
lib/configure.py | 56 +-
lib/examples/Modules/LilyPond_Book.lyx | 10 +-
lib/layouts/lilypond.module | 6 +
lib/layouts/stdinsets.inc | 4 +-
lib/scripts/layout2layout.py | 7 +-
po/de.gmo | Bin 620058 -> 620448 bytes
po/de.po | 973 ++++++++++----------
po/sk.po | 21 +-
src/Floating.cpp | 100 ++-
src/Floating.h | 11 +-
src/Text3.cpp | 26 +-
src/TextClass.cpp | 24 +-
src/TextMetrics.cpp | 5 +-
src/frontends/qt/GuiApplication.cpp | 7 +-
src/frontends/qt/GuiFontMetrics.cpp | 36 +-
src/frontends/qt/GuiFontMetrics.h | 30 +-
src/frontends/qt/GuiKeySymbol.cpp | 3 +-
src/frontends/qt/GuiSpellchecker.cpp | 2 +-
src/frontends/qt/ui/SpellcheckerUi.ui | 2 +-
src/insets/InsetLayout.cpp | 23 +
src/insets/InsetLayout.h | 12 +
src/insets/InsetText.cpp | 6 +
src/mathed/InsetMathNest.cpp | 2 +-
src/output_docbook.cpp | 2 +-
src/support/Cache.h | 2 +
src/tests/dummy_functions.cpp | 1 +
src/tex2lyx/dummy_impl.cpp | 2 +
src/xml.cpp | 2 +-
31 files changed, 850 insertions(+), 651 deletions(-)
copy development/batchtests/compare_tests/nested_insets/diffs.expected.lyx => autotests/export/docbook/LilyPond_Book.lyx (66%)
copy autotests/export/docbook/{issue1732_charstyles-docbook.xml => LilyPond_Book.xml} (50%)
hooks/post-receive
--
Repository for new features
More information about the lyx-cvs
mailing list