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;
}
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();
}
-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;
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());
}
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:
else
dr.screenUpdate(Update::Force | Update::FitCursor);
dr.forceBufferUpdate();
+ // we only need to do this if we have deleted or restored a
+ // BiBTeX inset. but there is no other place to do it. one
+ // obvious idea is to try to do it in a copy constructor for
+ // InsetBibTeX, but when that is invoked, the buffer_ member
+ // is not yet set. another idea is to look at the InsetLists
+ // of the various paragraphs. but we'd have to recurse through
+ // the contained insets to make that work. it doesn't seem to
+ // be worth it, as this will not happen that often.
+ buffer().invalidateBibfileCache();
+ buffer().removeBiblioTempFiles();
break;
case LFUN_REDO:
else
dr.screenUpdate(Update::Force | Update::FitCursor);
dr.forceBufferUpdate();
+ // see above
+ buffer().invalidateBibfileCache();
+ buffer().removeBiblioTempFiles();
break;
case LFUN_FONT_STATE:
break;
case LFUN_MARK_TOGGLE:
- cur.setSelection(false);
+ cur.selection(false);
if (cur.mark()) {
cur.setMark(false);
dr.setMessage(from_utf8(N_("Mark removed")));
}
- 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 {
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
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();
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...
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.
// 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.
if (!inset || !cur.result().dispatched())
cur.dispatch(cmd);
- cur.endUndoGroup();
-
// Notify left insets
if (cur != old) {
bool badcursor = old.fixIfBroken() | cur.fixIfBroken();
cursor().fixIfBroken();
}
+ cur.endUndoGroup();
+
// Do we have a selection?
theSelection().haveSelection(cursor().selection());
}
d->cursor_.reset();
buffer_.text().setCursor(d->cursor_, newpit, newpos);
- d->cursor_.setSelection(false);
+ d->cursor_.selection(false);
d->cursor_.resetAnchor();
recenter();
}
// find label
shared_ptr<Toc> 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());
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
// 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();
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;
}
-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();
}
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);
}