X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FBufferView.cpp;h=6922770f2966c558fe8d28f867c094f43eeeed0d;hb=3573b7270c717b5715f507da47e4ce238dbb987c;hp=6de832dae58715af6b55b0286c882e39595b596d;hpb=55b3374f3e3047a0aa7584e0737d1fcd40fe6809;p=lyx.git diff --git a/src/BufferView.cpp b/src/BufferView.cpp index 6de832dae5..6922770f29 100644 --- a/src/BufferView.cpp +++ b/src/BufferView.cpp @@ -370,13 +370,13 @@ int BufferView::leftMargin() const bool BufferView::isTopScreen() const { - return d->scrollbarParameters_.position == d->scrollbarParameters_.min; + return 0 == d->scrollbarParameters_.min; } bool BufferView::isBottomScreen() const { - return d->scrollbarParameters_.position == d->scrollbarParameters_.max; + return 0 == d->scrollbarParameters_.max; } @@ -559,7 +559,6 @@ void BufferView::updateScrollbar() for (size_t i = last.first + 1; i != parsize; ++i) d->scrollbarParameters_.max += d->par_height_[i]; - d->scrollbarParameters_.position = 0; // The reference is the top position so we remove one page. if (lyxrc.scroll_below_document) d->scrollbarParameters_.max -= minVisiblePart(); @@ -600,17 +599,19 @@ string BufferView::contextMenu(int x, int y) const } -void BufferView::scrollDocView(int value, bool update) + +void BufferView::scrollDocView(int const value, bool update) { - int const offset = value - d->scrollbarParameters_.position; + // The scrollbar values are relative to the top of the screen, therefore the + // offset is equal to the target value. // No scrolling at all? No need to redraw anything - if (offset == 0) + if (value == 0) return; // If the offset is less than 2 screen height, prefer to scroll instead. - if (abs(offset) <= 2 * height_) { - d->anchor_ypos_ -= offset; + if (abs(value) <= 2 * height_) { + d->anchor_ypos_ -= value; buffer_.changed(true); updateHoveredInset(); return; @@ -707,9 +708,7 @@ Change const BufferView::getCurrentChange() const DocIterator dit = d->cursor_.selectionBegin(); // The selected content might have been changed (see #7685) - while (dit.inMathed()) - // Find enclosing text cursor - dit.pop_back(); + dit = dit.getInnerText(); return dit.paragraph().lookupChange(dit.pos()); } @@ -1132,11 +1131,7 @@ bool BufferView::getStatus(FuncRequest const & cmd, FuncStatus & flag) case LFUN_CHANGE_PREVIOUS: case LFUN_ALL_CHANGES_ACCEPT: case LFUN_ALL_CHANGES_REJECT: - // TODO: context-sensitive enabling of LFUNs - // In principle, these command should only be enabled if there - // is a change in the document. However, without proper - // optimizations, this will inevitably result in poor performance. - flag.setEnabled(true); + flag.setEnabled(buffer_.areChangesPresent()); break; case LFUN_SCREEN_UP: @@ -1593,7 +1588,7 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) break; case LFUN_MARK_TOGGLE: - cur.setSelection(false); + cur.selection(false); if (cur.mark()) { cur.setMark(false); dr.setMessage(from_utf8(N_("Mark removed"))); @@ -1777,26 +1772,30 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) } - case LFUN_INSET_SELECT_ALL: - if (cur.depth() > 1 + case LFUN_INSET_SELECT_ALL: { + // true if all cells are selected + bool const all_selected = cur.depth() > 1 && cur.selBegin().at_begin() - && cur.selEnd().at_end()) { - // All the contents of the inset if selected. + && cur.selEnd().at_end(); + // true if some cells are selected + bool const cells_selected = cur.depth() > 1 + && cur.selBegin().at_cell_begin() + && cur.selEnd().at_cell_end(); + if (all_selected || (cells_selected && !cur.inset().isTable())) { + // All the contents of the inset if selected, or only at + // least one cell but inset is not a table. // Select the inset from outside. cur.pop(); cur.resetAnchor(); - cur.setSelection(true); + cur.selection(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. + } else if (cells_selected) { + // At least one complete cell is selected and inset is a table. // Select all cells cur.idx() = 0; cur.pos() = 0; cur.resetAnchor(); - cur.setSelection(true); + cur.selection(true); cur.idx() = cur.lastidx(); cur.pos() = cur.lastpos(); } else { @@ -1804,13 +1803,14 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) cur.pit() = 0; cur.pos() = 0; cur.resetAnchor(); - cur.setSelection(true); + cur.selection(true); cur.pit() = cur.lastpit(); cur.pos() = cur.lastpos(); } cur.setCurrentFont(); dr.screenUpdate(Update::Force); break; + } // This would be in Buffer class if only Cursor did not @@ -1850,9 +1850,17 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr) if (!cur.nextInset() || cur.nextInset() == ins) cur.forwardInset(); } - cur.endUndoGroup(); cur = savecur; cur.fixIfBroken(); + /** This is a dummy undo record only to remember the cursor + * that has just been set; this will be used on a redo action + * (see ticket #10097) + + * FIXME: a better fix would be to have a way to set the + * cursor value directly, but I am not sure it is worth it. + */ + cur.recordUndo(); + cur.endUndoGroup(); dr.screenUpdate(Update::Force); dr.forceBufferUpdate(); @@ -2124,7 +2132,7 @@ void BufferView::updateHoveredInset() const int const y = d->mouse_position_cache_.y_; Inset const * covering_inset = getCoveringInset(buffer_.text(), x, y); - d->clickable_inset_ = covering_inset && covering_inset->clickable(x, y); + d->clickable_inset_ = covering_inset && covering_inset->clickable(*this, x, y); if (covering_inset == d->last_inset_) // Same inset, no need to do anything... @@ -2180,7 +2188,7 @@ void BufferView::mouseEventDispatch(FuncRequest const & cmd0) Cursor old = cursor(); Cursor cur(*this); cur.push(buffer_.inset()); - cur.setSelection(d->cursor_.selection()); + cur.selection(d->cursor_.selection()); // Either the inset under the cursor or the // surrounding Text will handle this event. @@ -2203,9 +2211,14 @@ void BufferView::mouseEventDispatch(FuncRequest const & cmd0) // inset (depending on cmd.x(), cmd.y()). This is needed for // editing to fix bug 9628, but e.g. the context menu needs a // cursor in front of the inset. - if (inset->hasSettings() && + if ((inset->hasSettings() || !inset->contextMenuName().empty() + || inset->lyxCode() == SEPARATOR_CODE) && cur.nextInset() != inset && cur.prevInset() == inset) cur.posBackward(); + } else if (cur.inTexted() && cur.pos() + && cur.paragraph().isEnvSeparator(cur.pos() - 1)) { + // Always place cursor in front of a separator inset. + cur.posBackward(); } // Put anchor at the same position. @@ -2225,8 +2238,6 @@ void BufferView::mouseEventDispatch(FuncRequest const & cmd0) if (!inset || !cur.result().dispatched()) cur.dispatch(cmd); - cur.endUndoGroup(); - // Notify left insets if (cur != old) { bool badcursor = old.fixIfBroken() | cur.fixIfBroken(); @@ -2235,6 +2246,8 @@ void BufferView::mouseEventDispatch(FuncRequest const & cmd0) cursor().fixIfBroken(); } + cur.endUndoGroup(); + // Do we have a selection? theSelection().haveSelection(cursor().selection()); @@ -2362,7 +2375,7 @@ void BufferView::setCursorFromRow(int row, TexRow const & texrow) } d->cursor_.reset(); buffer_.text().setCursor(d->cursor_, newpit, newpos); - d->cursor_.setSelection(false); + d->cursor_.selection(false); d->cursor_.resetAnchor(); recenter(); } @@ -2397,8 +2410,8 @@ void BufferView::gotoLabel(docstring const & label) // find label shared_ptr toc = buf->tocBackend().toc("label"); - TocIterator toc_it = toc->begin(); - TocIterator end = toc->end(); + Toc::const_iterator toc_it = toc->begin(); + Toc::const_iterator end = toc->end(); for (; toc_it != end; ++toc_it) { if (label == toc_it->str()) { lyx::dispatch(toc_it->action()); @@ -2448,7 +2461,7 @@ void BufferView::setCursor(DocIterator const & dit) dit[i].inset().edit(d->cursor_, true); d->cursor_.setCursor(dit); - d->cursor_.setSelection(false); + d->cursor_.selection(false); d->cursor_.setCurrentFont(); // FIXME // It seems on general grounds as if this is probably needed, but @@ -2512,11 +2525,8 @@ bool BufferView::mouseSetCursor(Cursor & cur, bool select) // FIXME: (2) if we had a working InsetText::notifyCursorLeaves, // the leftinset bool would not be necessary (badcursor instead). bool update = leftinset; - if (!do_selection && d->cursor_.inTexted()) { + if (!do_selection && d->cursor_.inTexted()) update |= checkDepm(cur, d->cursor_); - if (cur.pos() && cur.paragraph().isEnvSeparator(cur.pos() - 1)) - cur.posBackward(); - } if (!do_selection) d->cursor_.resetAnchor(); @@ -2580,7 +2590,7 @@ bool BufferView::selectIfEmpty(DocIterator & cur) d->cursor_.setCursor(cur); d->cursor_.pit() = beg_pit; d->cursor_.pos() = 0; - d->cursor_.setSelection(false); + d->cursor_.selection(false); d->cursor_.resetAnchor(); d->cursor_.pit() = end_pit; d->cursor_.pos() = end_pos; @@ -2905,15 +2915,26 @@ int BufferView::horizScrollOffset() const } -CursorSlice const & BufferView::currentRowSlice() const +int BufferView::horizScrollOffset(Text const * text, + pit_type pit, pos_type pos) const { - return d->current_row_slice_; + // Is this a row that is currently scrolled? + if (!d->current_row_slice_.empty() + && &text->inset() == d->current_row_slice_.inset().asInsetText() + && pit == d->current_row_slice_.pit() + && pos == d->current_row_slice_.pos()) + return d->horiz_scroll_offset_; + return 0; } -CursorSlice const & BufferView::lastRowSlice() const +bool BufferView::hadHorizScrollOffset(Text const * text, + pit_type pit, pos_type pos) const { - return d->last_row_slice_; + return !d->last_row_slice_.empty() + && &text->inset() == d->last_row_slice_.inset().asInsetText() + && pit == d->last_row_slice_.pit() + && pos == d->last_row_slice_.pos(); } @@ -2979,8 +3000,7 @@ void BufferView::checkCursorScrollOffset(PainterInfo & pi) 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); + RowPainter rp(pi, buffer().text(), row, -d->horiz_scroll_offset_, 0); rp.paintText(); pi.pain.setDrawingEnabled(drawing); }