On Fri, Mar 31, 2006 at 02:22:18PM +0200, Jean-Marc Lasgouttes wrote:
> 
> Can someone provide the complete patch for 2195 (aka speedup patch)
> that would apply to 1.4.x? I remember seeing it, but I do not have it
> anymore.

Here is the patch. It is r13328 + r13415 + replacing a "<" by a "<=" to
keep Juergen happy (I missed that revision as I only looked at those
under my name) 

Works for me in 1.4.x.

- Martin

Index: LyXAction.C
===================================================================
--- LyXAction.C (revision 13538)
+++ LyXAction.C (working copy)
@@ -97,7 +97,7 @@ void LyXAction::init()
                { LFUN_UNDERBAR, "accent-underbar", Noop },
                { LFUN_UNDERDOT, "accent-underdot", Noop },
                { LFUN_APPENDIX, "appendix", Noop },
-               { LFUN_LEFTSEL, "backward-select", ReadOnly },
+               { LFUN_LEFTSEL, "backward-select", ReadOnly | SingleParUpdate },
                { LFUN_BOOKMARK_GOTO, "bookmark-goto", ReadOnly },
                { LFUN_BOOKMARK_SAVE, "bookmark-save", ReadOnly },
                { LFUN_BREAKLINE, "break-line", Noop },
@@ -143,8 +143,8 @@ void LyXAction::init()
                { LFUN_DEPTH_MIN, "depth-decrement", Noop },
                { LFUN_DEPTH_PLUS, "depth-increment", Noop },
                { LFUN_LDOTS, "dots-insert", Noop },
-               { LFUN_DOWN, "down", ReadOnly | NoUpdate},
-               { LFUN_DOWNSEL, "down-select", ReadOnly },
+               { LFUN_DOWN, "down", ReadOnly | NoUpdate },
+               { LFUN_DOWNSEL, "down-select", ReadOnly | SingleParUpdate },
                { LFUN_DROP_LAYOUTS_CHOICE, "drop-layouts-choice", ReadOnly },
                { LFUN_END_OF_SENTENCE, "end-of-sentence-period-insert", Noop },
                { LFUN_ENVIRONMENT_INSERT, "environment-insert", Noop },
@@ -173,7 +173,7 @@ void LyXAction::init()
                { LFUN_FONT_STATE, "font-state", ReadOnly },
                { LFUN_UNDERLINE, "font-underline", Noop },
                { LFUN_INSET_FOOTNOTE, "footnote-insert", Noop },
-               { LFUN_RIGHTSEL, "forward-select", ReadOnly },
+               { LFUN_RIGHTSEL, "forward-select", ReadOnly | SingleParUpdate },
                { LFUN_HFILL, "hfill-insert", Noop },
                { LFUN_HELP_OPEN, "help-open", NoBuffer | Argument},
                { LFUN_HTMLURL, "html-insert", Noop },
@@ -198,10 +198,10 @@ void LyXAction::init()
                { LFUN_LAYOUT_PARAGRAPH, "layout-paragraph", ReadOnly },
                { LFUN_LAYOUT_TABULAR, "layout-tabular", Noop },
                { LFUN_HOME, "line-begin", ReadOnly | NoUpdate},
-               { LFUN_HOMESEL, "line-begin-select", ReadOnly },
+               { LFUN_HOMESEL, "line-begin-select", ReadOnly | SingleParUpdate 
},
                { LFUN_DELETE_LINE_FORWARD, "line-delete-forward", Noop },
                { LFUN_END, "line-end", ReadOnly | NoUpdate},
-               { LFUN_ENDSEL, "line-end-select", ReadOnly },
+               { LFUN_ENDSEL, "line-end-select", ReadOnly | SingleParUpdate },
 #if 0
                { LFUN_INSET_LIST, "list-insert", Noop },
 #endif
@@ -283,7 +283,7 @@ void LyXAction::init()
                { LFUN_TOGGLECURSORFOLLOW, "toggle-cursor-follows-scrollbar", 
ReadOnly },
                { LFUN_UNDO, "undo", Noop },
                { LFUN_UP, "up", ReadOnly | NoUpdate},
-               { LFUN_UPSEL, "up-select", ReadOnly },
+               { LFUN_UPSEL, "up-select", ReadOnly | SingleParUpdate },
                { LFUN_URL, "url-insert", Noop },
                { LFUN_VC_CHECKIN, "vc-check-in", ReadOnly },
                { LFUN_VC_CHECKOUT, "vc-check-out", ReadOnly },
@@ -291,14 +291,14 @@ void LyXAction::init()
                { LFUN_VC_REVERT, "vc-revert", ReadOnly },
                { LFUN_VC_UNDO, "vc-undo-last", ReadOnly },
                { LFUN_WORDLEFT, "word-backward", ReadOnly | NoUpdate},
-               { LFUN_WORDLEFTSEL, "word-backward-select", ReadOnly },
+               { LFUN_WORDLEFTSEL, "word-backward-select", ReadOnly | 
SingleParUpdate },
                { LFUN_CAPITALIZE_WORD, "word-capitalize", Noop },
                { LFUN_DELETE_WORD_BACKWARD, "word-delete-backward", Noop },
                { LFUN_DELETE_WORD_FORWARD, "word-delete-forward", Noop },
                { LFUN_WORDFINDBACKWARD, "word-find-backward", ReadOnly },
                { LFUN_WORDFINDFORWARD, "word-find-forward", ReadOnly },
                { LFUN_WORDRIGHT, "word-forward", ReadOnly | NoUpdate},
-               { LFUN_WORDRIGHTSEL, "word-forward-select", ReadOnly },
+               { LFUN_WORDRIGHTSEL, "word-forward-select", ReadOnly | 
SingleParUpdate },
                { LFUN_LOWCASE_WORD, "word-lowcase", Noop },
                { LFUN_WORDSEL, "word-select", ReadOnly },
                { LFUN_UPCASE_WORD, "word-upcase", Noop },
@@ -348,7 +348,7 @@ void LyXAction::init()
                { LFUN_FINISHED_UP, "", ReadOnly },
                { LFUN_FINISHED_DOWN, "", ReadOnly },
                { LFUN_MOUSE_PRESS, "", ReadOnly },
-               { LFUN_MOUSE_MOTION, "", ReadOnly },
+               { LFUN_MOUSE_MOTION, "", ReadOnly | SingleParUpdate },
                { LFUN_MOUSE_RELEASE, "", ReadOnly },
                { LFUN_MOUSE_DOUBLE, "", ReadOnly },
                { LFUN_MOUSE_TRIPLE, "", ReadOnly },
Index: insets/insetenv.h
===================================================================
--- insets/insetenv.h   (revision 13538)
+++ insets/insetenv.h   (working copy)
@@ -34,8 +34,6 @@ public:
        ///
        InsetBase::EDITABLE editable() const { return HIGHLY_EDITABLE; }
        ///
-       bool isTextInset() const { return true; }
-       ///
        LyXLayout_ptr const & layout() const;
        /** returns true if, when outputing LaTeX, font changes should
             be closed before generating this inset. This is needed for
Index: insets/insetbase.h
===================================================================
--- insets/insetbase.h  (revision 13538)
+++ insets/insetbase.h  (working copy)
@@ -21,6 +21,7 @@ class BufferView;
 class CursorSlice;
 class FuncRequest;
 class FuncStatus;
+class InsetText;
 class LaTeXFeatures;
 class LCursor;
 class LyXLex;
@@ -216,8 +217,10 @@ public:
        virtual EDITABLE editable() const;
        /// can we go further down on mouse click?
        virtual bool descendable() const { return false; }
-       ///
-       virtual bool isTextInset() const { return false; }
+       /// does this contain text that can be change track marked in DVI?
+       virtual bool canTrackChanges() const { return false; }
+       /// is this inset based on the TextInset class?
+       virtual InsetText * asTextInset() const { return 0; }
        /// return true if the inset should be removed automatically
        virtual bool autoDelete() const;
 
Index: insets/insetcollapsable.C
===================================================================
--- insets/insetcollapsable.C   (revision 13538)
+++ insets/insetcollapsable.C   (working copy)
@@ -138,7 +138,7 @@ void InsetCollapsable::metrics(MetricsIn
                dim = dimensionCollapsed();
                if (status() == Open) {
                        InsetText::metrics(mi, textdim_);
-                       openinlined_ = (textdim_.wid + dim.wid <= 
mi.base.textwidth);
+                       openinlined_ = textdim_.wid + 2 * dim.wid <= 
mi.base.textwidth;
                        if (openinlined_) {
                                dim.wid += textdim_.wid;
                                dim.des = max(dim.des - textdim_.asc + dim.asc, 
textdim_.des);
@@ -171,6 +171,7 @@ void InsetCollapsable::draw(PainterInfo 
                button_dim.y2 = top + dimc.height();
 
                pi.pain.buttonText(xx, top + dimc.asc, label, labelfont_);
+
                if (status() == Open) {
                        int textx, texty;
                        if (openinlined_) {
Index: insets/insettext.h
===================================================================
--- insets/insettext.h  (revision 13538)
+++ insets/insettext.h  (working copy)
@@ -57,7 +57,9 @@ public:
        ///
        EDITABLE editable() const { return HIGHLY_EDITABLE; }
        ///
-       bool isTextInset() const { return true; }
+       bool canTrackChanges() const { return true; }
+       ///
+       InsetText * asTextInset() const { return const_cast<InsetText *>(this); 
}
        ///
        int latex(Buffer const &, std::ostream &,
                  OutputParams const &) const;
@@ -137,6 +139,10 @@ public:
        bool neverIndent() const;
        ///
        InsetText(InsetText const &);
+       ///
+       bool & Wide() const { return wide_inset_; }
+       ///
+       bool const Tall() const;
 
 protected:
        ///
@@ -158,6 +164,8 @@ private:
        mutable lyx::pit_type old_pit;
        ///
        static int border_;
+       ///
+       mutable bool wide_inset_;
 public:
        ///
        mutable LyXText text_;
Index: insets/insetcollapsable.h
===================================================================
--- insets/insetcollapsable.h   (revision 13538)
+++ insets/insetcollapsable.h   (working copy)
@@ -57,8 +57,6 @@ public:
        /// can we go further down on mouse click?
        bool descendable() const;
        ///
-       bool isTextInset() const { return true; }
-       ///
        void setLabel(std::string const & l);
        ///
        virtual void setButtonLabel() {}
Index: insets/insettabular.h
===================================================================
--- insets/insettabular.h       (revision 13538)
+++ insets/insettabular.h       (working copy)
@@ -69,7 +69,7 @@ public:
        ///
        bool insetAllowed(InsetBase::Code) const { return true; }
        ///
-       bool isTextInset() const { return true; }
+       bool canTrackChanges() const { return true; }
        /** returns true if, when outputing LaTeX, font changes should
            be closed before generating this inset. This is needed for
            insets that may contain several paragraphs */
Index: insets/insettext.C
===================================================================
--- insets/insettext.C  (revision 13538)
+++ insets/insettext.C  (working copy)
@@ -200,6 +200,7 @@ void InsetText::draw(PainterInfo & pi, i
        // update our idea of where we are
        setPosCache(pi, x, y);
 
+       text_.background_color_ = backgroundColor();
        text_.draw(pi, x + border_, y);
 
        if (drawFrame_) {
@@ -207,7 +208,7 @@ void InsetText::draw(PainterInfo & pi, i
                int const a = text_.ascent() + border_;
                int const h = a + text_.descent() + border_;
                int const ww = pi.base.bv->workWidth();
-               if (w > ww - 40)  {
+               if (w > ww - 40 || Wide())  {
                        pi.pain.line(0, y - a, ww, y - a, frameColor());
                        pi.pain.line(0, y - a + h, ww, y - a + h, frameColor());
                } else {
@@ -219,13 +220,16 @@ void InsetText::draw(PainterInfo & pi, i
 
 void InsetText::drawSelection(PainterInfo & pi, int x, int y) const
 {
-       if (backgroundColor() != LColor::background) {
-               // repaint the background if needed
-               int const w = text_.width() + 2 * border_;
-               int const a = text_.ascent() + border_;
-               int const h = a + text_.descent() + border_;
-               pi.pain.fillRectangle(x, y - a, w, h, backgroundColor());
-       }
+       int const w = text_.width() + 2 * border_;
+       int const a = text_.ascent() + border_;
+       int const h = a + text_.descent() + border_;
+       int const ww = pi.base.bv->workWidth();
+       if (Wide())
+               pi.pain.fillRectangle(0, y - a, ww, h, 
+                       backgroundColor());
+       else
+               pi.pain.fillRectangle(x, y - a, w, h, 
+                       backgroundColor());
        text_.drawSelection(pi, x, y);
 }
 
@@ -254,6 +258,12 @@ InsetBase * InsetText::editXY(LCursor & 
 }
 
 
+bool const InsetText::Tall() const
+{
+       return text_.ascent() + text_.descent() > 2  * defaultRowHeight(); 
+}
+
+
 void InsetText::doDispatch(LCursor & cur, FuncRequest & cmd)
 {
        lyxerr[Debug::DEBUG] << BOOST_CURRENT_FUNCTION
Index: debug.h
===================================================================
--- debug.h     (revision 13538)
+++ debug.h     (working copy)
@@ -74,6 +74,8 @@ public:
                ///
                EXTERNAL   = (1 << 23),
                ///
+               PAINTING   = (1 << 24),
+               ///
                DEBUG      = (1 << 31),
                ///
                ANY = 0xffffffff
Index: BufferView_pimpl.C
===================================================================
--- BufferView_pimpl.C  (revision 13538)
+++ BufferView_pimpl.C  (working copy)
@@ -658,6 +658,17 @@ bool BufferView::Pimpl::fitCursor()
 }
 
 
+bool BufferView::Pimpl::multiParSel()
+{
+       if (!cursor_.selection())
+               return false;
+       bool ret = multiparsel_cache_;
+       multiparsel_cache_ = cursor_.selBegin().pit() != cursor_.selEnd().pit();
+       // Either this, or previous selection spans paragraphs
+       return ret || multiparsel_cache_;
+}
+
+
 void BufferView::Pimpl::update(Update::flags flags)
 {
        lyxerr[Debug::DEBUG]
@@ -682,12 +693,16 @@ void BufferView::Pimpl::update(Update::f
 
                // First drawing step
                ViewMetricsInfo vi = metrics(flags & Update::SinglePar);
-               bool forceupdate(flags & Update::Force);
+               bool forceupdate(flags & (Update::Force | Update::SinglePar));
 
                if ((flags & Update::FitCursor) && fitCursor()) {
                        forceupdate = true;
                        vi = metrics();
                }
+               if ((flags & Update::MultiParSel) && multiParSel()) {
+                       forceupdate = true;
+                       vi = metrics();
+               }
                if (forceupdate) {
                        // Second drawing step
                        screen().redraw(*bv_, vi);
@@ -984,7 +999,7 @@ bool BufferView::Pimpl::workAreaDispatch
                if (cur.result().update())
                        update(Update::FitCursor | Update::Force);
                else
-                       update();
+                       update(Update::FitCursor | Update::MultiParSel);
        }
 
        // See workAreaKeyPress
Index: paragraph_pimpl.C
===================================================================
--- paragraph_pimpl.C   (revision 13538)
+++ paragraph_pimpl.C   (working copy)
@@ -536,7 +536,7 @@ void Paragraph::Pimpl::simpleTeXSpecialC
                        && runparams.flavor == OutputParams::LATEX
                        && features.isAvailable("dvipost");
 
-               if (inset->isTextInset()) {
+               if (inset->canTrackChanges()) {
                        column += Changes::latexMarkChange(os, running_change,
                                Change::UNCHANGED, output);
                        running_change = Change::UNCHANGED;
Index: mathed/math_hullinset.h
===================================================================
--- mathed/math_hullinset.h     (revision 13538)
+++ mathed/math_hullinset.h     (working copy)
@@ -189,7 +189,7 @@ public:
        /// what appears in the minibuffer when opening
        virtual std::string const editMessage() const;
        ///
-       virtual bool isTextInset() const { return true; }
+       virtual bool canTrackChanges() const { return true; }
        ///
        virtual void mutateToText();
        ///
Index: BufferView_pimpl.h
===================================================================
--- BufferView_pimpl.h  (revision 13538)
+++ BufferView_pimpl.h  (working copy)
@@ -59,6 +59,8 @@ public:
        void resizeCurrentBuffer();
        //
        bool fitCursor();
+       //
+       bool multiParSel();
        ///
        void update(Update::flags flags = Update::Force);
        ///
@@ -103,6 +105,10 @@ public:
        FuncStatus getStatus(FuncRequest const & cmd);
        /// a function should be executed
        bool dispatch(FuncRequest const & ev);
+       /// Flag: do a full redraw of inside text of inset
+       bool repaintAll() { return refresh_inside_; }
+       ///
+       void repaintAll(bool r) {refresh_inside_ = r; }
 private:
        /// An error list (replaces the error insets)
        ErrorList errorlist_;
@@ -183,13 +189,15 @@ private:
        ///
        LCursor cursor_;
        ///
+       bool multiparsel_cache_;
        ///
        lyx::pit_type anchor_ref_;
        ///
        int offset_ref_;
        ///
        ViewMetricsInfo metrics(bool singlepar = false);
-
-
+       /// Working variable indicating a full screen refresh
+       mutable bool refresh_inside_;
+       
 };
 #endif // BUFFERVIEW_PIMPL_H
Index: text3.C
===================================================================
--- text3.C     (revision 13538)
+++ text3.C     (working copy)
@@ -628,12 +628,16 @@ void LyXText::dispatch(LCursor & cur, Fu
 
        case LFUN_DELETE:
                if (!cur.selection()) {
+                       if (cur.pos() == cur.paragraph().size())
+                               // Par boundary, force full-screen update
+                               singleParUpdate = false;
                        needsUpdate = Delete(cur);
                        cur.resetAnchor();
                        // It is possible to make it a lot faster still
                        // just comment out the line below...
                } else {
                        cutSelection(cur, true, false);
+                       singleParUpdate = false;
                }
                moveCursor(cur, false);
                break;
@@ -656,6 +660,9 @@ void LyXText::dispatch(LCursor & cur, Fu
        case LFUN_BACKSPACE:
                if (!cur.selection()) {
                        if 
(bv->owner()->getIntl().getTransManager().backspace()) {
+                               // Par boundary, full-screen update
+                               if (cur.pos() == 0)
+                                       singleParUpdate = false;
                                needsUpdate = backspace(cur);
                                cur.resetAnchor();
                                // It is possible to make it a lot faster still
@@ -663,6 +670,7 @@ void LyXText::dispatch(LCursor & cur, Fu
                        }
                } else {
                        cutSelection(cur, true, false);
+                       singleParUpdate = false;
                }
                bv->switchKeyMap();
                break;
@@ -1532,10 +1540,14 @@ void LyXText::dispatch(LCursor & cur, Fu
 
        if (singleParUpdate)
                // Inserting characters does not change par height
-               if (cur.bottom().paragraph().dim().height() 
+               if (cur.bottom().paragraph().dim().height() 
                    == olddim.height()) {
                        // if so, update _only_ this paragraph
-                       cur.bv().update(Update::SinglePar | Update::Force);
+                       cur.bv().update(Update::SinglePar |
+                                       Update::FitCursor |
+                                       Update::MultiParSel);
+                       cur.noUpdate();
+                       return;
                } else
                        needsUpdate = true;
        if (!needsUpdate
Index: rowpainter.C
===================================================================
--- rowpainter.C        (revision 13538)
+++ rowpainter.C        (working copy)
@@ -164,8 +164,17 @@ void RowPainter::paintInset(pos_type con
        pi.ltr_pos = (text_.bidi.level(pos) % 2 == 0);
        pi.erased_ = erased_ || isDeletedText(par_, pos);
        theCoords.insets().add(inset, int(x_), yo_);
-       inset->drawSelection(pi, int(x_), yo_);
+       InsetBase * in = const_cast<InsetBase *>(inset);
+       // non-wide insets are painted completely. Recursive
+       bool tmp = bv_.repaintAll();
+       if (!in->asTextInset() || !static_cast<InsetText*>(in)->Wide()) {
+               bv_.repaintAll(true);
+               lyxerr[Debug::PAINTING] << endl << "Paint inset fully" << endl;
+       }
+       if (bv_.repaintAll())
+               inset->drawSelection(pi, int(x_), yo_);
        inset->draw(pi, int(x_), yo_);
+       bv_.repaintAll(tmp);
        x_ += inset->width();
 }
 
@@ -720,25 +729,52 @@ void RowPainter::paintText()
 }
 
 
-lyx::size_type calculateRowSignature(Row const & row, Paragraph const & par)
+lyx::size_type calculateRowSignature(Row const & row, Paragraph const & par,
+       int x, int y)
 {
        boost::crc_32_type crc;
        for (lyx::pos_type i = row.pos(); i < row.endpos(); ++i) {
                const unsigned char b[] = { par.getChar(i) };
                crc.process_bytes(b, 1);
        }
+       const unsigned char b[] = { x, y, row.width() };
+       crc.process_bytes(b, 3);
        return crc.checksum();
 }
 
 
-bool isCursorOnRow(PainterInfo & pi, pit_type pit, RowList::const_iterator rit)
+bool CursorOnRow(PainterInfo & pi, pit_type const pit, 
+       RowList::const_iterator rit, LyXText const & text)
 {
+       // Is there a cursor on this row (or inside inset on row)
        LCursor & cur = pi.base.bv->cursor();
-       for (lyx::size_type d = 0; d < cur.depth(); d++)
-               if (cur[d].pit() == pit
-                   && cur[d].pos() >= rit->pos()
-                   && cur[d].pos() <= rit->endpos())
+       for (lyx::size_type d = 0; d < cur.depth(); d++) {
+               CursorSlice const & sl = cur[d];
+               if (sl.text() == &text
+                   && sl.pit() == pit
+                   && sl.pos() >= rit->pos()
+                   && sl.pos() <= rit->endpos())
                        return true;
+       }
+       return false;
+}
+
+
+bool innerCursorOnRow(PainterInfo & pi, pit_type pit, 
+       RowList::const_iterator rit, LyXText const & text)
+{
+       // Is there a cursor inside an inset on this row, and is this inset
+       // the only "character" on this row
+       LCursor & cur = pi.base.bv->cursor();
+       if (rit->pos() + 1 != rit->endpos())
+               return false;
+       for (lyx::size_type d = 0; d < cur.depth(); d++) {
+               CursorSlice const & sl = cur[d];
+               if (sl.text() == &text
+                   && sl.pit() == pit 
+                   && sl.pos() == rit->pos())
+                       return d < cur.depth() - 1;
+       }
        return false;
 }
 
@@ -762,17 +798,33 @@ void paintPar
        lyx::size_type rowno(0);
        for (RowList::const_iterator rit = rb; rit != re; ++rit, ++rowno) {
                y += rit->ascent();
+               // Allow setting of bv->repaintAll() for nested insets in
+               // this row only
+               bool tmp = pi.base.bv->repaintAll();
 
                // Row signature; has row changed since last paint?
-               lyx::size_type const row_sig = calculateRowSignature(*rit, par);
-
-               bool cursor_on_row = isCursorOnRow(pi, pit, rit);
+               lyx::size_type const row_sig = calculateRowSignature(*rit, par, 
x, y);
+               bool row_has_changed = par.rowSignature()[rowno] != row_sig;
                
-               // If selection is on, the current row signature differs from
+               bool cursor_on_row = CursorOnRow(pi, pit, rit, text);
+               bool in_inset_alone_on_row = innerCursorOnRow(pi, pit, rit,
+                       text);
+
+               // If this is the only object on the row, we can make it wide
+               for (pos_type i = rit->pos() ; i != rit->endpos(); ++i) {
+                       InsetBase* in 
+                           = const_cast<InsetBase*>(par.getInset(i));
+                       if (in && in->asTextInset()) {
+                               static_cast<InsetText*>(in)->Wide()
+                                   = in_inset_alone_on_row  &&
+                                       static_cast<InsetText*>(in)->Tall();
+                       }
+               }
+
+               // If selection is on, the current row signature differs 
                // from cache, or cursor is inside an inset _on this row_, 
                // then paint the row
-               if (repaintAll || par.rowSignature()[rowno] != row_sig
-                           || cursor_on_row) {
+               if (repaintAll || row_has_changed || cursor_on_row) {
                        // Add to row signature cache
                        par.rowSignature()[rowno] = row_sig;
 
@@ -781,15 +833,25 @@ void paintPar
                        RowPainter rp(inside ? pi : nullpi, text, pit, *rit, x, 
y);
                        // Clear background of this row 
                        // (if paragraph background was not cleared)
-                       if (!repaintAll) {
-                               pi.pain.fillRectangle(x, y - rit->ascent(), 
+                       if (!repaintAll && 
+                           (!in_inset_alone_on_row || row_has_changed)) {
+                               pi.pain.fillRectangle(( rowno ? 0 : x - 10 ), y 
- rit->ascent(), 
                                    pi.base.bv->workWidth(), rit->height(),
                                    text.backgroundColor());
+                               // If outer row has changed, force nested
+                               // insets to repaint completely
+                               if (row_has_changed)
+                                       pi.base.bv->repaintAll(true);
                        }
                        
                        // Instrumentation for testing row cache (see also
                        // 12 lines lower):
-                       //lyxerr << "#";
+                       if (text.isMainText())
+                               lyxerr[Debug::PAINTING] << "#";
+                       else
+                               lyxerr[Debug::PAINTING] << "[" <<
+                                   repaintAll << row_has_changed <<
+                                   cursor_on_row << "]";
                        rp.paintAppendix();
                        rp.paintDepthBar();
                        rp.paintChangeBar();
@@ -800,8 +862,10 @@ void paintPar
                        rp.paintText();
                }
                y += rit->descent();
+               // Restore, see above
+               pi.base.bv->repaintAll(tmp);
        }
-       //lyxerr << "." << endl;
+       lyxerr[Debug::PAINTING] << "." << endl;
 }
 
 } // namespace anon
@@ -814,8 +878,11 @@ void paintText(BufferView const & bv, Vi
        bool const select = bv.cursor().selection();
 
        PainterInfo pi(const_cast<BufferView *>(&bv), pain);
-       if (select || !vi.singlepar) {
-               // Clear background (Delegated to rows if no selection)
+       // Should the whole screen, including insets, be refreshed?
+       bool repaintAll(select || !vi.singlepar);
+       
+       if (repaintAll) {
+               // Clear background (if not delegated to rows)
                pain.fillRectangle(0, vi.y1, bv.workWidth(), vi.y2 - vi.y1,
                        text->backgroundColor());
        }
@@ -826,9 +893,10 @@ void paintText(BufferView const & bv, Vi
        int yy = vi.y1;
        // draw contents
        for (pit_type pit = vi.p1; pit <= vi.p2; ++pit) {
+               bv.repaintAll(repaintAll);
                Paragraph const & par = text->getPar(pit);
                yy += par.ascent();
-               paintPar(pi, *bv.text(), pit, 0, yy, select || !vi.singlepar);
+               paintPar(pi, *bv.text(), pit, 0, yy, repaintAll);
                yy += par.descent();
        }
 
@@ -865,9 +933,11 @@ void paintTextInset(LyXText const & text
 //     lyxerr << "  paintTextInset: y: " << y << endl;
 
        y -= text.getPar(0).ascent();
+       // This flag can not be set from within same inset:
+       bool repaintAll = pi.base.bv->repaintAll();
        for (int pit = 0; pit < int(text.paragraphs().size()); ++pit) {
                y += text.getPar(pit).ascent();
-               paintPar(pi, text, pit, x, y, true);
+               paintPar(pi, text, pit, x, y, repaintAll);
                y += text.getPar(pit).descent();
        }
 }
Index: BufferView.C
===================================================================
--- BufferView.C        (revision 13538)
+++ BufferView.C        (working copy)
@@ -369,6 +369,18 @@ void BufferView::putSelectionAt(DocItera
 }
 
 
+bool const BufferView::repaintAll() const
+{ 
+       return pimpl_->repaintAll();
+}
+
+       
+void const BufferView::repaintAll(bool r) const
+{ 
+       pimpl_->repaintAll(r);
+}
+
+
 LCursor & BufferView::cursor()
 {
        return pimpl_->cursor_;
Index: BufferView.h
===================================================================
--- BufferView.h        (revision 13538)
+++ BufferView.h        (working copy)
@@ -40,7 +40,8 @@ namespace Update {
        enum flags {
                FitCursor = 1,
                Force = 2,
-               SinglePar = 4
+               SinglePar = 4,
+               MultiParSel = 8
        };
 
 inline flags operator|(flags const f, flags const g)
@@ -198,7 +199,10 @@ public:
         */
        void putSelectionAt(DocIterator const & cur,
                int length, bool backwards);
-
+       ///
+       bool const repaintAll() const;
+       ///
+       void const repaintAll(bool r) const;
 
 private:
        ///
Index: debug.C
===================================================================
--- debug.C     (revision 13538)
+++ debug.C     (working copy)
@@ -63,6 +63,7 @@ error_item errorTags[] = {
        { Debug::GRAPHICS,  "graphics",  N_("Graphics conversion and loading")},
        { Debug::CHANGES,   "changes",   N_("Change tracking")},
        { Debug::EXTERNAL,  "external",  N_("External template/inset 
messages")},
+       { Debug::PAINTING,  "painting",  N_("RowPainter profiling")},
        { Debug::DEBUG,     "debug",     N_("Developers' general debug 
messages")},
        { Debug::ANY,       "any",       N_("All debugging messages")}
 };

Attachment: pgpf7q1m94skX.pgp
Description: PGP signature

Reply via email to