/// a slice pointing to the start of the row where the cursor
/// is (at last draw time)
CursorSlice current_row_slice_;
- /// a slice pointing to the start of the row where cursor was
- /// at previous draw event
- CursorSlice last_row_slice_;
// The vertical size of the blinking caret. Only used for math
// Using it for text could be bad when undo restores the cursor
*/
buffer_.updateMacros();
- // SinglePar is ignored for now (this should probably change). We
- // set it ourselves below, at the price of always rebreaking the
- // paragraph at cursor. This can be expensive for large tables.
- flags = flags & ~Update::SinglePar;
-
// First check whether the metrics and inset positions should be updated
if (flags & Update::Force) {
// This will update the CoordCache items and replace Force
updateMetrics(flags);
}
- // Detect whether we can only repaint a single paragraph.
+ // Detect whether we can only repaint a single paragraph (if we
+ // are not already redrawing all).
// We handle this before FitCursor because the later will require
// correct metrics at cursor position.
- if (!(flags & Update::ForceDraw)) {
- if (singleParUpdate())
- flags = flags | Update::SinglePar;
- else
+ if (!(flags & Update::ForceDraw)
+ && (flags & Update::SinglePar)
+ && !singleParUpdate())
updateMetrics(flags);
- }
// Then make sure that the screen contains the cursor if needed
if (flags & Update::FitCursor) {
LYXERR(Debug::PAINTING, "Cumulative flags: " << flagsAsString(flags));
// Now compute the update strategy
- // Possibly values in flag are None, Decoration, ForceDraw
+ // Possibly values in flag are None, SinglePar, Decoration, ForceDraw
LATTEST((d->update_flags_ & ~(Update::None | Update::SinglePar
| Update::Decoration | Update::ForceDraw)) == 0);
d->cursor_.setCurrentFont();
// Do not forget to reset the anchor (see #9912)
d->cursor_.resetAnchor();
- processUpdateFlags(Update::FitCursor);
+ processUpdateFlags(Update::Force | Update::FitCursor);
}
return success;
int offset = coordOffset(dit).y_;
int ypos = pm.position() + offset;
Dimension const & row_dim =
- pm.getRow(cs.pos(), dit.boundary()).dimension();
+ pm.getRow(cs.pos(), dit.boundary()).dim();
int scrolled = 0;
if (recenter)
scrolled = scroll(ypos - height_/2);
d->anchor_pit_ = bot_pit;
CursorSlice const & cs = dit.innerTextSlice();
Dimension const & row_dim =
- pm.getRow(cs.pos(), dit.boundary()).dimension();
+ pm.getRow(cs.pos(), dit.boundary()).dim();
if (recenter)
d->anchor_ypos_ = height_/2;
void BufferView::editInset(string const & name, Inset * inset)
{
- d->edited_insets_[name] = inset;
+ if (inset)
+ d->edited_insets_[name] = inset;
+ else
+ d->edited_insets_.erase(name);
}
// At least one complete cell is selected and inset is a table.
// Select all cells
cur.idx() = 0;
+ cur.pit() = 0;
cur.pos() = 0;
cur.resetAnchor();
cur.selection(true);
cur.idx() = cur.lastidx();
+ cur.pit() = cur.lastpit();
cur.pos() = cur.lastpos();
} else {
// select current cell
void BufferView::gotoLabel(docstring const & label)
{
+ FuncRequest action;
+ bool have_inactive = false;
for (Buffer const * buf : buffer().allRelatives()) {
// find label
for (TocItem const & item : *buf->tocBackend().toc("label")) {
- if (label == item.str()) {
+ if (label == item.str() && item.isOutput()) {
lyx::dispatch(item.action());
return;
}
+ // If we find an inactive label, save it for the case
+ // that no active one is there
+ if (label == item.str() && !have_inactive) {
+ have_inactive = true;
+ action = item.action();
+ }
}
}
+ // We only found an inactive label. Go there.
+ if (have_inactive)
+ lyx::dispatch(action);
}
LBUFERR(t);
TextMetricsCache::iterator tmc_it = d->text_metrics_.find(t);
if (tmc_it == d->text_metrics_.end()) {
- tmc_it = d->text_metrics_.insert(
- make_pair(t, TextMetrics(this, const_cast<Text *>(t)))).first;
+ tmc_it = d->text_metrics_.emplace(std::piecewise_construct,
+ std::forward_as_tuple(t),
+ std::forward_as_tuple(this, const_cast<Text *>(t))).first;
}
return tmc_it->second;
}
return false;
bool need_anchor_change = false;
- bool changed = d->cursor_.text()->deleteEmptyParagraphMechanism(cur, old,
+ bool changed = Text::deleteEmptyParagraphMechanism(cur, old,
need_anchor_change);
if (need_anchor_change)
}
-bool BufferView::hadHorizScrollOffset(Text const * text,
- pit_type pit, pos_type pos) const
-{
- 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();
-}
-
-
void BufferView::setCurrentRowSlice(CursorSlice const & rowSlice)
{
// nothing to do if the cursor was already on this row
- if (d->current_row_slice_ == rowSlice) {
- d->last_row_slice_ = CursorSlice();
+ if (d->current_row_slice_ == rowSlice)
return;
- }
// if the (previous) current row was scrolled, we have to
// remember it in order to repaint it next time.
- if (d->horiz_scroll_offset_ != 0)
- d->last_row_slice_ = d->current_row_slice_;
- else
- d->last_row_slice_ = CursorSlice();
+ if (d->horiz_scroll_offset_ != 0) {
+ // search the old row in cache and mark it changed
+ for (auto & tm_pair : d->text_metrics_) {
+ if (&tm_pair.first->inset() == rowSlice.inset().asInsetText()) {
+ tm_pair.second.setRowChanged(rowSlice.pit(), rowSlice.pos());
+ // We found it, no need to continue.
+ break;
+ }
+ }
+ }
// Since we changed row, the scroll offset is not valid anymore
d->horiz_scroll_offset_ = 0;
<< d->horiz_scroll_offset_ << " to " << offset);
if (d->update_strategy_ == NoScreenUpdate
- && (offset != d->horiz_scroll_offset_
- || !d->last_row_slice_.empty())) {
+ && offset != d->horiz_scroll_offset_) {
// FIXME: if one uses SingleParUpdate, then home/end
// will not work on long rows. Why?
d->update_strategy_ = FullScreenUpdate;