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();
else
d->scrollbarParameters_.max -= d->scrollbarParameters_.page_step;
+
+ // 0 must be inside the range as it denotes the current position
+ if (d->scrollbarParameters_.max < 0)
+ d->scrollbarParameters_.max = 0;
+ if (d->scrollbarParameters_.min > 0)
+ d->scrollbarParameters_.min = 0;
}
}
-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;
}
-bool BufferView::scrollToCursor(DocIterator const & dit, bool recenter)
+bool BufferView::scrollToCursor(DocIterator const & dit, bool const recenter)
{
// We are not properly started yet, delay until resizing is
// done.
if (buffer_.isReadonly()
&& !lyxaction.funcHasFlag(act, LyXAction::ReadOnly)
&& !lyxaction.funcHasFlag(act, LyXAction::NoBuffer)) {
- flag.message(from_utf8(N_("Document is read-only")));
+ if (buffer_.hasReadonlyFlag())
+ flag.message(from_utf8(N_("Document is read-only")));
+ else
+ flag.message(from_utf8(N_("Document has been modified externally")));
flag.setEnabled(false);
return true;
}
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:
case LFUN_PARAGRAPH_GOTO: {
int const id = convert<int>(cmd.getArg(0));
- int const pos = convert<int>(cmd.getArg(1));
+ pos_type const pos = convert<int>(cmd.getArg(1));
+ if (id < 0)
+ break;
+ string const str_id_end = cmd.getArg(2);
+ string const str_pos_end = cmd.getArg(3);
int i = 0;
for (Buffer * b = &buffer_; i == 0 || b != &buffer_;
b = theBufferList().next(b)) {
<< b->absFileName() << "'.");
if (b == &buffer_) {
- // Set the cursor
- cur.pos() = pos;
- mouseSetCursor(cur);
- dr.screenUpdate(Update::Force | Update::FitCursor);
+ bool success;
+ if (str_id_end.empty() || str_pos_end.empty()) {
+ // Set the cursor
+ cur.pos() = pos;
+ mouseSetCursor(cur);
+ success = true;
+ } else {
+ int const id_end = convert<int>(str_id_end);
+ pos_type const pos_end = convert<int>(str_pos_end);
+ success = setCursorFromEntries({id, pos},
+ {id_end, pos_end});
+ }
+ if (success)
+ dr.screenUpdate(Update::Force | Update::FitCursor);
} else {
// Switch to other buffer view and resend cmd
lyx::dispatch(FuncRequest(
docstring const data =
find2string(searched_string, true, false, fw);
bool found = lyxfind(this, FuncRequest(LFUN_WORD_FIND, data));
- if (found) {
+ if (found)
dr.screenUpdate(Update::Force | Update::FitCursor);
- cur.dispatched();
- dispatched = true;
- } else {
- cur.undispatched();
- dispatched = false;
- }
break;
}
lyx::dispatch(FuncRequest(LFUN_DIALOG_SHOW, "findreplace"));
break;
}
- if (lyxfind(this, req)) {
+ if (lyxfind(this, req))
dr.screenUpdate(Update::Force | Update::FitCursor);
- cur.dispatched();
- dispatched = true;
- } else {
- cur.undispatched();
- dispatched = false;
- }
+
d->search_request_cache_ = req;
break;
}
if (lyxreplace(this, cmd, has_deleted)) {
dr.forceBufferUpdate();
dr.screenUpdate(Update::Force | Update::FitCursor);
- cur.dispatched();
- dispatched = true;
- } else {
- cur.undispatched();
- dispatched = false;
}
break;
}
break;
case LFUN_MARK_TOGGLE:
- cur.setSelection(false);
+ cur.selection(false);
if (cur.mark()) {
cur.setMark(false);
dr.setMessage(from_utf8(N_("Mark removed")));
// Select the inset from outside.
cur.pop();
cur.resetAnchor();
- cur.setSelection(true);
+ cur.selection(true);
cur.posForward();
} else if (cells_selected) {
// At least one complete cell is selected and inset is a table.
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();
}
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.
}
-void BufferView::setCursorFromRow(int row)
+bool BufferView::setCursorFromRow(int row)
{
- setCursorFromRow(row, buffer_.texrow());
+ TexRow::TextEntry start, end;
+ tie(start,end) = buffer_.texrow().getEntriesFromRow(row);
+ LYXERR(Debug::LATEX,
+ "setCursorFromRow: for row " << row << ", TexRow has found "
+ "start (id=" << start.id << ",pos=" << start.pos << "), "
+ "end (id=" << end.id << ",pos=" << end.pos << ")");
+ return setCursorFromEntries(start, end);
}
-void BufferView::setCursorFromRow(int row, TexRow const & texrow)
+bool BufferView::setCursorFromEntries(TexRow::TextEntry start,
+ TexRow::TextEntry end)
{
- int tmpid;
- int tmppos;
- pit_type newpit = 0;
- pos_type newpos = 0;
-
- texrow.getIdFromRow(row, tmpid, tmppos);
-
- bool posvalid = (tmpid != -1);
- if (posvalid) {
- // we need to make sure that the row and position
- // we got back are valid, because the buffer may well
- // have changed since we last generated the LaTeX.
- DocIterator dit = buffer_.getParFromID(tmpid);
- if (dit == doc_iterator_end(&buffer_))
- posvalid = false;
- else if (dit.depth() > 1) {
- // We are in an inset.
- pos_type lastpos = dit.lastpos();
- dit.pos() = tmppos > lastpos ? lastpos : tmppos;
- setCursor(dit);
- recenter();
- return;
- } else {
- newpit = dit.pit();
- // now have to check pos.
- newpos = tmppos;
- Paragraph const & par = buffer_.text().getPar(newpit);
- if (newpos > par.size()) {
- LYXERR0("Requested position no longer valid.");
- newpos = par.size() - 1;
- }
- }
- }
- if (!posvalid) {
- frontend::Alert::error(_("Inverse Search Failed"),
- _("Invalid position requested by inverse search.\n"
- "You need to update the viewed document."));
- return;
+ DocIterator dit_start, dit_end;
+ tie(dit_start,dit_end) =
+ TexRow::getDocIteratorsFromEntries(start, end, buffer_);
+ if (!dit_start)
+ return false;
+ // Setting selection start
+ d->cursor_.clearSelection();
+ setCursor(dit_start);
+ // Setting selection end
+ if (dit_end) {
+ d->cursor_.resetAnchor();
+ setCursorSelectionTo(dit_end);
}
- d->cursor_.reset();
- buffer_.text().setCursor(d->cursor_, newpit, newpos);
- d->cursor_.setSelection(false);
- d->cursor_.resetAnchor();
- recenter();
+ return true;
}
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
}
+void BufferView::setCursorSelectionTo(DocIterator const & dit)
+{
+ size_t const n = dit.depth();
+ for (size_t i = 0; i < n; ++i)
+ dit[i].inset().edit(d->cursor_, true);
+
+ d->cursor_.selection(true);
+ d->cursor_.setCursorSelectionTo(dit);
+ d->cursor_.setCurrentFont();
+}
+
+
bool BufferView::checkDepm(Cursor & cur, Cursor & old)
{
// Would be wrong to delete anything if we have a selection.
}
-bool BufferView::mouseSetCursor(Cursor & cur, bool select)
+bool BufferView::mouseSetCursor(Cursor & cur, bool const select)
{
LASSERT(&cur.bv() == this, return false);
if (leftinset)
d->cursor_.fixIfBroken();
- // FIXME: shift-mouse selection doesn't work well across insets.
- bool const do_selection =
- select && &d->cursor_.normalAnchor().inset() == &cur.inset();
-
// do the dEPM magic if needed
// FIXME: (1) move this to InsetText::notifyCursorLeaves?
// 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())
- update |= checkDepm(cur, d->cursor_);
- if (!do_selection)
- d->cursor_.resetAnchor();
- d->cursor_.setCursor(cur);
- d->cursor_.boundary(cur.boundary());
- if (do_selection)
+ if (select) {
d->cursor_.setSelection();
- else
+ d->cursor_.setCursorSelectionTo(cur);
+ } else {
+ if (d->cursor_.inTexted())
+ update |= checkDepm(cur, d->cursor_);
+ d->cursor_.resetAnchor();
+ d->cursor_.setCursor(cur);
d->cursor_.clearSelection();
-
+ }
+ d->cursor_.boundary(cur.boundary());
d->cursor_.finishUndo();
d->cursor_.setCurrentFont();
if (update)
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;
}
// remember width for the case that sl.inset() is positioned in an RTL inset
- if (i && dit[i - 1].text()) {
- // If this Inset is inside a Text Inset, retrieve the Dimension
- // from the containing text instead of using Inset::dimension() which
- // might not be implemented.
- // FIXME (Abdel 23/09/2007): this is a bit messy because of the
- // elimination of Inset::dim_ cache. This coordOffset() method needs
- // to be rewritten in light of the new design.
- Dimension const & dim = coordCache().getInsets().dim(&sl.inset());
- lastw = dim.wid;
- } else {
- Dimension const dim = sl.inset().dimension(*this);
- lastw = dim.wid;
- }
+ lastw = sl.inset().dimension(*this).wid;
//lyxerr << "Cursor::getPos, i: "
// << i << " x: " << xx << " y: " << y << endl;
void BufferView::cursorPosAndHeight(Point & p, int & h) const
{
Cursor const & cur = cursor();
- Font const font = cur.getFont();
+ Font const font = cur.real_current_font;
frontend::FontMetrics const & fm = theFontMetrics(font);
int const asc = fm.maxAscent();
int const des = fm.maxDescent();
}
-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);
}