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