#include "frontends/alert.h"
#include "frontends/FileDialog.h"
#include "frontends/FontMetrics.h"
+#include "frontends/Selection.h"
#include "graphics/Previews.h"
#include <functional>
#include <vector>
+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 {
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 {
}
-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.
// If we're quitting lyx, don't bother updating stuff
if (quitting) {
buffer_ = 0;
- return;
+ return 0;
}
//FIXME Fix for bug 3440 is here.
offset_ref_ = 0;
if (!buffer_)
- return;
-
- 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_);
-}
+ return 0;
+ LYXERR(Debug::INFO) << BOOST_CURRENT_FUNCTION
+ << "Buffer addr: " << buffer_ << endl;
+ cursor_.push(buffer_->inset());
+ cursor_.resetAnchor();
+ buffer_->text().setCurrentFont(cursor_);
-bool BufferView::loadLyXFile(FileName const & filename, bool tolastfiles)
-{
- // 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) {
- setBuffer(theBufferList().getBuffer(filename.absFilename()));
- return true;
- }
- // FIXME: should be LFUN_REVERT
- if (!theBufferList().close(theBufferList().getBuffer(filename.absFilename()), false))
- return false;
- // Fall through to new load. (Asger)
- buffer_ = 0;
- }
-
- Buffer * b = 0;
+ // Update the metrics now that we have a proper Cursor.
+ updateMetrics(false);
- if (isFileReadable(filename)) {
- b = theBufferList().newBuffer(filename.absFilename());
- if (!lyx::loadLyXFile(b, filename)) {
- theBufferList().release(b);
- return false;
- }
- } 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 false;
- } else
- return false;
- }
+ // 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.
- setBuffer(b);
- // Send the "errors" signal in case of parsing errors
- b->errors("Parse");
+ // 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();
- // Update the labels and section numbering.
- updateLabels(*buffer_);
- // scroll to the position when the file was last closed
- if (lyxrc.use_lastfilepos) {
- pit_type pit;
- pos_type pos;
- boost::tie(pit, pos) = LyX::ref().session().lastFilePos().load(filename);
- // if successfully move to pit (returned par_id is not zero), update metrics and reset font
- if (moveToPosition(pit, pos, 0, 0).get<1>()) {
- if (fitCursor())
- updateMetrics(false);
- buffer_->text().setCurrentFont(cursor_);
- }
+ if (fitCursor())
+ // Update the metrics if the cursor new position was off screen.
+ updateMetrics(false);
}
- if (tolastfiles)
- LyX::ref().session().lastFiles().add(FileName(b->fileName()));
-
- return true;
+ if (graphics::Previews::status() != LyXRC::PREVIEW_OFF)
+ graphics::Previews::get().generateBufferPreviews(*buffer_);
+ return buffer_;
}
void BufferView::translateAndInsert(char_type c, Text * t, Cursor & cur)
{
- if (!lyxrc.rtl_support)
- return;
-
- if (cursor_.innerText()->real_current_font.isRightToLeft()) {
- if (intl_->keymap == Intl::PRIMARY)
- intl_->keyMapSec();
- } else {
- if (intl_->keymap == Intl::SECONDARY)
- intl_->keyMapPrim();
+ if (lyxrc.rtl_support) {
+ if (cursor_.innerText()->real_current_font.isRightToLeft()) {
+ if (intl_->keymap == Intl::PRIMARY)
+ intl_->keyMapSec();
+ } else {
+ if (intl_->keymap == Intl::SECONDARY)
+ intl_->keyMapPrim();
+ }
}
intl_->getTransManager().translateAndInsert(c, t, cur);
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:
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<InsetRef>(cur, Inset::REF_CODE));
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();
if (!cur.result().dispatched())
cur.dispatch(cmd);
+ //Do we have a selection?
+ theSelection().haveSelection(cursor().selection());
+
// Redraw if requested and necessary.
if (cur.result().dispatched() && cur.result().update())
return update(cur.result().update());
buffer_->texrow().getIdFromRow(row, tmpid, tmppos);
+ cursor_.reset(buffer_->inset());
if (tmpid == -1)
buffer_->text().setCursor(cursor_, 0, 0);
else
{
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?
cursor_.setSelection(cursor_, -length);
} else
cursor_.setSelection(cursor_, length);
- cap::saveSelection(cursor_);
}
}
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
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.