#include "insets/InsetGraphics.h"
#include "insets/InsetRef.h"
#include "insets/InsetText.h"
+#include "insets/InsetNote.h"
#include "frontends/alert.h"
#include "frontends/Application.h"
d->cursor_.setCurrentFont();
if (graphics::Previews::status() != LyXRC::PREVIEW_OFF)
- graphics::Previews::get().generateBufferPreviews(buffer_);
+ thePreviews().generateBufferPreviews(buffer_);
}
LastFilePosSection::FilePos fp;
fp.pit = d->cursor_.bottom().pit();
fp.pos = d->cursor_.bottom().pos();
- LyX::ref().session().lastFilePos().save(buffer_.fileName(), fp);
+ theSession().lastFilePos().save(buffer_.fileName(), fp);
delete d;
}
docstring BufferView::contextMenu(int x, int y) const
{
+ //If there is a selection, return the containing inset menu
+ if (d->cursor_.selection())
+ return d->cursor_.inset().contextMenu(*this, x, y);
+
// Get inset under mouse, if there is one.
Inset const * covering_inset = getCoveringInset(buffer_.text(), x, y);
if (covering_inset)
// If the offset is less than 2 screen height, prefer to scroll instead.
if (abs(offset) <= 2 * height_) {
scroll(offset);
+ updateMetrics();
+ buffer_.changed();
return;
}
int const height = 2 * defaultRowHeight();
int const first = height;
int const last = height_ - height;
- Cursor & cur = d->cursor_;
+ int newy = 0;
+ Cursor const & oldcur = d->cursor_;
- switch (cursorStatus(cur)) {
+ switch (cursorStatus(oldcur)) {
case CUR_ABOVE:
- // We reset the cursor because cursorStatus() does not
- // work when the cursor is within mathed.
- cur.reset(buffer_.inset());
- tm.setCursorFromCoordinates(cur, 0, first);
- cur.clearSelection();
+ newy = first;
break;
case CUR_BELOW:
- // We reset the cursor because cursorStatus() does not
- // work when the cursor is within mathed.
- cur.reset(buffer_.inset());
- tm.setCursorFromCoordinates(cur, 0, last);
- cur.clearSelection();
+ newy = last;
break;
case CUR_INSIDE:
- int const y = getPos(cur, cur.boundary()).y_;
- int const newy = min(last, max(y, first));
- if (y != newy) {
- cur.reset(buffer_.inset());
- tm.setCursorFromCoordinates(cur, 0, newy);
- }
+ int const y = getPos(oldcur, oldcur.boundary()).y_;
+ newy = min(last, max(y, first));
+ if (y == newy)
+ return;
}
+ // We reset the cursor because cursorStatus() does not
+ // work when the cursor is within mathed.
+ Cursor cur(*this);
+ cur.reset(buffer_.inset());
+ tm.setCursorFromCoordinates(cur, 0, newy);
+ mouseSetCursor(cur);
}
// acturately locate a bookmark in a 'live' lyx session.
// pit and pos will be updated with bottom level pit/pos
// when lyx exits.
- LyX::ref().session().bookmarks().save(
+ theSession().bookmarks().save(
buffer_.fileName(),
d->cursor_.bottom().pit(),
d->cursor_.bottom().pos(),
int ypos = pm.position() + offset;
Dimension const & row_dim =
pm.getRow(cs.pos(), dit.boundary()).dimension();
+ int scrolled = 0;
if (ypos - row_dim.ascent() < 0)
- scrollUp(- ypos + row_dim.ascent());
+ scrolled = scrollUp(- ypos + row_dim.ascent());
else if (ypos + row_dim.descent() > height_)
- scrollDown(ypos - height_ + row_dim.descent());
+ scrolled = scrollDown(ypos - height_ + row_dim.descent());
// else, nothing to do, the cursor is already visible so we just return.
+ if (scrolled != 0) {
+ updateMetrics();
+ buffer_.changed();
+ }
return;
}
case LFUN_SCREEN_RECENTER:
case LFUN_BIBTEX_DATABASE_ADD:
case LFUN_BIBTEX_DATABASE_DEL:
+ case LFUN_NOTES_MUTATE:
+ case LFUN_ALL_INSETS_TOGGLE:
case LFUN_STATISTICS:
flag.setEnabled(true);
break;
break;
case LFUN_LAYOUT:
- flag.setEnabled(!cur.inset().forceEmptyLayout(cur.idx()));
+ flag.setEnabled(!cur.inset().forcePlainLayout(cur.idx()));
break;
case LFUN_LAYOUT_PARAGRAPH:
if (!inset || !cur.result().dispatched())
cur.dispatch(cmd);
+ // FIXME I'm adding the last break to solve a crash,
+ // but that is obviously not right.
if (!cur.result().dispatched())
// It did not work too; no action needed.
break;
+ break;
}
case LFUN_PARAGRAPH_GOTO: {
buffer_.text().cursorBottom(d->cursor_);
// accept everything in a single step to support atomic undo
buffer_.text().acceptOrRejectChanges(d->cursor_, Text::ACCEPT);
+ // FIXME: Move this LFUN to Buffer so that we don't have to do this:
+ processUpdateFlags(Update::Force | Update::FitCursor);
break;
case LFUN_ALL_CHANGES_REJECT:
// reject everything in a single step to support atomic undo
// Note: reject does not work recursively; the user may have to repeat the operation
buffer_.text().acceptOrRejectChanges(d->cursor_, Text::REJECT);
+ // FIXME: Move this LFUN to Buffer so that we don't have to do this:
+ processUpdateFlags(Update::Force | Update::FitCursor);
break;
case LFUN_WORD_FIND: {
FuncRequest req = cmd;
if (cmd.argument().empty() && !d->search_request_cache_.argument().empty())
req = d->search_request_cache_;
+ if (req.argument().empty()) {
+ theLyXFunc().dispatch(FuncRequest(LFUN_DIALOG_SHOW, "findreplace"));
+ break;
+ }
if (find(this, req))
showCursor();
else
case LFUN_MARK_ON:
cur.clearSelection();
- cur.mark() = true;
+ cur.setMark(true);
cur.resetAnchor();
cur.message(from_utf8(N_("Mark on")));
break;
case LFUN_MARK_TOGGLE:
cur.clearSelection();
if (cur.mark()) {
- cur.mark() = false;
+ cur.setMark(false);
cur.message(from_utf8(N_("Mark removed")));
} else {
- cur.mark() = true;
+ cur.setMark(true);
cur.message(from_utf8(N_("Mark set")));
}
cur.resetAnchor();
showCursor();
p = getPos(cur, cur.boundary());
}
- scroll(cmd.action == LFUN_SCREEN_UP? - height_ : height_);
+ int const scrolled = scroll(cmd.action == LFUN_SCREEN_UP
+ ? - height_ : height_);
+ if (cmd.action == LFUN_SCREEN_UP && scrolled > - height_)
+ p = Point(0, 0);
+ if (cmd.action == LFUN_SCREEN_DOWN && scrolled < height_)
+ p = Point(width_, height_);
cur.reset(buffer_.inset());
+ updateMetrics();
+ buffer_.changed();
d->text_metrics_[&buffer_.text()].editXY(cur, p.x_, p.y_);
//FIXME: what to do with cur.x_target()?
cur.finishUndo();
processUpdateFlags(Update::Force);
break;
+ // This could be rewriten using some command like forall <insetname> <command>
+ // once the insets refactoring is done.
+ case LFUN_NOTES_MUTATE: {
+ if (cmd.argument().empty())
+ break;
+
+ if (mutateNotes(cur, cmd.getArg(0), cmd.getArg(1))) {
+ processUpdateFlags(Update::Force);
+ }
+ break;
+ }
+
+ case LFUN_ALL_INSETS_TOGGLE: {
+ string action;
+ string const name = split(to_utf8(cmd.argument()), action, ' ');
+ InsetCode const inset_code = insetCode(name);
+
+ FuncRequest fr(LFUN_INSET_TOGGLE, action);
+
+ Inset & inset = cur.buffer().inset();
+ InsetIterator it = inset_iterator_begin(inset);
+ InsetIterator const end = inset_iterator_end(inset);
+ for (; it != end; ++it) {
+ if (it->asInsetCollapsable()
+ && (inset_code == NO_CODE
+ || inset_code == it->lyxCode())) {
+ Cursor tmpcur = cur;
+ tmpcur.pushBackward(*it);
+ it->dispatch(tmpcur, fr);
+ }
+ }
+ processUpdateFlags(Update::Force | Update::FitCursor);
+ break;
+ }
+
default:
return false;
}
{
Cursor & cur = d->cursor_;
+ LYXERR(Debug::SELECTION, "requestSelection: cur.selection: " << cur.selection());
if (!cur.selection()) {
d->xsel_cache_.set = false;
return docstring();
}
+ LYXERR(Debug::SELECTION, "requestSelection: xsel_cache.set: " << d->xsel_cache_.set);
if (!d->xsel_cache_.set ||
cur.top() != d->xsel_cache_.cursor ||
cur.anchor_.top() != d->xsel_cache_.anchor)
Cursor old = cursor();
Cursor cur(*this);
cur.push(buffer_.inset());
- cur.selection() = d->cursor_.selection();
+ cur.setSelection(d->cursor_.selection());
// Either the inset under the cursor or the
// surrounding Text will handle this event.
// Put anchor at the same position.
cur.resetAnchor();
+ cur.beginUndoGroup();
+
// Try to dispatch to an non-editable inset near this position
// via the temp cursor. If the inset wishes to change the real
// cursor it has to do so explicitly by using
if (!inset || !cur.result().dispatched())
cur.dispatch(cmd);
+ cur.endUndoGroup();
+
// Notify left insets
if (cur != old) {
old.fixIfBroken();
if (scroll_value)
scroll(scroll_step * scroll_value);
}
+ updateMetrics();
+ buffer_.changed();
}
-void BufferView::scroll(int y)
+int BufferView::scroll(int y)
{
if (y > 0)
- scrollDown(y);
- else if (y < 0)
- scrollUp(-y);
+ return scrollDown(y);
+ if (y < 0)
+ return scrollUp(-y);
+ return 0;
}
-void BufferView::scrollDown(int offset)
+int BufferView::scrollDown(int offset)
{
Text * text = &buffer_.text();
TextMetrics & tm = d->text_metrics_[text];
int bottom_pos = last.second->position() + last.second->descent();
if (last.first + 1 == int(text->paragraphs().size())) {
if (bottom_pos <= height_)
- return;
+ return 0;
offset = min(offset, bottom_pos - height_);
break;
}
tm.newParMetricsDown();
}
d->anchor_ypos_ -= offset;
- updateMetrics();
- buffer_.changed();
+ return -offset;
}
-void BufferView::scrollUp(int offset)
+int BufferView::scrollUp(int offset)
{
Text * text = &buffer_.text();
TextMetrics & tm = d->text_metrics_[text];
int top_pos = first.second->position() - first.second->ascent();
if (first.first == 0) {
if (top_pos >= 0)
- return;
+ return 0;
offset = min(offset, - top_pos);
break;
}
tm.newParMetricsUp();
}
d->anchor_ypos_ += offset;
- updateMetrics();
- buffer_.changed();
+ return offset;
}
}
+bool BufferView::setCursorFromInset(Inset const * inset)
+{
+ // are we already there?
+ if (cursor().nextInset() == inset)
+ return true;
+
+ // Inset is not at cursor position. Find it in the document.
+ Cursor cur(*this);
+ cur.reset(buffer().inset());
+ while (cur && cur.nextInset() != inset)
+ cur.forwardInset();
+
+ if (cur) {
+ setCursor(cur);
+ return true;
+ }
+ return false;
+}
+
+
void BufferView::gotoLabel(docstring const & label)
{
Toc & toc = buffer().tocBackend().toc("label");
dit[i].inset().edit(d->cursor_, true);
d->cursor_.setCursor(dit);
- d->cursor_.selection() = false;
+ d->cursor_.setSelection(false);
}