]> git.lyx.org Git - lyx.git/blobdiff - src/BufferView.cpp
tex2lyx/text.cpp: code simplification
[lyx.git] / src / BufferView.cpp
index ac22a4e618996a53145199735e6c0df51b551425..fff47d05597d682fd43ddcbe4707e7ff9b598099 100644 (file)
@@ -51,7 +51,6 @@
 #include "TextMetrics.h"
 #include "TexRow.h"
 #include "TocBackend.h"
-#include "VSpace.h"
 #include "WordLangTuple.h"
 
 #include "insets/InsetBibtex.h"
 #include "frontends/Painter.h"
 #include "frontends/Selection.h"
 
-#include "graphics/Previews.h"
-
 #include "support/convert.h"
 #include "support/debug.h"
 #include "support/ExceptionMessage.h"
 #include "support/filetools.h"
 #include "support/gettext.h"
+#include "support/lassert.h"
 #include "support/lstrings.h"
 #include "support/Package.h"
 #include "support/types.h"
@@ -669,7 +667,10 @@ void BufferView::setCursorFromScrollbar()
        // FIXME: Care about the d->cursor_ flags to redraw if needed
        Cursor old = d->cursor_;
        mouseSetCursor(cur);
-       bool badcursor = notifyCursorLeavesOrEnters(old, d->cursor_);
+       // the DEPM call in mouseSetCursor() might have destroyed the
+       // paragraph the cursor is in.
+       bool badcursor = old.fixIfBroken();
+       badcursor |= notifyCursorLeavesOrEnters(old, d->cursor_);
        if (badcursor)
                d->cursor_.fixIfBroken();
 }
@@ -700,7 +701,6 @@ CursorStatus BufferView::cursorStatus(DocIterator const & dit) const
 
 void BufferView::bookmarkEditPosition()
 {
-       d->cursor_.markEditPosition();
        // Don't eat cpu time for each keystroke
        if (d->cursor_.paragraph().id() == d->bookmark_edit_position_)
                return;
@@ -885,20 +885,28 @@ bool BufferView::scrollToCursor(DocIterator const & dit, bool recenter)
                if (recenter)
                        scrolled = scroll(ypos - height_/2);
 
+               // We try to visualize the whole row, if the row height is larger than
+               // the screen height, we scroll to a heuristic value of height_ / 4.
+               // FIXME: This heuristic value should be replaced by a recursive search
+               // for a row in the inset that can be visualized completely.
+               else if (row_dim.height() > height_) {
+                       if (ypos < defaultRowHeight())
+                               scrolled = scroll(ypos - height_ / 4);
+                       else if (ypos > height_ - defaultRowHeight())
+                               scrolled = scroll(ypos - 3 * height_ / 4);
+               }
+
                // If the top part of the row falls of the screen, we scroll
                // up to align the top of the row with the top of the screen.
-               else if (ypos - row_dim.ascent() < 0)
-                       scrolled = scrollUp(-ypos + row_dim.ascent());
+               else if (ypos - row_dim.ascent() < 0 && ypos < height_) {
+                       int ynew = row_dim.ascent();
+                       scrolled = scrollUp(ynew - ypos);
+               }
 
                // If the bottom of the row falls of the screen, we scroll down.
-               // However, we have to be careful not to scroll that much that
-               // the top falls of the screen.
-               else if (ypos + row_dim.descent() > height_) {
+               else if (ypos + row_dim.descent() > height_ && ypos > 0) {
                        int ynew = height_ - row_dim.descent();
-                       if (ynew < row_dim.ascent())
-                               ynew = row_dim.ascent();
-                       int const scroll = ypos - ynew;
-                       scrolled = scrollDown(scroll);
+                       scrolled = scrollDown(ypos - ynew);
                }
 
                // else, nothing to do, the cursor is already visible so we just return.
@@ -1457,6 +1465,7 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
                buffer_.text().cursorBottom(cur);
                // accept everything in a single step to support atomic undo
                buffer_.text().acceptOrRejectChanges(cur, Text::ACCEPT);
+               cur.resetAnchor();
                // FIXME: Move this LFUN to Buffer so that we don't have to do this:
                dr.screenUpdate(Update::Force | Update::FitCursor);
                dr.forceBufferUpdate();
@@ -1470,6 +1479,7 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
                // reject everything in a single step to support atomic undo
                // Note: reject does not work recursively; the user may have to repeat the operation
                buffer_.text().acceptOrRejectChanges(cur, Text::REJECT);
+               cur.resetAnchor();
                // FIXME: Move this LFUN to Buffer so that we don't have to do this:
                dr.screenUpdate(Update::Force | Update::FitCursor);
                dr.forceBufferUpdate();
@@ -1682,6 +1692,7 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
 
                d->text_metrics_[&buffer_.text()].editXY(cur, p.x_, p.y_,
                        true, act == LFUN_SCREEN_UP); 
+               cur.resetAnchor();
                //FIXME: what to do with cur.x_target()?
                bool update = in_texted && cur.bv().checkDepm(cur, old);
                cur.finishUndo();
@@ -1752,7 +1763,7 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
                        Inset * ins = cur.nextInset();
                        if (!ins)
                                break;
-                       docstring insname = ins->name();
+                       docstring insname = ins->layoutName();
                        while (!insname.empty()) {
                                if (insname == name || name == from_utf8("*")) {
                                        cur.recordUndo();
@@ -1879,6 +1890,25 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
                break;
        }
 
+       // FIXME:
+       // The change of language of buffer belongs to the Buffer class.
+       // We have to do it here because we need a cursor for Undo.
+       // When Undo::recordUndoBufferParams() is implemented someday
+       // LFUN_BUFFER_LANGUAGE should be handled by the Buffer class.
+       case LFUN_BUFFER_LANGUAGE: {
+               Language const * oldL = buffer_.params().language;
+               Language const * newL = languages.getLanguage(argument);
+               if (!newL || oldL == newL)
+                       break;
+               if (oldL->rightToLeft() == newL->rightToLeft()) {
+                       cur.recordUndoFullDocument();
+                       buffer_.changeLanguage(oldL, newL);
+                       cur.setCurrentFont();
+                       dr.forceBufferUpdate();
+               }
+               break;
+       }
+
        default:
                // OK, so try the Buffer itself...
                buffer_.dispatch(cmd, dr);
@@ -2084,6 +2114,11 @@ void BufferView::mouseEventDispatch(FuncRequest const & cmd0)
        // Do we have a selection?
        theSelection().haveSelection(cursor().selection());
 
+       if (cur.needBufferUpdate()) {
+               cur.clearBufferUpdate();
+               buffer().updateBuffer();
+       }
+
        // If the command has been dispatched,
        if (cur.result().dispatched() || cur.result().screenUpdate())
                processUpdateFlags(cur.result().screenUpdate());
@@ -2181,16 +2216,42 @@ int BufferView::scrollUp(int offset)
 
 void BufferView::setCursorFromRow(int row)
 {
-       int tmpid = -1;
-       int tmppos = -1;
+       int tmpid;
+       int tmppos;
+       pit_type newpit = 0;
+       pos_type newpos = 0;
 
        buffer_.texrow().getIdFromRow(row, tmpid, tmppos);
 
+       bool posvalid = (tmpid != -1);
+       if (posvalid) {
+               // we need to make sure that the row and position
+               // we got back are valid, because the buffer may well
+               // have changed since we last generated the LaTeX.
+               DocIterator const dit = buffer_.getParFromID(tmpid);
+               if (dit == doc_iterator_end(&buffer_))
+                       posvalid = false;
+               else {
+                       newpit = dit.pit();
+                       // now have to check pos.
+                       newpos = tmppos;
+                       Paragraph const & par = buffer_.text().getPar(newpit);
+                       if (newpos > par.size()) {
+                               LYXERR0("Requested position no longer valid.");
+                               newpos = par.size() - 1;
+                       }
+               }
+       }
+       if (!posvalid) {
+               frontend::Alert::error(_("Inverse Search Failed"),
+                       _("Invalid position requested by inverse search.\n"
+                   "You need to update the viewed document."));
+               return;
+       }
        d->cursor_.reset();
-       if (tmpid == -1)
-               buffer_.text().setCursor(d->cursor_, 0, 0);
-       else
-               buffer_.text().setCursor(d->cursor_, buffer_.getParFromID(tmpid).pit(), tmppos);
+       buffer_.text().setCursor(d->cursor_, newpit, newpos);
+       d->cursor_.setSelection(false);
+       d->cursor_.resetAnchor();
        recenter();
 }
 
@@ -2276,6 +2337,11 @@ void BufferView::setCursor(DocIterator const & dit)
 
        d->cursor_.setCursor(dit);
        d->cursor_.setSelection(false);
+       // FIXME
+       // It seems on general grounds as if this is probably needed, but
+       // it is not yet clear.
+       // See bug #7394 and r38388.
+       // d->cursor.resetAnchor();
 }
 
 
@@ -2315,12 +2381,13 @@ bool BufferView::mouseSetCursor(Cursor & cur, bool select)
        d->cursor_.macroModeClose();
 
        // Has the cursor just left the inset?
-       bool leftinset = (&d->cursor_.inset() != &cur.inset());
+       bool const leftinset = (&d->cursor_.inset() != &cur.inset());
        if (leftinset)
                d->cursor_.fixIfBroken();
 
        // FIXME: shift-mouse selection doesn't work well across insets.
-       bool do_selection = select && &d->cursor_.normalAnchor().inset() == &cur.inset();
+       bool const do_selection = 
+                       select && &d->cursor_.normalAnchor().inset() == &cur.inset();
 
        // do the dEPM magic if needed
        // FIXME: (1) move this to InsetText::notifyCursorLeaves?