X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ftext3.C;h=9ddee5cf60f2574b5ce4fd8a2e52492ee0aa6687;hb=d1f2a9c0000f0ad038425900b001c16a56c72afa;hp=ec4058a006194fb2ee824c57974c101b3e6bb8b6;hpb=e113eaeb70abe43de9446d8116155bef214c60ed;p=lyx.git diff --git a/src/text3.C b/src/text3.C index ec4058a006..9ddee5cf60 100644 --- a/src/text3.C +++ b/src/text3.C @@ -17,10 +17,14 @@ #include "lyxtext.h" +#include "FloatList.h" +#include "FuncStatus.h" #include "buffer.h" #include "bufferparams.h" #include "BufferView.h" #include "cursor.h" +#include "coordcache.h" +#include "CutAndPaste.h" #include "debug.h" #include "dispatchresult.h" #include "factory.h" @@ -28,6 +32,9 @@ #include "gettext.h" #include "intl.h" #include "language.h" +#include "LyXAction.h" +#include "lyxfunc.h" +#include "lyxlex.h" #include "lyxrc.h" #include "lyxrow.h" #include "paragraph.h" @@ -40,24 +47,31 @@ #include "frontends/LyXView.h" #include "insets/insetcommand.h" +#include "insets/insetfloatlist.h" #include "insets/insetnewline.h" +#include "insets/insetquotes.h" #include "insets/insetspecialchar.h" #include "insets/insettext.h" #include "support/lstrings.h" -#include "support/tostr.h" -#include "support/std_sstream.h" +#include "support/lyxlib.h" +#include "support/convert.h" -#include "mathed/formulabase.h" +#include "mathed/math_hullinset.h" +#include "mathed/math_macrotemplate.h" #include - -using bv_funcs::replaceSelection; +#include using lyx::pos_type; +using lyx::cap::copySelection; +using lyx::cap::cutSelection; +using lyx::cap::pasteSelection; +using lyx::cap::replaceSelection; + using lyx::support::isStrUnsignedInt; -using lyx::support::strToUnsignedInt; +using lyx::support::token; using std::endl; using std::find; @@ -68,10 +82,6 @@ using std::vector; extern string current_layout; -// the selection possible is needed, that only motion events are -// used, where the bottom press event was on the drawing area too -bool selection_possible = false; - namespace { @@ -80,163 +90,83 @@ namespace { bool toggleall = false; - void toggleAndShow(BufferView * bv, LyXText * text, + void toggleAndShow(LCursor & cur, LyXText * text, LyXFont const & font, bool toggleall = true) { - if (!bv->available()) - return; - - text->toggleFree(font, toggleall); - bv->update(); + text->toggleFree(cur, font, toggleall); if (font.language() != ignore_language || font.number() != LyXFont::IGNORE) { - LyXCursor & cursor = text->cursor; - Paragraph & par = *text->cursorPar(); - text->bidi.computeTables(par, *bv->buffer(), - *par.getRow(cursor.pos())); - if (cursor.boundary() != - text->bidi.isBoundary(*bv->buffer(), par, - cursor.pos(), + Paragraph & par = cur.paragraph(); + text->bidi.computeTables(par, cur.buffer(), cur.textRow()); + if (cur.boundary() != + text->bidi.isBoundary(cur.buffer(), par, + cur.pos(), text->real_current_font)) - text->setCursor(cursor.par(), cursor.pos(), - false, !cursor.boundary()); - } - } - - - /// Apply the contents of freefont at the current cursor location. - void apply_freefont(BufferView * bv, LyXText * text) - { - toggleAndShow(bv, text, freefont, toggleall); - bv->owner()->view_state_changed(); - bv->owner()->message(_("Character set")); - } - - - /** Set the freefont using the contents of \param data dispatched from - * the frontends and apply it at the current cursor location. - */ - void update_and_apply_freefont(BufferView * bv, LyXText * text, - string const & data) - { - LyXFont font; - bool toggle; - if (bv_funcs::string2font(data, font, toggle)) { - freefont = font; - toggleall = toggle; - apply_freefont(bv, text); + text->setCursor(cur, cur.pit(), cur.pos(), + false, !cur.boundary()); } } - void emph(BufferView * bv, LyXText * text) - { - LyXFont font(LyXFont::ALL_IGNORE); - font.setEmph(LyXFont::TOGGLE); - toggleAndShow(bv, text, font); - } - - - void bold(BufferView * bv, LyXText * text) - { - LyXFont font(LyXFont::ALL_IGNORE); - font.setSeries(LyXFont::BOLD_SERIES); - toggleAndShow(bv, text, font); - } - - - void noun(BufferView * bv, LyXText * text) - { - LyXFont font(LyXFont::ALL_IGNORE); - font.setNoun(LyXFont::TOGGLE); - toggleAndShow(bv, text, font); - } - - - void lang(BufferView * bv, string const & l, LyXText * text) - { - Language const * lang = languages.getLanguage(l); - if (!lang) - return; - - LyXFont font(LyXFont::ALL_IGNORE); - font.setLanguage(lang); - toggleAndShow(bv, text, font); - } - - - void code(BufferView * bv, LyXText * text) - { - LyXFont font(LyXFont::ALL_IGNORE); - font.setFamily(LyXFont::TYPEWRITER_FAMILY); // no good - toggleAndShow(bv, text, font); - } - - - void sans(BufferView * bv, LyXText * text) - { - LyXFont font(LyXFont::ALL_IGNORE); - font.setFamily(LyXFont::SANS_FAMILY); - toggleAndShow(bv, text, font); - } - - - void roman(BufferView * bv, LyXText * text) - { - LyXFont font(LyXFont::ALL_IGNORE); - font.setFamily(LyXFont::ROMAN_FAMILY); - toggleAndShow(bv, text, font); - } - - - void styleReset(BufferView * bv, LyXText * text) - { - LyXFont font(LyXFont::ALL_INHERIT, ignore_language); - toggleAndShow(bv, text, font); - } - - - void underline(BufferView * bv, LyXText * text) + void moveCursor(LCursor & cur, bool selecting) { - LyXFont font(LyXFont::ALL_IGNORE); - font.setUnderbar(LyXFont::TOGGLE); - toggleAndShow(bv, text, font); + if (selecting || cur.mark()) + cur.setSelection(); + if (!cur.selection()) + cur.bv().haveSelection(false); + cur.bv().switchKeyMap(); } - void fontSize(BufferView * bv, string const & size, LyXText * text) + void finishChange(LCursor & cur, bool selecting) { - LyXFont font(LyXFont::ALL_IGNORE); - font.setLyXSize(size); - toggleAndShow(bv, text, font); + finishUndo(); + moveCursor(cur, selecting); } - void moveCursor(BufferView * bv, bool selecting) + void mathDispatch(LCursor & cur, FuncRequest const & cmd, bool display) { - LyXText * lt = bv->getLyXText(); - -// if (!lt->selection.set()) -// lt->selection.cursor = lt->cursor; - - if (selecting || lt->selection.mark()) - lt->setSelection(); - - if (!lt->selection.set()) - bv->haveSelection(false); - bv->switchKeyMap(); + recordUndo(cur); + string sel = cur.selectionAsString(false); + lyxerr << "selection is: '" << sel << "'" << endl; + + if (sel.empty()) { + const int old_pos = cur.pos(); + cur.insert(new MathHullInset); + BOOST_ASSERT(old_pos == cur.pos()); + cur.nextInset()->edit(cur, true); + cur.dispatch(FuncRequest(LFUN_MATH_MUTATE, "simple")); + // don't do that also for LFUN_MATH_MODE + // unless you want end up with always changing + // to mathrm when opening an inlined inset -- + // I really hate "LyXfunc overloading"... + if (display) + cur.dispatch(FuncRequest(LFUN_MATH_DISPLAY)); + cur.dispatch(FuncRequest(LFUN_INSERT_MATH, cmd.argument)); + } else { + // create a macro if we see "\\newcommand" + // somewhere, and an ordinary formula + // otherwise + cutSelection(cur, true, true); + if (sel.find("\\newcommand") == string::npos + && sel.find("\\def") == string::npos) + { + cur.insert(new MathHullInset); + cur.dispatch(FuncRequest(LFUN_RIGHT)); + cur.dispatch(FuncRequest(LFUN_MATH_MUTATE, "simple")); + cur.dispatch(FuncRequest(LFUN_INSERT_MATH, sel)); + } else { + istringstream is(sel); + cur.insert(new MathMacroTemplate(is)); + } + } + cur.message(N_("Math editor mode")); } +} // namespace anon - void finishChange(BufferView * bv, bool selecting = false) - { - finishUndo(); - moveCursor(bv, selecting); - bv->owner()->view_state_changed(); - } - -} // anon namespace namespace bv_funcs { @@ -251,54 +181,17 @@ string const freefont2string() } - -InsetOld * LyXText::checkInsetHit(int x, int y) -{ - ParagraphList::iterator pit; - ParagraphList::iterator end; - - getParsInRange(paragraphs(), - bv()->top_y() - yo_, - bv()->top_y() - yo_ + bv()->workHeight(), - pit, end); - - lyxerr << "checkInsetHit: x: " << x << " y: " << y << endl; - for ( ; pit != end; ++pit) { - InsetList::iterator iit = pit->insetlist.begin(); - InsetList::iterator iend = pit->insetlist.end(); - for ( ; iit != iend; ++iit) { - InsetOld * inset = iit->inset; - //lyxerr << "examining inset " << inset - // << " xy: " << inset->x() << "/" << inset->y() - // << " x: " << inset->x() << "..." << inset->x() + inset->width() - // << " y: " << inset->y() - inset->ascent() << "..." - // << inset->y() + inset->descent() - // << endl; - if (x >= inset->x() - && x <= inset->x() + inset->width() - && y >= inset->y() - inset->ascent() - && y <= inset->y() + inset->descent()) - { - lyxerr << "Hit inset: " << inset << endl; - return inset; - } - } - } - lyxerr << "No inset hit. " << endl; - return 0; -} - - -bool LyXText::gotoNextInset(vector const & codes, - string const & contents) +bool LyXText::gotoNextInset(LCursor & cur, + vector const & codes, string const & contents) { - ParagraphList::iterator end = paragraphs().end(); - ParagraphList::iterator pit = cursorPar(); - pos_type pos = cursor.pos(); + BOOST_ASSERT(this == cur.text()); + pit_type end = paragraphs().size(); + pit_type pit = cur.pit(); + pos_type pos = cur.pos(); - InsetOld * inset; + InsetBase * inset; do { - if (pos + 1 < pit->size()) { + if (pos + 1 < pars_[pit].size()) { ++pos; } else { ++pit; @@ -306,531 +199,561 @@ bool LyXText::gotoNextInset(vector const & codes, } } while (pit != end && - !(pit->isInset(pos) && - (inset = pit->getInset(pos)) != 0 && + !(pars_[pit].isInset(pos) && + (inset = pars_[pit].getInset(pos)) != 0 && find(codes.begin(), codes.end(), inset->lyxCode()) != codes.end() && (contents.empty() || - static_cast(pit->getInset(pos))->getContents() + static_cast(pars_[pit].getInset(pos))->getContents() == contents))); if (pit == end) return false; - setCursor(parOffset(pit), pos, false); + setCursor(cur, pit, pos, false); return true; } -void LyXText::gotoInset(vector const & codes, - bool same_content) +void LyXText::gotoInset(LCursor & cur, + vector const & codes, bool same_content) { - clearSelection(); + cur.clearSelection(); string contents; - if (same_content && cursor.pos() < cursorPar()->size() - && cursorPar()->isInset(cursor.pos())) { - InsetOld const * inset = cursorPar()->getInset(cursor.pos()); + if (same_content + && cur.pos() < cur.lastpos() + && cur.paragraph().isInset(cur.pos())) { + InsetBase const * inset = cur.paragraph().getInset(cur.pos()); if (find(codes.begin(), codes.end(), inset->lyxCode()) != codes.end()) contents = static_cast(inset)->getContents(); } - if (!gotoNextInset(codes, contents)) { - if (cursor.pos() || cursorPar() != paragraphs().begin()) { - LyXCursor tmp = cursor; - cursor.par(0); - cursor.pos(0); - if (!gotoNextInset(codes, contents)) { - cursor = tmp; - bv()->owner()->message(_("No more insets")); + if (!gotoNextInset(cur, codes, contents)) { + if (cur.pos() || cur.pit() != 0) { + CursorSlice tmp = cur.top(); + cur.pit() = 0; + cur.pos() = 0; + if (!gotoNextInset(cur, codes, contents)) { + cur.top() = tmp; + cur.message(_("No more insets")); } } else { - bv()->owner()->message(_("No more insets")); + cur.message(_("No more insets")); } } - bv()->update(); - selection.cursor = cursor; + cur.resetAnchor(); } -void LyXText::gotoInset(InsetOld::Code code, bool same_content) +void LyXText::gotoInset(LCursor & cur, InsetBase_code code, bool same_content) { - gotoInset(vector(1, code), same_content); + gotoInset(cur, vector(1, code), same_content); } -void LyXText::cursorPrevious() +bool LyXText::cursorPrevious(LCursor & cur) { + pos_type cpos = cur.pos(); + lyx::pit_type cpar = cur.pit(); - RowList::iterator crit = cursorRow(); - ParagraphList::iterator cpar = cursorPar(); + int x = cur.x_target(); - int x = bv()->x_target() - xo_; - int y = bv()->top_y() - yo_; - setCursorFromCoordinates(x, y); + setCursorFromCoordinates(cur, x, 0); + bool updated = cursorUp(cur); - if (cpar == cursorPar() && crit == cursorRow()) { + if (cpar == cur.pit() && cpos == cur.pos()) { // we have a row which is taller than the workarea. The // simplest solution is to move to the previous row instead. - cursorUp(true); + updated |= cursorUp(cur); } - bv()->updateScrollbar(); + cur.bv().updateScrollbar(); finishUndo(); + return updated; } -void LyXText::cursorNext() +bool LyXText::cursorNext(LCursor & cur) { - RowList::iterator crit = cursorRow(); - ParagraphList::iterator cpar = cursorPar(); + pos_type cpos = cur.pos(); + lyx::pit_type cpar = cur.pit(); - int x = bv()->x_target() - xo_; - int y = bv()->top_y() + bv()->workHeight() - yo_; - setCursorFromCoordinates(x, y); + int x = cur.x_target(); + setCursorFromCoordinates(cur, x, cur.bv().workHeight() - 1); + bool updated = cursorDown(cur); - if (cpar == cursorPar() && crit == cursorRow()) { + if (cpar == cur.pit() && cpos == cur.pos()) { // we have a row which is taller than the workarea. The // simplest solution is to move to the next row instead. - cursorDown(true); + updated |= cursorDown(cur); } - bv()->updateScrollbar(); + cur.bv().updateScrollbar(); finishUndo(); + return updated; } namespace { -void specialChar(LyXText * lt, BufferView * bv, InsetSpecialChar::Kind kind) +void specialChar(LCursor & cur, InsetSpecialChar::Kind kind) { - bv->update(); - InsetSpecialChar * new_inset = new InsetSpecialChar(kind); - replaceSelection(lt); - if (!bv->insertInset(new_inset)) - delete new_inset; - else - bv->update(); + lyx::cap::replaceSelection(cur); + cur.insert(new InsetSpecialChar(kind)); + cur.posRight(); } -void doInsertInset(LyXText const & lt, FuncRequest const & cmd, - bool edit, bool pastesel) +void doInsertInset(LCursor & cur, LyXText * text, + FuncRequest const & cmd, bool edit, bool pastesel) { - InsetOld * inset = createInset(cmd); + InsetBase * inset = createInset(&cur.bv(), cmd); if (!inset) return; - BufferView * bv = cmd.view(); - + recordUndo(cur); bool gotsel = false; - if (lt.selection.set()) { - bv->owner()->dispatch(FuncRequest(LFUN_CUT)); + if (cur.selection()) { + cur.bv().owner()->dispatch(FuncRequest(LFUN_CUT)); gotsel = true; } - if (bv->insertInset(inset)) { - if (edit) - inset->edit(bv, true); - if (gotsel && pastesel) - bv->owner()->dispatch(FuncRequest(LFUN_PASTE)); - } else - delete inset; + text->insertInset(cur, inset); + + if (edit) + inset->edit(cur, true); + + if (gotsel && pastesel) + cur.bv().owner()->dispatch(FuncRequest(LFUN_PASTE)); +} + + +void update(LCursor & cur) +{ + //we don't call update(true, false) directly to save a metrics call + if (cur.bv().fitCursor()) + cur.bv().update(false, true); } + } // anon namespace -void LyXText::number() +void LyXText::number(LCursor & cur) { LyXFont font(LyXFont::ALL_IGNORE); font.setNumber(LyXFont::TOGGLE); - toggleAndShow(bv(), this, font); + toggleAndShow(cur, this, font); } -bool LyXText::rtl() const +bool LyXText::isRTL(Paragraph const & par) const { - return cursorPar()->isRightToLeftPar(bv()->buffer()->params()); + return par.isRightToLeftPar(bv()->buffer()->params()); } -DispatchResult LyXText::dispatch(FuncRequest const & cmd) +void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) { - //lyxerr[Debug::ACTION] << "LyXText::dispatch: cmd: " << cmd << endl; + lyxerr[Debug::ACTION] << "LyXText::dispatch: cmd: " << cmd << endl; + lyxerr << "*** LyXText::dispatch: cmd: " << cmd << endl; - BufferView * bv = cmd.view(); + BOOST_ASSERT(cur.text() == this); + BufferView * bv = &cur.bv(); + CursorSlice oldTopSlice = cur.top(); + bool sel = cur.selection(); + bool needsUpdate = !lyxaction.funcHasFlag(cmd.action, LyXAction::NoUpdate); switch (cmd.action) { case LFUN_APPENDIX: { - ParagraphList::iterator pit = cursorPar(); - bool start = !pit->params().startOfAppendix(); + Paragraph & par = cur.paragraph(); + bool start = !par.params().startOfAppendix(); // ensure that we have only one start_of_appendix in this document - ParagraphList::iterator tmp = paragraphs().begin(); - ParagraphList::iterator end = paragraphs().end(); - - for (; tmp != end; ++tmp) { - if (tmp->params().startOfAppendix()) { - recUndo(parOffset(tmp)); - tmp->params().startOfAppendix(false); - redoParagraph(tmp); + for (pit_type tmp = 0, end = pars_.size(); tmp != end; ++tmp) { + if (pars_[tmp].params().startOfAppendix()) { + recUndo(tmp); + pars_[tmp].params().startOfAppendix(false); break; } } - recUndo(parOffset(pit)); - pit->params().startOfAppendix(start); + recordUndo(cur); + par.params().startOfAppendix(start); // we can set the refreshing parameters now updateCounters(); - redoParagraph(cursorPar()); - bv->update(); break; } case LFUN_DELETE_WORD_FORWARD: - clearSelection(); - deleteWordForward(); - finishChange(bv); + cur.clearSelection(); + deleteWordForward(cur); + finishChange(cur, false); break; case LFUN_DELETE_WORD_BACKWARD: - clearSelection(); - deleteWordBackward(); - finishChange(bv); + cur.clearSelection(); + deleteWordBackward(cur); + finishChange(cur, false); break; case LFUN_DELETE_LINE_FORWARD: - clearSelection(); - deleteLineForward(); - finishChange(bv); + cur.clearSelection(); + deleteLineForward(cur); + finishChange(cur, false); break; case LFUN_WORDRIGHT: - if (!selection.mark()) - clearSelection(); - if (rtl()) - cursorLeftOneWord(); + if (!cur.mark()) + cur.clearSelection(); + if (isRTL(cur.paragraph())) + needsUpdate = cursorLeftOneWord(cur); else - cursorRightOneWord(); - finishChange(bv); + needsUpdate = cursorRightOneWord(cur); + finishChange(cur, false); break; case LFUN_WORDLEFT: - if (!selection.mark()) - clearSelection(); - if (rtl()) - cursorRightOneWord(); + if (!cur.mark()) + cur.clearSelection(); + if (isRTL(cur.paragraph())) + needsUpdate = cursorRightOneWord(cur); else - cursorLeftOneWord(); - finishChange(bv); + needsUpdate = cursorLeftOneWord(cur); + finishChange(cur, false); break; case LFUN_BEGINNINGBUF: - if (!selection.mark()) - clearSelection(); - cursorTop(); - finishChange(bv); + if (cur.depth() == 1) { + if (!cur.mark()) + cur.clearSelection(); + cursorTop(cur); + finishChange(cur, false); + } else { + cur.undispatched(); + } + break; + + case LFUN_BEGINNINGBUFSEL: + if (cur.depth() == 1) { + if (!cur.selection()) + cur.resetAnchor(); + cursorTop(cur); + finishChange(cur, true); + } else { + cur.undispatched(); + } break; case LFUN_ENDBUF: - if (selection.mark()) - clearSelection(); - cursorBottom(); - finishChange(bv); + if (cur.depth() == 1) { + if (!cur.mark()) + cur.clearSelection(); + cursorBottom(cur); + finishChange(cur, false); + } else { + cur.undispatched(); + } break; + case LFUN_ENDBUFSEL: + if (cur.depth() == 1) { + if (!cur.selection()) + cur.resetAnchor(); + cursorBottom(cur); + finishChange(cur, true); + } else { + cur.undispatched(); + } + break; + + case LFUN_RIGHT: case LFUN_RIGHTSEL: - if (!selection.set()) - selection.cursor = cursor; - if (rtl()) - cursorLeft(bv); + lyxerr << BOOST_CURRENT_FUNCTION + << " LFUN_RIGHT[SEL]:\n" << cur << endl; + cur.selHandle(cmd.action == LFUN_RIGHTSEL); + if (isRTL(cur.paragraph())) + needsUpdate = cursorLeft(cur); else - cursorRight(bv); - finishChange(bv, true); + needsUpdate = cursorRight(cur); + if (!needsUpdate && oldTopSlice == cur.top()) { + cur.undispatched(); + cmd = FuncRequest(LFUN_FINISHED_RIGHT); + } break; + case LFUN_LEFT: case LFUN_LEFTSEL: - if (!selection.set()) - selection.cursor = cursor; - if (rtl()) - cursorRight(bv); + //lyxerr << "handle LFUN_LEFT[SEL]:\n" << cur << endl; + cur.selHandle(cmd.action == LFUN_LEFTSEL); + if (isRTL(cur.paragraph())) + needsUpdate = cursorRight(cur); else - cursorLeft(bv); - finishChange(bv, true); + needsUpdate = cursorLeft(cur); + if (oldTopSlice == cur.top()) { + cur.undispatched(); + cmd = FuncRequest(LFUN_FINISHED_LEFT); + } break; + case LFUN_UP: case LFUN_UPSEL: - if (!selection.set()) - selection.cursor = cursor; - cursorUp(true); - finishChange(bv, true); + update(cur); + //lyxerr << "handle LFUN_UP[SEL]:\n" << cur << endl; + cur.selHandle(cmd.action == LFUN_UPSEL); + needsUpdate = cursorUp(cur); + if (oldTopSlice == cur.top()) { + cur.undispatched(); + cmd = FuncRequest(LFUN_FINISHED_UP); + } break; + case LFUN_DOWN: case LFUN_DOWNSEL: - if (!selection.set()) - selection.cursor = cursor; - cursorDown(true); - finishChange(bv, true); + update(cur); + //lyxerr << "handle LFUN_DOWN[SEL]:\n" << cur << endl; + cur.selHandle(cmd.action == LFUN_DOWNSEL); + needsUpdate = cursorDown(cur); + if (oldTopSlice == cur.top()) { + cur.undispatched(); + cmd = FuncRequest(LFUN_FINISHED_DOWN); + } + break; + + case LFUN_UP_PARAGRAPH: + if (!cur.mark()) + cur.clearSelection(); + needsUpdate = cursorUpParagraph(cur); + finishChange(cur, false); break; case LFUN_UP_PARAGRAPHSEL: - if (!selection.set()) - selection.cursor = cursor; - cursorUpParagraph(); - finishChange(bv, true); + if (!cur.selection()) + cur.resetAnchor(); + cursorUpParagraph(cur); + finishChange(cur, true); + break; + + case LFUN_DOWN_PARAGRAPH: + if (!cur.mark()) + cur.clearSelection(); + needsUpdate = cursorDownParagraph(cur); + finishChange(cur, false); break; case LFUN_DOWN_PARAGRAPHSEL: - if (!selection.set()) - selection.cursor = cursor; - cursorDownParagraph(); - finishChange(bv, true); + if (!cur.selection()) + cur.resetAnchor(); + cursorDownParagraph(cur); + finishChange(cur, true); break; case LFUN_PRIORSEL: - if (!selection.set()) - selection.cursor = cursor; - cursorPrevious(); - finishChange(bv, true); + update(cur); + if (!cur.selection()) + cur.resetAnchor(); + cursorPrevious(cur); + finishChange(cur, true); break; case LFUN_NEXTSEL: - if (!selection.set()) - selection.cursor = cursor; - cursorNext(); - finishChange(bv, true); + update(cur); + if (!cur.selection()) + cur.resetAnchor(); + cursorNext(cur); + finishChange(cur, true); break; case LFUN_HOMESEL: - if (!selection.set()) - selection.cursor = cursor; - cursorHome(); - finishChange(bv, true); + update(cur); + if (!cur.selection()) + cur.resetAnchor(); + cursorHome(cur); + finishChange(cur, true); break; case LFUN_ENDSEL: - if (!selection.set()) - selection.cursor = cursor; - cursorEnd(); - finishChange(bv, true); + update(cur); + if (!cur.selection()) + cur.resetAnchor(); + cursorEnd(cur); + finishChange(cur, true); break; case LFUN_WORDRIGHTSEL: - if (rtl()) - cursorLeftOneWord(); + if (!cur.selection()) + cur.resetAnchor(); + if (isRTL(cur.paragraph())) + cursorLeftOneWord(cur); else - cursorRightOneWord(); - finishChange(bv, true); + cursorRightOneWord(cur); + finishChange(cur, true); break; case LFUN_WORDLEFTSEL: - if (rtl()) - cursorRightOneWord(); + if (!cur.selection()) + cur.resetAnchor(); + if (isRTL(cur.paragraph())) + cursorRightOneWord(cur); else - cursorLeftOneWord(); - finishChange(bv, true); + cursorLeftOneWord(cur); + finishChange(cur, true); break; case LFUN_WORDSEL: { - LyXCursor cur1 = cursor; - LyXCursor cur2; - getWord(cur1, cur2, lyx::WHOLE_WORD); - setCursor(cur1.par(), cur1.pos()); - clearSelection(); - setCursor(cur2.par(), cur2.pos()); - finishChange(bv, true); + selectWord(cur, lyx::WHOLE_WORD); + finishChange(cur, true); break; } - case LFUN_RIGHT: - finishChange(bv); - return moveRight(); - - case LFUN_LEFT: - finishChange(bv); - return moveLeft(); - - case LFUN_UP: - finishChange(bv); - return moveUp(); - - case LFUN_DOWN: - finishChange(bv); - return moveDown(); - - case LFUN_UP_PARAGRAPH: - if (!selection.mark()) - clearSelection(); - cursorUpParagraph(); - finishChange(bv); - break; - - case LFUN_DOWN_PARAGRAPH: - if (!selection.mark()) - clearSelection(); - cursorDownParagraph(); - finishChange(bv, false); - break; - case LFUN_PRIOR: - if (!selection.mark()) - clearSelection(); - finishChange(bv, false); - if (cursorPar() == firstPar() && cursorRow() == firstRow()) - return DispatchResult(false, FINISHED_UP); - cursorPrevious(); + update(cur); + if (!cur.mark()) + cur.clearSelection(); + finishChange(cur, false); + if (cur.pit() == 0 && cur.textRow().pos() == 0) { + cur.undispatched(); + cmd = FuncRequest(LFUN_FINISHED_UP); + } else { + needsUpdate = cursorPrevious(cur); + } break; case LFUN_NEXT: - if (!selection.mark()) - clearSelection(); - finishChange(bv, false); - if (cursorPar() == lastPar() && cursorRow() == lastRow()) - return DispatchResult(false, FINISHED_DOWN); - cursorNext(); + update(cur); + if (!cur.mark()) + cur.clearSelection(); + finishChange(cur, false); + if (cur.pit() == cur.lastpit() + && cur.textRow().endpos() == cur.lastpos()) { + cur.undispatched(); + cmd = FuncRequest(LFUN_FINISHED_DOWN); + } else { + needsUpdate = cursorNext(cur); + } break; case LFUN_HOME: - if (!selection.mark()) - clearSelection(); - cursorHome(); - finishChange(bv, false); + if (!cur.mark()) + cur.clearSelection(); + cursorHome(cur); + finishChange(cur, false); break; case LFUN_END: - if (!selection.mark()) - clearSelection(); - cursorEnd(); - finishChange(bv, false); + if (!cur.mark()) + cur.clearSelection(); + cursorEnd(cur); + finishChange(cur, false); break; case LFUN_BREAKLINE: { - lyx::pos_type body = cursorPar()->beginOfBody(); - // Not allowed by LaTeX (labels or empty par) - if (cursor.pos() <= body) - break; - - replaceSelection(bv->getLyXText()); - insertInset(new InsetNewline); - moveCursor(bv, false); + if (cur.pos() > cur.paragraph().beginOfBody()) { + lyx::cap::replaceSelection(cur); + cur.insert(new InsetNewline); + cur.posRight(); + moveCursor(cur, false); + } break; } case LFUN_DELETE: - if (!selection.set()) { - Delete(); - selection.cursor = cursor; + if (!cur.selection()) { + Delete(cur); + cur.resetAnchor(); // It is possible to make it a lot faster still // just comment out the line below... } else { - cutSelection(true, false); + cutSelection(cur, true, false); } - moveCursor(bv, false); - bv->owner()->view_state_changed(); + moveCursor(cur, false); break; case LFUN_DELETE_SKIP: // Reverse the effect of LFUN_BREAKPARAGRAPH_SKIP. - if (!selection.set()) { - if (cursor.pos() == cursorPar()->size()) { - cursorRight(bv); - cursorLeft(bv); - Delete(); - selection.cursor = cursor; - } else { - Delete(); - selection.cursor = cursor; + if (!cur.selection()) { + if (cur.pos() == cur.lastpos()) { + cursorRight(cur); + cursorLeft(cur); } + Delete(cur); + cur.resetAnchor(); } else { - cutSelection(true, false); + cutSelection(cur, true, false); } - bv->update(); break; case LFUN_BACKSPACE: - if (!selection.set()) { + if (!cur.selection()) { if (bv->owner()->getIntl().getTransManager().backspace()) { - backspace(); - selection.cursor = cursor; + backspace(cur); + cur.resetAnchor(); // It is possible to make it a lot faster still // just comment out the line below... } } else { - cutSelection(true, false); + cutSelection(cur, true, false); } - bv->owner()->view_state_changed(); bv->switchKeyMap(); - bv->update(); break; case LFUN_BACKSPACE_SKIP: // Reverse the effect of LFUN_BREAKPARAGRAPH_SKIP. - if (!selection.set()) { - LyXCursor cur = cursor; - backspace(); - selection.cursor = cur; + if (!cur.selection()) { +#ifdef WITH_WARNINGS +#warning look here +#endif + //CursorSlice cur = cursor(); + backspace(cur); + //anchor() = cur; } else { - cutSelection(true, false); + cutSelection(cur, true, false); } - bv->update(); break; case LFUN_BREAKPARAGRAPH: - replaceSelection(bv->getLyXText()); - breakParagraph(bv->buffer()->paragraphs(), 0); - bv->update(); - selection.cursor = cursor; + lyx::cap::replaceSelection(cur); + breakParagraph(cur, 0); + cur.resetAnchor(); bv->switchKeyMap(); - bv->owner()->view_state_changed(); break; case LFUN_BREAKPARAGRAPHKEEPLAYOUT: - replaceSelection(bv->getLyXText()); - breakParagraph(bv->buffer()->paragraphs(), 1); - bv->update(); - selection.cursor = cursor; + lyx::cap::replaceSelection(cur); + breakParagraph(cur, 1); + cur.resetAnchor(); bv->switchKeyMap(); - bv->owner()->view_state_changed(); break; case LFUN_BREAKPARAGRAPH_SKIP: { // When at the beginning of a paragraph, remove - // indentation and add a "defskip" at the top. - // Otherwise, do the same as LFUN_BREAKPARAGRAPH. - LyXCursor cur = cursor; - replaceSelection(bv->getLyXText()); - if (cur.pos() == 0) { - ParagraphParameters & params = getPar(cur)->params(); - setParagraph( - params.spacing(), - params.align(), - params.labelWidthString(), 1); - } else { - breakParagraph(bv->buffer()->paragraphs(), 0); - } - bv->update(); - selection.cursor = cur; + // indentation. Otherwise, do the same as LFUN_BREAKPARAGRAPH. + lyx::cap::replaceSelection(cur); + if (cur.pos() == 0) + cur.paragraph().params().labelWidthString(string()); + else + breakParagraph(cur, 0); + cur.resetAnchor(); bv->switchKeyMap(); - bv->owner()->view_state_changed(); break; } case LFUN_PARAGRAPH_SPACING: { - ParagraphList::iterator pit = cursorPar(); - Spacing::Space cur_spacing = pit->params().spacing().getSpace(); - float cur_value = 1.0; + Paragraph & par = cur.paragraph(); + Spacing::Space cur_spacing = par.params().spacing().getSpace(); + string cur_value = "1.0"; if (cur_spacing == Spacing::Other) - cur_value = pit->params().spacing().getValue(); + cur_value = par.params().spacing().getValueAsString(); istringstream is(cmd.argument); string tmp; is >> tmp; Spacing::Space new_spacing = cur_spacing; - float new_value = cur_value; + string new_value = cur_value; if (tmp.empty()) { lyxerr << "Missing argument to `paragraph-spacing'" << endl; @@ -842,10 +765,10 @@ DispatchResult LyXText::dispatch(FuncRequest const & cmd) new_spacing = Spacing::Double; } else if (tmp == "other") { new_spacing = Spacing::Other; - float tmpval = 0.0; + string tmpval = "0.0"; is >> tmpval; lyxerr << "new_value = " << tmpval << endl; - if (tmpval != 0.0) + if (tmpval != "0.0") new_value = tmpval; } else if (tmp == "default") { new_spacing = Spacing::Default; @@ -853,11 +776,8 @@ DispatchResult LyXText::dispatch(FuncRequest const & cmd) lyxerr << _("Unknown spacing argument: ") << cmd.argument << endl; } - if (cur_spacing != new_spacing || cur_value != new_value) { - pit->params().spacing(Spacing(new_spacing, new_value)); - redoParagraph(); - bv->update(); - } + if (cur_spacing != new_spacing || cur_value != new_value) + par.params().spacing(Spacing(new_spacing, new_value)); break; } @@ -865,155 +785,120 @@ DispatchResult LyXText::dispatch(FuncRequest const & cmd) string const name = cmd.getArg(0); InsetBase * inset = bv->owner()->getDialogs().getOpenInset(name); if (inset) { - FuncRequest fr(bv, LFUN_INSET_MODIFY, cmd.argument); - inset->dispatch(fr); + FuncRequest fr(LFUN_INSET_MODIFY, cmd.argument); + inset->dispatch(cur, fr); } else { - FuncRequest fr(bv, LFUN_INSET_INSERT, cmd.argument); - dispatch(fr); + FuncRequest fr(LFUN_INSET_INSERT, cmd.argument); + dispatch(cur, fr); } break; } case LFUN_INSET_INSERT: { - InsetOld * inset = createInset(cmd); - if (inset && !bv->insertInset(inset)) - delete inset; + recordUndo(cur); + InsetBase * inset = createInset(bv, cmd); + if (inset) { + insertInset(cur, inset); + cur.posRight(); + } break; } case LFUN_INSET_SETTINGS: - bv->cursor().innerInset()->showInsetDialog(bv); + if (cur.inset().asUpdatableInset()) + cur.inset().asUpdatableInset()->showInsetDialog(bv); + break; + + case LFUN_NEXT_INSET_TOGGLE: { + InsetBase * inset = cur.nextInset(); + if (inset) { + cur.clearSelection(); + FuncRequest fr = cmd; + fr.action = LFUN_INSET_TOGGLE; + inset->dispatch(cur, fr); + } break; + } - case LFUN_INSET_TOGGLE: - clearSelection(); - if (!toggleInset()) - return DispatchResult(false); - bv->update(); + case LFUN_KEYMAP_TOGGLE: + cur.clearSelection(); bv->switchKeyMap(); break; case LFUN_SPACE_INSERT: - if (cursorPar()->layout()->free_spacing) - insertChar(' '); - else - doInsertInset(*this, cmd, false, false); - moveCursor(bv, false); + if (cur.paragraph().layout()->free_spacing) + insertChar(cur, ' '); + else { + doInsertInset(cur, this, cmd, false, false); + cur.posRight(); + } + moveCursor(cur, false); break; case LFUN_HYPHENATION: - specialChar(this, bv, InsetSpecialChar::HYPHENATION); + specialChar(cur, InsetSpecialChar::HYPHENATION); break; case LFUN_LIGATURE_BREAK: - specialChar(this, bv, InsetSpecialChar::LIGATURE_BREAK); + specialChar(cur, InsetSpecialChar::LIGATURE_BREAK); break; case LFUN_LDOTS: - specialChar(this, bv, InsetSpecialChar::LDOTS); + specialChar(cur, InsetSpecialChar::LDOTS); break; case LFUN_END_OF_SENTENCE: - specialChar(this, bv, InsetSpecialChar::END_OF_SENTENCE); + specialChar(cur, InsetSpecialChar::END_OF_SENTENCE); break; case LFUN_MENU_SEPARATOR: - specialChar(this, bv, InsetSpecialChar::MENU_SEPARATOR); - break; - - case LFUN_MARK_OFF: - clearSelection(); - bv->update(); - selection.cursor = cursor; - cmd.message(N_("Mark off")); - break; - - case LFUN_MARK_ON: - clearSelection(); - selection.mark(true); - bv->update(); - selection.cursor = cursor; - cmd.message(N_("Mark on")); - break; - - case LFUN_SETMARK: - clearSelection(); - if (selection.mark()) { - cmd.message(N_("Mark removed")); - } else { - selection.mark(true); - cmd.message(N_("Mark set")); - } - selection.cursor = cursor; - bv->update(); + specialChar(cur, InsetSpecialChar::MENU_SEPARATOR); break; case LFUN_UPCASE_WORD: - changeCase(LyXText::text_uppercase); - bv->update(); + changeCase(cur, LyXText::text_uppercase); break; case LFUN_LOWCASE_WORD: - changeCase(LyXText::text_lowercase); - bv->update(); + changeCase(cur, LyXText::text_lowercase); break; case LFUN_CAPITALIZE_WORD: - changeCase(LyXText::text_capitalization); - bv->update(); + changeCase(cur, LyXText::text_capitalization); break; case LFUN_TRANSPOSE_CHARS: - recUndo(cursor.par()); - redoParagraph(); - bv->update(); + recordUndo(cur); break; case LFUN_PASTE: - cmd.message(_("Paste")); - replaceSelection(bv->getLyXText()); + cur.message(_("Paste")); + lyx::cap::replaceSelection(cur); +#ifdef WITH_WARNINGS #warning FIXME Check if the arg is in the domain of available selections. +#endif if (isStrUnsignedInt(cmd.argument)) - pasteSelection(strToUnsignedInt(cmd.argument)); + pasteSelection(cur, convert(cmd.argument)); else - pasteSelection(0); - clearSelection(); // bug 393 - bv->update(); + pasteSelection(cur, 0); + cur.clearSelection(); // bug 393 bv->switchKeyMap(); finishUndo(); break; case LFUN_CUT: - cutSelection(true, true); - cmd.message(_("Cut")); - bv->update(); + cutSelection(cur, true, true); + cur.message(_("Cut")); break; case LFUN_COPY: - copySelection(); - cmd.message(_("Copy")); - break; - - case LFUN_BEGINNINGBUFSEL: - if (in_inset_) - return DispatchResult(false); - if (!selection.set()) - selection.cursor = cursor; - cursorTop(); - finishChange(bv, true); - break; - - case LFUN_ENDBUFSEL: - if (in_inset_) - return DispatchResult(false); - if (!selection.set()) - selection.cursor = cursor; - cursorBottom(); - finishChange(bv, true); + copySelection(cur); + cur.message(_("Copy")); break; case LFUN_GETXY: - cmd.message(tostr(cursorX()) + ' ' + tostr(cursorY())); + cur.message(convert(cursorX(cur.top())) + ' ' + + convert(cursorY(cur.top()))); break; case LFUN_SETXY: { @@ -1025,21 +910,21 @@ DispatchResult LyXText::dispatch(FuncRequest const & cmd) lyxerr << "SETXY: Could not parse coordinates in '" << cmd.argument << std::endl; else - setCursorFromCoordinates(x, y); + setCursorFromCoordinates(cur, x, y); break; } case LFUN_GETFONT: if (current_font.shape() == LyXFont::ITALIC_SHAPE) - cmd.message("E"); + cur.message("E"); else if (current_font.shape() == LyXFont::SMALLCAPS_SHAPE) - cmd.message("N"); + cur.message("N"); else - cmd.message("0"); + cur.message("0"); break; case LFUN_GETLAYOUT: - cmd.message(cursorPar()->layout()->name()); + cur.message(cur.paragraph().layout()->name()); break; case LFUN_LAYOUT: { @@ -1052,7 +937,7 @@ DispatchResult LyXText::dispatch(FuncRequest const & cmd) // function list/array with information about what // functions needs arguments and their type. if (cmd.argument.empty()) { - cmd.errorMessage(_("LyX function 'layout' needs an argument.")); + cur.errorMessage(_("LyX function 'layout' needs an argument.")); break; } @@ -1070,20 +955,20 @@ DispatchResult LyXText::dispatch(FuncRequest const & cmd) } if (!hasLayout) { - cmd.errorMessage(string(N_("Layout ")) + cmd.argument + + cur.errorMessage(string(N_("Layout ")) + cmd.argument + N_(" not known")); break; } bool change_layout = (current_layout != layout); - if (!change_layout && selection.set() && - selStart().par() != selEnd().par()) + if (!change_layout && cur.selection() && + cur.selBegin().pit() != cur.selEnd().pit()) { - ParagraphList::iterator spit = getPar(selStart()); - ParagraphList::iterator epit = boost::next(getPar(selEnd())); + pit_type spit = cur.selBegin().pit(); + pit_type epit = cur.selEnd().pit() + 1; while (spit != epit) { - if (spit->layout()->name() != current_layout) { + if (pars_[spit].layout()->name() != current_layout) { change_layout = true; break; } @@ -1093,69 +978,78 @@ DispatchResult LyXText::dispatch(FuncRequest const & cmd) if (change_layout) { current_layout = layout; - setLayout(layout); + setLayout(cur, layout); bv->owner()->setLayout(layout); - bv->update(); bv->switchKeyMap(); } break; } case LFUN_PASTESELECTION: { - // this was originally a bv->text->clearSelection(), i.e - // the outermost LyXText! - clearSelection(); + cur.clearSelection(); string const clip = bv->getClipboard(); if (!clip.empty()) { if (cmd.argument == "paragraph") - insertStringAsParagraphs(clip); + insertStringAsParagraphs(cur, clip); else - insertStringAsLines(clip); - bv->update(); + insertStringAsLines(cur, clip); } break; } case LFUN_GOTOERROR: - gotoInset(InsetOld::ERROR_CODE, false); + gotoInset(cur, InsetBase::ERROR_CODE, false); break; case LFUN_GOTONOTE: - gotoInset(InsetOld::NOTE_CODE, false); + gotoInset(cur, InsetBase::NOTE_CODE, false); break; case LFUN_REFERENCE_GOTO: { - vector tmp; - tmp.push_back(InsetOld::LABEL_CODE); - tmp.push_back(InsetOld::REF_CODE); - gotoInset(tmp, true); + vector tmp; + tmp.push_back(InsetBase::LABEL_CODE); + tmp.push_back(InsetBase::REF_CODE); + gotoInset(cur, tmp, true); break; } case LFUN_QUOTE: { - replaceSelection(bv->getLyXText()); - ParagraphList::iterator pit = cursorPar(); - lyx::pos_type pos = cursor.pos(); + lyx::cap::replaceSelection(cur); + Paragraph & par = cur.paragraph(); + lyx::pos_type pos = cur.pos(); char c; - if (!pos) + if (pos == 0) c = ' '; - else if (pit->isInset(pos - 1) && pit->getInset(pos - 1)->isSpace()) + else if (cur.prevInset() && cur.prevInset()->isSpace()) c = ' '; else - c = pit->getChar(pos - 1); + c = par.getChar(pos - 1); - LyXLayout_ptr const & style = pit->layout(); + LyXLayout_ptr const & style = par.layout(); BufferParams const & bufparams = bv->buffer()->params(); - if (style->pass_thru || - pit->getFontSettings(bufparams,pos).language()->lang() == "hebrew" || - !bv->insertInset(new InsetQuotes(c, bufparams))) + if (!style->pass_thru + && par.getFontSettings(bufparams, pos).language()->lang() != "hebrew") { + string arg = cmd.argument; + if (arg == "single") + cur.insert(new InsetQuotes(c, + bufparams.quotes_language, + InsetQuotes::SingleQ)); + else if (arg == "double") + cur.insert(new InsetQuotes(c, + bufparams.quotes_language, + InsetQuotes::DoubleQ)); + else + cur.insert(new InsetQuotes(c, bufparams)); + cur.posRight(); + } + else bv->owner()->dispatch(FuncRequest(LFUN_SELFINSERT, "\"")); break; } case LFUN_DATE_INSERT: { - replaceSelection(bv->getLyXText()); + lyx::cap::replaceSelection(cur); time_t now_time_t = time(NULL); struct tm * now_tm = localtime(&now_time_t); setlocale(LC_TIME, ""); @@ -1169,82 +1063,35 @@ DispatchResult LyXText::dispatch(FuncRequest const & cmd) ::strftime(datetmp, 32, arg.c_str(), now_tm); for (int i = 0; i < datetmp_len; i++) - insertChar(datetmp[i]); + insertChar(cur, datetmp[i]); - selection.cursor = cursor; - moveCursor(bv, false); + cur.resetAnchor(); + moveCursor(cur, false); break; } case LFUN_MOUSE_TRIPLE: - if (!bv->buffer()) - break; if (cmd.button() == mouse_button::button1) { - selection_possible = true; - cursorHome(); - selection.cursor = cursor; - cursorEnd(); - setSelection(); - bv->haveSelection(selection.set()); + cursorHome(cur); + cur.resetAnchor(); + cursorEnd(cur); + cur.setSelection(); + bv->haveSelection(cur.selection()); } break; case LFUN_MOUSE_DOUBLE: - if (!bv->buffer()) - break; if (cmd.button() == mouse_button::button1) { - selection_possible = true; - selectWord(lyx::WHOLE_WORD_STRICT); - bv->haveSelection(selection.set()); - } - break; - - case LFUN_MOUSE_MOTION: { - // Only use motion with button 1 - //if (ev.button() != mouse_button::button1) - // return false; - - if (!bv->buffer()) - break; - // The test for not selection possible is needed, that - // only motion events are used, where the bottom press - // event was on the drawing area too - if (!selection_possible) { - lyxerr[Debug::ACTION] << "BufferView::Pimpl::" - "Dispatch: no selection possible\n"; - break; - } - RowList::iterator cursorrow = cursorRow(); - - setCursorFromCoordinates(cmd.x, cmd.y); - - // This is to allow jumping over large insets - // FIXME: shouldn't be top-text-specific - if (cursorrow == cursorRow() && !in_inset_) { - if (cmd.y - bv->top_y() >= bv->workHeight()) - cursorDown(true); - else if (cmd.y - bv->top_y() < 0) - cursorUp(true); + selectWord(cur, lyx::WHOLE_WORD_STRICT); + bv->haveSelection(cur.selection()); } - setSelection(); break; - } // Single-click on work area case LFUN_MOUSE_PRESS: { - if (!bv->buffer()) - break; - - // ok ok, this is a hack (for xforms) - // We shouldn't go further down as we really should only do the - // scrolling and be done with this. Otherwise we may open some - // dialogs (Jug 20020424). - if (cmd.button() == mouse_button::button4) { - bv->scroll(-lyxrc.wheel_jump); - break; - } - if (cmd.button() == mouse_button::button5) { - bv->scroll(lyxrc.wheel_jump); + // Right click on a footnote flag opens float menu + if (cmd.button() == mouse_button::button3) { + cur.clearSelection(); break; } @@ -1253,29 +1100,25 @@ DispatchResult LyXText::dispatch(FuncRequest const & cmd) // it could get cleared on the unlocking of the inset so // we have to check this first bool paste_internally = false; - if (cmd.button() == mouse_button::button2 && selection.set()) { + if (cmd.button() == mouse_button::button2 && cur.selection()) { bv->owner()->dispatch(FuncRequest(LFUN_COPY)); paste_internally = true; } - selection_possible = true; - // Clear the selection - clearSelection(); + cur.clearSelection(); - // Right click on a footnote flag opens float menu - if (cmd.button() == mouse_button::button3) { - selection_possible = false; - break; - } - - setCursorFromCoordinates(cmd.x, cmd.y); - selection.cursor = cursor; + setCursorFromCoordinates(cur, cmd.x, cmd.y); + cur.resetAnchor(); finishUndo(); - bv->x_target(cursorX() + xo_); + cur.setTargetX(); + + // Has the cursor just left the inset? + if (bv->cursor().inMathed() && !cur.inMathed()) + bv->cursor().inset().notifyCursorLeaves(bv->cursor()); - if (bv->fitCursor()) - selection_possible = false; + // Set cursor here. + bv->cursor() = cur; // Insert primary selection with middle mouse // if there is a local selection in the current buffer, @@ -1285,33 +1128,63 @@ DispatchResult LyXText::dispatch(FuncRequest const & cmd) bv->owner()->dispatch(FuncRequest(LFUN_PASTE)); else bv->owner()->dispatch(FuncRequest(LFUN_PASTESELECTION, "paragraph")); - selection_possible = false; } + break; } - case LFUN_MOUSE_RELEASE: { - if (!bv->buffer()) - break; + case LFUN_MOUSE_MOTION: { + // Only use motion with button 1 + //if (cmd.button() != mouse_button::button1) + // return false; - // do nothing if we used the mouse wheel - if (cmd.button() == mouse_button::button4 - || cmd.button() == mouse_button::button5) - return DispatchResult(true, false); + // ignore motions deeper nested than the real anchor + LCursor & bvcur = cur.bv().cursor(); + if (bvcur.anchor_.hasPart(cur)) { + CursorSlice old = bvcur.top(); + + int const wh = bv->workHeight(); + int const y = std::max(0, std::min(wh - 1, cmd.y)); + + setCursorFromCoordinates(cur, cmd.x, y); + cur.x_target() = cmd.x; + if (cmd.y >= wh) + cursorDown(cur); + else if (cmd.y < 0) + cursorUp(cur); + // This is to allow jumping over large insets + if (cur.top() == old) { + if (cmd.y >= wh) + cursorDown(cur); + else if (cmd.y < 0) + cursorUp(cur); + } + + if (cur.top() == old) + cur.noUpdate(); + else { + // don't set anchor_ + bvcur.setCursor(cur); + bvcur.selection() = true; + lyxerr << "MOTION: " << bv->cursor() << endl; + } - selection_possible = false; + } else + cur.undispatched(); + break; + } + case LFUN_MOUSE_RELEASE: { if (cmd.button() == mouse_button::button2) break; // finish selection if (cmd.button() == mouse_button::button1) - bv->haveSelection(selection.set()); + bv->haveSelection(cur.selection()); bv->switchKeyMap(); - bv->owner()->view_state_changed(); bv->owner()->updateMenubar(); - bv->owner()->updateToolbar(); + bv->owner()->updateToolbars(); break; } @@ -1326,12 +1199,12 @@ DispatchResult LyXText::dispatch(FuncRequest const & cmd) // true (on). if (lyxrc.auto_region_delete) { - if (selection.set()) - cutSelection(false, false); + if (cur.selection()) + cutSelection(cur, false, false); bv->haveSelection(false); } - clearSelection(); + cur.clearSelection(); LyXFont const old_font = real_current_font; string::const_iterator cit = cmd.argument.begin(); @@ -1340,13 +1213,12 @@ DispatchResult LyXText::dispatch(FuncRequest const & cmd) bv->owner()->getIntl().getTransManager(). TranslateAndInsert(*cit, this); - selection.cursor = cursor; - moveCursor(bv, false); + cur.resetAnchor(); + moveCursor(cur, false); // real_current_font.number can change so we need to // update the minibuffer if (old_font != real_current_font) - bv->owner()->view_state_changed(); bv->updateScrollbar(); break; } @@ -1366,9 +1238,19 @@ DispatchResult LyXText::dispatch(FuncRequest const & cmd) } case LFUN_INSERT_LABEL: { - InsetCommandParams p("label"); + // Try to generate a valid label + string const contents = cmd.argument.empty() ? + cur.getPossibleLabel() : cmd.argument; + + InsetCommandParams p("label", contents); string const data = InsetCommandMailer::params2string("label", p); - bv->owner()->getDialogs().show("label", data, 0); + + if (cmd.argument.empty()) { + bv->owner()->getDialogs().show("label", data, 0); + } else { + FuncRequest fr(LFUN_INSET_INSERT, data); + dispatch(cur, fr); + } break; } @@ -1387,7 +1269,6 @@ DispatchResult LyXText::dispatch(FuncRequest const & cmd) case LFUN_INSET_FLOAT: case LFUN_INSET_FOOTNOTE: case LFUN_INSET_MARGINAL: - case LFUN_INSET_MINIPAGE: case LFUN_INSET_OPTARG: case LFUN_INSET_WIDE_FLOAT: case LFUN_INSET_WRAP: @@ -1395,12 +1276,14 @@ DispatchResult LyXText::dispatch(FuncRequest const & cmd) case LFUN_ENVIRONMENT_INSERT: // Open the inset, and move the current selection // inside it. - doInsertInset(*this, cmd, true, true); + doInsertInset(cur, this, cmd, true, true); + cur.posRight(); break; case LFUN_INDEX_INSERT: // Just open the inset - doInsertInset(*this, cmd, true, false); + doInsertInset(cur, this, cmd, true, false); + cur.posRight(); break; case LFUN_INDEX_PRINT: @@ -1409,119 +1292,670 @@ DispatchResult LyXText::dispatch(FuncRequest const & cmd) case LFUN_INSERT_LINE: case LFUN_INSERT_PAGEBREAK: // do nothing fancy - doInsertInset(*this, cmd, false, false); + doInsertInset(cur, this, cmd, false, false); + cur.posRight(); break; case LFUN_DEPTH_MIN: - bv_funcs::changeDepth(bv, this, bv_funcs::DEC_DEPTH); - bv->update(); + changeDepth(cur, DEC_DEPTH); break; case LFUN_DEPTH_PLUS: - bv_funcs::changeDepth(bv, this, bv_funcs::INC_DEPTH); - bv->update(); + changeDepth(cur, INC_DEPTH); break; - case LFUN_MATH_DELIM: case LFUN_MATH_DISPLAY: - case LFUN_INSERT_MATH: - case LFUN_MATH_LIMITS: - case LFUN_MATH_MACRO: - case LFUN_MATH_MUTATE: - case LFUN_MATH_SPACE: + mathDispatch(cur, cmd, true); + break; + case LFUN_MATH_IMPORT_SELECTION: case LFUN_MATH_MODE: - case LFUN_MATH_NONUMBER: - case LFUN_MATH_NUMBER: - case LFUN_MATH_EXTERN: - case LFUN_MATH_SIZE: - mathDispatch(cmd); + if (cmd.argument == "on") + // don't pass "on" as argument + mathDispatch(cur, FuncRequest(LFUN_MATH_MODE), false); + else + mathDispatch(cur, cmd, false); break; - case LFUN_EMPH: - emph(bv, this); - bv->owner()->view_state_changed(); + case LFUN_MATH_MACRO: + if (cmd.argument.empty()) + cur.errorMessage(N_("Missing argument")); + else { + string s = cmd.argument; + string const s1 = token(s, ' ', 1); + int const nargs = s1.empty() ? 0 : convert(s1); + string const s2 = token(s, ' ', 2); + string const type = s2.empty() ? "newcommand" : s2; + cur.insert(new MathMacroTemplate(token(s, ' ', 0), nargs, s2)); + //cur.nextInset()->edit(cur, true); + } break; - case LFUN_BOLD: - bold(bv, this); - bv->owner()->view_state_changed(); + // passthrough hat and underscore outside mathed: + case LFUN_SUBSCRIPT: + mathDispatch(cur, FuncRequest(LFUN_SELFINSERT, "_"), false); break; - - case LFUN_NOUN: - noun(bv, this); - bv->owner()->view_state_changed(); + case LFUN_SUPERSCRIPT: + mathDispatch(cur, FuncRequest(LFUN_SELFINSERT, "^"), false); break; - case LFUN_CODE: - code(bv, this); - bv->owner()->view_state_changed(); + case LFUN_INSERT_MATH: + case LFUN_INSERT_MATRIX: + case LFUN_MATH_DELIM: { + cur.insert(new MathHullInset); + cur.dispatch(FuncRequest(LFUN_RIGHT)); + cur.dispatch(FuncRequest(LFUN_MATH_MUTATE, "simple")); + cur.dispatch(cmd); break; + } - case LFUN_SANS: - sans(bv, this); - bv->owner()->view_state_changed(); + case LFUN_EMPH: { + LyXFont font(LyXFont::ALL_IGNORE); + font.setEmph(LyXFont::TOGGLE); + toggleAndShow(cur, this, font); break; + } - case LFUN_ROMAN: - roman(bv, this); - bv->owner()->view_state_changed(); + case LFUN_BOLD: { + LyXFont font(LyXFont::ALL_IGNORE); + font.setSeries(LyXFont::BOLD_SERIES); + toggleAndShow(cur, this, font); break; + } - case LFUN_DEFAULT: - styleReset(bv, this); - bv->owner()->view_state_changed(); + case LFUN_NOUN: { + LyXFont font(LyXFont::ALL_IGNORE); + font.setNoun(LyXFont::TOGGLE); + toggleAndShow(cur, this, font); break; + } - case LFUN_UNDERLINE: - underline(bv, this); - bv->owner()->view_state_changed(); + case LFUN_CODE: { + LyXFont font(LyXFont::ALL_IGNORE); + font.setFamily(LyXFont::TYPEWRITER_FAMILY); // no good + toggleAndShow(cur, this, font); break; + } - case LFUN_FONT_SIZE: - fontSize(bv, cmd.argument, this); - bv->owner()->view_state_changed(); + case LFUN_SANS: { + LyXFont font(LyXFont::ALL_IGNORE); + font.setFamily(LyXFont::SANS_FAMILY); + toggleAndShow(cur, this, font); break; + } - case LFUN_LANGUAGE: - lang(bv, cmd.argument, this); + case LFUN_ROMAN: { + LyXFont font(LyXFont::ALL_IGNORE); + font.setFamily(LyXFont::ROMAN_FAMILY); + toggleAndShow(cur, this, font); + break; + } + + case LFUN_DEFAULT: { + LyXFont font(LyXFont::ALL_INHERIT, ignore_language); + toggleAndShow(cur, this, font); + break; + } + + case LFUN_UNDERLINE: { + LyXFont font(LyXFont::ALL_IGNORE); + font.setUnderbar(LyXFont::TOGGLE); + toggleAndShow(cur, this, font); + break; + } + + case LFUN_FONT_SIZE: { + LyXFont font(LyXFont::ALL_IGNORE); + font.setLyXSize(cmd.argument); + toggleAndShow(cur, this, font); + break; + } + + case LFUN_LANGUAGE: { + Language const * lang = languages.getLanguage(cmd.argument); + if (!lang) + break; + LyXFont font(LyXFont::ALL_IGNORE); + font.setLanguage(lang); + toggleAndShow(cur, this, font); bv->switchKeyMap(); - bv->owner()->view_state_changed(); break; + } case LFUN_FREEFONT_APPLY: - apply_freefont(bv, this); + toggleAndShow(cur, this, freefont, toggleall); + cur.message(_("Character set")); break; - case LFUN_FREEFONT_UPDATE: - update_and_apply_freefont(bv, this, cmd.argument); + // Set the freefont using the contents of \param data dispatched from + // the frontends and apply it at the current cursor location. + case LFUN_FREEFONT_UPDATE: { + LyXFont font; + bool toggle; + if (bv_funcs::string2font(cmd.argument, font, toggle)) { + freefont = font; + toggleall = toggle; + toggleAndShow(cur, this, freefont, toggleall); + cur.message(_("Character set")); + } break; + } case LFUN_FINISHED_LEFT: - lyxerr << "swallow LFUN_FINISHED_LEFT" << endl; - if (rtl()) - cursorRight(true); + lyxerr[Debug::DEBUG] << "handle LFUN_FINISHED_LEFT:\n" << cur << endl; break; case LFUN_FINISHED_RIGHT: - lyxerr << "swallow LFUN_FINISHED_RIGHT" << endl; - if (!rtl()) - cursorRight(true); + lyxerr[Debug::DEBUG] << "handle LFUN_FINISHED_RIGHT:\n" << cur << endl; + ++cur.pos(); break; case LFUN_FINISHED_UP: - lyxerr << "swallow LFUN_FINISHED_UP" << endl; - cursorUp(true); + lyxerr[Debug::DEBUG] << "handle LFUN_FINISHED_UP:\n" << cur << endl; + cursorUp(cur); break; case LFUN_FINISHED_DOWN: - lyxerr << "swallow LFUN_FINISHED_DOWN" << endl; - cursorDown(true); + lyxerr[Debug::DEBUG] << "handle LFUN_FINISHED_DOWN:\n" << cur << endl; + cursorDown(cur); + break; + + case LFUN_LAYOUT_PARAGRAPH: { + string data; + params2string(cur.paragraph(), data); + data = "show\n" + data; + bv->owner()->getDialogs().show("paragraph", data); + break; + } + + case LFUN_PARAGRAPH_UPDATE: { + if (!bv->owner()->getDialogs().visible("paragraph")) + break; + string data; + params2string(cur.paragraph(), data); + + // Will the paragraph accept changes from the dialog? + InsetBase & inset = cur.inset(); + bool const accept = !inset.forceDefaultParagraphs(&inset); + + data = "update " + convert(accept) + '\n' + data; + bv->owner()->getDialogs().update("paragraph", data); + break; + } + + case LFUN_UMLAUT: + case LFUN_CIRCUMFLEX: + case LFUN_GRAVE: + case LFUN_ACUTE: + case LFUN_TILDE: + case LFUN_CEDILLA: + case LFUN_MACRON: + case LFUN_DOT: + case LFUN_UNDERDOT: + case LFUN_UNDERBAR: + case LFUN_CARON: + case LFUN_SPECIAL_CARON: + case LFUN_BREVE: + case LFUN_TIE: + case LFUN_HUNG_UMLAUT: + case LFUN_CIRCLE: + case LFUN_OGONEK: + bv->owner()->getLyXFunc().handleKeyFunc(cmd.action); + if (!cmd.argument.empty()) + bv->owner()->getIntl().getTransManager() + .TranslateAndInsert(cmd.argument[0], this); break; + case LFUN_FLOAT_LIST: { + LyXTextClass const & tclass = bv->buffer()->params().getLyXTextClass(); + if (tclass.floats().typeExist(cmd.argument)) { + // not quite sure if we want this... + recordUndo(cur); + cur.clearSelection(); + breakParagraph(cur); + + if (cur.lastpos() != 0) { + cursorLeft(cur); + breakParagraph(cur); + } + + setLayout(cur, tclass.defaultLayoutName()); + setParagraph(cur, Spacing(), LYX_ALIGN_LAYOUT, string(), 0); + insertInset(cur, new InsetFloatList(cmd.argument)); + cur.posRight(); + } else { + lyxerr << "Non-existent float type: " + << cmd.argument << endl; + } + break; + } + + case LFUN_ACCEPT_CHANGE: { + acceptChange(cur); + break; + } + + case LFUN_REJECT_CHANGE: { + rejectChange(cur); + break; + } + + case LFUN_THESAURUS_ENTRY: { + string arg = cmd.argument; + if (arg.empty()) { + arg = cur.selectionAsString(false); + // FIXME + if (arg.size() > 100 || arg.empty()) { + // Get word or selection + selectWordWhenUnderCursor(cur, lyx::WHOLE_WORD); + arg = cur.selectionAsString(false); + } + } + bv->owner()->getDialogs().show("thesaurus", arg); + break; + } + + case LFUN_PARAGRAPH_APPLY: { + // Given data, an encoding of the ParagraphParameters + // generated in the Paragraph dialog, this function sets + // the current paragraph appropriately. + istringstream is(cmd.argument); + LyXLex lex(0, 0); + lex.setStream(is); + ParagraphParameters params; + params.read(lex); + setParagraph(cur, + params.spacing(), + params.align(), + params.labelWidthString(), + params.noindent()); + cur.message(_("Paragraph layout set")); + break; + } + + case LFUN_INSET_DIALOG_SHOW: { + InsetBase * inset = cur.nextInset(); + if (inset) { + FuncRequest fr(LFUN_INSET_DIALOG_SHOW); + inset->dispatch(cur, fr); + } + break; + } + + case LFUN_ESCAPE: + if (cur.selection()) { + cur.selection() = false; + } else { + cur.undispatched(); + cmd = FuncRequest(LFUN_FINISHED_LEFT); + } + break; + + default: + lyxerr << BOOST_CURRENT_FUNCTION + << " Not DISPATCHED by LyXText" << endl; + cur.undispatched(); + break; + } + + if (!needsUpdate + && &oldTopSlice.inset() == &cur.inset() + && oldTopSlice.idx() == cur.idx() + && !sel + && !cur.selection()) + cur.noUpdate(); + else + cur.needsUpdate(); +} + + +bool LyXText::getStatus(LCursor & cur, FuncRequest const & cmd, + FuncStatus & flag) const +{ + BOOST_ASSERT(cur.text() == this); + LyXFont const & font = real_current_font; + bool enable = true; + + switch (cmd.action) { + + case LFUN_DEPTH_MIN: + enable = changeDepthAllowed(cur, DEC_DEPTH); + break; + + case LFUN_DEPTH_PLUS: + enable = changeDepthAllowed(cur, INC_DEPTH); + break; + + case LFUN_INSET_OPTARG: + enable = numberOfOptArgs(cur.paragraph()) + < cur.paragraph().layout()->optionalargs; + break; + + case LFUN_APPENDIX: + flag.setOnOff(cur.paragraph().params().startOfAppendix()); + break; + +#if 0 + // the functions which insert insets + InsetBase::Code code = InsetBase::NO_CODE; + switch (cmd.action) { + case LFUN_DIALOG_SHOW_NEW_INSET: + if (cmd.argument == "bibitem") + code = InsetBase::BIBITEM_CODE; + else if (cmd.argument == "bibtex") + code = InsetBase::BIBTEX_CODE; + else if (cmd.argument == "box") + code = InsetBase::BOX_CODE; + else if (cmd.argument == "branch") + code = InsetBase::BRANCH_CODE; + else if (cmd.argument == "citation") + code = InsetBase::CITE_CODE; + else if (cmd.argument == "ert") + code = InsetBase::ERT_CODE; + else if (cmd.argument == "external") + code = InsetBase::EXTERNAL_CODE; + else if (cmd.argument == "float") + code = InsetBase::FLOAT_CODE; + else if (cmd.argument == "graphics") + code = InsetBase::GRAPHICS_CODE; + else if (cmd.argument == "include") + code = InsetBase::INCLUDE_CODE; + else if (cmd.argument == "index") + code = InsetBase::INDEX_CODE; + else if (cmd.argument == "label") + code = InsetBase::LABEL_CODE; + else if (cmd.argument == "note") + code = InsetBase::NOTE_CODE; + else if (cmd.argument == "ref") + code = InsetBase::REF_CODE; + else if (cmd.argument == "toc") + code = InsetBase::TOC_CODE; + else if (cmd.argument == "url") + code = InsetBase::URL_CODE; + else if (cmd.argument == "vspace") + code = InsetBase::VSPACE_CODE; + else if (cmd.argument == "wrap") + code = InsetBase::WRAP_CODE; + break; + + case LFUN_INSET_ERT: + code = InsetBase::ERT_CODE; + break; + case LFUN_INSET_FOOTNOTE: + code = InsetBase::FOOT_CODE; + break; + case LFUN_TABULAR_INSERT: + code = InsetBase::TABULAR_CODE; + break; + case LFUN_INSET_MARGINAL: + code = InsetBase::MARGIN_CODE; + break; + case LFUN_INSET_FLOAT: + case LFUN_INSET_WIDE_FLOAT: + code = InsetBase::FLOAT_CODE; + break; + case LFUN_INSET_WRAP: + code = InsetBase::WRAP_CODE; + break; + case LFUN_FLOAT_LIST: + code = InsetBase::FLOAT_LIST_CODE; + break; +#if 0 + case LFUN_INSET_LIST: + code = InsetBase::LIST_CODE; + break; + case LFUN_INSET_THEOREM: + code = InsetBase::THEOREM_CODE; + break; +#endif + case LFUN_INSET_CAPTION: + code = InsetBase::CAPTION_CODE; + break; + case LFUN_INSERT_NOTE: + code = InsetBase::NOTE_CODE; + break; + case LFUN_INSERT_CHARSTYLE: + code = InsetBase::CHARSTYLE_CODE; + if (buf->params().getLyXTextClass().charstyles().empty()) + enable = false; + break; + case LFUN_INSERT_BOX: + code = InsetBase::BOX_CODE; + break; + case LFUN_INSERT_BRANCH: + code = InsetBase::BRANCH_CODE; + if (buf->params().branchlist().empty()) + enable = false; + break; + case LFUN_INSERT_LABEL: + code = InsetBase::LABEL_CODE; + break; + case LFUN_INSET_OPTARG: + code = InsetBase::OPTARG_CODE; + break; + case LFUN_ENVIRONMENT_INSERT: + code = InsetBase::BOX_CODE; + break; + case LFUN_INDEX_INSERT: + code = InsetBase::INDEX_CODE; + break; + case LFUN_INDEX_PRINT: + code = InsetBase::INDEX_PRINT_CODE; + break; + case LFUN_TOC_INSERT: + code = InsetBase::TOC_CODE; + break; + case LFUN_HTMLURL: + case LFUN_URL: + code = InsetBase::URL_CODE; + break; + case LFUN_QUOTE: + // always allow this, since we will inset a raw quote + // if an inset is not allowed. + break; + case LFUN_HYPHENATION: + case LFUN_LIGATURE_BREAK: + case LFUN_HFILL: + case LFUN_MENU_SEPARATOR: + case LFUN_LDOTS: + case LFUN_END_OF_SENTENCE: + code = InsetBase::SPECIALCHAR_CODE; + break; + case LFUN_SPACE_INSERT: + // slight hack: we know this is allowed in math mode + if (cur.inTexted()) + code = InsetBase::SPACE_CODE; + break; + case LFUN_INSET_DIALOG_SHOW: { + InsetBase * inset = cur.nextInset(); + enable = inset; + if (inset) { + code = inset->lyxCode(); + if (!(code == InsetBase::INCLUDE_CODE + || code == InsetBase::BIBTEX_CODE + || code == InsetBase::FLOAT_LIST_CODE + || code == InsetBase::TOC_CODE)) + enable = false; + } + break; + } default: - return DispatchResult(false); + break; } - return DispatchResult(true, true); + if (code != InsetBase::NO_CODE + && (cur.empty() || !cur.inset().insetAllowed(code))) + enable = false; + +#endif + + case LFUN_DIALOG_SHOW_NEW_INSET: + case LFUN_INSET_ERT: + case LFUN_INSERT_BOX: + case LFUN_INSERT_BRANCH: + case LFUN_ENVIRONMENT_INSERT: + case LFUN_INDEX_INSERT: + case LFUN_INDEX_PRINT: + case LFUN_TOC_INSERT: + case LFUN_HTMLURL: + case LFUN_URL: + case LFUN_QUOTE: + case LFUN_HYPHENATION: + case LFUN_LIGATURE_BREAK: + case LFUN_HFILL: + case LFUN_MENU_SEPARATOR: + case LFUN_LDOTS: + case LFUN_END_OF_SENTENCE: + case LFUN_SPACE_INSERT: + case LFUN_INSET_DIALOG_SHOW: + break; + + case LFUN_EMPH: + flag.setOnOff(font.emph() == LyXFont::ON); + break; + + case LFUN_NOUN: + flag.setOnOff(font.noun() == LyXFont::ON); + break; + + case LFUN_BOLD: + flag.setOnOff(font.series() == LyXFont::BOLD_SERIES); + break; + + case LFUN_SANS: + flag.setOnOff(font.family() == LyXFont::SANS_FAMILY); + break; + + case LFUN_ROMAN: + flag.setOnOff(font.family() == LyXFont::ROMAN_FAMILY); + break; + + case LFUN_CODE: + flag.setOnOff(font.family() == LyXFont::TYPEWRITER_FAMILY); + break; + + case LFUN_DELETE_WORD_FORWARD: + case LFUN_DELETE_WORD_BACKWARD: + case LFUN_DELETE_LINE_FORWARD: + case LFUN_WORDRIGHT: + case LFUN_WORDLEFT: + case LFUN_RIGHT: + case LFUN_RIGHTSEL: + case LFUN_LEFT: + case LFUN_LEFTSEL: + case LFUN_UP: + case LFUN_UPSEL: + case LFUN_DOWN: + case LFUN_DOWNSEL: + case LFUN_UP_PARAGRAPHSEL: + case LFUN_DOWN_PARAGRAPHSEL: + case LFUN_PRIORSEL: + case LFUN_NEXTSEL: + case LFUN_HOMESEL: + case LFUN_ENDSEL: + case LFUN_WORDRIGHTSEL: + case LFUN_WORDLEFTSEL: + case LFUN_WORDSEL: + case LFUN_UP_PARAGRAPH: + case LFUN_DOWN_PARAGRAPH: + case LFUN_PRIOR: + case LFUN_NEXT: + case LFUN_HOME: + case LFUN_END: + case LFUN_BREAKLINE: + case LFUN_DELETE: + case LFUN_DELETE_SKIP: + case LFUN_BACKSPACE: + case LFUN_BACKSPACE_SKIP: + case LFUN_BREAKPARAGRAPH: + case LFUN_BREAKPARAGRAPHKEEPLAYOUT: + case LFUN_BREAKPARAGRAPH_SKIP: + case LFUN_PARAGRAPH_SPACING: + case LFUN_INSET_APPLY: + case LFUN_INSET_INSERT: + case LFUN_NEXT_INSET_TOGGLE: + case LFUN_UPCASE_WORD: + case LFUN_LOWCASE_WORD: + case LFUN_CAPITALIZE_WORD: + case LFUN_TRANSPOSE_CHARS: + case LFUN_PASTE: + case LFUN_CUT: + case LFUN_COPY: + case LFUN_GETXY: + case LFUN_SETXY: + case LFUN_GETFONT: + case LFUN_GETLAYOUT: + case LFUN_LAYOUT: + case LFUN_PASTESELECTION: + case LFUN_GOTOERROR: + case LFUN_GOTONOTE: + case LFUN_REFERENCE_GOTO: + case LFUN_DATE_INSERT: + case LFUN_SELFINSERT: + case LFUN_INSERT_LABEL: + case LFUN_INSERT_NOTE: + case LFUN_INSERT_CHARSTYLE: + case LFUN_INSERT_BIBITEM: + case LFUN_INSET_FLOAT: + case LFUN_INSET_FOOTNOTE: + case LFUN_INSET_MARGINAL: + case LFUN_INSET_WIDE_FLOAT: + case LFUN_INSET_WRAP: + case LFUN_TABULAR_INSERT: + case LFUN_INSERT_LINE: + case LFUN_INSERT_PAGEBREAK: + case LFUN_MATH_DISPLAY: + case LFUN_MATH_IMPORT_SELECTION: + case LFUN_MATH_MODE: + case LFUN_MATH_MACRO: + case LFUN_INSERT_MATH: + case LFUN_INSERT_MATRIX: + case LFUN_MATH_DELIM: + case LFUN_SUBSCRIPT: + case LFUN_SUPERSCRIPT: + case LFUN_DEFAULT: + case LFUN_UNDERLINE: + case LFUN_FONT_SIZE: + case LFUN_LANGUAGE: + case LFUN_FREEFONT_APPLY: + case LFUN_FREEFONT_UPDATE: + case LFUN_LAYOUT_PARAGRAPH: + case LFUN_PARAGRAPH_UPDATE: + case LFUN_UMLAUT: + case LFUN_CIRCUMFLEX: + case LFUN_GRAVE: + case LFUN_ACUTE: + case LFUN_TILDE: + case LFUN_CEDILLA: + case LFUN_MACRON: + case LFUN_DOT: + case LFUN_UNDERDOT: + case LFUN_UNDERBAR: + case LFUN_CARON: + case LFUN_SPECIAL_CARON: + case LFUN_BREVE: + case LFUN_TIE: + case LFUN_HUNG_UMLAUT: + case LFUN_CIRCLE: + case LFUN_OGONEK: + case LFUN_FLOAT_LIST: + case LFUN_ACCEPT_CHANGE: + case LFUN_REJECT_CHANGE: + case LFUN_THESAURUS_ENTRY: + case LFUN_PARAGRAPH_APPLY: + case LFUN_ESCAPE: + case LFUN_KEYMAP_TOGGLE: + case LFUN_ENDBUF: + case LFUN_BEGINNINGBUF: + case LFUN_BEGINNINGBUFSEL: + case LFUN_ENDBUFSEL: + // these are handled in our dispatch() + enable = true; + break; + + default: + return false; + } + flag.enabled(enable); + return true; }