X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FBufferView.cpp;h=8a947c169fb12e30e80f6aff2bd8065a0406cd69;hb=51cc8aa9f6b784f806b1d9cc97fe0749ffac29af;hp=92ce6f634de6f9b5ccfdebd5bfe7f2c56593af6d;hpb=c6e1db7682dc8d58a68147b5eee1d004829ef6d2;p=lyx.git diff --git a/src/BufferView.cpp b/src/BufferView.cpp index 92ce6f634d..8a947c169f 100644 --- a/src/BufferView.cpp +++ b/src/BufferView.cpp @@ -227,7 +227,8 @@ enum ScreenUpdateStrategy { struct BufferView::Private { - Private(BufferView & bv): wh_(0), cursor_(bv), + Private(BufferView & bv) : update_strategy_(NoScreenUpdate), + wh_(0), cursor_(bv), anchor_pit_(0), anchor_ypos_(0), inlineCompletionUniqueChars_(0), last_inset_(0), clickable_inset_(false), @@ -1102,6 +1103,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; @@ -1111,13 +1113,13 @@ bool BufferView::getStatus(FuncRequest const & cmd, FuncStatus & flag) iss >> opt; flag.setEnabled(opt.repl_buf_name.empty() || !buffer_.isReadonly()); + break; } - case LFUN_LABEL_GOTO: { + case LFUN_LABEL_GOTO: flag.setEnabled(!cmd.argument().empty() || getInsetByCode(cur, REF_CODE)); break; - } case LFUN_CHANGES_TRACK: flag.setEnabled(true); @@ -1250,7 +1252,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); @@ -1271,7 +1273,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); @@ -1287,7 +1292,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); @@ -1316,7 +1324,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); @@ -1404,20 +1415,21 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) for (Buffer * b = &buffer_; i == 0 || b != &buffer_; b = theBufferList().next(b)) { - DocIterator dit = b->getParFromID(id); - if (dit.atEnd()) { + Cursor cur(*this); + cur.setCursor(b->getParFromID(id)); + if (cur.atEnd()) { LYXERR(Debug::INFO, "No matching paragraph found! [" << id << "]."); ++i; continue; } - LYXERR(Debug::INFO, "Paragraph " << dit.paragraph().id() + LYXERR(Debug::INFO, "Paragraph " << cur.paragraph().id() << " found in buffer `" << b->absFileName() << "'."); if (b == &buffer_) { // Set the cursor - dit.pos() = pos; - setCursor(dit); + cur.pos() = pos; + mouseSetCursor(cur); dr.screenUpdate(Update::Force | Update::FitCursor); } else { // Switch to other buffer view and resend cmd @@ -1736,6 +1748,8 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) Cursor old = cur; bool const in_texted = cur.inTexted(); cur.setCursor(doc_iterator_begin(cur.buffer())); + if (cur != old) + notifyCursorLeavesOrEnters(old, cur); cur.selHandle(false); buffer_.changed(true); updateHoveredInset(); @@ -1815,6 +1829,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: { @@ -1992,7 +2041,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(); @@ -2925,6 +2974,19 @@ 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); @@ -2933,13 +2995,14 @@ void BufferView::checkCursorScrollOffset(PainterInfo & pi) -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 = Length(2, Length::EM).inPixels(workWidth()); + int const MARGIN = Length(2, Length::EM).inPixels(pi.base); if (cur_x < offset + MARGIN) { // scroll right offset = cur_x - MARGIN; @@ -2948,7 +3011,7 @@ void BufferView::checkCursorScrollOffset(PainterInfo & pi) offset = cur_x - workWidth() + MARGIN; } - if (offset < row.x || row.width() <= workWidth()) + if (offset < row.left_margin || row.width() <= workWidth()) offset = 0; if (offset != d->horiz_scroll_offset_)