]> git.lyx.org Git - lyx.git/blobdiff - src/lyxfunc.C
the spellcheck cleanup
[lyx.git] / src / lyxfunc.C
index abe1b46809e77973b076d483f7deda2144be55d9..a4bac22fb7dadafc68621160c4b1f061c35ed74e 100644 (file)
@@ -29,6 +29,7 @@
 #include "BufferView.h"
 #include "cursor.h"
 #include "debug.h"
+#include "dispatchresult.h"
 #include "encoding.h"
 #include "exporter.h"
 #include "format.h"
@@ -48,8 +49,7 @@
 #include "lyxvc.h"
 #include "paragraph.h"
 #include "ParagraphParameters.h"
-#include "TextCache.h"
-#include "undo_funcs.h"
+#include "undo.h"
 
 #include "insets/insetcommand.h"
 #include "insets/insetexternal.h"
@@ -73,6 +73,7 @@
 #include "support/path_defines.h"
 #include "support/tostr.h"
 #include "support/std_sstream.h"
+#include "support/os.h"
 
 using bv_funcs::apply_freefont;
 using bv_funcs::changeDepth;
@@ -104,6 +105,8 @@ using lyx::support::system_lyxdir;
 using lyx::support::token;
 using lyx::support::trim;
 using lyx::support::user_lyxdir;
+using lyx::support::prefixIs;
+using lyx::support::os::getTmpDir;
 
 using std::endl;
 using std::make_pair;
@@ -276,7 +279,8 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & ev) const
 
        if (ev.action == LFUN_NOACTION) {
                setStatusMessage(N_("Nothing to do"));
-               return flag.disabled(true);
+               flag.disabled(true);
+               return flag;
        }
 
        switch (ev.action) {
@@ -285,6 +289,7 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & ev) const
        case LFUN_THESAURUS_ENTRY:
 #endif
                flag.unknown(true);
+               flag.disabled(true);
                break;
        default:
                flag |= lyx_gui::getStatus(ev);
@@ -314,8 +319,9 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & ev) const
                } else {
                        // no
                        setStatusMessage(N_("Command not allowed with"
-                                          "out any document open"));
-                       return flag.disabled(true);
+                                           "out any document open"));
+                       flag.disabled(true);
+                       return flag;
                }
        }
 
@@ -372,13 +378,13 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & ev) const
 
        case LFUN_LAYOUT:
        case LFUN_LAYOUT_PARAGRAPH: {
-               InsetOld * inset = view()->getLyXText()->cursor.par()->inInset();
+               InsetOld * inset = view()->getLyXText()->cursorPar()->inInset();
                disable = inset && inset->forceDefaultParagraphs(inset);
                break;
        }
 
        case LFUN_INSET_OPTARG:
-               disable = (view()->getLyXText()->cursor.par()->layout()->optionalargs == 0);
+               disable = (view()->getLyXText()->cursorPar()->layout()->optionalargs == 0);
                break;
 
        case LFUN_TABULAR_FEATURE:
@@ -400,7 +406,7 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & ev) const
                                break;
                        }
                        flag.setOnOff(ev.argument[0] == align);
-               } else
+               } else {
                        disable = true;
 
                        char align = mathcursor->halign();
@@ -441,11 +447,9 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & ev) const
                                disable = true;
                        }
                } else {
-                       static InsetTabular inset(*owner->buffer(), 1, 1);
-                       FuncStatus ret;
-
+                       static InsetTabular inset(*buf, 1, 1);
                        disable = true;
-                       ret = inset.getStatus(ev.argument);
+                       FuncStatus ret = inset.getStatus(ev.argument);
                        if (ret.onoff(true) || ret.onoff(false))
                                flag.setOnOff(false);
                }
@@ -468,9 +472,10 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & ev) const
                disable = buf->isUnnamed() || buf->isClean();
                break;
        case LFUN_BOOKMARK_GOTO:
-               disable =  !view()->
+               disable = !view()->
                        isSavedPosition(strToUnsignedInt(ev.argument));
                break;
+
        case LFUN_MERGE_CHANGES:
        case LFUN_ACCEPT_CHANGE:
        case LFUN_REJECT_CHANGE:
@@ -478,6 +483,7 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & ev) const
        case LFUN_REJECT_ALL_CHANGES:
                disable = !buf->params().tracking_changes;
                break;
+
        case LFUN_INSET_TOGGLE: {
                LyXText * lt = view()->getLyXText();
                disable = !(isEditableInset(lt->getInset())
@@ -525,6 +531,9 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & ev) const
                        case InsetOld::BRANCH_CODE:
                                disable = ev.argument != "branch";
                                break;
+                       case InsetOld::BOX_CODE:
+                               disable = ev.argument != "box";
+                               break;
                        default:
                                break;
                }
@@ -653,6 +662,9 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & ev) const
        case LFUN_INSERT_NOTE:
                code = InsetOld::NOTE_CODE;
                break;
+       case LFUN_INSERT_BOX:
+               code = InsetOld::BOX_CODE;
+               break;
        case LFUN_INSERT_BRANCH:
                code = InsetOld::BRANCH_CODE;
                if (buf->params().branchlist().empty())
@@ -698,19 +710,18 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & ev) const
                        code = InsetOld::SPACE_CODE;
                break;
        case LFUN_INSET_DIALOG_SHOW: {
-                       LyXText * lt = view()->getLyXText();
-                       InsetOld * inset = lt->getInset();
-                       disable = !inset;
-                       if (!disable) {
-                               code = inset->lyxCode();
-                               if (!(code == InsetOld::INCLUDE_CODE
-                                       || code == InsetOld::BIBTEX_CODE
-                                       || code == InsetOld::FLOAT_LIST_CODE
-                                       || code == InsetOld::TOC_CODE))
-                                       disable = true;
-                       }
+               InsetOld * inset = view()->getLyXText()->getInset();
+               disable = !inset;
+               if (!disable) {
+                       code = inset->lyxCode();
+                       if (!(code == InsetOld::INCLUDE_CODE
+                               || code == InsetOld::BIBTEX_CODE
+                               || code == InsetOld::FLOAT_LIST_CODE
+                               || code == InsetOld::TOC_CODE))
+                               disable = true;
                }
                break;
+       }
        default:
                break;
        }
@@ -730,7 +741,7 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & ev) const
                flag.setOnOff(buf->isReadonly());
                break;
        case LFUN_APPENDIX:
-               flag.setOnOff(view()->getLyXText()->cursor.par()->params().startOfAppendix());
+               flag.setOnOff(view()->getLyXText()->cursorPar()->params().startOfAppendix());
                break;
        case LFUN_SWITCHBUFFER:
                // toggle on the current buffer, but do not toggle off
@@ -803,7 +814,7 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & ev) const
        // solution, we consider only the first action of the sequence
        if (ev.action == LFUN_SEQUENCE) {
                // argument contains ';'-terminated commands
-#warning LyXAction arguements not handled here.
+#warning LyXAction arguments not handled here.
                flag = getStatus(FuncRequest(lyxaction.lookupFunc(token(ev.argument, ';', 0))));
        }
 
@@ -811,39 +822,27 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & ev) const
 }
 
 
-void LyXFunc::dispatch(string const & s, bool verbose)
-{
-       FuncRequest func = lyxaction.lookupFunc(s);
-
-       if (func.action == LFUN_UNKNOWN_ACTION) {
-               owner->message(bformat(_("Unknown function (%1$s)"), s));
-               return;
-       }
-
-       dispatch(func, verbose);
-}
-
-
 namespace {
-       bool ensureBufferClean(BufferView * bv) {
-
-               Buffer & buf = *bv->buffer();
-               if (buf.isClean())
-                       return true;
-
-               string const file = MakeDisplayPath(buf.fileName(), 30);
-               string text = bformat(_("The document %1$s has unsaved "
-                                       "changes.\n\nDo you want to save "
-                                       "the document?"), file);
-               int const ret = Alert::prompt(_("Save changed document?"),
-                                             text, 0, 1, _("&Save"),
-                                             _("&Cancel"));
 
-               if (ret == 0)
-                       bv->owner()->dispatch(FuncRequest(LFUN_MENUWRITE));
-
-               return buf.isClean();
-       }
+bool ensureBufferClean(BufferView * bv)
+{
+       Buffer & buf = *bv->buffer();
+       if (buf.isClean())
+               return true;
+
+       string const file = MakeDisplayPath(buf.fileName(), 30);
+       string text = bformat(_("The document %1$s has unsaved "
+                               "changes.\n\nDo you want to save "
+                               "the document?"), file);
+       int const ret = Alert::prompt(_("Save changed document?"),
+                                     text, 0, 1, _("&Save"),
+                                     _("&Cancel"));
+
+       if (ret == 0)
+               bv->owner()->dispatch(FuncRequest(LFUN_MENUWRITE));
+
+       return buf.isClean();
+}
 
 } //namespace anon
 
@@ -886,16 +885,23 @@ void LyXFunc::dispatch(FuncRequest const & func, bool verbose)
        {
                Cursor cursor;
                buildCursor(cursor, *view());
-               if (cursor.dispatch(FuncRequest(func, view())) == DISPATCHED) {
+               DispatchResult result =
+                       cursor.dispatch(FuncRequest(func, view()));
+
+               if (result.dispatched()) {
+                       if (result.update()) {
+                               view()->update();
+                       }
                        lyxerr << "dispatched by Cursor::dispatch()\n";
                        goto exit_with_message;
                }
+               lyxerr << "### NOT DispatchResult(true, true) BY Cursor::dispatch() ###\n";
        }
 #endif
 
 
        if (view()->available() && view()->theLockingInset()) {
-               InsetOld::RESULT result;
+               DispatchResult result;
                if (action > 1 || (action == LFUN_UNKNOWN_ACTION &&
                                     !keyseq.deleted()))
                {
@@ -905,10 +911,8 @@ void LyXFunc::dispatch(FuncRequest const & func, bool verbose)
                        int dummy_y;
                        inset->getCursorPos(view(), inset_x, dummy_y);
 #endif
-                       if ((action == LFUN_UNKNOWN_ACTION)
-                           && argument.empty()) {
+                       if (action == LFUN_UNKNOWN_ACTION && argument.empty())
                                argument = encoded_last_key;
-                       }
 
                        // the insets can't try to handle this,
                        // a table cell in the dummy position will
@@ -926,38 +930,51 @@ void LyXFunc::dispatch(FuncRequest const & func, bool verbose)
                        if (action == LFUN_UNDO) {
                                view()->undo();
                                goto exit_with_message;
-                       } else if (action == LFUN_REDO) {
+                       }
+
+                       if (action == LFUN_REDO) {
                                view()->redo();
                                goto exit_with_message;
-                       } else if (((result=inset->
-                                    // Hand-over to inset's own dispatch:
-                                    localDispatch(FuncRequest(view(), action, argument))) ==
-                                   DISPATCHED) ||
-                                  (result == DISPATCHED_NOUPDATE))
+                       }
+
+                       // Hand-over to inset's own dispatch:
+                       result = inset->dispatch(FuncRequest(view(), action, argument));
+                       if (result.dispatched()) {
+                               if (result.update())
+                                       view()->update();
+
                                goto exit_with_message;
-                                       // If UNDISPATCHED, just soldier on
-                       else if (result == FINISHED) {
+                       }
+
+                       // If DispatchResult(false), just soldier on
+                       if (result.val() == FINISHED) {
                                owner->clearMessage();
                                goto exit_with_message;
                                // We do not need special RTL handling here:
                                // FINISHED means that the cursor should be
                                // one position after the inset.
-                       } else if (result == FINISHED_RIGHT) {
+                       }
+
+                       if (result.val() == FINISHED_RIGHT) {
                                view()->text->cursorRight(view());
                                moveCursorUpdate();
                                owner->clearMessage();
                                goto exit_with_message;
-                       } else if (result == FINISHED_UP) {
-                               RowList::iterator const irow = view()->text->cursorIRow();
-                               if (irow != view()->text->firstRow()) {
+                       }
+
+                       if (result.val() == FINISHED_UP) {
+                               LyXText * text = view()->text;
+                               ParagraphList::iterator pit = text->cursorPar();
+                               Row const & row = *pit->getRow(text->cursor.pos());
+                               if (text->isFirstRow(pit, row)) {
 #if 1
-                                       view()->text->setCursorFromCoordinates(
-                                               view()->text->cursor.x() + inset_x,
-                                               view()->text->cursor.y() -
-                                               irow->baseline() - 1);
-                                       view()->text->cursor.x_fix(view()->text->cursor.x());
+                                       text->setCursorFromCoordinates(
+                                               text->cursor.x() + inset_x,
+                                               text->cursor.y() -
+                                               row.baseline() - 1);
+                                       view()->x_target(text->cursor.x());
 #else
-                                       view()->text->cursorUp(view());
+                                       text->cursorUp(view());
 #endif
                                        moveCursorUpdate();
                                } else {
@@ -965,62 +982,69 @@ void LyXFunc::dispatch(FuncRequest const & func, bool verbose)
                                }
                                owner->clearMessage();
                                goto exit_with_message;
-                       } else if (result == FINISHED_DOWN) {
-                               RowList::iterator const irow = view()->text->cursorIRow();
-                               if (irow != view()->text->lastRow()) {
+                       }
+
+                       if (result.val() == FINISHED_DOWN) {
+                               LyXText * text = view()->text;
+                               ParagraphList::iterator pit = text->cursorPar();
+                               Row const & row = *pit->getRow(text->cursor.pos());
+                               if (text->isLastRow(pit, row)) {
 #if 1
-                                       view()->text->setCursorFromCoordinates(
-                                               view()->text->cursor.x() + inset_x,
-                                               view()->text->cursor.y() -
-                                               irow->baseline() +
-                                               irow->height() + 1);
-                                       view()->text->cursor.x_fix(view()->text->cursor.x());
+                                       text->setCursorFromCoordinates(
+                                               text->cursor.x() + inset_x,
+                                               text->cursor.y() -
+                                               row.baseline() +
+                                               row.height() + 1);
+                                       view()->x_target(text->cursor.x());
 #else
-                                       view()->text->cursorDown(view());
+                                       text->cursorDown(view());
 #endif
                                } else {
-                                       view()->text->cursorRight(view());
+                                       text->cursorRight(view());
                                }
                                moveCursorUpdate();
                                owner->clearMessage();
                                goto exit_with_message;
                        }
+
 #warning I am not sure this is still right, please have a look! (Jug 20020417)
-                       else { // result == UNDISPATCHED
-                               //setMessage(N_("Text mode"));
-                               switch (action) {
-                               case LFUN_UNKNOWN_ACTION:
-                               case LFUN_BREAKPARAGRAPH:
-                               case LFUN_BREAKLINE:
+                       // result == DispatchResult()
+                       //setMessage(N_("Text mode"));
+                       switch (action) {
+                       case LFUN_UNKNOWN_ACTION:
+                       case LFUN_BREAKPARAGRAPH:
+                       case LFUN_BREAKLINE:
+                               view()->text->cursorRight(view());
+                               view()->switchKeyMap();
+                               owner->view_state_changed();
+                               break;
+                       case LFUN_RIGHT:
+                               if (!view()->text->cursorPar()->isRightToLeftPar(owner->buffer()->params())) {
                                        view()->text->cursorRight(view());
-                                       view()->switchKeyMap();
+                                       moveCursorUpdate();
                                        owner->view_state_changed();
-                                       break;
-                               case LFUN_RIGHT:
-                                       if (!view()->text->cursor.par()->isRightToLeftPar(owner->buffer()->params())) {
-                                               view()->text->cursorRight(view());
-                                               moveCursorUpdate();
-                                               owner->view_state_changed();
-                                       }
-                                       goto exit_with_message;
-                               case LFUN_LEFT:
-                                       if (view()->text->cursor.par()->isRightToLeftPar(owner->buffer()->params())) {
-                                               view()->text->cursorRight(view());
-                                               moveCursorUpdate();
-                                               owner->view_state_changed();
-                                       }
-                                       goto exit_with_message;
-                               case LFUN_DOWN:
-                                       if (view()->text->cursorRow() != view()->text->lastRow())
-                                               view()->text->cursorDown(view());
-                                       else
-                                               view()->text->cursorRight(view());
+                               }
+                               goto exit_with_message;
+                       case LFUN_LEFT:
+                               if (view()->text->cursorPar()->isRightToLeftPar(owner->buffer()->params())) {
+                                       view()->text->cursorRight(view());
                                        moveCursorUpdate();
                                        owner->view_state_changed();
-                                       goto exit_with_message;
-                               default:
-                                       break;
                                }
+                               goto exit_with_message;
+                       case LFUN_DOWN: {
+                               LyXText * text = view()->text;
+                               ParagraphList::iterator pit = text->cursorPar();
+                               if (text->isLastRow(pit, *pit->getRow(text->cursor.pos())))
+                                       view()->text->cursorDown(view());
+                               else
+                                       view()->text->cursorRight(view());
+                               moveCursorUpdate();
+                               owner->view_state_changed();
+                               goto exit_with_message;
+                       }
+                       default:
+                               break;
                        }
                }
        }
@@ -1063,7 +1087,8 @@ void LyXFunc::dispatch(FuncRequest const & func, bool verbose)
                }
                bool fw = (action == LFUN_WORDFINDFORWARD);
                if (!searched_string.empty())
-                       lyx::find::find(view(), searched_string, fw);
+                       lyx::find::find(view(), searched_string,
+                                       true, false, fw);
                break;
        }
 
@@ -1181,8 +1206,7 @@ void LyXFunc::dispatch(FuncRequest const & func, bool verbose)
                QuitLyX();
                break;
 
-       case LFUN_TOCVIEW:
-       {
+       case LFUN_TOCVIEW: {
                InsetCommandParams p("tableofcontents");
                string const data = InsetCommandMailer::params2string("toc", p);
                owner->getDialogs().show("toc", data, 0);
@@ -1229,8 +1253,8 @@ void LyXFunc::dispatch(FuncRequest const & func, bool verbose)
 //#warning Find another implementation here (or another lyxfunc)!
 #endif
 #endif
-       case LFUN_HELP_OPEN:
-       {
+
+       case LFUN_HELP_OPEN: {
                string const arg = argument;
                if (arg.empty()) {
                        setErrorMessage(N_("Missing argument"));
@@ -1250,18 +1274,15 @@ void LyXFunc::dispatch(FuncRequest const & func, bool verbose)
 
                // --- version control -------------------------------
        case LFUN_VC_REGISTER:
-       {
                if (!ensureBufferClean(view()))
                        break;
                if (!owner->buffer()->lyxvc().inUse()) {
                        owner->buffer()->lyxvc().registrer();
                        view()->reload();
                }
-       }
-       break;
+               break;
 
        case LFUN_VC_CHECKIN:
-       {
                if (!ensureBufferClean(view()))
                        break;
                if (owner->buffer()->lyxvc().inUse()
@@ -1269,11 +1290,9 @@ void LyXFunc::dispatch(FuncRequest const & func, bool verbose)
                        owner->buffer()->lyxvc().checkIn();
                        view()->reload();
                }
-       }
-       break;
+               break;
 
        case LFUN_VC_CHECKOUT:
-       {
                if (!ensureBufferClean(view()))
                        break;
                if (owner->buffer()->lyxvc().inUse()
@@ -1281,22 +1300,17 @@ void LyXFunc::dispatch(FuncRequest const & func, bool verbose)
                        owner->buffer()->lyxvc().checkOut();
                        view()->reload();
                }
-       }
-       break;
+               break;
 
        case LFUN_VC_REVERT:
-       {
                owner->buffer()->lyxvc().revert();
                view()->reload();
-       }
-       break;
+               break;
 
        case LFUN_VC_UNDO:
-       {
                owner->buffer()->lyxvc().undoLast();
                view()->reload();
-       }
-       break;
+               break;
 
        // --- buffers ----------------------------------------
 
@@ -1312,20 +1326,19 @@ void LyXFunc::dispatch(FuncRequest const & func, bool verbose)
                open(argument);
                break;
 
-       case LFUN_LAYOUT_TABULAR:
-           if (view()->theLockingInset()) {
-               if (view()->theLockingInset()->lyxCode()== InsetOld::TABULAR_CODE) {
-                   InsetTabular * inset = static_cast<InsetTabular *>
-                       (view()->theLockingInset());
-                   inset->openLayoutDialog(view());
-               } else if (view()->theLockingInset()->
-                          getFirstLockingInsetOfType(InsetOld::TABULAR_CODE)!=0) {
-                   InsetTabular * inset = static_cast<InsetTabular *>(
-                       view()->theLockingInset()->getFirstLockingInsetOfType(InsetOld::TABULAR_CODE));
-                   inset->openLayoutDialog(view());
+       case LFUN_LAYOUT_TABULAR: {
+               UpdatableInset * tli = view()->theLockingInset();
+               if (tli) {
+                       if (tli->lyxCode() == InsetOld::TABULAR_CODE) {
+                               static_cast<InsetTabular *>(tli)->openLayoutDialog(view());
+                       } else if (tli->getFirstLockingInsetOfType(InsetOld::TABULAR_CODE)) {
+                               static_cast<InsetTabular *>(
+                                       tli->getFirstLockingInsetOfType(InsetOld::TABULAR_CODE))
+                                               ->openLayoutDialog(view());
+                       }
                }
-           }
-           break;
+               break;
+       }
 
        case LFUN_DROP_LAYOUTS_CHOICE:
                owner->getToolbar().openLayoutList();
@@ -1346,26 +1359,29 @@ void LyXFunc::dispatch(FuncRequest const & func, bool verbose)
                break;
 
        case LFUN_NOTIFY:
-       {
                dispatch_buffer = keyseq.print();
                lyxserver->notifyClient(dispatch_buffer);
-       }
-       break;
+               break;
 
-       case LFUN_GOTOFILEROW:
-       {
+       case LFUN_GOTOFILEROW: {
                string file_name;
                int row;
-               istringstream istr(argument.c_str());
-               istr >> file_name >> row;
-               // Must replace extension of the file to be .lyx and get full path
-               string const s(ChangeExtension(file_name, ".lyx"));
-
-               // Either change buffer or load the file
-               if (bufferlist.exists(s)) {
-                       view()->buffer(bufferlist.getBuffer(s));
+               istringstream is(argument);
+               is >> file_name >> row;
+               if (prefixIs(file_name, getTmpDir())) {
+                       // Needed by inverse dvi search. If it is a file
+                       // in tmpdir, call the apropriated function
+                       view()->buffer(bufferlist.getBufferFromTmp(file_name));
                } else {
-                       view()->loadLyXFile(s);
+                       // Must replace extension of the file to be .lyx
+                       // and get full path
+                       string const s = ChangeExtension(file_name, ".lyx");
+                       // Either change buffer or load the file
+                       if (bufferlist.exists(s)) {
+                               view()->buffer(bufferlist.getBuffer(s));
+                       } else {
+                               view()->loadLyXFile(s);
+                       }
                }
 
                view()->setCursorFromRow(row);
@@ -1373,15 +1389,13 @@ void LyXFunc::dispatch(FuncRequest const & func, bool verbose)
                view()->center();
                // see BufferView_pimpl::center()
                view()->updateScrollbar();
+               break;
        }
-       break;
-
-       case LFUN_GOTO_PARAGRAPH:
-       {
-               istringstream istr(argument.c_str());
 
+       case LFUN_GOTO_PARAGRAPH: {
+               istringstream is(argument);
                int id;
-               istr >> id;
+               is >> id;
                ParIterator par = owner->buffer()->getParFromID(id);
                if (par == owner->buffer()->par_iterator_end()) {
                        lyxerr[Debug::INFO] << "No matching paragraph found! ["
@@ -1394,12 +1408,16 @@ void LyXFunc::dispatch(FuncRequest const & func, bool verbose)
 
                if (view()->theLockingInset())
                        view()->unlockInset(view()->theLockingInset());
+
+               LyXText * lt = view()->getLyXText();
                if (par->inInset()) {
                        FuncRequest cmd(view(), LFUN_INSET_EDIT, "left");
-                       par->inInset()->localDispatch(cmd);
+                       par.inset()->dispatch(cmd);
+                       lt = par->inInset()->getLyXText(view());
                }
+
                // Set the cursor
-               view()->getLyXText()->setCursor(par.pit(), 0);
+               lt->setCursor(par.pit(), 0);
                view()->switchKeyMap();
                owner->view_state_changed();
 
@@ -1416,15 +1434,14 @@ void LyXFunc::dispatch(FuncRequest const & func, bool verbose)
        case LFUN_MATH_NUMBER:
        case LFUN_MATH_NONUMBER:
        case LFUN_MATH_LIMITS:
-       {
                setErrorMessage(N_("This is only allowed in math mode!"));
-       }
-       break;
+               break;
 
        // passthrough hat and underscore outside mathed:
        case LFUN_SUBSCRIPT:
                dispatch(FuncRequest(view(), LFUN_SELFINSERT, "_"));
                break;
+
        case LFUN_SUPERSCRIPT:
                dispatch(FuncRequest(view(), LFUN_SELFINSERT, "^"));
                break;
@@ -1473,22 +1490,18 @@ void LyXFunc::dispatch(FuncRequest const & func, bool verbose)
                        data = InsetCommandMailer::params2string(name, p);
                }
                owner->getDialogs().show(name, data, 0);
+               break;
        }
-       break;
 
-       case LFUN_DIALOG_SHOW_NEXT_INSET: {
-       }
-       break;
+       case LFUN_DIALOG_SHOW_NEXT_INSET:
+               break;
 
        case LFUN_INSET_DIALOG_SHOW: {
-               LyXText * lt = view()->getLyXText();
-               InsetOld * inset = lt->getInset();
-               if (inset) {
-                       FuncRequest cmd(view(), LFUN_INSET_DIALOG_SHOW);
-                       inset->localDispatch(cmd);
-               }
+               InsetOld * inset = view()->getLyXText()->getInset();
+               if (inset)
+                       inset->dispatch(FuncRequest(view(), LFUN_INSET_DIALOG_SHOW));
+               break;
        }
-       break;
 
        case LFUN_DIALOG_UPDATE: {
                string const & name = argument;
@@ -1497,12 +1510,12 @@ void LyXFunc::dispatch(FuncRequest const & func, bool verbose)
                if (inset) {
                        FuncRequest fr(view(), LFUN_INSET_DIALOG_UPDATE,
                                       func.argument);
-                       inset->localDispatch(fr);
+                       inset->dispatch(fr);
                } else if (name == "paragraph") {
                        dispatch(FuncRequest(LFUN_PARAGRAPH_UPDATE));
                }
+               break;
        }
-       break;
 
        case LFUN_DIALOG_HIDE:
                Dialogs::hide(argument, 0);
@@ -1512,11 +1525,9 @@ void LyXFunc::dispatch(FuncRequest const & func, bool verbose)
                owner->getDialogs().disconnect(argument);
                break;
 
-       case LFUN_CHILDOPEN:
-       {
+       case LFUN_CHILDOPEN: {
                string const filename =
-                       MakeAbsPath(argument,
-                                   owner->buffer()->filePath());
+                       MakeAbsPath(argument, owner->buffer()->filePath());
                setMessage(N_("Opening child document ") +
                           MakeDisplayPath(filename) + "...");
                view()->savePosition(0);
@@ -1524,8 +1535,8 @@ void LyXFunc::dispatch(FuncRequest const & func, bool verbose)
                        view()->buffer(bufferlist.getBuffer(filename));
                else
                        view()->loadLyXFile(filename);
+               break;
        }
-       break;
 
        case LFUN_TOGGLECURSORFOLLOW:
                lyxrc.cursor_follows_scrollbar = !lyxrc.cursor_follows_scrollbar;
@@ -1547,50 +1558,51 @@ void LyXFunc::dispatch(FuncRequest const & func, bool verbose)
                owner->getIntl().ToggleKeyMap();
                break;
 
+       case LFUN_REPEAT: {
+               // repeat command
+               string countstr;
+               argument = split(argument, countstr, ' ');
+               istringstream is(countstr);
+               int count = 0;
+               is >> count;
+               lyxerr << "repeat: count: " << count << " cmd: " << argument << endl;
+               for (int i = 0; i < count; ++i)
+                       dispatch(lyxaction.lookupFunc(argument));
+               break;
+       }
+
        case LFUN_SEQUENCE:
-       {
                // argument contains ';'-terminated commands
                while (!argument.empty()) {
                        string first;
                        argument = split(argument, first, ';');
-                       dispatch(first);
+                       dispatch(lyxaction.lookupFunc(first));
                }
-       }
-       break;
+               break;
 
-       case LFUN_SAVEPREFERENCES:
-       {
+       case LFUN_SAVEPREFERENCES: {
                Path p(user_lyxdir());
                lyxrc.write("preferences");
+               break;
        }
-       break;
 
        case LFUN_SCREEN_FONT_UPDATE:
-       {
                // handle the screen font changes.
                lyxrc.set_font_norm_type();
                lyx_gui::update_fonts();
-               // We also need to empty the textcache so that
-               // the buffer will be formatted correctly after
-               // a zoom change.
-               textcache.clear();
-               // Of course we should only do the resize and the textcache.clear
-               // if values really changed...but not very important right now. (Lgb)
                // All visible buffers will need resize
                view()->resize();
                view()->update();
-       }
-       break;
+               break;
 
-       case LFUN_SET_COLOR:
-       {
+       case LFUN_SET_COLOR: {
                string lyx_name;
                string const x11_name = split(argument, lyx_name, ' ');
                if (lyx_name.empty() || x11_name.empty()) {
                        setErrorMessage(N_("Syntax: set-color <lyx_name>"
                                                " <x11_name>"));
                        break;
-                       }
+               }
 
                bool const graphicsbg_changed =
                        (lyx_name == lcolor.getLyXName(LColor::graphicsbg) &&
@@ -1611,9 +1623,7 @@ void LyXFunc::dispatch(FuncRequest const & func, bool verbose)
 #warning FIXME!! The graphics cache no longer has a changeDisplay method.
 #endif
 #if 0
-                       lyx::graphics::GCache & gc =
-                               lyx::graphics::GCache::get();
-                       gc.changeDisplay(true);
+                       lyx::graphics::GCache::get().changeDisplay(true);
 #endif
                }
 
@@ -1626,25 +1636,20 @@ void LyXFunc::dispatch(FuncRequest const & func, bool verbose)
                break;
 
        case LFUN_FORKS_KILL:
-       {
-               if (!isStrInt(argument))
-                       break;
-
-               pid_t const pid = strToInt(argument);
-               ForkedcallsController & fcc = ForkedcallsController::get();
-               fcc.kill(pid);
+               if (isStrInt(argument)) {
+                       pid_t const pid = strToInt(argument);
+                       ForkedcallsController & fcc = ForkedcallsController::get();
+                       fcc.kill(pid);
+               }
                break;
-       }
 
        case LFUN_TOOLTIPS_TOGGLE:
                owner->getDialogs().toggleTooltips();
                break;
 
-       case LFUN_EXTERNAL_EDIT: {
-               InsetExternal()
-                       .localDispatch(FuncRequest(view(), action, argument));
+       case LFUN_EXTERNAL_EDIT:
+               InsetExternal().dispatch(FuncRequest(view(), action, argument));
                break;
-       }
 
        default:
                // Then if it was none of the above