Hello everybody,
this patch should cure all crashes related to accepting a change. I will
provide a similar patch for reject-change tomorrow (hopefully).
One thing that I am not very happy about is the invocation of DEPM,
because the latter makes use of cursors, calls the undo mechanism, etc.
(too much for this simple case).
I intend to write a simplified version of DEPM. What I would like to use
is a loop iterating over a range of paragraphs that (1) removes empty
lines, (2) strips leading spaces, and (3) removes double spaces.
Does anybody know whether there are already some methods that I can reuse?
Michael
[EMAIL PROTECTED] schrieb:
Author: schmitt
Date: Sun Jan 21 22:20:51 2007
New Revision: 16799
URL: http://www.lyx.org/trac/changeset/16799
Log:
* src/text.C: acceptChange(): complete rewrite; there should be no
crashes any more
Modified:
lyx-devel/trunk/src/text.C
Modified: lyx-devel/trunk/src/text.C
URL: http://www.lyx.org/trac/file/lyx-devel/trunk/src/text.C?rev=16799
==============================================================================
--- lyx-devel/trunk/src/text.C (original)
+++ lyx-devel/trunk/src/text.C Sun Jan 21 22:20:51 2007
@@ -847,42 +847,88 @@
void LyXText::acceptChange(LCursor & cur)
{
- // FIXME: change tracking (MG)
-
BOOST_ASSERT(this == cur.text());
- if (!cur.selection() && cur.lastpos() != 0)
+ if (!cur.selection())
return;
- // FIXME: we must handle start = end = 0
-
- recordUndoSelection(cur, Undo::INSERT);
-
- DocIterator it = cur.selectionBegin();
- DocIterator et = cur.selectionEnd();
- pit_type pit = it.pit();
- for (; pit <= et.pit(); ++pit) {
- pos_type left = (pit == it.pit() ? it.pos() : 0);
- pos_type right = (pit == et.pit() ? et.pos() :
pars_[pit].size());
-
- // handle imaginary end-of-par character first
- if (right == pars_[pit].size() &&
!pars_[pit].isUnchanged(right)) {
- if (pars_[pit].isInserted(right)) {
- pars_[pit].setChange(right,
Change(Change::UNCHANGED));
- } else {
- // if (pit + 1 < et.pit()) {
- // setCursorIntern(cur, pit + 1, 0);
- // backspacePos0(cur);
- // }
+ recordUndoSelection(cur, Undo::ATOMIC);
+
+ DocIterator beg = cur.selectionBegin();
+ DocIterator end = cur.selectionEnd();
+
+ // first, accept changes within each individual paragraph (do not
consider end-of-par)
+
+ for (pit_type pit = beg.pit(); pit <= end.pit(); ++pit) {
+ // ignore empty paragraphs; otherwise, an assertion will fail for acceptChanges(0, 0)
+ if (pars_[pit].size() == 0)
+ continue;
+
+ // do not consider first paragraph if the cursor starts at pos
size()
+ if (pit == beg.pit() && beg.pos() == pars_[pit].size())
+ continue;
+
+ // do not consider last paragraph if the cursor ends at pos 0
+ if (pit == end.pit() && end.pos() == 0)
+ break; // last iteration anyway
+
+ pos_type left = (pit == beg.pit() ? beg.pos() : 0);
+ pos_type right = (pit == end.pit() ? end.pos() :
pars_[pit].size());
+ pars_[pit].acceptChanges(left, right);
+ }
+
+ // next, accept imaginary end-of-par characters
+ // iterate from last to first paragraph such that we don't have to care for a changing 'end'
+
+ pos_type endpit = end.pit();
+ for (pit_type pit = endpit; pit >= beg.pit(); --pit) {
+ pos_type pos = pars_[pit].size();
+
+ // last paragraph of the selection requires special handling
+ if (pit == end.pit()) {
+ // skip if the selection ends before the end-of-par
+ if (end.pos < pos)
+ continue;
+
+ // skip if the selection ends with the end-of-par and
this is not the
+ // last paragraph of the document
+ // note: the user must be able to accept the end-of-par
of the last par!
+ if (end.pos == pos && pit != pars_.size() - 1)
+ continue;
+ }
+
+
+ if (!pars_[pit].isUnchanged(pos)) {
+ if (pars_[pit].isInserted(pos)) {
+ pars_[pit].setChange(pos,
Change(Change::UNCHANGED));
+ } else { // isDeleted
+ if (pit == pars_.size()) {
+ // we cannot remove a par break at the
end of the last paragraph
+ // instead, we mark it unchanged
+ pars_[pit].setChange(pos,
Change(Change::UNCHANGED));
+ } else {
+ mergeParagraph(cur.buffer().params(),
pars_, pit);
+ endpit--;
+ }
}
}
-
- pars_[pit].acceptChanges(left, right);
- }
+ }
+
+ // 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 >= beg.pit(); --pit) {
+ bool dummy;
+ LCursor old = cur;
+ setCursorIntern(cur, pit, 0);
+ deleteEmptyParagraphMechanism(cur, old, dummy);
+ }
+
finishUndo();
cur.clearSelection();
- setCursorIntern(cur, it.pit(), it.pos());
+ setCursorIntern(cur, beg.pit(), beg.pos());
cur.updateFlags(Update::Force);
+ updateLabels(cur.buffer());
}
_______________________________________________
Cvslog mailing list
[EMAIL PROTECTED]
http://www.lyx.org/mailman/listinfo/cvslog