Fix bug 2195: Slowness in rendering inside insets, especially

on the Mac

	Changes to the within-inset row rendering caching code.

	* insets/insetenv.h: 
	* insets/insetcollapsable.h: remove method
	* insets/insettabular.h:
	* insets/insetbase.h: rename, add methods
	* insets/insettext.[Ch]: rename method; add Tall()
	* paragraph_pimpl.C
	(Paragraph::Pimpl::simpleTeXSpecialC): rename call
	* mathed/math_hullinset.h: rename method
	* rowpainter.C
	(RowPainter::paintInset):
	(paintPar): remove isTrueTextInset, move to insets 



git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/branches/BRANCH_1_4_X@13568 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Jean-Marc Lasgouttes 2006-04-06 12:06:37 +00:00
parent b5d8f230a1
commit 5adf6d5d58
23 changed files with 277 additions and 98 deletions

View File

@ -5,12 +5,6 @@ This file describes some known problems in LyX 1.4.1 that did not
occur in 1.3.7. Note that fixes are available for many of these, but occur in 1.3.7. Note that fixes are available for many of these, but
they have not yet been applied because of incomplete testing. they have not yet been applied because of incomplete testing.
** Noticeable delays when editing documents
- creating/deleting paragraphs in large documents or documents with
images and previews.
http://bugzilla.lyx.org/show_bug.cgi?id=2287
** Change tracking ** Change tracking
- Pasted text inserted wrong after switch of change tracking state. - Pasted text inserted wrong after switch of change tracking state.

View File

@ -369,6 +369,18 @@ void BufferView::putSelectionAt(DocIterator const & cur,
} }
bool const BufferView::repaintAll() const
{
return pimpl_->repaintAll();
}
void const BufferView::repaintAll(bool r) const
{
pimpl_->repaintAll(r);
}
LCursor & BufferView::cursor() LCursor & BufferView::cursor()
{ {
return pimpl_->cursor_; return pimpl_->cursor_;

View File

@ -40,7 +40,8 @@ namespace Update {
enum flags { enum flags {
FitCursor = 1, FitCursor = 1,
Force = 2, Force = 2,
SinglePar = 4 SinglePar = 4,
MultiParSel = 8
}; };
inline flags operator|(flags const f, flags const g) inline flags operator|(flags const f, flags const g)
@ -198,7 +199,10 @@ public:
*/ */
void putSelectionAt(DocIterator const & cur, void putSelectionAt(DocIterator const & cur,
int length, bool backwards); int length, bool backwards);
///
bool const repaintAll() const;
///
void const repaintAll(bool r) const;
private: private:
/// ///

View File

@ -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) void BufferView::Pimpl::update(Update::flags flags)
{ {
lyxerr[Debug::DEBUG] lyxerr[Debug::DEBUG]
@ -682,12 +693,16 @@ void BufferView::Pimpl::update(Update::flags flags)
// First drawing step // First drawing step
ViewMetricsInfo vi = metrics(flags & Update::SinglePar); ViewMetricsInfo vi = metrics(flags & Update::SinglePar);
bool forceupdate(flags & Update::Force); bool forceupdate(flags & (Update::Force | Update::SinglePar));
if ((flags & Update::FitCursor) && fitCursor()) { if ((flags & Update::FitCursor) && fitCursor()) {
forceupdate = true; forceupdate = true;
vi = metrics(); vi = metrics();
} }
if ((flags & Update::MultiParSel) && multiParSel()) {
forceupdate = true;
vi = metrics();
}
if (forceupdate) { if (forceupdate) {
// Second drawing step // Second drawing step
screen().redraw(*bv_, vi); screen().redraw(*bv_, vi);
@ -984,7 +999,7 @@ bool BufferView::Pimpl::workAreaDispatch(FuncRequest const & cmd0)
if (cur.result().update()) if (cur.result().update())
update(Update::FitCursor | Update::Force); update(Update::FitCursor | Update::Force);
else else
update(); update(Update::FitCursor | Update::MultiParSel);
} }
// See workAreaKeyPress // See workAreaKeyPress

View File

@ -59,6 +59,8 @@ public:
void resizeCurrentBuffer(); void resizeCurrentBuffer();
// //
bool fitCursor(); bool fitCursor();
//
bool multiParSel();
/// ///
void update(Update::flags flags = Update::Force); void update(Update::flags flags = Update::Force);
/// ///
@ -103,6 +105,10 @@ public:
FuncStatus getStatus(FuncRequest const & cmd); FuncStatus getStatus(FuncRequest const & cmd);
/// a function should be executed /// a function should be executed
bool dispatch(FuncRequest const & ev); 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: private:
/// An error list (replaces the error insets) /// An error list (replaces the error insets)
ErrorList errorlist_; ErrorList errorlist_;
@ -183,13 +189,15 @@ private:
/// ///
LCursor cursor_; LCursor cursor_;
/// ///
bool multiparsel_cache_;
/// ///
lyx::pit_type anchor_ref_; lyx::pit_type anchor_ref_;
/// ///
int offset_ref_; int offset_ref_;
/// ///
ViewMetricsInfo metrics(bool singlepar = false); ViewMetricsInfo metrics(bool singlepar = false);
/// Working variable indicating a full screen refresh
mutable bool refresh_inside_;
}; };
#endif // BUFFERVIEW_PIMPL_H #endif // BUFFERVIEW_PIMPL_H

View File

@ -1,3 +1,25 @@
2006-03-18 Georg Baum <Georg.Baum@post.rwth-aachen.de>
* rowpainter.C (paintInset): remove unneeded casts
(paintPar): ditto
2006-03-17 Martin Vermeer <martin.vermeer@hut.fi>
Changes to the within-inset row rendering caching code.
* paragraph_pimpl.C (simpleTeXSpecialChar): use canTrackChanges
* rowpainter.C (paintInset):
(paintPar): remove isTrueTextInset, move to insets
2006-03-10 Martin Vermeer <martin.vermeer@hut.fi>
* BufferView.[Ch]:
* BufferView_pimpl.[Ch]:
* LyXAction.C:
* debug.[Ch]:
* rowpainter.C:
* text3.C: Inside-inset speedup, esp. for the Mac (bug 2195)
2006-03-29 Jean-Marc Lasgouttes <lasgouttes@lyx.org> 2006-03-29 Jean-Marc Lasgouttes <lasgouttes@lyx.org>
* LaTeX.C (handleFoundFile): do not add directories to the * LaTeX.C (handleFoundFile): do not add directories to the
@ -24,39 +46,39 @@
2006-03-23 Lars Gullik Bjønnes <larsbj@gullik.net> 2006-03-23 Lars Gullik Bjønnes <larsbj@gullik.net>
* output_latex.h: * output_latex.h:
* buffer.h: * buffer.h:
* CutAndPaste.h: * CutAndPaste.h:
* pariterator.h: * pariterator.h:
* paragraph_funcs.h: * paragraph_funcs.h:
* output_linuxdoc.h: * output_linuxdoc.h:
* output_docbook.h: get forward declaration of ParagraphList * output_docbook.h: get forward declaration of ParagraphList
* output_plaintext.C: * output_plaintext.C:
* bufferlist.C: * bufferlist.C:
* undo.C: * undo.C:
* lyxtext.h: * lyxtext.h:
* undo.h: * undo.h:
* buffer_funcs.C: get proper ParagraphList decls * buffer_funcs.C: get proper ParagraphList decls
* output_linuxdoc.C (linuxdocParagraphs): * output_linuxdoc.C (linuxdocParagraphs):
* output_latex.C (TeXOnePar): use std::distance * output_latex.C (TeXOnePar): use std::distance
* CutAndPaste.C (pasteSelectionHelper, copySelectionHelper): * CutAndPaste.C (pasteSelectionHelper, copySelectionHelper):
* paragraph_funcs.C (breakParagraph, * paragraph_funcs.C (breakParagraph,
breakParagraphConservative, mergeParagraph): breakParagraphConservative, mergeParagraph):
* text.C (acceptChange, rejectChange): * text.C (acceptChange, rejectChange):
* text2.C (deleteEmptyParagraphMechanism): use boost::next * text2.C (deleteEmptyParagraphMechanism): use boost::next
* output_docbook.C (several places): use boost::next and * output_docbook.C (several places): use boost::next and
std::distance std::distance
* ParagraphList_fwd.h: modify to provid a forward declaratoin * ParagraphList_fwd.h: modify to provid a forward declaratoin
of the new ParagraphList. of the new ParagraphList.
* ParagraphList.h: new file, setup user of RandomAccessList * ParagraphList.h: new file, setup user of RandomAccessList
* paragraph.C: remove ParagraphList constructor from this file * paragraph.C: remove ParagraphList constructor from this file
2006-03-18 Martin Vermeer <martin.vermeer@hut.fi> 2006-03-18 Martin Vermeer <martin.vermeer@hut.fi>

View File

@ -97,7 +97,7 @@ void LyXAction::init()
{ LFUN_UNDERBAR, "accent-underbar", Noop }, { LFUN_UNDERBAR, "accent-underbar", Noop },
{ LFUN_UNDERDOT, "accent-underdot", Noop }, { LFUN_UNDERDOT, "accent-underdot", Noop },
{ LFUN_APPENDIX, "appendix", Noop }, { LFUN_APPENDIX, "appendix", Noop },
{ LFUN_LEFTSEL, "backward-select", ReadOnly }, { LFUN_LEFTSEL, "backward-select", ReadOnly | SingleParUpdate },
{ LFUN_BOOKMARK_GOTO, "bookmark-goto", ReadOnly }, { LFUN_BOOKMARK_GOTO, "bookmark-goto", ReadOnly },
{ LFUN_BOOKMARK_SAVE, "bookmark-save", ReadOnly }, { LFUN_BOOKMARK_SAVE, "bookmark-save", ReadOnly },
{ LFUN_BREAKLINE, "break-line", Noop }, { LFUN_BREAKLINE, "break-line", Noop },
@ -143,8 +143,8 @@ void LyXAction::init()
{ LFUN_DEPTH_MIN, "depth-decrement", Noop }, { LFUN_DEPTH_MIN, "depth-decrement", Noop },
{ LFUN_DEPTH_PLUS, "depth-increment", Noop }, { LFUN_DEPTH_PLUS, "depth-increment", Noop },
{ LFUN_LDOTS, "dots-insert", Noop }, { LFUN_LDOTS, "dots-insert", Noop },
{ LFUN_DOWN, "down", ReadOnly | NoUpdate}, { LFUN_DOWN, "down", ReadOnly | NoUpdate },
{ LFUN_DOWNSEL, "down-select", ReadOnly }, { LFUN_DOWNSEL, "down-select", ReadOnly | SingleParUpdate },
{ LFUN_DROP_LAYOUTS_CHOICE, "drop-layouts-choice", ReadOnly }, { LFUN_DROP_LAYOUTS_CHOICE, "drop-layouts-choice", ReadOnly },
{ LFUN_END_OF_SENTENCE, "end-of-sentence-period-insert", Noop }, { LFUN_END_OF_SENTENCE, "end-of-sentence-period-insert", Noop },
{ LFUN_ENVIRONMENT_INSERT, "environment-insert", Noop }, { LFUN_ENVIRONMENT_INSERT, "environment-insert", Noop },
@ -173,7 +173,7 @@ void LyXAction::init()
{ LFUN_FONT_STATE, "font-state", ReadOnly }, { LFUN_FONT_STATE, "font-state", ReadOnly },
{ LFUN_UNDERLINE, "font-underline", Noop }, { LFUN_UNDERLINE, "font-underline", Noop },
{ LFUN_INSET_FOOTNOTE, "footnote-insert", Noop }, { LFUN_INSET_FOOTNOTE, "footnote-insert", Noop },
{ LFUN_RIGHTSEL, "forward-select", ReadOnly }, { LFUN_RIGHTSEL, "forward-select", ReadOnly | SingleParUpdate },
{ LFUN_HFILL, "hfill-insert", Noop }, { LFUN_HFILL, "hfill-insert", Noop },
{ LFUN_HELP_OPEN, "help-open", NoBuffer | Argument}, { LFUN_HELP_OPEN, "help-open", NoBuffer | Argument},
{ LFUN_HTMLURL, "html-insert", Noop }, { LFUN_HTMLURL, "html-insert", Noop },
@ -198,10 +198,10 @@ void LyXAction::init()
{ LFUN_LAYOUT_PARAGRAPH, "layout-paragraph", ReadOnly }, { LFUN_LAYOUT_PARAGRAPH, "layout-paragraph", ReadOnly },
{ LFUN_LAYOUT_TABULAR, "layout-tabular", Noop }, { LFUN_LAYOUT_TABULAR, "layout-tabular", Noop },
{ LFUN_HOME, "line-begin", ReadOnly | NoUpdate}, { 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_DELETE_LINE_FORWARD, "line-delete-forward", Noop },
{ LFUN_END, "line-end", ReadOnly | NoUpdate}, { LFUN_END, "line-end", ReadOnly | NoUpdate},
{ LFUN_ENDSEL, "line-end-select", ReadOnly }, { LFUN_ENDSEL, "line-end-select", ReadOnly | SingleParUpdate },
#if 0 #if 0
{ LFUN_INSET_LIST, "list-insert", Noop }, { LFUN_INSET_LIST, "list-insert", Noop },
#endif #endif
@ -283,7 +283,7 @@ void LyXAction::init()
{ LFUN_TOGGLECURSORFOLLOW, "toggle-cursor-follows-scrollbar", ReadOnly }, { LFUN_TOGGLECURSORFOLLOW, "toggle-cursor-follows-scrollbar", ReadOnly },
{ LFUN_UNDO, "undo", Noop }, { LFUN_UNDO, "undo", Noop },
{ LFUN_UP, "up", ReadOnly | NoUpdate}, { LFUN_UP, "up", ReadOnly | NoUpdate},
{ LFUN_UPSEL, "up-select", ReadOnly }, { LFUN_UPSEL, "up-select", ReadOnly | SingleParUpdate },
{ LFUN_URL, "url-insert", Noop }, { LFUN_URL, "url-insert", Noop },
{ LFUN_VC_CHECKIN, "vc-check-in", ReadOnly }, { LFUN_VC_CHECKIN, "vc-check-in", ReadOnly },
{ LFUN_VC_CHECKOUT, "vc-check-out", ReadOnly }, { LFUN_VC_CHECKOUT, "vc-check-out", ReadOnly },
@ -291,14 +291,14 @@ void LyXAction::init()
{ LFUN_VC_REVERT, "vc-revert", ReadOnly }, { LFUN_VC_REVERT, "vc-revert", ReadOnly },
{ LFUN_VC_UNDO, "vc-undo-last", ReadOnly }, { LFUN_VC_UNDO, "vc-undo-last", ReadOnly },
{ LFUN_WORDLEFT, "word-backward", ReadOnly | NoUpdate}, { 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_CAPITALIZE_WORD, "word-capitalize", Noop },
{ LFUN_DELETE_WORD_BACKWARD, "word-delete-backward", Noop }, { LFUN_DELETE_WORD_BACKWARD, "word-delete-backward", Noop },
{ LFUN_DELETE_WORD_FORWARD, "word-delete-forward", Noop }, { LFUN_DELETE_WORD_FORWARD, "word-delete-forward", Noop },
{ LFUN_WORDFINDBACKWARD, "word-find-backward", ReadOnly }, { LFUN_WORDFINDBACKWARD, "word-find-backward", ReadOnly },
{ LFUN_WORDFINDFORWARD, "word-find-forward", ReadOnly }, { LFUN_WORDFINDFORWARD, "word-find-forward", ReadOnly },
{ LFUN_WORDRIGHT, "word-forward", ReadOnly | NoUpdate}, { 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_LOWCASE_WORD, "word-lowcase", Noop },
{ LFUN_WORDSEL, "word-select", ReadOnly }, { LFUN_WORDSEL, "word-select", ReadOnly },
{ LFUN_UPCASE_WORD, "word-upcase", Noop }, { LFUN_UPCASE_WORD, "word-upcase", Noop },
@ -348,7 +348,7 @@ void LyXAction::init()
{ LFUN_FINISHED_UP, "", ReadOnly }, { LFUN_FINISHED_UP, "", ReadOnly },
{ LFUN_FINISHED_DOWN, "", ReadOnly }, { LFUN_FINISHED_DOWN, "", ReadOnly },
{ LFUN_MOUSE_PRESS, "", ReadOnly }, { LFUN_MOUSE_PRESS, "", ReadOnly },
{ LFUN_MOUSE_MOTION, "", ReadOnly }, { LFUN_MOUSE_MOTION, "", ReadOnly | SingleParUpdate },
{ LFUN_MOUSE_RELEASE, "", ReadOnly }, { LFUN_MOUSE_RELEASE, "", ReadOnly },
{ LFUN_MOUSE_DOUBLE, "", ReadOnly }, { LFUN_MOUSE_DOUBLE, "", ReadOnly },
{ LFUN_MOUSE_TRIPLE, "", ReadOnly }, { LFUN_MOUSE_TRIPLE, "", ReadOnly },

View File

@ -63,6 +63,7 @@ error_item errorTags[] = {
{ Debug::GRAPHICS, "graphics", N_("Graphics conversion and loading")}, { Debug::GRAPHICS, "graphics", N_("Graphics conversion and loading")},
{ Debug::CHANGES, "changes", N_("Change tracking")}, { Debug::CHANGES, "changes", N_("Change tracking")},
{ Debug::EXTERNAL, "external", N_("External template/inset messages")}, { Debug::EXTERNAL, "external", N_("External template/inset messages")},
{ Debug::PAINTING, "painting", N_("RowPainter profiling")},
{ Debug::DEBUG, "debug", N_("Developers' general debug messages")}, { Debug::DEBUG, "debug", N_("Developers' general debug messages")},
{ Debug::ANY, "any", N_("All debugging messages")} { Debug::ANY, "any", N_("All debugging messages")}
}; };

View File

@ -74,6 +74,8 @@ public:
/// ///
EXTERNAL = (1 << 23), EXTERNAL = (1 << 23),
/// ///
PAINTING = (1 << 24),
///
DEBUG = (1 << 31), DEBUG = (1 << 31),
/// ///
ANY = 0xffffffff ANY = 0xffffffff

View File

@ -1,17 +1,31 @@
2006-03-18 Georg Baum <Georg.Baum@post.rwth-aachen.de>
* insetbase.h (asTextInset):
* insettext.h (asTextInset): constify
2006-03-17 Martin Vermeer <martin.vermeer@hut.fi>
Changes to the within-inset row rendering caching code.
* insetenv.h (isTextInset):
* insetcollapsable.h (isTextInset): remove method
* insettabular.h (canTrackChanges):
* insetbase.h (canTrackChange): rename from isTextInset, add methods
* insettext.[Ch]: rename method; add Tall()
2006-03-11 Jürgen Spitzmüller <j.spitzmueller@gmx.de> 2006-03-11 Jürgen Spitzmüller <j.spitzmueller@gmx.de>
*insettabular (doDispatch, insertAsciiString): * insettabular (doDispatch, insertAsciiString): fix insertion of
fix insertion of \t- and \n-separated content from external \t- and \n-separated content from external clipboard (bug 2394).
clipboard (bug 2394).
2006-03-23 Lars Gullik Bjønnes <larsbj@gullik.net> 2006-03-23 Lars Gullik Bjønnes <larsbj@gullik.net>
* insettext.h: get forward declaration of ParagraphList * insettext.h: get forward declaration of ParagraphList
* insetbibitem.C: get proper ParagraphList decls * insetbibitem.C: get proper ParagraphList decls
* insettext.C (appendParagraphs): * insettext.C (appendParagraphs):
* insetcharstyle.C (docbook): use std::distance * insetcharstyle.C (docbook): use std::distance
2006-03-24 Jean-Marc Lasgouttes <lasgouttes@lyx.org> 2006-03-24 Jean-Marc Lasgouttes <lasgouttes@lyx.org>
@ -41,7 +55,8 @@
2006-02-22 Jürgen Spitzmüller <j.spitzmueller@gmx.de> 2006-02-22 Jürgen Spitzmüller <j.spitzmueller@gmx.de>
* insetfootlike.C (metrics, draw): use buffer's default font (bug 2308). * insetfootlike.C (metrics, draw): use buffer's default font (bug
2308).
2006-02-05 Martin Vermeer <martin.vermeer@hut.fi> 2006-02-05 Martin Vermeer <martin.vermeer@hut.fi>

View File

@ -21,6 +21,7 @@ class BufferView;
class CursorSlice; class CursorSlice;
class FuncRequest; class FuncRequest;
class FuncStatus; class FuncStatus;
class InsetText;
class LaTeXFeatures; class LaTeXFeatures;
class LCursor; class LCursor;
class LyXLex; class LyXLex;
@ -216,8 +217,10 @@ public:
virtual EDITABLE editable() const; virtual EDITABLE editable() const;
/// can we go further down on mouse click? /// can we go further down on mouse click?
virtual bool descendable() const { return false; } virtual bool descendable() const { return false; }
/// /// does this contain text that can be change track marked in DVI?
virtual bool isTextInset() const { return false; } virtual bool canTrackChanges() const { return false; }
/// is this inset based on the TextInset class?
virtual InsetText const * asTextInset() const { return 0; }
/// return true if the inset should be removed automatically /// return true if the inset should be removed automatically
virtual bool autoDelete() const; virtual bool autoDelete() const;

View File

@ -138,7 +138,7 @@ void InsetCollapsable::metrics(MetricsInfo & mi, Dimension & dim) const
dim = dimensionCollapsed(); dim = dimensionCollapsed();
if (status() == Open) { if (status() == Open) {
InsetText::metrics(mi, textdim_); InsetText::metrics(mi, textdim_);
openinlined_ = (textdim_.wid + dim.wid <= mi.base.textwidth); openinlined_ = textdim_.wid + 2 * dim.wid <= mi.base.textwidth;
if (openinlined_) { if (openinlined_) {
dim.wid += textdim_.wid; dim.wid += textdim_.wid;
dim.des = max(dim.des - textdim_.asc + dim.asc, textdim_.des); dim.des = max(dim.des - textdim_.asc + dim.asc, textdim_.des);
@ -171,6 +171,7 @@ void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const
button_dim.y2 = top + dimc.height(); button_dim.y2 = top + dimc.height();
pi.pain.buttonText(xx, top + dimc.asc, label, labelfont_); pi.pain.buttonText(xx, top + dimc.asc, label, labelfont_);
if (status() == Open) { if (status() == Open) {
int textx, texty; int textx, texty;
if (openinlined_) { if (openinlined_) {

View File

@ -57,8 +57,6 @@ public:
/// can we go further down on mouse click? /// can we go further down on mouse click?
bool descendable() const; bool descendable() const;
/// ///
bool isTextInset() const { return true; }
///
void setLabel(std::string const & l); void setLabel(std::string const & l);
/// ///
virtual void setButtonLabel() {} virtual void setButtonLabel() {}

View File

@ -34,8 +34,6 @@ public:
/// ///
InsetBase::EDITABLE editable() const { return HIGHLY_EDITABLE; } InsetBase::EDITABLE editable() const { return HIGHLY_EDITABLE; }
/// ///
bool isTextInset() const { return true; }
///
LyXLayout_ptr const & layout() const; LyXLayout_ptr const & layout() const;
/** returns true if, when outputing LaTeX, font changes should /** returns true if, when outputing LaTeX, font changes should
be closed before generating this inset. This is needed for be closed before generating this inset. This is needed for

View File

@ -69,7 +69,7 @@ public:
/// ///
bool insetAllowed(InsetBase::Code) const { return true; } 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 /** returns true if, when outputing LaTeX, font changes should
be closed before generating this inset. This is needed for be closed before generating this inset. This is needed for
insets that may contain several paragraphs */ insets that may contain several paragraphs */

View File

@ -200,6 +200,7 @@ void InsetText::draw(PainterInfo & pi, int x, int y) const
// update our idea of where we are // update our idea of where we are
setPosCache(pi, x, y); setPosCache(pi, x, y);
text_.background_color_ = backgroundColor();
text_.draw(pi, x + border_, y); text_.draw(pi, x + border_, y);
if (drawFrame_) { if (drawFrame_) {
@ -207,7 +208,7 @@ void InsetText::draw(PainterInfo & pi, int x, int y) const
int const a = text_.ascent() + border_; int const a = text_.ascent() + border_;
int const h = a + text_.descent() + border_; int const h = a + text_.descent() + border_;
int const ww = pi.base.bv->workWidth(); 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, ww, y - a, frameColor());
pi.pain.line(0, y - a + h, ww, y - a + h, frameColor()); pi.pain.line(0, y - a + h, ww, y - a + h, frameColor());
} else { } else {
@ -219,13 +220,16 @@ void InsetText::draw(PainterInfo & pi, int x, int y) const
void InsetText::drawSelection(PainterInfo & pi, int x, int y) const void InsetText::drawSelection(PainterInfo & pi, int x, int y) const
{ {
if (backgroundColor() != LColor::background) { int const w = text_.width() + 2 * border_;
// repaint the background if needed int const a = text_.ascent() + border_;
int const w = text_.width() + 2 * border_; int const h = a + text_.descent() + border_;
int const a = text_.ascent() + border_; int const ww = pi.base.bv->workWidth();
int const h = a + text_.descent() + border_; if (Wide())
pi.pain.fillRectangle(x, y - a, w, h, backgroundColor()); pi.pain.fillRectangle(0, y - a, ww, h,
} backgroundColor());
else
pi.pain.fillRectangle(x, y - a, w, h,
backgroundColor());
text_.drawSelection(pi, x, y); text_.drawSelection(pi, x, y);
} }
@ -254,6 +258,12 @@ InsetBase * InsetText::editXY(LCursor & cur, int x, int y)
} }
bool const InsetText::Tall() const
{
return text_.ascent() + text_.descent() > 2 * defaultRowHeight();
}
void InsetText::doDispatch(LCursor & cur, FuncRequest & cmd) void InsetText::doDispatch(LCursor & cur, FuncRequest & cmd)
{ {
lyxerr[Debug::DEBUG] << BOOST_CURRENT_FUNCTION lyxerr[Debug::DEBUG] << BOOST_CURRENT_FUNCTION

View File

@ -57,7 +57,9 @@ public:
/// ///
EDITABLE editable() const { return HIGHLY_EDITABLE; } EDITABLE editable() const { return HIGHLY_EDITABLE; }
/// ///
bool isTextInset() const { return true; } bool canTrackChanges() const { return true; }
///
InsetText const * asTextInset() const { return this; }
/// ///
int latex(Buffer const &, std::ostream &, int latex(Buffer const &, std::ostream &,
OutputParams const &) const; OutputParams const &) const;
@ -137,6 +139,10 @@ public:
bool neverIndent() const; bool neverIndent() const;
/// ///
InsetText(InsetText const &); InsetText(InsetText const &);
///
bool & Wide() const { return wide_inset_; }
///
bool const Tall() const;
protected: protected:
/// ///
@ -158,6 +164,8 @@ private:
mutable lyx::pit_type old_pit; mutable lyx::pit_type old_pit;
/// ///
static int border_; static int border_;
///
mutable bool wide_inset_;
public: public:
/// ///
mutable LyXText text_; mutable LyXText text_;

View File

@ -1,3 +1,7 @@
2006-03-17 Martin Vermeer <martin.vermeer@hut.fi>
* math_hullinset.h (canTrackChanges): renamed from isTextInset.
2006-03-14 Georg Baum <Georg.Baum@post.rwth-aachen.de> 2006-03-14 Georg Baum <Georg.Baum@post.rwth-aachen.de>
* math_parser.C (parse1): Parse \tag and \tag* correctly * math_parser.C (parse1): Parse \tag and \tag* correctly

View File

@ -189,7 +189,7 @@ public:
/// what appears in the minibuffer when opening /// what appears in the minibuffer when opening
virtual std::string const editMessage() const; virtual std::string const editMessage() const;
/// ///
virtual bool isTextInset() const { return true; } virtual bool canTrackChanges() const { return true; }
/// ///
virtual void mutateToText(); virtual void mutateToText();
/// ///

View File

@ -536,7 +536,7 @@ void Paragraph::Pimpl::simpleTeXSpecialChars(Buffer const & buf,
&& runparams.flavor == OutputParams::LATEX && runparams.flavor == OutputParams::LATEX
&& features.isAvailable("dvipost"); && features.isAvailable("dvipost");
if (inset->isTextInset()) { if (inset->canTrackChanges()) {
column += Changes::latexMarkChange(os, running_change, column += Changes::latexMarkChange(os, running_change,
Change::UNCHANGED, output); Change::UNCHANGED, output);
running_change = Change::UNCHANGED; running_change = Change::UNCHANGED;

View File

@ -164,8 +164,17 @@ void RowPainter::paintInset(pos_type const pos, LyXFont const & font)
pi.ltr_pos = (text_.bidi.level(pos) % 2 == 0); pi.ltr_pos = (text_.bidi.level(pos) % 2 == 0);
pi.erased_ = erased_ || isDeletedText(par_, pos); pi.erased_ = erased_ || isDeletedText(par_, pos);
theCoords.insets().add(inset, int(x_), yo_); theCoords.insets().add(inset, int(x_), yo_);
inset->drawSelection(pi, int(x_), yo_); InsetText const * const in = inset->asTextInset();
// non-wide insets are painted completely. Recursive
bool tmp = bv_.repaintAll();
if (!in || !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_); inset->draw(pi, int(x_), yo_);
bv_.repaintAll(tmp);
x_ += inset->width(); 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; boost::crc_32_type crc;
for (lyx::pos_type i = row.pos(); i < row.endpos(); ++i) { for (lyx::pos_type i = row.pos(); i < row.endpos(); ++i) {
const unsigned char b[] = { par.getChar(i) }; const unsigned char b[] = { par.getChar(i) };
crc.process_bytes(b, 1); crc.process_bytes(b, 1);
} }
const unsigned char b[] = { x, y, row.width() };
crc.process_bytes(b, 3);
return crc.checksum(); 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(); LCursor & cur = pi.base.bv->cursor();
for (lyx::size_type d = 0; d < cur.depth(); d++) for (lyx::size_type d = 0; d < cur.depth(); d++) {
if (cur[d].pit() == pit CursorSlice const & sl = cur[d];
&& cur[d].pos() >= rit->pos() if (sl.text() == &text
&& cur[d].pos() <= rit->endpos()) && sl.pit() == pit
&& sl.pos() >= rit->pos()
&& sl.pos() < rit->endpos())
return true; 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; return false;
} }
@ -762,17 +798,33 @@ void paintPar
lyx::size_type rowno(0); lyx::size_type rowno(0);
for (RowList::const_iterator rit = rb; rit != re; ++rit, ++rowno) { for (RowList::const_iterator rit = rb; rit != re; ++rit, ++rowno) {
y += rit->ascent(); 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? // Row signature; has row changed since last paint?
lyx::size_type const row_sig = calculateRowSignature(*rit, par); lyx::size_type const row_sig = calculateRowSignature(*rit, par, x, y);
bool row_has_changed = par.rowSignature()[rowno] != row_sig;
bool cursor_on_row = isCursorOnRow(pi, pit, rit);
// 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 const * const in = par.getInset(i);
if (in) {
InsetText const * const t = in->asTextInset();
if (t)
t->Wide() = in_inset_alone_on_row &&
t->Tall();
}
}
// If selection is on, the current row signature differs
// from cache, or cursor is inside an inset _on this row_, // from cache, or cursor is inside an inset _on this row_,
// then paint the row // then paint the row
if (repaintAll || par.rowSignature()[rowno] != row_sig if (repaintAll || row_has_changed || cursor_on_row) {
|| cursor_on_row) {
// Add to row signature cache // Add to row signature cache
par.rowSignature()[rowno] = row_sig; par.rowSignature()[rowno] = row_sig;
@ -781,15 +833,25 @@ void paintPar
RowPainter rp(inside ? pi : nullpi, text, pit, *rit, x, y); RowPainter rp(inside ? pi : nullpi, text, pit, *rit, x, y);
// Clear background of this row // Clear background of this row
// (if paragraph background was not cleared) // (if paragraph background was not cleared)
if (!repaintAll) { if (!repaintAll &&
pi.pain.fillRectangle(x, y - rit->ascent(), (!in_inset_alone_on_row || row_has_changed)) {
pi.pain.fillRectangle(( rowno ? 0 : x - 10 ), y - rit->ascent(),
pi.base.bv->workWidth(), rit->height(), pi.base.bv->workWidth(), rit->height(),
text.backgroundColor()); 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 // Instrumentation for testing row cache (see also
// 12 lines lower): // 12 lines lower):
//lyxerr << "#"; if (text.isMainText())
lyxerr[Debug::PAINTING] << "#";
else
lyxerr[Debug::PAINTING] << "[" <<
repaintAll << row_has_changed <<
cursor_on_row << "]";
rp.paintAppendix(); rp.paintAppendix();
rp.paintDepthBar(); rp.paintDepthBar();
rp.paintChangeBar(); rp.paintChangeBar();
@ -800,8 +862,10 @@ void paintPar
rp.paintText(); rp.paintText();
} }
y += rit->descent(); y += rit->descent();
// Restore, see above
pi.base.bv->repaintAll(tmp);
} }
//lyxerr << "." << endl; lyxerr[Debug::PAINTING] << "." << endl;
} }
} // namespace anon } // namespace anon
@ -814,8 +878,11 @@ void paintText(BufferView const & bv, ViewMetricsInfo const & vi)
bool const select = bv.cursor().selection(); bool const select = bv.cursor().selection();
PainterInfo pi(const_cast<BufferView *>(&bv), pain); PainterInfo pi(const_cast<BufferView *>(&bv), pain);
if (select || !vi.singlepar) { // Should the whole screen, including insets, be refreshed?
// Clear background (Delegated to rows if no selection) 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, pain.fillRectangle(0, vi.y1, bv.workWidth(), vi.y2 - vi.y1,
text->backgroundColor()); text->backgroundColor());
} }
@ -826,9 +893,10 @@ void paintText(BufferView const & bv, ViewMetricsInfo const & vi)
int yy = vi.y1; int yy = vi.y1;
// draw contents // draw contents
for (pit_type pit = vi.p1; pit <= vi.p2; ++pit) { for (pit_type pit = vi.p1; pit <= vi.p2; ++pit) {
bv.repaintAll(repaintAll);
Paragraph const & par = text->getPar(pit); Paragraph const & par = text->getPar(pit);
yy += par.ascent(); yy += par.ascent();
paintPar(pi, *bv.text(), pit, 0, yy, select || !vi.singlepar); paintPar(pi, *bv.text(), pit, 0, yy, repaintAll);
yy += par.descent(); yy += par.descent();
} }
@ -865,9 +933,11 @@ void paintTextInset(LyXText const & text, PainterInfo & pi, int x, int y)
// lyxerr << " paintTextInset: y: " << y << endl; // lyxerr << " paintTextInset: y: " << y << endl;
y -= text.getPar(0).ascent(); 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) { for (int pit = 0; pit < int(text.paragraphs().size()); ++pit) {
y += text.getPar(pit).ascent(); y += text.getPar(pit).ascent();
paintPar(pi, text, pit, x, y, true); paintPar(pi, text, pit, x, y, repaintAll);
y += text.getPar(pit).descent(); y += text.getPar(pit).descent();
} }
} }

View File

@ -628,12 +628,16 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
case LFUN_DELETE: case LFUN_DELETE:
if (!cur.selection()) { if (!cur.selection()) {
if (cur.pos() == cur.paragraph().size())
// Par boundary, force full-screen update
singleParUpdate = false;
needsUpdate = Delete(cur); needsUpdate = Delete(cur);
cur.resetAnchor(); cur.resetAnchor();
// It is possible to make it a lot faster still // It is possible to make it a lot faster still
// just comment out the line below... // just comment out the line below...
} else { } else {
cutSelection(cur, true, false); cutSelection(cur, true, false);
singleParUpdate = false;
} }
moveCursor(cur, false); moveCursor(cur, false);
break; break;
@ -656,6 +660,9 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
case LFUN_BACKSPACE: case LFUN_BACKSPACE:
if (!cur.selection()) { if (!cur.selection()) {
if (bv->owner()->getIntl().getTransManager().backspace()) { if (bv->owner()->getIntl().getTransManager().backspace()) {
// Par boundary, full-screen update
if (cur.pos() == 0)
singleParUpdate = false;
needsUpdate = backspace(cur); needsUpdate = backspace(cur);
cur.resetAnchor(); cur.resetAnchor();
// It is possible to make it a lot faster still // It is possible to make it a lot faster still
@ -663,6 +670,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
} }
} else { } else {
cutSelection(cur, true, false); cutSelection(cur, true, false);
singleParUpdate = false;
} }
bv->switchKeyMap(); bv->switchKeyMap();
break; break;
@ -1532,10 +1540,14 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
if (singleParUpdate) if (singleParUpdate)
// Inserting characters does not change par height // Inserting characters does not change par height
if (cur.bottom().paragraph().dim().height() if (cur.bottom().paragraph().dim().height()
== olddim.height()) { == olddim.height()) {
// if so, update _only_ this paragraph // 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 } else
needsUpdate = true; needsUpdate = true;
if (!needsUpdate if (!needsUpdate

View File

@ -58,6 +58,8 @@ What's new
* User Interface: * User Interface:
- Fix slowness in rendering inside insets, especially on the Mac (bug 2195)
- Convert line endings for external copy/paste on OS X (bug 1955). - Convert line endings for external copy/paste on OS X (bug 1955).
- Disable saving when document is unchanged (bug 2313). - Disable saving when document is unchanged (bug 2313).