]> git.lyx.org Git - lyx.git/blobdiff - src/BufferView.cpp
Do not modify the changed() status of rows when no drawing has taken place
[lyx.git] / src / BufferView.cpp
index 4bd1c12e77d57f4e87a4774d0310a7bb77feef04..7cb99cdf4d9cb298a2d34370e71057e14c5320ab 100644 (file)
@@ -35,6 +35,7 @@
 #include "Language.h"
 #include "LaTeXFeatures.h"
 #include "LayoutFile.h"
+#include "Length.h"
 #include "Lexer.h"
 #include "LyX.h"
 #include "LyXAction.h"
@@ -1101,6 +1102,7 @@ bool BufferView::getStatus(FuncRequest const & cmd, FuncStatus & flag)
        case LFUN_KEYMAP_PRIMARY:
        case LFUN_KEYMAP_SECONDARY:
        case LFUN_KEYMAP_TOGGLE:
+       case LFUN_INSET_SELECT_ALL:
                flag.setEnabled(true);
                break;
 
@@ -1249,7 +1251,7 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
 
        case LFUN_BUFFER_PARAMS_APPLY: {
                DocumentClassConstPtr olddc = buffer_.params().documentClassPtr();
-               cur.recordUndoFullDocument();
+               cur.recordUndoBufferParams();
                istringstream ss(to_utf8(cmd.argument()));
                Lexer lex;
                lex.setStream(ss);
@@ -1270,7 +1272,10 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
        }
 
        case LFUN_LAYOUT_MODULES_CLEAR: {
-               cur.recordUndoFullDocument();
+               // FIXME: this modifies the document in cap::switchBetweenClasses
+               //  without calling recordUndo. Fix this before using
+               //  recordUndoBufferParams().
+               cur.recordUndoFullBuffer();
                buffer_.params().clearLayoutModules();
                makeDocumentClass();
                dr.screenUpdate(Update::Force);
@@ -1286,7 +1291,10 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
                                "conflicts with installed modules.");
                        break;
                }
-               cur.recordUndoFullDocument();
+               // FIXME: this modifies the document in cap::switchBetweenClasses
+               //  without calling recordUndo. Fix this before using
+               //  recordUndoBufferParams().
+               cur.recordUndoFullBuffer();
                buffer_.params().addLayoutModule(argument);
                makeDocumentClass();
                dr.screenUpdate(Update::Force);
@@ -1315,7 +1323,10 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
                        break;
 
                // Save the old, possibly modular, layout for use in conversion.
-               cur.recordUndoFullDocument();
+               // FIXME: this modifies the document in cap::switchBetweenClasses
+               //  without calling recordUndo. Fix this before using
+               //  recordUndoBufferParams().
+               cur.recordUndoFullBuffer();
                buffer_.params().setBaseClass(argument);
                makeDocumentClass();
                dr.screenUpdate(Update::Force);
@@ -1814,6 +1825,41 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
        }
 
 
+       case LFUN_INSET_SELECT_ALL:
+               if (cur.depth() > 1
+                   && cur.selBegin().at_begin()
+                   && cur.selEnd().at_end()) {
+                       // All the contents of the inset if selected.
+                       // Select the inset from outside.
+                       cur.pop();
+                       cur.resetAnchor();
+                       cur.setSelection(true);
+                       cur.posForward();
+               } else if (cur.selBegin().idx() != cur.selEnd().idx()
+                          || (cur.depth() > 1
+                                  && cur.selBegin().at_cell_begin()
+                              && cur.selEnd().at_cell_end())) {
+                       // At least one complete cell is selected.
+                       // Select all cells
+                       cur.idx() = 0;
+                       cur.pos() = 0;
+                       cur.resetAnchor();
+                       cur.setSelection(true);
+                       cur.idx() = cur.lastidx();
+                       cur.pos() = cur.lastpos();
+               } else {
+                       // select current cell
+                       cur.pit() = 0;
+                       cur.pos() = 0;
+                       cur.resetAnchor();
+                       cur.setSelection(true);
+                       cur.pit() = cur.lastpit();
+                       cur.pos() = cur.lastpos();
+               }
+               dr.screenUpdate(Update::Force);
+               break;
+
+
        // This would be in Buffer class if only Cursor did not
        // require a bufferview
        case LFUN_INSET_FORALL: {
@@ -1991,7 +2037,7 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
                if (!newL || oldL == newL)
                        break;
                if (oldL->rightToLeft() == newL->rightToLeft()) {
-                       cur.recordUndoFullDocument();
+                       cur.recordUndoFullBuffer();
                        buffer_.changeLanguage(oldL, newL);
                        cur.setCurrentFont();
                        dr.forceBufferUpdate();
@@ -2924,40 +2970,56 @@ void BufferView::checkCursorScrollOffset(PainterInfo & pi)
        // Set the row on which the cursor lives.
        setCurrentRowSlice(rowSlice);
 
+       /** 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. I
+        * am not sure why the extra row computation fixes the problem,
+        * actually.
+        *
+        * 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, 0, 0);
+       RowPainter rp(pi, buffer().text(), d->cursor_.bottom().pit(), row,
+                     -d->horiz_scroll_offset_, 0);
        rp.paintText();
        pi.pain.setDrawingEnabled(drawing);
+       /** END of bad code */
 
        // Current x position of the cursor in pixels
        int const cur_x = getPos(d->cursor_).x_;
 
        // Horizontal scroll offset of the cursor row in pixels
        int offset = d->horiz_scroll_offset_;
-       int const MARGIN = 10;
+       int const MARGIN = Length(2, Length::EM).inPixels(workWidth());
        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;
-       } else if(offset > 0
-                 && row.width() - offset < workWidth()){
-               offset = row.width() - workWidth();
        }
 
+       if (offset < row.left_margin || row.width() <= workWidth())
+               offset = 0;
+
        if (offset != d->horiz_scroll_offset_)
-               LYXERR0("Offset is now " << offset);
+               LYXERR(Debug::PAINTING, "Horiz. scroll offset changed from "
+                      << d->horiz_scroll_offset_ << " to " << offset);
 
        if (d->update_strategy_ == NoScreenUpdate
            && (offset != d->horiz_scroll_offset_
                || !d->last_row_slice_.empty())) {
                // FIXME: if one uses SingleParUpdate, then home/end
                // will not work on long rows. Why?
-               d->update_strategy_ = FullScreenUpdate;//DecorationUpdate;
+               d->update_strategy_ = FullScreenUpdate;
        }
 
        d->horiz_scroll_offset_ = offset;
@@ -2984,6 +3046,7 @@ void BufferView::draw(frontend::Painter & pain)
        case NoScreenUpdate:
                // If no screen painting is actually needed, only some the different
                // coordinates of insets and paragraphs needs to be updated.
+               LYXERR(Debug::PAINTING, "Strategy: NoScreenUpdate");
                pi.full_repaint = true;
                pi.pain.setDrawingEnabled(false);
                tm.draw(pi, 0, y);
@@ -2991,6 +3054,7 @@ void BufferView::draw(frontend::Painter & pain)
 
        case SingleParUpdate:
                pi.full_repaint = false;
+               LYXERR(Debug::PAINTING, "Strategy: SingleParUpdate");
                // In general, only the current row of the outermost paragraph
                // will be redrawn. Particular cases where selection spans
                // multiple paragraph are correctly detected in TextMetrics.
@@ -3003,6 +3067,12 @@ void BufferView::draw(frontend::Painter & pain)
                // because of the single backing pixmap.
 
        case FullScreenUpdate:
+
+               LYXERR(Debug::PAINTING,
+                      ((d->update_strategy_ == FullScreenUpdate)
+                       ? "Strategy: FullScreenUpdate"
+                       : "Strategy: DecorationUpdate"));
+
                // The whole screen, including insets, will be refreshed.
                pi.full_repaint = true;