... but I feel good. Why not huh ? Mildly tested a few times with save/load/view dvi
john Index: BufferView.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/BufferView.C,v retrieving revision 1.123 diff -u -p -r1.123 BufferView.C --- BufferView.C 8 Mar 2003 05:37:51 -0000 1.123 +++ BufferView.C 12 Mar 2003 03:10:05 -0000 @@ -333,135 +333,50 @@ bool BufferView::insertLyXFile(string co bool BufferView::removeAutoInsets() { - // keep track of which pos and par the cursor was on - Paragraph * cursor_par = text->cursor.par(); - Paragraph * cursor_par_prev = cursor_par ? cursor_par->previous() : 0; - Paragraph * cursor_par_next = cursor_par ? cursor_par->next() : 0; - pos_type cursor_pos = text->cursor.pos(); - bool found = false; - // Trap the deletion of the paragraph the cursor is in. - // Iterate until we find a paragraph that won't be immediately deleted. - // In reality this should mean we only execute the body of the while - // loop once at most. However for safety we iterate rather than just - // make this an if () conditional. - while ((cursor_par_prev || cursor_par_next) - && text->setCursor(this, - cursor_par_prev ? cursor_par_prev : cursor_par_next, - 0)) { - // We just removed cursor_par so have to fix the "cursor" - if (cursor_par_prev) { - // '.' = cursor_par - // a -> a. - // . - cursor_par = cursor_par_prev; - cursor_pos = cursor_par->size(); - } else { - // . -> .a - // a - cursor_par = cursor_par_next; - cursor_pos = 0; - } - cursor_par_prev = cursor_par->previous(); - cursor_par_next = cursor_par->next(); - } - // Iterate through the paragraphs removing autoDelete insets as we go. - // If the paragraph ends up empty after all the autoDelete insets are - // removed that paragraph will be removed by the next setCursor() call. ParIterator it = buffer()->par_iterator_begin(); ParIterator end = buffer()->par_iterator_end(); for (; it != end; ++it) { Paragraph * par = *it; - Paragraph * par_prev = par ? par->previous() : 0; - bool removed = false; - - if (text->setCursor(this, par, 0) - && cursor_par == par_prev) { - // The previous setCursor line was deleted and that - // was the cursor_par line. This can only happen if an - // error box was the sole item on cursor_par. - // It is possible for cursor_par_prev to be stray if - // the line it pointed to only had a error box on it - // so we have to set it to a known correct value. - // This is often the same value it already had. - cursor_par_prev = par->previous(); - if (cursor_par_prev) { - // '|' = par, '.' = cursor_par, 'E' = error box - // First step below may occur before while{} - // a |a a a a. - // E -> .E -> |.E -> . -> |b - // . b b |b - // b - cursor_par = cursor_par_prev; - cursor_pos = cursor_par_prev->size(); - cursor_par_prev = cursor_par->previous(); - // cursor_par_next remains the same - } else if (cursor_par_next) { - // First step below may occur before while{} - // . - // E -> |.E -> |. -> . -> .|a - // a a a |a - cursor_par = cursor_par_next; - cursor_pos = 0; - // cursor_par_prev remains unset - cursor_par_next = cursor_par->next(); - } else { - // I can't find a way to trigger this - // so it should be unreachable code - // unless the buffer is corrupted. - lyxerr << "BufferView::removeAutoInsets() is bad\n"; - } - } InsetList::iterator pit = par->insetlist.begin(); InsetList::iterator pend = par->insetlist.end(); + bool removed = false; + while (pit != pend) { - if (pit.getInset()->autoDelete()) { - removed = true; - pos_type const pos = pit.getPos(); - - par->erase(pos); - // We just invalidated par's inset iterators so - // we get the next valid iterator position - pit = par->insetlist.insetIterator(pos); - // and ensure we have a valid end iterator. - pend = par->insetlist.end(); - - if (cursor_par == par) { - // update the saved cursor position - if (cursor_pos > pos) - --cursor_pos; - } - } else { + if (!pit.getInset()->autoDelete()) { ++pit; + continue; } + + pos_type const pos = pit.getPos(); + + par->erase(pos); + removed = true; + found = true; + + // We just invalidated par's inset iterators so + // we get the next valid iterator position + // FIXME: erase should return the next iterator like STL + pit = par->insetlist.insetIterator(pos); + + // and ensure we have a valid end iterator. + pend = par->insetlist.end(); + + ++pit; } + if (removed) { - found = true; + // don't leave cursor in an impossible position + if (par == text->cursor.par()) + text->cursor.pos(0); + text->redoParagraph(this); } } - - // It is possible that the last line is empty if it was cursor_par - // and/or only had an error inset on it. So we set the cursor to the - // start of the doc to force its removal and ensure a valid saved cursor - if (text->setCursor(this, text->ownerParagraph(), 0) - && 0 == cursor_par_next) { - cursor_par = cursor_par_prev; - cursor_pos = cursor_par->size(); - } else if (cursor_pos > cursor_par->size()) { - // Some C-Enter lines were removed by the setCursor call which - // then invalidated cursor_pos. It could still be "wrong" because - // the cursor may appear to have jumped but since we collapsed - // some C-Enter lines this should be a reasonable compromise. - cursor_pos = cursor_par->size(); - } - - // restore the original cursor in its corrected location. - text->setCursorIntern(this, cursor_par, cursor_pos); return found; } Index: lyxtext.h =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/lyxtext.h,v retrieving revision 1.139 diff -u -p -r1.139 lyxtext.h --- lyxtext.h 10 Mar 2003 00:05:05 -0000 1.139 +++ lyxtext.h 12 Mar 2003 03:10:06 -0000 @@ -305,8 +305,8 @@ public: WordLangTuple const selectNextWordToSpellcheck(BufferView *, float & value) const; /// void selectSelectedWord(BufferView *); - /// returns true if par was empty and was removed - bool setCursor(BufferView *, Paragraph * par, + + void setCursor(BufferView *, Paragraph * par, lyx::pos_type pos, bool setfont = true, bool boundary = false) const; @@ -534,16 +534,6 @@ private: void breakAgain(BufferView *, Row * row) const; /// Calculate and set the height of the row void setHeightOfRow(BufferView *, Row * row_ptr) const; - - // fix the cursor `cur' after a characters has been deleted at `where' - // position. Called by deleteEmptyParagraphMechanism - void fixCursorAfterDelete(BufferView * bv, - LyXCursor & cur, - LyXCursor const & where) const; - - /// delete double space (false) or empty paragraphs (true) around old_cursor - bool deleteEmptyParagraphMechanism(BufferView *, - LyXCursor const & old_cursor) const; public: /** Updates all counters starting BEHIND the row. Changed paragraphs Index: paragraph.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/paragraph.C,v retrieving revision 1.248 diff -u -p -r1.248 paragraph.C --- paragraph.C 11 Mar 2003 16:38:37 -0000 1.248 +++ paragraph.C 12 Mar 2003 03:10:08 -0000 @@ -25,6 +25,7 @@ #include "ParameterStruct.h" #include "gettext.h" #include "changes.h" +#include "paragraph_funcs.h" #include "insets/insetbibitem.h" #include "insets/insetoptarg.h" @@ -147,6 +148,9 @@ void Paragraph::write(Buffer const * buf BufferParams const & bparams, depth_type & dth) const { + if (ignorePar(*this)) + return; + // The beginning or end of a deeper (i.e. nested) area? if (dth != params().depth()) { if (params().depth() > dth) { Index: paragraph_funcs.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/paragraph_funcs.C,v retrieving revision 1.18 diff -u -p -r1.18 paragraph_funcs.C --- paragraph_funcs.C 10 Mar 2003 17:49:24 -0000 1.18 +++ paragraph_funcs.C 12 Mar 2003 03:10:08 -0000 @@ -714,3 +714,12 @@ void latexParagraphs(Buffer const * buf, texrow.newline(); } } + + +bool ignorePar(Paragraph const & par) +{ + if (!par.empty()) + return false; + + return !par.layout()->free_spacing && !par.isFreeSpacing(); +} Index: paragraph_funcs.h =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/paragraph_funcs.h,v retrieving revision 1.13 diff -u -p -r1.13 paragraph_funcs.h --- paragraph_funcs.h 10 Mar 2003 17:49:24 -0000 1.13 +++ paragraph_funcs.h 12 Mar 2003 03:10:08 -0000 @@ -86,4 +86,7 @@ void latexParagraphs(Buffer const * buf, TexRow & texrow, bool moving_arg = false); +/// Return true if this paragraph should not be saved/exported +bool ignorePar(Paragraph const & par); + #endif // PARAGRAPH_FUNCS_H Index: text2.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/text2.C,v retrieving revision 1.286 diff -u -p -r1.286 text2.C --- text2.C 11 Mar 2003 16:38:37 -0000 1.286 +++ text2.C 12 Mar 2003 03:10:14 -0000 @@ -1737,13 +1737,12 @@ bool LyXText::updateInset(BufferView * b } -bool LyXText::setCursor(BufferView * bview, Paragraph * par, +void LyXText::setCursor(BufferView * bview, Paragraph * par, pos_type pos, bool setfont, bool boundary) const { LyXCursor old_cursor = cursor; setCursorIntern(bview, par, pos, setfont, boundary); - return deleteEmptyParagraphMechanism(bview, old_cursor); } @@ -2061,7 +2060,6 @@ void LyXText::setCursorFromCoordinates(B setCursorFromCoordinates(bview, cursor, x, y); setCurrentFont(bview); - deleteEmptyParagraphMechanism(bview, old_cursor); } @@ -2214,214 +2212,6 @@ void LyXText::cursorDownParagraph(Buffer } else { setCursor(bview, cursor.par(), cursor.par()->size()); } -} - -// fix the cursor `cur' after a characters has been deleted at `where' -// position. Called by deleteEmptyParagraphMechanism -void LyXText::fixCursorAfterDelete(BufferView * bview, - LyXCursor & cur, - LyXCursor const & where) const -{ - // if cursor is not in the paragraph where the delete occured, - // do nothing - if (cur.par() != where.par()) - return; - - // if cursor position is after the place where the delete occured, - // update it - if (cur.pos() > where.pos()) - cur.pos(cur.pos()-1); - - // check also if we don't want to set the cursor on a spot behind the - // pagragraph because we erased the last character. - if (cur.pos() > cur.par()->size()) - cur.pos(cur.par()->size()); - - // recompute row et al. for this cursor - setCursor(bview, cur, cur.par(), cur.pos(), cur.boundary()); -} - - -bool LyXText::deleteEmptyParagraphMechanism(BufferView * bview, - LyXCursor const & old_cursor) const -{ - // Would be wrong to delete anything if we have a selection. - if (selection.set()) - return false; - - // We allow all kinds of "mumbo-jumbo" when freespacing. - if (old_cursor.par()->layout()->free_spacing - || old_cursor.par()->isFreeSpacing()) { - return false; - } - - /* Ok I'll put some comments here about what is missing. - I have fixed BackSpace (and thus Delete) to not delete - double-spaces automagically. I have also changed Cut, - Copy and Paste to hopefully do some sensible things. - There are still some small problems that can lead to - double spaces stored in the document file or space at - the beginning of paragraphs. This happens if you have - the cursor betwenn to spaces and then save. Or if you - cut and paste and the selection have a space at the - beginning and then save right after the paste. I am - sure none of these are very hard to fix, but I will - put out 1.1.4pre2 with FIX_DOUBLE_SPACE defined so - that I can get some feedback. (Lgb) - */ - - // If old_cursor.pos() == 0 and old_cursor.pos()(1) == LineSeparator - // delete the LineSeparator. - // MISSING - - // If old_cursor.pos() == 1 and old_cursor.pos()(0) == LineSeparator - // delete the LineSeparator. - // MISSING - - // If the pos around the old_cursor were spaces, delete one of them. - if (old_cursor.par() != cursor.par() - || old_cursor.pos() != cursor.pos()) { - // Only if the cursor has really moved - - if (old_cursor.pos() > 0 - && old_cursor.pos() < old_cursor.par()->size() - && old_cursor.par()->isLineSeparator(old_cursor.pos()) - && old_cursor.par()->isLineSeparator(old_cursor.pos() - 1)) { - old_cursor.par()->erase(old_cursor.pos() - 1); - redoParagraphs(bview, old_cursor, old_cursor.par()->next()); - -#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 -// other bufferviews. It will probably be easier to do that in a more -// automated way in LyXCursor code. (JMarc 26/09/2001) -#endif - // correct all cursors held by the LyXText - fixCursorAfterDelete(bview, cursor, old_cursor); - fixCursorAfterDelete(bview, selection.cursor, - old_cursor); - fixCursorAfterDelete(bview, selection.start, - old_cursor); - fixCursorAfterDelete(bview, selection.end, old_cursor); - fixCursorAfterDelete(bview, last_sel_cursor, - old_cursor); - fixCursorAfterDelete(bview, toggle_cursor, old_cursor); - fixCursorAfterDelete(bview, toggle_end_cursor, - old_cursor); - return false; - } - } - - // don't delete anything if this is the ONLY paragraph! - if (!old_cursor.par()->next() && !old_cursor.par()->previous()) - return false; - - // Do not delete empty paragraphs with keepempty set. - if (old_cursor.par()->layout()->keepempty) - return false; - - // only do our magic if we changed paragraph - if (old_cursor.par() == cursor.par()) - return false; - - // record if we have deleted a paragraph - // we can't possibly have deleted a paragraph before this point - bool deleted = false; - - if ((old_cursor.par()->empty() - || (old_cursor.par()->size() == 1 - && old_cursor.par()->isLineSeparator(0)))) { - // ok, we will delete anything - LyXCursor tmpcursor; - - // make sure that you do not delete any environments - status(bview, LyXText::NEED_MORE_REFRESH); - deleted = true; - - if (old_cursor.row()->previous()) { - refresh_row = old_cursor.row()->previous(); - refresh_y = old_cursor.y() - old_cursor.row()->baseline() - refresh_row->height(); - tmpcursor = cursor; - cursor = old_cursor; // that undo can restore the right cursor position - Paragraph * endpar = old_cursor.par()->next(); - if (endpar && endpar->getDepth()) { - while (endpar && endpar->getDepth()) { - endpar = endpar->next(); - } - } - setUndo(bview, Undo::DELETE, old_cursor.par(), endpar); - cursor = tmpcursor; - - // delete old row - removeRow(old_cursor.row()); - if (ownerParagraph() == old_cursor.par()) { - ownerParagraph(ownerParagraph()->next()); - } - // delete old par - delete old_cursor.par(); - - /* Breakagain the next par. Needed because of - * the parindent that can occur or dissappear. - * The next row can change its height, if - * there is another layout before */ - if (refresh_row->next()) { - breakAgain(bview, refresh_row->next()); - updateCounters(bview); - } - setHeightOfRow(bview, refresh_row); - } else { - refresh_row = old_cursor.row()->next(); - refresh_y = old_cursor.y() - old_cursor.row()->baseline(); - - tmpcursor = cursor; - cursor = old_cursor; // that undo can restore the right cursor position - Paragraph * endpar = old_cursor.par()->next(); - if (endpar && endpar->getDepth()) { - while (endpar && endpar->getDepth()) { - endpar = endpar->next(); - } - } - setUndo(bview, Undo::DELETE, old_cursor.par(), endpar); - cursor = tmpcursor; - - // delete old row - removeRow(old_cursor.row()); - // delete old par - if (ownerParagraph() == old_cursor.par()) { - ownerParagraph(ownerParagraph()->next()); - } - - delete old_cursor.par(); - - /* Breakagain the next par. Needed because of - the parindent that can occur or dissappear. - The next row can change its height, if - there is another layout before */ - if (refresh_row) { - breakAgain(bview, refresh_row); - updateCounters(bview); - } - } - - // correct cursor y - setCursorIntern(bview, cursor.par(), cursor.pos()); - - if (selection.cursor.par() == old_cursor.par() - && selection.cursor.pos() == old_cursor.pos()) { - // correct selection - selection.cursor = cursor; - } - } - if (!deleted) { - if (old_cursor.par()->stripLeadingSpaces()) { - redoParagraphs(bview, old_cursor, - old_cursor.par()->next()); - // correct cursor y - setCursorIntern(bview, cursor.par(), cursor.pos()); - selection.cursor = cursor; - } - } - return deleted; } Index: insets/insettext.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/insets/insettext.C,v retrieving revision 1.351 diff -u -p -r1.351 insettext.C --- insets/insettext.C 10 Mar 2003 17:49:24 -0000 1.351 +++ insets/insettext.C 12 Mar 2003 03:10:18 -0000 @@ -819,6 +819,7 @@ void InsetText::insetUnlock(BufferView * ->cursor.par()->layout()->name()); } else bv->owner()->setLayout(bv->text->cursor.par()->layout()->name()); +#warning FIXME DEPM // hack for deleteEmptyParMech if (!paragraphs.begin()->empty()) { lt->setCursor(bv, &*(paragraphs.begin()), 0);