From 7930b9e5b6b3796eba60ccfa474a772b1ccf9248 Mon Sep 17 00:00:00 2001 From: Georg Baum Date: Tue, 22 May 2007 10:51:38 +0000 Subject: [PATCH] fix bug 1973 (hopefully) * src/Text2.cpp (Text::setCharFont): Assert (Text::setInsetFont): New, set the font recursively in insets (Text::setFont): Call setInsetFont instead of setCharFont if needed * src/DocIterator.cpp (DocIterator::forwardIdx): Implement * src/Text.h (Text::setInsetFont): New, set the font recursively in insets (Text::setCharFont): Document git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@18452 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/DocIterator.cpp | 13 +++++++++ src/Text.h | 19 +++++++++++++- src/Text2.cpp | 64 +++++++++++++++++++++++++++++++++++++++------ 3 files changed, 87 insertions(+), 9 deletions(-) diff --git a/src/DocIterator.cpp b/src/DocIterator.cpp index 68c64b9b60..3ef66b46c7 100644 --- a/src/DocIterator.cpp +++ b/src/DocIterator.cpp @@ -432,6 +432,19 @@ void DocIterator::forwardPar() } +void DocIterator::forwardIdx() +{ + CursorSlice & tip = top(); + + //prevent endless loops + BOOST_ASSERT(tip.idx() < lastidx()); + + ++tip.idx(); + tip.pit() = 0; + tip.pos() = 0; +} + + void DocIterator::forwardChar() { forwardPos(); diff --git a/src/Text.h b/src/Text.h index f65c5f76da..edc2524a66 100644 --- a/src/Text.h +++ b/src/Text.h @@ -59,10 +59,23 @@ public: /// Font getLabelFont(Buffer const & buffer, Paragraph const & par) const; - /// + /** Set font of character at position \p pos in paragraph \p pit. + * Must not be called if \p pos denotes an inset with text contents, + * and the inset is not allowed inside a font change (see below). + */ void setCharFont(Buffer const & buffer, pit_type pit, pos_type pos, Font const & font); + /** Needed to propagate font changes to all text cells of insets + * that are not allowed inside a font change (bug 1973). + * Must not be called if \p pos denotes an ordinary character or an + * inset that is alowed inside a font change. + * FIXME: This should be removed, see documentation of noFontChange + * in insetbase.h + */ + void setInsetFont(Buffer const & buffer, pit_type pit, pos_type pos, + Font const & font, bool toggleall = false); + /// what you expect when pressing \ at cursor position void breakParagraph(Cursor & cur, bool keep_layout = false); @@ -89,6 +102,10 @@ public: /// Set font over selection paragraphs and rebreak. /// FIXME: replace Cursor with DocIterator. void setFont(Cursor & cur, Font const &, bool toggleall = false); + /// Set font from \p begin to \p end and rebreak. + void setFont(Buffer const & buffer, DocIterator const & begin, + DocIterator const & end, Font const &, + bool toggleall = false); /// void toggleFree(Cursor & cur, Font const &, bool toggleall = false); diff --git a/src/Text2.cpp b/src/Text2.cpp index 88339ffad2..026600e79e 100644 --- a/src/Text2.cpp +++ b/src/Text2.cpp @@ -270,6 +270,9 @@ Font Text::getLabelFont(Buffer const & buffer, Paragraph const & par) const void Text::setCharFont(Buffer const & buffer, pit_type pit, pos_type pos, Font const & fnt) { + BOOST_ASSERT(!pars_[pit].isInset(pos) || + !pars_[pit].getInset(pos)->noFontChange()); + Font font = fnt; Layout_ptr const & layout = pars_[pit].layout(); @@ -307,6 +310,36 @@ void Text::setCharFont(Buffer const & buffer, pit_type pit, } +void Text::setInsetFont(Buffer const & buffer, pit_type pit, + pos_type pos, Font const & font, bool toggleall) +{ + BOOST_ASSERT(pars_[pit].isInset(pos) && + pars_[pit].getInset(pos)->noFontChange()); + + Inset * const inset = pars_[pit].getInset(pos); + DocIterator dit = doc_iterator_begin(*inset); + // start of the last cell + DocIterator end = dit; + end.idx() = end.lastidx(); + + while (true) { + Text * text = dit.text(); + Inset * cell = dit.realInset(); + if (text && cell) { + DocIterator cellbegin = doc_iterator_begin(*cell); + // last position of the cell + DocIterator cellend = cellbegin; + cellend.pit() = cellend.lastpit(); + cellend.pos() = cellend.lastpos(); + text->setFont(buffer, cellbegin, cellend, font, toggleall); + } + if (dit == end) + break; + dit.forwardIdx(); + } +} + + // return past-the-last paragraph influenced by a layout change on pit pit_type Text::undoSpan(pit_type pit) { @@ -433,7 +466,6 @@ void Text::changeDepth(Cursor & cur, DEPTH_CHANGE type) } -// set font over selection void Text::setFont(Cursor & cur, Font const & font, bool toggleall) { BOOST_ASSERT(this == cur.text()); @@ -464,20 +496,36 @@ void Text::setFont(Cursor & cur, Font const & font, bool toggleall) // Ok, we have a selection. recordUndoSelection(cur); - DocIterator dit = cur.selectionBegin(); - DocIterator ditend = cur.selectionEnd(); + setFont(cur.buffer(), cur.selectionBegin(), cur.selectionEnd(), font, + toggleall); +} - BufferParams const & params = cur.buffer().params(); +void Text::setFont(Buffer const & buffer, DocIterator const & begin, + DocIterator const & end, Font const & font, + bool toggleall) +{ // Don't use forwardChar here as ditend might have // pos() == lastpos() and forwardChar would miss it. // Can't use forwardPos either as this descends into // nested insets. - for (; dit != ditend; dit.forwardPosNoDescend()) { + Language const * language = buffer.params().language; + for (DocIterator dit = begin; dit != end; dit.forwardPosNoDescend()) { if (dit.pos() != dit.lastpos()) { - Font f = getFont(cur.buffer(), dit.paragraph(), dit.pos()); - f.update(font, params.language, toggleall); - setCharFont(cur.buffer(), dit.pit(), dit.pos(), f); + pit_type const pit = dit.pit(); + pos_type const pos = dit.pos(); + if (pars_[pit].isInset(pos) && + pars_[pit].getInset(pos)->noFontChange()) + // We need to propagate the font change to all + // text cells of the inset (bug 1973). + // FIXME: This should change, see documentation + // of noFontChange in insetbase.h + setInsetFont(buffer, pit, pos, font, toggleall); + else { + Font f = getFont(buffer, dit.paragraph(), pos); + f.update(font, language, toggleall); + setCharFont(buffer, pit, pos, f); + } } } } -- 2.39.2