]> git.lyx.org Git - lyx.git/blobdiff - src/BufferView.cpp
latex_lang should not have a babel language
[lyx.git] / src / BufferView.cpp
index 2d4288a0fe3c693ad5f6a566a90c97ae7e3a44ef..390b62e01d88a96a02455291e8caea33bbb50c34 100644 (file)
 #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 {
 
@@ -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,101 +209,41 @@ void BufferView::setBuffer(Buffer * b)
        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;
 
-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;
-       }
+       LYXERR(Debug::INFO) << BOOST_CURRENT_FUNCTION
+                                       << "Buffer addr: " << buffer_ << endl;
+       cursor_.push(buffer_->inset());
+       cursor_.resetAnchor();
+       buffer_->text().setCurrentFont(cursor_);
 
-       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_;
 }
 
 
@@ -628,15 +570,14 @@ boost::tuple<pit_type, pos_type, int> BufferView::moveToPosition(pit_type bottom
 
 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);
@@ -694,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:
@@ -705,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<InsetRef>(cur, Inset::REF_CODE));
@@ -954,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();
@@ -1310,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
@@ -1400,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?
@@ -1452,7 +1407,6 @@ void BufferView::putSelectionAt(DocIterator const & cur,
                        cursor_.setSelection(cursor_, -length);
                } else
                        cursor_.setSelection(cursor_, length);
-               cap::saveSelection(cursor_);
        }
 }
 
@@ -1493,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
@@ -1512,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.