Abdel, Jean-Marc,
here is my first attempt to incorporate a simple & efficient DEPM into
accept/reject change.
I think this code will be even smarter if accept/rejectChange() become
members of LyXText. Unfortunately, I ran out of time today...
Anyway, please provide comments on the existing patch.
Michael
Index: src/insets/insettext.C
===================================================================
--- src/insets/insettext.C (Revision 16842)
+++ src/insets/insettext.C (Arbeitskopie)
@@ -280,14 +280,13 @@
void InsetText::acceptChanges(BufferParams const & bparams)
{
ParagraphList & pars = paragraphs();
- pit_type const pars_size = (pit_type) pars.size();
+ pit_type pars_size = (pit_type) pars.size();
// first, accept changes within each individual paragraph
// (do not consider end-of-par)
for (pit_type pit = 0; pit < pars_size; ++pit) {
- if (pars[pit].empty()) // prevent assertion failure
- continue;
- pars[pit].acceptChanges(bparams, 0, pars[pit].size());
+ if (!pars[pit].empty()) // prevent assertion failure
+ pars[pit].acceptChanges(bparams, 0, pars[pit].size());
}
// next, accept imaginary end-of-par characters
@@ -304,27 +303,26 @@
} else {
mergeParagraph(bparams, pars, pit);
--pit;
+ --pars_size;
}
}
}
- // FIXME: finally, invoke the DEPM
- // This cannot be done here but at a higher calling level
- // because we need BufferView::checkDepm().
+ // finally, invoke the DEPM
+ text_.deleteEmptyParagraphMechanism(0, pars.size() - 1,
bparams.trackChanges);
}
void InsetText::rejectChanges(BufferParams const & bparams)
{
ParagraphList & pars = paragraphs();
- pit_type const pars_size = (pit_type) pars.size();
+ pit_type pars_size = (pit_type) pars.size();
- // first, reject changes within each individual paragraph (do not
- // consider end-of-par)
+ // first, reject changes within each individual paragraph
+ // (do not consider end-of-par)
for (pit_type pit = 0; pit < pars_size; ++pit) {
- if (pars[pit].empty()) // prevent assertion failure
- continue;
- pars[pit].rejectChanges(bparams, 0, pars[pit].size());
+ if (!pars[pit].empty()) // prevent assertion failure
+ pars[pit].rejectChanges(bparams, 0, pars[pit].size());
}
// next, reject imaginary end-of-par characters
@@ -341,13 +339,13 @@
} else {
mergeParagraph(bparams, pars, pit);
--pit;
+ --pars_size;
}
}
}
- // FIXME: finally, invoke the DEPM
- // This cannot be done here but at a higher calling level
- // because we need BufferView::checkDepm().
+ // finally, invoke the DEPM
+ text_.deleteEmptyParagraphMechanism(0, pars.size() - 1,
bparams.trackChanges);
}
Index: src/text2.C
===================================================================
--- src/text2.C (Revision 16842)
+++ src/text2.C (Arbeitskopie)
@@ -1180,7 +1180,7 @@
&& oldpar.isLineSeparator(old.pos())
&& oldpar.isLineSeparator(old.pos() - 1)
&& !oldpar.isDeleted(old.pos() - 1)) {
- oldpar.eraseChar(old.pos() - 1, false); // do not track
changes in DEPM
+ oldpar.eraseChar(old.pos() - 1,
cur.buffer().params().trackChanges);
#ifdef WITH_WARNINGS
#warning This will not work anymore when we have multiple views of the same
buffer
// In this case, we will have to correct also the cursors held by
@@ -1244,6 +1244,45 @@
}
+void LyXText::deleteEmptyParagraphMechanism(pit_type first, pit_type last,
bool trackChanges)
+{
+ for (pit_type pit = first; pit <= last; ++pit) {
+ Paragraph & par = pars_[pit];
+
+ // We allow all kinds of "mumbo-jumbo" when freespacing.
+ if (par.isFreeSpacing())
+ continue;
+
+ for (pos_type pos = 1; pos < par.size(); ++pos) {
+ if (par.isLineSeparator(pos) && par.isLineSeparator(pos
- 1)
+ && !par.isDeleted(pos - 1)) {
+ if (par.eraseChar(pos - 1, trackChanges)) {
+ --pos;
+ }
+ }
+ }
+
+ // don't delete anything if this is the ONLY paragraph
+ if (pars_.size() == 1)
+ continue;
+
+ // don't delete empty paragraphs with keepempty set
+ if (par.allowEmpty())
+ continue;
+
+ if (par.empty() || (par.size() == 1 && par.isLineSeparator(0)))
{
+ pars_.erase(boost::next(pars_.begin(), pit));
+ --pit;
+ --last;
+ continue;
+ }
+
+ par.stripLeadingSpaces(trackChanges);
+ }
+}
+
+
+
void LyXText::recUndo(LCursor & cur, pit_type first, pit_type last) const
{
recordUndo(cur, Undo::ATOMIC, first, last);
Index: src/lyxtext.h
===================================================================
--- src/lyxtext.h (Revision 16842)
+++ src/lyxtext.h (Arbeitskopie)
@@ -153,8 +153,13 @@
/// just selects the word the cursor is in
void selectWord(LCursor & cur, word_location loc);
+ /// what type of change operation to make
+ enum ChangeOp {
+ ACCEPT,
+ REJECT
+ };
/// accept or reject the selected change
- void acceptOrRejectChange(LCursor & cur, bool accept);
+ void acceptOrRejectChange(LCursor & cur, ChangeOp op);
/// returns true if par was empty and was removed
bool setCursor(LCursor & cur, pit_type par, pos_type pos,
@@ -343,6 +348,10 @@
bool deleteEmptyParagraphMechanism(LCursor & cur,
LCursor & old, bool & need_anchor_change);
+ /// delete double spaces, leading spaces, and empty paragraphs
+ /// from \first to \last paragraph
+ void deleteEmptyParagraphMechanism(pit_type first, pit_type last, bool
trackChanges);
+
public:
/// the current font settings
LyXFont current_font;
Index: src/text3.C
===================================================================
--- src/text3.C (Revision 16842)
+++ src/text3.C (Arbeitskopie)
@@ -1429,12 +1429,12 @@
}
case LFUN_CHANGE_ACCEPT: {
- acceptOrRejectChange(cur, true);
+ acceptOrRejectChange(cur, ACCEPT);
break;
}
case LFUN_CHANGE_REJECT: {
- acceptOrRejectChange(cur, false);
+ acceptOrRejectChange(cur, REJECT);
break;
}
Index: src/BufferView.C
===================================================================
--- src/BufferView.C (Revision 16842)
+++ src/BufferView.C (Arbeitskopie)
@@ -859,7 +859,7 @@
#warning FIXME changes
#endif
while (findNextChange(this))
- getLyXText()->acceptOrRejectChange(cursor_, true);
+ getLyXText()->acceptOrRejectChange(cursor_,
LyXText::ChangeOp::ACCEPT);
update();
break;
}
@@ -870,7 +870,7 @@
#warning FIXME changes
#endif
while (findNextChange(this))
- getLyXText()->acceptOrRejectChange(cursor_, false);
+ getLyXText()->acceptOrRejectChange(cursor_,
LyXText::ChangeOp::REJECT);
break;
}
Index: src/text.C
===================================================================
--- src/text.C (Revision 16842)
+++ src/text.C (Arbeitskopie)
@@ -845,7 +845,7 @@
}
-void LyXText::acceptOrRejectChange(LCursor & cur, bool accept)
+void LyXText::acceptOrRejectChange(LCursor & cur, ChangeOp op)
{
BOOST_ASSERT(this == cur.text());
@@ -884,7 +884,7 @@
pos_type left = (pit == begPit ? begPos : 0);
pos_type right = (pit == endPit ? endPos : parSize);
- if (accept) {
+ if (op == ACCEPT) {
pars_[pit].acceptChanges(cur.buffer().params(), left,
right);
} else {
pars_[pit].rejectChanges(cur.buffer().params(), left,
right);
@@ -905,7 +905,7 @@
if (pit == endPit && pit != pars_.size() - 1)
break; // last iteration anway
- if (accept) {
+ if (op == ACCEPT) {
if (pars_[pit].isInserted(pos)) {
pars_[pit].setChange(pos,
Change(Change::UNCHANGED));
} else if (pars_[pit].isDeleted(pos)) {
@@ -936,15 +936,11 @@
}
// finally, invoke the DEPM
- // FIXME: the following code will be changed in the near future
- setCursorIntern(cur, endPit, 0);
- for (pit_type pit = endPit - 1; pit >= begPit; --pit) {
- bool dummy;
- LCursor old = cur;
- setCursorIntern(cur, pit, 0);
- deleteEmptyParagraphMechanism(cur, old, dummy);
- }
+ deleteEmptyParagraphMechanism(begPit, endPit,
cur.buffer().params().trackChanges);
+
+ //
+
finishUndo();
cur.clearSelection();
setCursorIntern(cur, begPit, begPos);