X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FBufferView2.C;h=da33665c2797885bfbff2d4212e47fc0091ec5f3;hb=d11fd01ce743c4974a96f241a99853f46078c80c;hp=35e0a4b1f33385f659bdbb05056fa6e3b0b75c29;hpb=51b32d4984bfa7e4cfc1f3020ca3d4fa0f3cba6b;p=lyx.git diff --git a/src/BufferView2.C b/src/BufferView2.C index 35e0a4b1f3..da33665c27 100644 --- a/src/BufferView2.C +++ b/src/BufferView2.C @@ -1,8 +1,8 @@ /* This file is part of - * ====================================================== - * + * ====================================================== + * * LyX, The Document Processor - * + * * Copyright 1995 Matthias Ettrich * Copyright 1995-2001 The LyX Team. * @@ -73,7 +73,7 @@ bool BufferView::insertLyXFile(string const & filen) MakeDisplayPath(fname, 50)); return false; } - + beforeChange(text); ifstream ifs(fname.c_str()); @@ -83,9 +83,9 @@ bool BufferView::insertLyXFile(string const & filen) MakeDisplayPath(fname, 50)); return false; } - + int const c = ifs.peek(); - + LyXLex lex(0, 0); lex.setStream(ifs); @@ -95,7 +95,7 @@ bool BufferView::insertLyXFile(string const & filen) lyxerr[Debug::INFO] << "Will insert file with header" << endl; res = buffer()->readFile(lex, text->cursor.par()); } else { - lyxerr[Debug::INFO] << "Will insert file without header" + lyxerr[Debug::INFO] << "Will insert file without header" << endl; res = buffer()->readLyXformat2(lex, text->cursor.par()); } @@ -107,10 +107,11 @@ bool BufferView::insertLyXFile(string const & filen) bool BufferView::removeAutoInsets() { - Paragraph * cur_par = text->cursor.par(); - Paragraph * cur_par_prev = cur_par ? cur_par->previous() : 0; - Paragraph * cur_par_next = cur_par ? cur_par->next() : 0; - pos_type cur_pos = text->cursor.pos(); + // 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; @@ -119,27 +120,30 @@ bool BufferView::removeAutoInsets() // 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 ((cur_par_prev || cur_par_next) + while ((cursor_par_prev || cursor_par_next) && text->setCursor(this, - cur_par_prev ? cur_par_prev : cur_par_next, + cursor_par_prev ? cursor_par_prev : cursor_par_next, 0)) { - // We just removed cur_par so have to fix the "cursor" - if (cur_par_prev) { - // '.' = cur_par + // We just removed cursor_par so have to fix the "cursor" + if (cursor_par_prev) { + // '.' = cursor_par // a -> a. // . - cur_par = cur_par_prev; - cur_pos = cur_par->size(); + cursor_par = cursor_par_prev; + cursor_pos = cursor_par->size(); } else { // . -> .a // a - cur_par = cur_par_next; - cur_pos = 0; + cursor_par = cursor_par_next; + cursor_pos = 0; } - cur_par_prev = cur_par->previous(); - cur_par_next = cur_par->next(); + 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) { @@ -148,35 +152,35 @@ bool BufferView::removeAutoInsets() bool removed = false; if (text->setCursor(this, par, 0) - && cur_par == par_prev) { + && cursor_par == par_prev) { // The previous setCursor line was deleted and that - // was the cur_par line. This can only happen if an - // error box was the sole item on cur_par. - // It is possible for cur_par_prev to be stray if + // 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. - cur_par_prev = par->previous(); - if (cur_par_prev) { - // '|' = par, '.' = cur_par, 'E' = error box + 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 - cur_par = cur_par_prev; - cur_pos = cur_par_prev->size(); - cur_par_prev = cur_par->previous(); - // cur_par_next remains the same - } else if (cur_par_next) { + 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 - cur_par = cur_par_next; - cur_pos = 0; - // cur_par_prev remains unset - cur_par_next = cur_par->next(); + 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 @@ -193,14 +197,16 @@ bool BufferView::removeAutoInsets() pos_type const pos = pit.getPos(); par->erase(pos); - // get the next valid iterator position + // We just invalidated par's inset iterators so + // we get the next valid iterator position pit = par->InsetIterator(pos); - // ensure we have a valid end iterator + // and ensure we have a valid end iterator. pend = par->inset_iterator_end(); - if (cur_par == par) { - if (cur_pos > pos) - --cur_pos; + if (cursor_par == par) { + // update the saved cursor position + if (cursor_pos > pos) + --cursor_pos; } } else { ++pit; @@ -212,21 +218,23 @@ bool BufferView::removeAutoInsets() } } - // It is possible that the last line is empty if it was cur_par and/or - // only had an error inset on it. + // 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 == cur_par_next) { - cur_par = cur_par_prev; - cur_pos = cur_par->size(); - } else if (cur_pos > cur_par->size()) { + && 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 cur_pos. It could still be "wrong" because + // 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. - cur_pos = cur_par->size(); + cursor_pos = cursor_par->size(); } - text->setCursorIntern(this, cur_par, cur_pos); + // restore the original cursor in its corrected location. + text->setCursorIntern(this, cursor_par, cursor_pos); return found; } @@ -246,13 +254,13 @@ void BufferView::insertErrors(TeXErrors & terr) int const errorrow = cit->error_in_line; // Insert error string for row number - int tmpid = -1; + int tmpid = -1; int tmppos = -1; if (buffer()->texrow.getIdFromRow(errorrow, tmpid, tmppos)) { buffer()->texrow.increasePos(tmpid, tmppos); } - + Paragraph * texrowpar = 0; if (tmpid == -1) { @@ -277,7 +285,7 @@ void BufferView::insertErrors(TeXErrors & terr) void BufferView::setCursorFromRow(int row) { - int tmpid = -1; + int tmpid = -1; int tmppos = -1; buffer()->texrow.getIdFromRow(row, tmpid, tmppos); @@ -348,7 +356,7 @@ void BufferView::menuRedo() return; } #endif - + if (available()) { owner()->message(_("Redo")); hideCursor(); @@ -385,7 +393,7 @@ void BufferView::pasteEnvironment() void BufferView::copy() { if (available()) { - text->copySelection(this); + getLyXText()->copySelection(this); owner()->message(_("Copy")); } } @@ -405,7 +413,8 @@ void BufferView::cut(bool realcut) void BufferView::paste() { - if (!available()) return; + if (!available()) + return; owner()->message(_("Paste")); @@ -414,19 +423,22 @@ void BufferView::paste() toggleSelection(); text->clearSelection(); update(text, BufferView::SELECT|BufferView::FITCUR); - + // paste text->pasteSelection(this); update(text, BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE); - - // clear the selection +// why fake a selection only I think it should be a real one and not only +// a painted one (Jug 20020318). +#if 0 + // clear the selection toggleSelection(); text->clearSelection(); update(text, BufferView::SELECT|BufferView::FITCUR); +#endif } -/* these functions are for the spellchecker */ +/* these functions are for the spellchecker */ string const BufferView::nextWord(float & value) { if (!available()) { @@ -437,11 +449,11 @@ string const BufferView::nextWord(float & value) return text->selectNextWordToSpellcheck(this, value); } - + void BufferView::selectLastWord() { if (!available()) return; - + LyXCursor cur = text->selection.cursor; hideCursor(); beforeChange(text); @@ -455,7 +467,7 @@ void BufferView::selectLastWord() void BufferView::endOfSpellCheck() { if (!available()) return; - + hideCursor(); beforeChange(text); text->selectSelectedWord(this); @@ -471,15 +483,15 @@ void BufferView::replaceWord(string const & replacestring) LyXText * tt = getLyXText(); hideCursor(); update(tt, BufferView::SELECT|BufferView::FITCUR); - - /* clear the selection (if there is any) */ + + /* clear the selection (if there is any) */ toggleSelection(false); update(tt, BufferView::SELECT|BufferView::FITCUR); - - /* clear the selection (if there is any) */ + + /* clear the selection (if there is any) */ toggleSelection(false); tt->replaceSelectionWithString(this, replacestring); - + tt->setSelectionOverString(this, replacestring); // Go back so that replacement string is also spellchecked @@ -548,7 +560,7 @@ void BufferView::showLockedInsetCursor(int x, int y, int asc, int desc) (cursor.par()->getInset(cursor.pos() - 1) == locking_inset)) text->setCursor(this, cursor, - cursor.par(), cursor.pos() - 1); + cursor.par(), cursor.pos() - 1); LyXScreen::Cursor_Shape shape = LyXScreen::BAR_SHAPE; LyXText * txt = getLyXText(); if (locking_inset->isTextInset() && @@ -593,12 +605,12 @@ int BufferView::unlockInset(UpdatableInset * inset) inset->insetUnlock(this); theLockingInset(0); // make sure we update the combo ! - owner()->setLayout(getLyXText()->cursor.par()->getLayout()); + owner()->setLayout(getLyXText()->cursor.par()->layout()); finishUndo(); return 0; } else if (inset && theLockingInset() && theLockingInset()->unlockInsetInInset(this, inset)) { - // owner inset has updated the layout combo + // owner inset has updated the layout combo finishUndo(); return 0; } @@ -613,8 +625,8 @@ void BufferView::lockedInsetStoreUndo(Undo::undo_kind kind) if (kind == Undo::EDIT) // in this case insets would not be stored! kind = Undo::FINISH; setUndo(this, kind, - text->cursor.par(), - text->cursor.par()->next()); + text->cursor.par(), + text->cursor.par()->next()); } @@ -650,9 +662,9 @@ bool BufferView::ChangeInsets(Inset::Code code, } if (changed_inset) { need_update = true; -#ifdef WITH_WARNINGS -#warning FIXME -#endif + + // FIXME + // The test it.size()==1 was needed to prevent crashes. // How to set the cursor corretly when it.size()>1 ?? if (it.size() == 1) { @@ -684,10 +696,10 @@ bool BufferView::ChangeCitationsIfUnique(string const & from, string const & to) { typedef pair StringPair; - - vector keys = buffer()->getBibkeyList(); - if (count_if(keys.begin(), keys.end(), - lyx::equal_1st_in_pair(from)) + + vector keys = buffer()->getBibkeyList(); + if (count_if(keys.begin(), keys.end(), + lyx::equal_1st_in_pair(from)) > 1) return false;