#include "buffer_funcs.h"
#include "BufferParams.h"
#include "BufferView.h"
+#include "Changes.h"
#include "Cursor.h"
#include "CutAndPaste.h"
#include "DispatchResult.h"
#include "support/gettext.h"
#include "support/lstrings.h"
#include "support/lyxtime.h"
+#include "support/os.h"
#include "mathed/InsetMathHull.h"
#include "mathed/MathMacroTemplate.h"
Buffer & buf = *cur.buffer();
pit_type & pit = cur.pit();
ParagraphList & pars = buf.text().paragraphs();
- ParagraphList::iterator bgn = pars.begin();
+ ParagraphList::iterator const bgn = pars.begin();
// The first paragraph of the area to be copied:
ParagraphList::iterator start = boost::next(bgn, pit);
// The final paragraph of area to be copied:
ParagraphList::iterator finish = start;
- ParagraphList::iterator end = pars.end();
+ ParagraphList::iterator const end = pars.end();
DocumentClass const & tc = buf.params().documentClass();
// Seek the one (on same level) below
for (; finish != end; ++finish) {
toclevel = finish->layout().toclevel;
- if (toclevel != Layout::NOT_IN_TOC && toclevel <= thistoclevel) {
+ if (toclevel != Layout::NOT_IN_TOC && toclevel <= thistoclevel)
break;
- }
}
+ // Do we need to set insets' buffer_ members, because we copied
+ // some stuff? We'll assume we do and reset it otherwise.
+ bool set_buffers = true;
+
switch (mode) {
case OutlineUp: {
if (start == pars.begin())
start = boost::next(pars.begin(), deletepit);
pit = newpit;
pars.erase(start, finish);
- return;
+ break;
}
case OutlineDown: {
if (finish == end)
for (; dest != end; ++dest) {
toclevel = dest->layout().toclevel;
if (toclevel != Layout::NOT_IN_TOC
- && toclevel <= thistoclevel) {
+ && toclevel <= thistoclevel)
break;
- }
}
// One such was found:
pit_type newpit = distance(bgn, dest);
start = boost::next(bgn, pit);
pit = newpit - len;
pars.erase(start, finish);
- return;
+ break;
}
case OutlineIn: {
pit_type const len = distance(start, finish);
}
}
}
- return;
+ set_buffers = false;
+ break;
}
case OutlineOut: {
pit_type const len = distance(start, finish);
}
}
}
- return;
+ set_buffers = false;
+ break;
}
}
+ if (set_buffers)
+ // FIXME This only really needs doing for the newly introduced
+ // paragraphs. Something like:
+ // pit_type const numpars = distance(start, finish);
+ // start = boost::next(bgn, pit);
+ // finish = boost::next(start, numpars);
+ // for (; start != finish; ++start)
+ // start->setBuffer(buf);
+ // But while this seems to work, it is kind of fragile.
+ buf.inset().setBuffer(buf);
}
LYXERR(Debug::ACTION, "Text::dispatch: cmd: " << cmd);
BufferView * bv = &cur.bv();
- TextMetrics & tm = bv->textMetrics(this);
- if (!tm.contains(cur.pit())) {
- lyx::dispatch(FuncRequest(LFUN_SCREEN_RECENTER));
- tm = bv->textMetrics(this);
+ TextMetrics * tm = &bv->textMetrics(this);
+ if (!tm->contains(cur.pit())) {
+ lyx::dispatch(FuncRequest(LFUN_SCREEN_SHOW_CURSOR));
+ tm = &bv->textMetrics(this);
}
// FIXME: We use the update flag to indicates wether a singlePar or a
if (cur.selection())
cutSelection(cur, true, false);
else
- tm.deleteLineForward(cur);
+ tm->deleteLineForward(cur);
finishChange(cur, false);
break;
cur.updateFlags(Update::FitCursor);
break;
+ case LFUN_INSET_BEGIN:
+ case LFUN_INSET_BEGIN_SELECT:
+ needsUpdate |= cur.selHandle(cmd.action == LFUN_INSET_BEGIN_SELECT);
+ if (cur.depth() == 1 || cur.pos() > 0)
+ needsUpdate |= cursorTop(cur);
+ else
+ cur.undispatched();
+ cur.updateFlags(Update::FitCursor);
+ break;
+
+ case LFUN_INSET_END:
+ case LFUN_INSET_END_SELECT:
+ needsUpdate |= cur.selHandle(cmd.action == LFUN_INSET_END_SELECT);
+ if (cur.depth() == 1 || cur.pos() < cur.lastpos())
+ needsUpdate |= cursorBottom(cur);
+ else
+ cur.undispatched();
+ cur.updateFlags(Update::FitCursor);
+ break;
+
case LFUN_CHAR_FORWARD:
case LFUN_CHAR_FORWARD_SELECT:
//LYXERR0(" LFUN_CHAR_FORWARD[SEL]:\n" << cur);
&& cur.boundary() == oldBoundary) {
cur.undispatched();
cmd = FuncRequest(LFUN_FINISHED_FORWARD);
+
+ // we will probably be moving out the inset, so we should execute
+ // the depm-mechanism, but only when the cursor has a place to
+ // go outside this inset, i.e. in a slice above.
+ if (cur.depth() > 1 && cur.pos() == cur.lastpos()
+ && cur.pit() == cur.lastpit()) {
+ // The cursor hasn't changed yet. To give the
+ // DEPM the possibility of doing something we must
+ // provide it with two different cursors.
+ Cursor dummy = cur;
+ dummy.pos() = dummy.pit() = 0;
+ cur.bv().checkDepm(dummy, cur);
+ }
}
break;
&& cur.boundary() == oldBoundary) {
cur.undispatched();
cmd = FuncRequest(LFUN_FINISHED_BACKWARD);
+
+ // we will probably be moving out the inset, so we should execute
+ // the depm-mechanism, but only when the cursor has a place to
+ // go outside this inset, i.e. in a slice above.
+ if (cur.depth() > 1 && cur.pos() == 0 && cur.pit() == 0) {
+ // The cursor hasn't changed yet. To give the
+ // DEPM the possibility of doing something we must
+ // provide it with two different cursors.
+ Cursor dummy = cur;
+ dummy.pos() = cur.lastpos();
+ dummy.pit() = cur.lastpit();
+ cur.bv().checkDepm(dummy, cur);
+ }
}
break;
case LFUN_LINE_BEGIN:
case LFUN_LINE_BEGIN_SELECT:
needsUpdate |= cur.selHandle(cmd.action == LFUN_LINE_BEGIN_SELECT);
- needsUpdate |= tm.cursorHome(cur);
+ needsUpdate |= tm->cursorHome(cur);
break;
case LFUN_LINE_END:
case LFUN_LINE_END_SELECT:
needsUpdate |= cur.selHandle(cmd.action == LFUN_LINE_END_SELECT);
- needsUpdate |= tm.cursorEnd(cur);
+ needsUpdate |= tm->cursorEnd(cur);
+ break;
+
+ case LFUN_SECTION_SELECT: {
+ Buffer const & buf = *cur.buffer();
+ pit_type const pit = cur.pit();
+ ParagraphList & pars = buf.text().paragraphs();
+ ParagraphList::iterator bgn = pars.begin();
+ // The first paragraph of the area to be selected:
+ ParagraphList::iterator start = boost::next(bgn, pit);
+ // The final paragraph of area to be selected:
+ ParagraphList::iterator finish = start;
+ ParagraphList::iterator end = pars.end();
+
+ int const thistoclevel = start->layout().toclevel;
+ if (thistoclevel == Layout::NOT_IN_TOC)
+ break;
+
+ cur.pos() = 0;
+ Cursor const old_cur = cur;
+ needsUpdate |= cur.selHandle(true);
+
+ // Move out (down) from this section header
+ if (finish != end)
+ ++finish;
+
+ // Seek the one (on same level) below
+ for (; finish != end; ++finish, ++cur.pit()) {
+ int const toclevel = finish->layout().toclevel;
+ if (toclevel != Layout::NOT_IN_TOC && toclevel <= thistoclevel)
+ break;
+ }
+ cur.pos() = cur.lastpos();
+
+ needsUpdate |= cur != old_cur;
break;
+ }
case LFUN_WORD_RIGHT:
case LFUN_WORD_RIGHT_SELECT:
break;
}
- case LFUN_INSET_SETTINGS: {
- Inset & inset = cur.inset();
- if (cmd.getArg(0) == insetName(inset.lyxCode())) {
- // This inset dialog has been explicitely requested.
- inset.showInsetDialog(bv);
- break;
- }
- // else, if there is an inset at the cursor, access this
- Inset * next_inset = cur.nextInset();
- if (next_inset) {
- next_inset->showInsetDialog(bv);
- break;
- }
- // if not then access the underlying inset.
- inset.showInsetDialog(bv);
- break;
- }
-
case LFUN_SET_GRAPHICS_GROUP: {
InsetGraphics * ins = graphics::getCurrentGraphicsInset(cur);
if (!ins)
type = Clipboard::JpegGraphicsType;
else if (arg == "linkback")
type = Clipboard::LinkBackGraphicsType;
+ else if (arg == "emf")
+ type = Clipboard::EmfGraphicsType;
+ else if (arg == "wmf")
+ type = Clipboard::WmfGraphicsType;
+
else
LASSERT(false, /**/);
case LFUN_SERVER_GET_XY:
cur.message(from_utf8(
- convert<string>(tm.cursorX(cur.top(), cur.boundary()))
- + ' ' + convert<string>(tm.cursorY(cur.top(), cur.boundary()))));
+ convert<string>(tm->cursorX(cur.top(), cur.boundary()))
+ + ' ' + convert<string>(tm->cursorY(cur.top(), cur.boundary()))));
break;
case LFUN_SERVER_SET_XY: {
lyxerr << "SETXY: Could not parse coordinates in '"
<< to_utf8(cmd.argument()) << endl;
else
- tm.setCursorFromCoordinates(cur, x, y);
+ tm->setCursorFromCoordinates(cur, x, y);
break;
}
pos_type pos = cur.pos();
BufferParams const & bufparams = bv->buffer().params();
Layout const & style = par.layout();
- if (!style.pass_thru
+ InsetLayout const & ilayout = cur.inset().getLayout(bufparams);
+ if (!style.pass_thru && !ilayout.isPassThru()
&& par.getFontSettings(bufparams, pos).language()->lang() != "hebrew") {
// this avoids a double undo
// FIXME: should not be needed, ideally
case LFUN_MOUSE_TRIPLE:
if (cmd.button() == mouse_button::button1) {
- tm.cursorHome(cur);
+ tm->cursorHome(cur);
cur.resetAnchor();
- tm.cursorEnd(cur);
+ tm->cursorEnd(cur);
cur.setSelection();
bv->cursor() = cur;
}
int const wh = bv->workHeight();
int const y = max(0, min(wh - 1, cmd.y));
- tm.setCursorFromCoordinates(cur, cmd.x, y);
+ tm->setCursorFromCoordinates(cur, cmd.x, y);
cur.setTargetX(cmd.x);
if (cmd.y >= wh)
lyx::dispatch(FuncRequest(LFUN_DOWN_SELECT));
}
if (!inset)
break;
+ cur.recordUndo();
insertInset(cur, inset);
cur.posForward();
break;
break;
}
- case LFUN_INDEX_PRINT:
+ case LFUN_INDEX_PRINT: {
+ InsetCommandParams p(INDEX_PRINT_CODE);
+ if (cmd.argument().empty())
+ p["type"] = from_ascii("idx");
+ else
+ p["type"] = cmd.argument();
+ string const data = InsetCommand::params2string("index_print", p);
+ FuncRequest fr(LFUN_INSET_INSERT, data);
+ dispatch(cur, fr);
+ break;
+ }
+
case LFUN_NOMENCL_PRINT:
case LFUN_TOC_INSERT:
case LFUN_LINE_INSERT:
break;
}
+ case LFUN_FONT_STRIKEOUT: {
+ Font font(ignore_font, ignore_language);
+ font.fontInfo().setStrikeout(FONT_TOGGLE);
+ toggleAndShow(cur, this, font);
+ break;
+ }
+
+ case LFUN_FONT_UULINE: {
+ Font font(ignore_font, ignore_language);
+ font.fontInfo().setUuline(FONT_TOGGLE);
+ toggleAndShow(cur, this, font);
+ break;
+ }
+
+ case LFUN_FONT_UWAVE: {
+ Font font(ignore_font, ignore_language);
+ font.fontInfo().setUwave(FONT_TOGGLE);
+ toggleAndShow(cur, this, font);
+ break;
+ }
+
case LFUN_FONT_UNDERLINE: {
Font font(ignore_font, ignore_language);
font.fontInfo().setUnderbar(FONT_TOGGLE);
case LFUN_DIALOG_SHOW_NEW_INSET:
if (cmd.argument() == "bibitem")
code = BIBITEM_CODE;
- else if (cmd.argument() == "bibtex")
+ else if (cmd.argument() == "bibtex") {
code = BIBTEX_CODE;
+ // not allowed in description items
+ enable = !inDescriptionItem(cur);
+ }
else if (cmd.argument() == "box")
code = BOX_CODE;
else if (cmd.argument() == "branch")
code = INCLUDE_CODE;
else if (cmd.argument() == "index")
code = INDEX_CODE;
+ else if (cmd.argument() == "index_print")
+ code = INDEX_PRINT_CODE;
else if (cmd.argument() == "nomenclature")
code = NOMENCL_CODE;
else if (cmd.argument() == "label")
break;
case LFUN_FLOAT_LIST_INSERT:
code = FLOAT_LIST_CODE;
+ // not allowed in description items
+ enable = !inDescriptionItem(cur);
break;
case LFUN_CAPTION_INSERT:
code = CAPTION_CODE;
break;
case LFUN_BRANCH_INSERT:
code = BRANCH_CODE;
- if (cur.buffer()->masterBuffer()->params().branchlist().empty())
+ if (cur.buffer()->masterBuffer()->params().branchlist().empty()
+ && cur.buffer()->params().branchlist().empty())
enable = false;
break;
case LFUN_PHANTOM_INSERT:
break;
case LFUN_INDEX_PRINT:
code = INDEX_PRINT_CODE;
+ // not allowed in description items
+ enable = !inDescriptionItem(cur);
break;
case LFUN_NOMENCL_INSERT:
if (cur.selIsMultiCell() || cur.selIsMultiLine()) {
break;
case LFUN_NOMENCL_PRINT:
code = NOMENCL_PRINT_CODE;
+ // not allowed in description items
+ enable = !inDescriptionItem(cur);
break;
case LFUN_TOC_INSERT:
code = TOC_CODE;
+ // not allowed in description items
+ enable = !inDescriptionItem(cur);
break;
case LFUN_HYPERLINK_INSERT:
if (cur.selIsMultiCell() || cur.selIsMultiLine()) {
}
// explicit graphics type?
- if ((arg == "pdf" && theClipboard().hasGraphicsContents(Clipboard::PdfGraphicsType))
- || (arg == "png" && theClipboard().hasGraphicsContents(Clipboard::PngGraphicsType))
- || (arg == "jpeg" && theClipboard().hasGraphicsContents(Clipboard::JpegGraphicsType))
- || (arg == "linkback" && theClipboard().hasGraphicsContents(Clipboard::LinkBackGraphicsType))) {
- enable = true;
+ Clipboard::GraphicsType type = Clipboard::AnyGraphicsType;
+ if ((arg == "pdf" && (type = Clipboard::PdfGraphicsType))
+ || (arg == "png" && (type = Clipboard::PngGraphicsType))
+ || (arg == "jpeg" && (type = Clipboard::JpegGraphicsType))
+ || (arg == "linkback" && (type = Clipboard::LinkBackGraphicsType))
+ || (arg == "emf" && (type = Clipboard::EmfGraphicsType))
+ || (arg == "wmf" && (type = Clipboard::WmfGraphicsType))) {
+ enable = theClipboard().hasGraphicsContents(type);
break;
}
case LFUN_CHANGE_ACCEPT:
case LFUN_CHANGE_REJECT:
- // TODO: context-sensitive enabling of LFUN_CHANGE_ACCEPT/REJECT
// In principle, these LFUNs should only be enabled if there
// is a change at the current position/in the current selection.
// However, without proper optimizations, this will inevitably
// result in unacceptable performance - just imagine a user who
// wants to select the complete content of a long document.
- enable = true;
+ if (!cur.selection()) {
+ Change const & change = cur.paragraph().lookupChange(cur.pos());
+ enable = change.changed();
+ } else
+ // TODO: context-sensitive enabling of LFUN_CHANGE_ACCEPT/REJECT
+ // for selections.
+ enable = true;
break;
case LFUN_OUTLINE_UP:
enable = cur.inset().insetAllowed(MATH_CODE);
break;
+ case LFUN_DATE_INSERT: {
+ string const format = cmd.argument().empty()
+ ? lyxrc.date_insert_format : to_utf8(cmd.argument());
+ enable = support::os::is_valid_strftime(format);
+ break;
+ }
+
case LFUN_WORD_DELETE_FORWARD:
case LFUN_WORD_DELETE_BACKWARD:
case LFUN_LINE_DELETE:
case LFUN_WORD_RIGHT_SELECT:
case LFUN_WORD_LEFT_SELECT:
case LFUN_WORD_SELECT:
+ case LFUN_SECTION_SELECT:
case LFUN_PARAGRAPH_UP:
case LFUN_PARAGRAPH_DOWN:
case LFUN_LINE_BEGIN:
case LFUN_SERVER_SET_XY:
case LFUN_SERVER_GET_LAYOUT:
case LFUN_LAYOUT:
- case LFUN_DATE_INSERT:
case LFUN_SELF_INSERT:
case LFUN_LINE_INSERT:
case LFUN_MATH_DISPLAY:
case LFUN_MATH_SUPERSCRIPT:
case LFUN_FONT_DEFAULT:
case LFUN_FONT_UNDERLINE:
+ case LFUN_FONT_STRIKEOUT:
+ case LFUN_FONT_UULINE:
+ case LFUN_FONT_UWAVE:
case LFUN_FONT_SIZE:
case LFUN_LANGUAGE:
case LFUN_TEXTSTYLE_APPLY:
case LFUN_PARAGRAPH_PARAMS_APPLY:
case LFUN_PARAGRAPH_PARAMS:
case LFUN_ESCAPE:
- case LFUN_BUFFER_END:
case LFUN_BUFFER_BEGIN:
+ case LFUN_BUFFER_END:
case LFUN_BUFFER_BEGIN_SELECT:
case LFUN_BUFFER_END_SELECT:
+ case LFUN_INSET_BEGIN:
+ case LFUN_INSET_END:
+ case LFUN_INSET_BEGIN_SELECT:
+ case LFUN_INSET_END_SELECT:
case LFUN_UNICODE_INSERT:
// these are handled in our dispatch()
enable = true;