]> git.lyx.org Git - lyx.git/blobdiff - src/BufferView.cpp
Fix 480937a103708a651/lyxgit, second attempt.
[lyx.git] / src / BufferView.cpp
index 24be1624ce759bbe3606895cbac163fa5c6d6d9c..0030f33f4c1d19f11c19dfef172014f1b6fb3c52 100644 (file)
@@ -46,6 +46,7 @@
 #include "Paragraph.h"
 #include "ParagraphParameters.h"
 #include "ParIterator.h"
+#include "RowPainter.h"
 #include "Session.h"
 #include "Text.h"
 #include "TextClass.h"
@@ -1123,16 +1124,6 @@ bool BufferView::getStatus(FuncRequest const & cmd, FuncStatus & flag)
                    || getInsetByCode<InsetRef>(cur, REF_CODE));
                break;
 
-       case LFUN_CHANGES_TRACK:
-               flag.setEnabled(true);
-               flag.setOnOff(buffer_.params().track_changes);
-               break;
-
-       case LFUN_CHANGES_OUTPUT:
-               flag.setEnabled(true);
-               flag.setOnOff(buffer_.params().output_changes);
-               break;
-
        case LFUN_CHANGES_MERGE:
        case LFUN_CHANGE_NEXT:
        case LFUN_CHANGE_PREVIOUS:
@@ -1145,16 +1136,6 @@ bool BufferView::getStatus(FuncRequest const & cmd, FuncStatus & flag)
                flag.setEnabled(true);
                break;
 
-       case LFUN_BUFFER_TOGGLE_COMPRESSION: {
-               flag.setOnOff(buffer_.params().compressed);
-               break;
-       }
-
-       case LFUN_BUFFER_TOGGLE_OUTPUT_SYNC: {
-               flag.setOnOff(buffer_.params().output_sync);
-               break;
-       }
-
        case LFUN_SCREEN_UP:
        case LFUN_SCREEN_DOWN:
        case LFUN_SCROLL:
@@ -1457,33 +1438,6 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
                break;
        }
 
-       case LFUN_CHANGES_TRACK:
-               buffer_.params().track_changes = !buffer_.params().track_changes;
-               break;
-
-       case LFUN_CHANGES_OUTPUT:
-               buffer_.params().output_changes = !buffer_.params().output_changes;
-               if (buffer_.params().output_changes) {
-                       bool dvipost    = LaTeXFeatures::isAvailable("dvipost");
-                       bool xcolorulem = LaTeXFeatures::isAvailable("ulem") &&
-                                         LaTeXFeatures::isAvailable("xcolor");
-
-                       if (!dvipost && !xcolorulem) {
-                               Alert::warning(_("Changes not shown in LaTeX output"),
-                                              _("Changes will not be highlighted in LaTeX output, "
-                                                "because neither dvipost nor xcolor/ulem are installed.\n"
-                                                "Please install these packages or redefine "
-                                                "\\lyxadded and \\lyxdeleted in the LaTeX preamble."));
-                       } else if (!xcolorulem) {
-                               Alert::warning(_("Changes not shown in LaTeX output"),
-                                              _("Changes will not be highlighted in LaTeX output "
-                                                "when using pdflatex, because xcolor and ulem are not installed.\n"
-                                                "Please install both packages or redefine "
-                                                "\\lyxadded and \\lyxdeleted in the LaTeX preamble."));
-                       }
-               }
-               break;
-
        case LFUN_CHANGE_NEXT:
                findNextChange(this);
                // FIXME: Move this LFUN to Buffer so that we don't have to do this:
@@ -1723,15 +1677,6 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
        }
                break;
 
-       case LFUN_BUFFER_TOGGLE_COMPRESSION:
-               // turn compression on/off
-               buffer_.params().compressed = !buffer_.params().compressed;
-               break;
-
-       case LFUN_BUFFER_TOGGLE_OUTPUT_SYNC:
-               buffer_.params().output_sync = !buffer_.params().output_sync;
-               break;
-
        case LFUN_SCREEN_UP:
        case LFUN_SCREEN_DOWN: {
                Point p = getPos(cur);
@@ -1860,6 +1805,7 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
                        cur.pit() = cur.lastpit();
                        cur.pos() = cur.lastpos();
                }
+               cur.setCurrentFont();
                dr.screenUpdate(Update::Force);
                break;
 
@@ -2365,13 +2311,19 @@ int BufferView::scrollUp(int offset)
 
 
 void BufferView::setCursorFromRow(int row)
+{
+       setCursorFromRow(row, buffer_.texrow());
+}
+
+
+void BufferView::setCursorFromRow(int row, TexRow const & texrow)
 {
        int tmpid;
        int tmppos;
        pit_type newpit = 0;
        pos_type newpos = 0;
 
-       buffer_.texrow().getIdFromRow(row, tmpid, tmppos);
+       texrow.getIdFromRow(row, tmpid, tmppos);
 
        bool posvalid = (tmpid != -1);
        if (posvalid) {
@@ -2841,8 +2793,7 @@ Point BufferView::coordOffset(DocIterator const & dit) const
                        // FIXME (Abdel 23/09/2007): this is a bit messy because of the
                        // elimination of Inset::dim_ cache. This coordOffset() method needs
                        // to be rewritten in light of the new design.
-                       Dimension const & dim = parMetrics(dit[i - 1].text(),
-                               dit[i - 1].pit()).insetDimension(&sl.inset());
+                       Dimension const & dim = coordCache().getInsets().dim(&sl.inset());
                        lastw = dim.wid;
                } else {
                        Dimension const dim = sl.inset().dimension(*this);
@@ -2981,7 +2932,7 @@ void BufferView::setCurrentRowSlice(CursorSlice const & rowSlice)
 }
 
 
-void BufferView::checkCursorScrollOffset()
+void BufferView::checkCursorScrollOffset(PainterInfo & pi)
 {
        CursorSlice rowSlice = d->cursor_.bottom();
        TextMetrics const & tm = textMetrics(rowSlice.text());
@@ -2999,22 +2950,64 @@ void BufferView::checkCursorScrollOffset()
        setCurrentRowSlice(rowSlice);
 
        // Current x position of the cursor in pixels
-       int const cur_x = getPos(d->cursor_).x_;
+       int cur_x = getPos(d->cursor_).x_;
+
+       // If cursor offset is left margin and offset is not the leftmost
+       // position of the row, there is a cache problem.
+       if (cur_x == row.left_margin && !row.empty()
+           && d->cursor_.pos() != row.front().left_pos()) {
+               /** FIXME: the code below adds an extraneous computation of
+                * inset positions, and can therefore be bad for performance
+                * (think for example about a very large tabular inset.
+                * Redawing the row where it is means redrawing the whole
+                * screen).
+                *
+                * The bug that this fixes is the following: assume that there
+                * is a very large math inset. Upon entering the inset, when
+                * pressing `End', the row is not scrolled and the cursor is
+                * not visible. The extra row computation makes sure that the
+                * inset positions are correctly computed and set in the
+                * cache. This would not happen if we did not have two-stage
+                * drawing.
+                *
+                * A proper fix should be found and this code should be removed.
+                */
+               // Force the recomputation of inset positions
+               bool const drawing = pi.pain.isDrawingEnabled();
+               pi.pain.setDrawingEnabled(false);
+               // No need to care about vertical position.
+               RowPainter rp(pi, buffer().text(), d->cursor_.bottom().pit(), row,
+                             -d->horiz_scroll_offset_, 0);
+               rp.paintText();
+               pi.pain.setDrawingEnabled(drawing);
+
+               // Recompute current Current x position of the cursor in pixels
+               cur_x = getPos(d->cursor_).x_;
+       }
 
        // Horizontal scroll offset of the cursor row in pixels
        int offset = d->horiz_scroll_offset_;
-       int const MARGIN = 2 * theFontMetrics(d->cursor_.real_current_font).em();
-       //lyxerr << "cur_x=" << cur_x << ", offset=" << offset << ", margin=" << MARGIN << endl;
-       if (cur_x < offset + MARGIN) {
-               // scroll right
-               offset = cur_x - MARGIN;
-       } else if (cur_x > offset + workWidth() - MARGIN) {
-               // scroll left
-               offset = cur_x - workWidth() + MARGIN;
+       int const MARGIN = 2 * theFontMetrics(d->cursor_.real_current_font).em()
+                          + row.right_margin;
+       if (row.right_x() <= workWidth() - row.right_margin) {
+               // Row is narrower than the work area, no offset needed.
+               offset = 0;
+       } else {
+               if (cur_x - offset < MARGIN) {
+                       // cursor would be too far right
+                       offset = cur_x - MARGIN;
+               } else if (cur_x - offset > workWidth() - MARGIN) {
+                       // cursor would be too far left
+                       offset = cur_x - workWidth() + MARGIN;
+               }
+               // Correct the offset to make sure that we do not scroll too much
+               if (offset < 0)
+                       offset = 0;
+               if (row.right_x() - offset < workWidth() - row.right_margin)
+                       offset = row.right_x() - workWidth() + row.right_margin;
        }
 
-       if (offset < row.left_margin || row.width() <= workWidth())
-               offset = 0;
+       //lyxerr << "cur_x=" << cur_x << ", offset=" << offset << ", row.wid=" << row.width() << ", margin=" << MARGIN << endl;
 
        if (offset != d->horiz_scroll_offset_)
                LYXERR(Debug::PAINTING, "Horiz. scroll offset changed from "
@@ -3045,7 +3038,7 @@ void BufferView::draw(frontend::Painter & pain)
 
        // Check whether the row where the cursor lives needs to be scrolled.
        // Update the drawing strategy if needed.
-       checkCursorScrollOffset();
+       checkCursorScrollOffset(pi);
 
        switch (d->update_strategy_) {