X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FBufferView.cpp;h=390b62e01d88a96a02455291e8caea33bbb50c34;hb=2ee5c3a1fbb330d626622c6c50c1ffca634391db;hp=071181bef7e8f3af047532a78251a6b5ad14e7f1;hpb=d3003c10225095fb472ec85bcbef407edd1b4cb1;p=lyx.git diff --git a/src/BufferView.cpp b/src/BufferView.cpp index 071181bef7..390b62e01d 100644 --- a/src/BufferView.cpp +++ b/src/BufferView.cpp @@ -78,6 +78,16 @@ #include #include +using std::distance; +using std::endl; +using std::istringstream; +using std::make_pair; +using std::min; +using std::max; +using std::mem_fun_ref; +using std::string; +using std::vector; + namespace lyx { @@ -91,16 +101,6 @@ using support::isFileReadable; using support::makeDisplayPath; using support::package; -using std::distance; -using std::endl; -using std::istringstream; -using std::make_pair; -using std::min; -using std::max; -using std::mem_fun_ref; -using std::string; -using std::vector; - namespace Alert = frontend::Alert; namespace { @@ -143,12 +143,14 @@ Buffer * BufferView::buffer() const } -void BufferView::setBuffer(Buffer * b) +Buffer * BufferView::setBuffer(Buffer * b) { LYXERR(Debug::INFO) << BOOST_CURRENT_FUNCTION << "[ b = " << b << "]" << endl; if (buffer_) { + // Save the current selection if any + cap::saveSelection(cursor_); // Save the actual cursor position and anchor inside the // buffer so that it can be restored in case we rechange // to this buffer later on. @@ -180,7 +182,7 @@ void BufferView::setBuffer(Buffer * b) // If we're quitting lyx, don't bother updating stuff if (quitting) { buffer_ = 0; - return; + return 0; } //FIXME Fix for bug 3440 is here. @@ -207,84 +209,41 @@ void BufferView::setBuffer(Buffer * b) offset_ref_ = 0; if (!buffer_) - return; + return 0; - LYXERR(Debug::INFO) << BOOST_CURRENT_FUNCTION - << "Buffer addr: " << buffer_ << endl; - cursor_.push(buffer_->inset()); - cursor_.resetAnchor(); - buffer_->text().setCurrentFont(cursor_); - if (buffer_->getCursor().size() > 0 && - buffer_->getAnchor().size() > 0) - { - cursor_.setCursor(buffer_->getAnchor().asDocIterator(&(buffer_->inset()))); - cursor_.resetAnchor(); - cursor_.setCursor(buffer_->getCursor().asDocIterator(&(buffer_->inset()))); - cursor_.setSelection(); - // do not set selection to the new buffer because we - // only paste recent selection. - - // Make sure that the restored cursor is not broken. This can happen for - // example if this Buffer has been modified by another view. - cursor_.fixIfBroken(); - } - updateMetrics(false); - if (graphics::Previews::status() != LyXRC::PREVIEW_OFF) - graphics::Previews::get().generateBufferPreviews(*buffer_); -} + LYXERR(Debug::INFO) << BOOST_CURRENT_FUNCTION + << "Buffer addr: " << buffer_ << endl; + cursor_.push(buffer_->inset()); + cursor_.resetAnchor(); + buffer_->text().setCurrentFont(cursor_); -// FIXME There is now no need for this to be in BufferView. It should all -// be moved to buffer_func.cpp. (Abdel) -Buffer * BufferView::loadLyXFile(FileName const & filename, bool auto_open) -{ - // File already open? - if (theBufferList().exists(filename.absFilename())) { - docstring const file = makeDisplayPath(filename.absFilename(), 20); - docstring text = bformat(_("The document %1$s is already " - "loaded.\n\nDo you want to revert " - "to the saved version?"), file); - int const ret = Alert::prompt(_("Revert to saved document?"), - text, 0, 1, _("&Revert"), _("&Switch to document")); - - if (ret != 0) { - Buffer * buf = theBufferList().getBuffer(filename.absFilename()); - setBuffer(buf); - return buf; - } - // FIXME: should be LFUN_REVERT - if (!theBufferList().close(theBufferList().getBuffer(filename.absFilename()), false)) - return 0; - // Fall through to new load. (Asger) - buffer_ = 0; - } + // Update the metrics now that we have a proper Cursor. + updateMetrics(false); - Buffer * b = 0; + // FIXME: This code won't be needed once we switch to + // "one Buffer" / "one BufferView". + if (buffer_->getCursor().size() > 0 && + buffer_->getAnchor().size() > 0) + { + cursor_.setCursor(buffer_->getAnchor().asDocIterator(&(buffer_->inset()))); + cursor_.resetAnchor(); + cursor_.setCursor(buffer_->getCursor().asDocIterator(&(buffer_->inset()))); + cursor_.setSelection(); + // do not set selection to the new buffer because we + // only paste recent selection. - if (isFileReadable(filename)) { - b = theBufferList().newBuffer(filename.absFilename()); - if (!lyx::loadLyXFile(b, filename)) { - theBufferList().release(b); - return 0; - } - } else { - docstring text = bformat(_("The document %1$s does not yet " - "exist.\n\nDo you want to create " - "a new document?"), from_utf8(filename.absFilename())); - int const ret = Alert::prompt(_("Create new document?"), - text, 0, 1, _("&Create"), _("Cancel")); - - if (ret == 0) { - b = newFile(filename.absFilename(), string(), true); - if (!b) - return 0; - } else - return 0; - } + // Make sure that the restored cursor is not broken. This can happen for + // example if this Buffer has been modified by another view. + cursor_.fixIfBroken(); - if (!auto_open) - setBuffer(b); + if (fitCursor()) + // Update the metrics if the cursor new position was off screen. + updateMetrics(false); + } - return b; + if (graphics::Previews::status() != LyXRC::PREVIEW_OFF) + graphics::Previews::get().generateBufferPreviews(*buffer_); + return buffer_; } @@ -676,6 +635,7 @@ FuncStatus BufferView::getStatus(FuncRequest const & cmd) case LFUN_NOTE_NEXT: case LFUN_REFERENCE_NEXT: case LFUN_WORD_FIND: + case LFUN_WORD_REPLACE: case LFUN_MARK_OFF: case LFUN_MARK_ON: case LFUN_MARK_TOGGLE: @@ -687,10 +647,6 @@ FuncStatus BufferView::getStatus(FuncRequest const & cmd) flag.enabled(true); break; - case LFUN_WORD_REPLACE: - flag.enabled(!cur.paragraph().isDeleted(cur.pos())); - break; - case LFUN_LABEL_GOTO: { flag.enabled(!cmd.argument().empty() || getInsetByCode(cur, Inset::REF_CODE)); @@ -936,9 +892,21 @@ Update::flags BufferView::dispatch(FuncRequest const & cmd) find(this, cmd); break; - case LFUN_WORD_REPLACE: - replace(this, cmd); + case LFUN_WORD_REPLACE: { + bool has_deleted = false; + if (cur.selection()) { + DocIterator beg = cur.selectionBegin(); + DocIterator end = cur.selectionEnd(); + if (beg.pit() == end.pit()) { + for (pos_type p = beg.pos() ; p < end.pos() ; ++p) { + if (cur.paragraph().isDeleted(p)) + has_deleted = true; + } + } + } + replace(this, cmd, has_deleted); break; + } case LFUN_MARK_OFF: cur.clearSelection(); @@ -1292,6 +1260,7 @@ void BufferView::setCursorFromRow(int row) buffer_->texrow().getIdFromRow(row, tmpid, tmppos); + cursor_.reset(buffer_->inset()); if (tmpid == -1) buffer_->text().setCursor(cursor_, 0, 0); else @@ -1382,11 +1351,15 @@ bool BufferView::mouseSetCursor(Cursor & cur) { BOOST_ASSERT(&cur.bv() == this); + // this event will clear selection so we save selection for + // persistent selection + cap::saveSelection(cursor()); + // Has the cursor just left the inset? bool badcursor = false; bool leftinset = (&cursor_.inset() != &cur.inset()); if (leftinset) - badcursor = cursor_.inset().notifyCursorLeaves(cursor_); + badcursor = notifyCursorLeaves(cursor_, cur); // do the dEPM magic if needed // FIXME: (1) move this to InsetText::notifyCursorLeaves? @@ -1434,7 +1407,6 @@ void BufferView::putSelectionAt(DocIterator const & cur, cursor_.setSelection(cursor_, -length); } else cursor_.setSelection(cursor_, length); - cap::saveSelection(cursor_); } } @@ -1475,6 +1447,15 @@ void BufferView::updateMetrics(bool singlepar) offset_ref_ = 0; } + if (!singlepar) { + // Clear out the position cache in case of full screen redraw, + coord_cache_.clear(); + + // Clear out paragraph metrics to avoid having invalid metrics + // in the cache from paragraphs not relayouted below + tm.clear(); + } + // If the paragraph metrics has changed, we can not // use the singlepar optimisation. if (singlepar @@ -1494,10 +1475,6 @@ void BufferView::updateMetrics(bool singlepar) if (!singlepar) tm.redoParagraph(pit); - // Clear out the position cache in case of full screen redraw. - if (!singlepar) - coord_cache_.clear(); - int y0 = tm.parMetrics(pit).ascent() - offset_ref_; // Redo paragraphs above anchor if necessary.