int BufferView::rightMargin() const
{
+ // The value used to be hardcoded to 10, which is 2.5mm at 100dpi
+ int const default_margin = Length(2.5, Length::MM).inPixels(0);
// The additional test for the case the outliner is opened.
- if (!full_screen_ ||
- !lyxrc.full_screen_limit ||
- width_ < lyxrc.full_screen_width + 20)
- return 10;
+ if (!full_screen_ || !lyxrc.full_screen_limit
+ || width_ < lyxrc.full_screen_width + 2 * default_margin)
+ return default_margin;
return (width_ - lyxrc.full_screen_width) / 2;
}
void BufferView::processUpdateFlags(Update::flags flags)
{
// This is close to a hot-path.
- LYXERR(Debug::DEBUG, "BufferView::processUpdateFlags()"
+ LYXERR(Debug::PAINTING, "BufferView::processUpdateFlags()"
<< "[fitcursor = " << (flags & Update::FitCursor)
<< ", forceupdate = " << (flags & Update::Force)
<< ", singlepar = " << (flags & Update::SinglePar)
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());
}
setCursor(dit);
// set the current font.
d->cursor_.setCurrentFont();
+ // Do not forget to reset the anchor (see #9912)
+ d->cursor_.resetAnchor();
// To center the screen on this new position we need the
// paragraph position which is computed at draw() time.
// So we need a redraw!
|| getInsetByCode<InsetRef>(cur, REF_CODE));
break;
- case LFUN_CHANGES_TRACK:
- flag.setEnabled(true);
- flag.setOnOff(buffer_.params().track_changes);
- break;
-
- case LFUN_CHANGES_OUTPUT:
- flag.setEnabled(true);
- flag.setOnOff(buffer_.params().output_changes);
- break;
-
case LFUN_CHANGES_MERGE:
case LFUN_CHANGE_NEXT:
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);
- break;
-
- case LFUN_BUFFER_TOGGLE_COMPRESSION: {
- flag.setOnOff(buffer_.params().compressed);
- break;
- }
-
- case LFUN_BUFFER_TOGGLE_OUTPUT_SYNC: {
- flag.setOnOff(buffer_.params().output_sync);
+ flag.setEnabled(buffer_.areChangesPresent());
break;
- }
case LFUN_SCREEN_UP:
case LFUN_SCREEN_DOWN:
break;
}
- case LFUN_CHANGES_TRACK:
- buffer_.params().track_changes = !buffer_.params().track_changes;
- break;
-
- case LFUN_CHANGES_OUTPUT:
- buffer_.params().output_changes = !buffer_.params().output_changes;
- if (buffer_.params().output_changes) {
- bool dvipost = LaTeXFeatures::isAvailable("dvipost");
- bool xcolorulem = LaTeXFeatures::isAvailable("ulem") &&
- LaTeXFeatures::isAvailable("xcolor");
-
- if (!dvipost && !xcolorulem) {
- Alert::warning(_("Changes not shown in LaTeX output"),
- _("Changes will not be highlighted in LaTeX output, "
- "because neither dvipost nor xcolor/ulem are installed.\n"
- "Please install these packages or redefine "
- "\\lyxadded and \\lyxdeleted in the LaTeX preamble."));
- } else if (!xcolorulem) {
- Alert::warning(_("Changes not shown in LaTeX output"),
- _("Changes will not be highlighted in LaTeX output "
- "when using pdflatex, because xcolor and ulem are not installed.\n"
- "Please install both packages or redefine "
- "\\lyxadded and \\lyxdeleted in the LaTeX preamble."));
- }
- }
- break;
-
case LFUN_CHANGE_NEXT:
findNextChange(this);
// FIXME: Move this LFUN to Buffer so that we don't have to do this:
}
break;
- case LFUN_BUFFER_TOGGLE_COMPRESSION:
- // turn compression on/off
- buffer_.params().compressed = !buffer_.params().compressed;
- break;
-
- case LFUN_BUFFER_TOGGLE_OUTPUT_SYNC:
- buffer_.params().output_sync = !buffer_.params().output_sync;
- break;
-
case LFUN_SCREEN_UP:
case LFUN_SCREEN_DOWN: {
Point p = getPos(cur);
}
- 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.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.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...
// 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.backwardPos();
+ 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());
// Set the row on which the cursor lives.
setCurrentRowSlice(rowSlice);
- // Current x position of the cursor in pixels
- int cur_x = getPos(d->cursor_).x_;
-
- // If cursor offset is left margin and offset is not the leftmost
- // position of the row, there is a cache problem.
- if (cur_x == row.left_margin && !row.empty()
- && d->cursor_.pos() != row.front().left_pos()) {
+ // If insets referred to by cursor are not all in the cache, the positions
+ // need to be recomputed.
+ if (!d->cursor_.inCoordCache()) {
/** 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.
* cache. This would not happen if we did not have two-stage
* drawing.
*
- * A proper fix should be found and this code should be removed.
+ * A proper fix would be to always have proper inset positions
+ * at this point.
*/
// Force the recomputation of inset positions
bool const drawing = pi.pain.isDrawingEnabled();
-d->horiz_scroll_offset_, 0);
rp.paintText();
pi.pain.setDrawingEnabled(drawing);
-
- // Recompute current Current x position of the cursor in pixels
- cur_x = getPos(d->cursor_).x_;
}
+ // Current x position of the cursor in pixels
+ int cur_x = getPos(d->cursor_).x_;
+
// Horizontal scroll offset of the cursor row in pixels
int offset = d->horiz_scroll_offset_;
int const MARGIN = 2 * theFontMetrics(d->cursor_.real_current_font).em()
+ row.right_margin;
- if (row.width() <= workWidth() - row.right_margin) {
+ if (row.right_x() <= workWidth() - row.right_margin) {
// Row is narrower than the work area, no offset needed.
offset = 0;
} else {
// Correct the offset to make sure that we do not scroll too much
if (offset < 0)
offset = 0;
- if (row.width() - offset < workWidth() - row.right_margin)
- offset = row.width() - workWidth() + row.right_margin;
+ if (row.right_x() - offset < workWidth() - row.right_margin)
+ offset = row.right_x() - workWidth() + row.right_margin;
}
//lyxerr << "cur_x=" << cur_x << ", offset=" << offset << ", row.wid=" << row.width() << ", margin=" << MARGIN << endl;