On Wed, Oct 25, 2006 at 03:47:35PM +0200, Jean-Marc Lasgouttes wrote: > >>>>> "Martin" == Martin Vermeer <[EMAIL PROTECTED]> writes: > > Martin> Or even simpler... > > It looks very simple indeed, but crashes on undo: load Intro, do a Up > on chapter 3 and then undo. > > Sorry I am a bit too busy now to debug it.
OK, I did it and also the name changes and comments.
This works for me now -- none of the earlier crashes.
- Martin
PS I notice an other bug: the "current header" in the ToC dialog is not
painted blue as it should in the case of chapter headers. The reason is
in QToc.C:
// Recognise part past the counter
if (iter->str.substr(iter->str.find(' ') + 1) == text_)
this uses the part past the first blank as a 'signature' to test
equality of headers. For "Chapter 5 Xxxx yyyy zzzz" this doesn't work.
I see no easy/safe fix for this.
Index: toc.C
===================================================================
--- toc.C (revision 15477)
+++ toc.C (working copy)
@@ -170,13 +170,14 @@
void outline(OutlineOp mode, LCursor & cur)
{
- recordUndo(cur);
Buffer * buf = & cur.buffer();
pit_type & pit = cur.pit();
ParagraphList & pars = buf->text().paragraphs();
ParagraphList::iterator bgn = pars.begin();
- ParagraphList::iterator s = boost::next(bgn, pit);
- ParagraphList::iterator p = s;
+ // The first paragraph of the area to be copied:
+ ParagraphList::iterator start = boost::next(bgn, pit);
+ // The final paragraph of area to be copied:
+ ParagraphList::iterator finish = start;
ParagraphList::iterator end = pars.end();
LyXTextClass::const_iterator lit =
@@ -184,86 +185,101 @@
LyXTextClass::const_iterator const lend =
buf->params().getLyXTextClass().end();
- int const thistoclevel = s->layout()->toclevel;
+ int const thistoclevel = start->layout()->toclevel;
int toclevel;
switch (mode) {
case Up: {
- if (p != end)
- ++p;
- for (; p != end; ++p) {
- toclevel = p->layout()->toclevel;
+ // Move out (down) from this section header
+ if (finish != end)
+ ++finish;
+ // Seek the one (on same level) below
+ for (; finish != end; ++finish) {
+ toclevel = finish->layout()->toclevel;
if (toclevel != LyXLayout::NOT_IN_TOC
&& toclevel <= thistoclevel) {
break;
}
}
- ParagraphList::iterator q = s;
- if (q != bgn)
- --q;
+ ParagraphList::iterator dest = start;
+ // Move out (up) from this header
+ if (dest != bgn)
+ --dest;
else
break;
- for (; q != bgn; --q) {
- toclevel = q->layout()->toclevel;
+ // Search previous same-level header above
+ for (; dest != bgn; --dest) {
+ toclevel = dest->layout()->toclevel;
if (toclevel != LyXLayout::NOT_IN_TOC
&& toclevel <= thistoclevel) {
break;
}
}
- pit_type const newpit = std::distance(pars.begin(), q);
- pit_type const len = std::distance(s, p);
+ // Not found; do nothing
+ if (dest == bgn)
+ break;
+ pit_type const newpit = std::distance(bgn, dest);
+ pit_type const len = std::distance(start, finish);
pit += len;
- pars.insert(q, s, p);
- s = boost::next(pars.begin(), pit);
- ParagraphList::iterator t = boost::next(s, len);
+ pit = std::min(pit, cur.lastpit());
+ recordUndo(cur, Undo::ATOMIC, newpit, pit);
+ pars.insert(dest, start, finish);
+ start = boost::next(bgn, pit);
pit = newpit;
- pars.erase(s, t);
+ pars.erase(start, finish);
break;
}
case Down: {
- if (p != end)
- ++p;
- for (; p != end; ++p) {
- toclevel = p->layout()->toclevel;
+ // Go down out of current header:
+ if (finish != end)
+ ++finish;
+ // Find next same-level header:
+ for (; finish != end; ++finish) {
+ toclevel = finish->layout()->toclevel;
if (toclevel != LyXLayout::NOT_IN_TOC
&& toclevel <= thistoclevel) {
break;
}
}
- ParagraphList::iterator q = p;
- if (q != end)
- ++q;
+ ParagraphList::iterator dest = finish;
+ // Go one down from *this* header:
+ if (dest != end)
+ ++dest;
else
break;
- for (; q != end; ++q) {
- toclevel = q->layout()->toclevel;
+ // Go further down to find header to insert in front of:
+ for (; dest != end; ++dest) {
+ toclevel = dest->layout()->toclevel;
if (toclevel != LyXLayout::NOT_IN_TOC
&& toclevel <= thistoclevel) {
break;
}
}
- pit_type const newpit = std::distance(pars.begin(), q);
- pit_type const len = std::distance(s, p);
- pars.insert(q, s, p);
- s = boost::next(pars.begin(), pit);
- ParagraphList::iterator t = boost::next(s, len);
+ // One such was found:
+ pit_type newpit = std::distance(bgn, dest);
+ pit_type const len = std::distance(start, finish);
+ recordUndo(cur, Undo::ATOMIC, pit, newpit -1);
+ pars.insert(dest, start, finish);
+ start = boost::next(bgn, pit);
pit = newpit - len;
- pars.erase(s, t);
+ pars.erase(start, finish);
break;
}
case In:
+ recordUndo(cur);
for (; lit != lend; ++lit) {
if ((*lit)->toclevel == thistoclevel + 1 &&
- s->layout()->labeltype ==
(*lit)->labeltype) {
- s->layout((*lit));
+ start->layout()->labeltype ==
(*lit)->labeltype) {
+ start->layout((*lit));
break;
}
}
break;
case Out:
+ recordUndo(cur);
for (; lit != lend; ++lit) {
if ((*lit)->toclevel == thistoclevel - 1 &&
- s->layout()->labeltype ==
(*lit)->labeltype) {
- s->layout((*lit));
+ start->layout()->labeltype ==
(*lit)->labeltype) {
+ start->layout((*lit));
break;
}
}
pgpC3xitHZxyU.pgp
Description: PGP signature
