X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Flyxfunc.C;h=b74ad0e369fee3580d5d2dcd0d38b8762fa5a2a8;hb=5d3718cad2a2ef6a4d6a495054ab0705ba27b6b5;hp=d1c33e2d14a49c4a21bd12c67b6da5a760810157;hpb=97ef9131ba95f605a48d09595bd2ace0f993a55b;p=lyx.git diff --git a/src/lyxfunc.C b/src/lyxfunc.C index d1c33e2d14..b74ad0e369 100644 --- a/src/lyxfunc.C +++ b/src/lyxfunc.C @@ -10,17 +10,12 @@ #include -#ifdef __GNUG__ -#pragma implementation -#endif - #include "lyxfunc.h" #include "version.h" #include "kbmap.h" #include "lyxrow.h" #include "bufferlist.h" #include "BufferView.h" -#include "frontends/xforms/ColorHandler.h" #include "lyxserver.h" #include "intl.h" #include "lyx_main.h" @@ -32,44 +27,23 @@ #include "gettext.h" #include "Lsstream.h" #include "trans_mgr.h" +#include "encoding.h" #include "layout.h" #include "bufferview_funcs.h" -#include "minibuffer.h" -#include "vspace.h" #include "frontends/LyXView.h" +#include "frontends/lyx_gui.h" +#include "vspace.h" #include "FloatList.h" #include "converter.h" #include "exporter.h" #include "importer.h" -#include "frontends/font_loader.h" #include "TextCache.h" #include "lyxfind.h" #include "undo_funcs.h" #include "ParagraphParameters.h" -#include "insets/inseturl.h" -#include "insets/insetlatexaccent.h" -#include "insets/insettoc.h" -#include "insets/insetref.h" -#include "insets/insetparent.h" -#include "insets/insetindex.h" -#include "insets/insetinclude.h" -#include "insets/insetbib.h" -#include "insets/insetcite.h" -#include "insets/insettext.h" -#include "insets/insetert.h" -#include "insets/insetexternal.h" -#include "insets/insetgraphics.h" -#include "insets/insetfoot.h" -#include "insets/insetmarginal.h" -#include "insets/insetminipage.h" -#include "insets/insetfloat.h" -#if 0 -#include "insets/insetlist.h" -#include "insets/insettheorem.h" -#endif +#include "insets/insetcommand.h" #include "insets/insettabular.h" -#include "insets/insetcaption.h" #include "mathed/formulamacro.h" #include "mathed/math_cursor.h" @@ -92,6 +66,8 @@ #include "support/path.h" #include "support/lyxfunctional.h" +#include "BoostFormat.h" + #include #include #include @@ -100,7 +76,6 @@ #include #include - using std::pair; using std::make_pair; using std::endl; @@ -115,59 +90,19 @@ extern bool selection_possible; extern boost::scoped_ptr toplevel_keymap; -extern void show_symbols_form(LyXFunc *); - -extern LyXAction lyxaction; // (alkis) extern tex_accent_struct get_accent(kb_action action); extern void ShowLatexLog(); -#if 0 - -/// -class MiniBufferController : public SigC::Object { -public: - /// - MiniBufferController() { - minibuffer - .cmdReady - .connect(slot(this, - &MiniBufferController::receiveCommand)); - minibuffer - .argReady - .connect(slot(this, - &MiniBufferController::receiveArg)); - } - /// - void receiveCmd(string const & cmd) {} - /// - void receiveArg(string const & arg) {} - - -private: -}; - -namespace { - -MiniBufferController mb_ctrl; - -} -#endif - - -/* === globals =========================================================== */ - - LyXFunc::LyXFunc(LyXView * o) : owner(o), + encoded_last_key(0), keyseq(toplevel_keymap.get(), toplevel_keymap.get()), - cancel_meta_seq(toplevel_keymap.get(), toplevel_keymap.get()) + cancel_meta_seq(toplevel_keymap.get(), toplevel_keymap.get()), + meta_fake_bit(key_modifier::none) { - meta_fake_bit = key_modifier::none; - lyx_dead_action = LFUN_NOACTION; - lyx_calling_dead_action = LFUN_NOACTION; } @@ -175,108 +110,90 @@ inline LyXText * LyXFunc::TEXT(bool flag = true) const { if (flag) - return owner->view()->text; - return owner->view()->getLyXText(); + return view()->text; + return view()->getLyXText(); } -// I changed this func slightly. I commented out the ...FinishUndo(), -// this means that all places that used to have a moveCursorUpdate, now -// have a ...FinishUndo() as the preceeding statement. I have also added -// a moveCursorUpdate to some of the functions that updated the cursor, but -// that did not show its new position. inline void LyXFunc::moveCursorUpdate(bool flag, bool selecting) { if (selecting || TEXT(flag)->selection.mark()) { - TEXT(flag)->setSelection(owner->view()); - if (TEXT(flag)->bv_owner) - owner->view()->toggleToggle(); + TEXT(flag)->setSelection(view()); + if (TEXT(flag)->isTopLevel()) + view()->toggleToggle(); } - owner->view()->update(TEXT(flag), BufferView::SELECT|BufferView::FITCUR); - owner->view()->showCursor(); + view()->update(TEXT(flag), BufferView::SELECT|BufferView::FITCUR); + view()->showCursor(); - /* ---> Everytime the cursor is moved, show the current font state. */ - // should this too me moved out of this func? - owner->view()->setState(); + view()->switchKeyMap(); } void LyXFunc::handleKeyFunc(kb_action action) { - char c = keyseq.getiso(); + char c = encoded_last_key; - if (keyseq.length() > 1) { + if (keyseq.length()) { c = 0; } - owner->getIntl()->getTrans() + owner->getIntl().getTransManager() .deadkey(c, get_accent(action).accent, TEXT(false)); // Need to clear, in case the minibuffer calls these // actions keyseq.clear(); // copied verbatim from do_accent_char - owner->view()->update(TEXT(false), + view()->update(TEXT(false), BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE); TEXT(false)->selection.cursor = TEXT(false)->cursor; } -void LyXFunc::processKeySym(KeySym keysym, key_modifier::state state) +void LyXFunc::processKeySym(LyXKeySymPtr keysym, + key_modifier::state state) { string argument; if (lyxerr.debugging(Debug::KEY)) { - char const * tmp = XKeysymToString(keysym); - string const stm = (tmp ? tmp : ""); lyxerr << "KeySym is " - << stm - << "[" - << keysym + << keysym->getSymbolName() << endl; } + // Do nothing if we have nothing (JMarc) - if (keysym == NoSymbol) { + if (!keysym->isOK()) { lyxerr[Debug::KEY] << "Empty kbd action (probably composing)" << endl; return; } - // Can we be sure that this will work for all X Window - // implementations? (Lgb) - // This code snippet makes lyx ignore some keys. Perhaps - // all of them should be explictly mentioned? - if ((keysym >= XK_Shift_L && keysym <= XK_Hyper_R) - || keysym == XK_Mode_switch || keysym == 0x0) { + if (keysym->isModifier()) { + lyxerr[Debug::KEY] << "isModifier true" << endl; return; } + Encoding const * encoding = view()->getEncoding(); + + encoded_last_key = keysym->getISOEncoded(encoding ? encoding->Name() : ""); + // Do a one-deep top-level lookup for // cancel and meta-fake keys. RVDK_PATCH_5 cancel_meta_seq.reset(); int action = cancel_meta_seq.addkey(keysym, state); - if (lyxerr.debugging(Debug::KEY)) { - lyxerr << "action first set to [" << action << "]" << endl; - } + lyxerr[Debug::KEY] << "action first set to [" << action << ']' << endl; // When not cancel or meta-fake, do the normal lookup. // Note how the meta_fake Mod1 bit is OR-ed in and reset afterwards. // Mostly, meta_fake_bit = key_modifier::none. RVDK_PATCH_5. if ((action != LFUN_CANCEL) && (action != LFUN_META_FAKE)) { -#if 0 - if (lyxerr.debugging(Debug::KEY)) { - lyxerr << "meta_fake_bit is [" - << meta_fake_bit << "]" << endl; - } -#endif // remove Caps Lock and Mod2 as a modifiers action = keyseq.addkey(keysym, (state | meta_fake_bit)); - if (lyxerr.debugging(Debug::KEY)) { - lyxerr << "action now set to [" - << action << "]" << endl; - } + lyxerr[Debug::KEY] << "action now set to [" + << action << ']' << endl; } + // Dont remove this unless you know what you are doing. meta_fake_bit = key_modifier::none; @@ -288,7 +205,7 @@ void LyXFunc::processKeySym(KeySym keysym, key_modifier::state state) if (lyxerr.debugging(Debug::KEY)) { lyxerr << "Key [action=" << action << "][" - << keyseq.print() << "]" + << keyseq.print() << ']' << endl; } @@ -300,77 +217,88 @@ void LyXFunc::processKeySym(KeySym keysym, key_modifier::state state) owner->message(keyseq.print()); } - if (action == LFUN_UNKNOWN_ACTION) { - // It is unknown, but what if we remove all - // the modifiers? (Lgb) + + // Maybe user can only reach the key via holding down shift. + // Let's see. But only if shift is the only modifier + if (action == LFUN_UNKNOWN_ACTION && state == key_modifier::shift) { + lyxerr[Debug::KEY] << "Trying without shift" << endl; action = keyseq.addkey(keysym, key_modifier::none); + lyxerr[Debug::KEY] << "Action now " << action << endl; + } - if (lyxerr.debugging(Debug::KEY)) { - lyxerr << "Removing modifiers...\n" - << "Action now set to [" - << action << "]" << endl; - } - if (action == LFUN_UNKNOWN_ACTION) { + if (action == LFUN_UNKNOWN_ACTION) { + // Hmm, we didn't match any of the keysequences. See + // if it's normal insertable text not already covered + // by a binding + if (keysym->isText() && keyseq.length() == 1) { + lyxerr[Debug::KEY] << "isText() is true, inserting." << endl; + action = LFUN_SELFINSERT; + } else { + lyxerr[Debug::KEY] << "Unknown, !isText() - giving up" << endl; owner->message(_("Unknown function.")); return; } } if (action == LFUN_SELFINSERT) { - // This is very X dependent. - unsigned int c = keysym; - string argument; + if (encoded_last_key != 0) { + string arg; + arg += encoded_last_key; - c = kb_keymap::getiso(c); + dispatch(FuncRequest(view(), LFUN_SELFINSERT, arg)); - if (c > 0) - argument = static_cast(c); - - dispatch(LFUN_SELFINSERT, argument); - lyxerr[Debug::KEY] << "SelfInsert arg[`" + lyxerr[Debug::KEY] << "SelfInsert arg[`" << argument << "']" << endl; + } + } else { + dispatch(action); } - else - verboseDispatch(action, false); } FuncStatus LyXFunc::getStatus(int ac) const { - kb_action action; - string argument; - action = lyxaction.retrieveActionArg(ac, argument); - return getStatus(action, argument); + return getStatus(lyxaction.retrieveActionArg(ac)); } -FuncStatus LyXFunc::getStatus(kb_action action, - string const & argument) const +FuncStatus LyXFunc::getStatus(FuncRequest const & ev) const { FuncStatus flag; Buffer * buf = owner->buffer(); - if (action == LFUN_NOACTION) { + if (ev.action == LFUN_NOACTION) { setStatusMessage(N_("Nothing to do")); return flag.disabled(true); } - if (action == LFUN_UNKNOWN_ACTION) { + switch (ev.action) { + case LFUN_UNKNOWN_ACTION: +#ifndef HAVE_LIBAIKSAURUS + case LFUN_THESAURUS_ENTRY: +#endif + flag.unknown(true); + break; + default: + flag |= lyx_gui::getStatus(ev); + } + + if (flag.unknown()) { setStatusMessage(N_("Unknown action")); - return flag.unknown(true); + return flag; } // the default error message if we disable the command setStatusMessage(N_("Command disabled")); // Check whether we need a buffer - if (!lyxaction.funcHasFlag(action, LyXAction::NoBuffer)) { + if (!lyxaction.funcHasFlag(ev.action, LyXAction::NoBuffer)) { // Yes we need a buffer, do we have one? if (buf) { // yes // Can we use a readonly buffer? if (buf->isReadonly() && - !lyxaction.funcHasFlag(action, + !lyxaction.funcHasFlag(ev.action, LyXAction::ReadOnly)) { // no setStatusMessage(N_("Document is read-only")); @@ -384,19 +312,19 @@ FuncStatus LyXFunc::getStatus(kb_action action, } } - UpdatableInset * tli = owner->view()->theLockingInset(); + UpdatableInset * tli = view()->theLockingInset(); // I would really like to avoid having this switch and rather try to // encode this in the function itself. bool disable = false; - switch (action) { + switch (ev.action) { case LFUN_MENUPRINT: disable = !Exporter::IsExportable(buf, "dvi") || lyxrc.print_command == "none"; break; case LFUN_EXPORT: - disable = argument == "fax" && - !Exporter::IsExportable(buf, argument); + disable = ev.argument != "custom" + && !Exporter::IsExportable(buf, ev.argument); break; case LFUN_UNDO: disable = buf->undostack.empty(); @@ -404,14 +332,20 @@ FuncStatus LyXFunc::getStatus(kb_action action, case LFUN_REDO: disable = buf->redostack.empty(); break; - case LFUN_SPELLCHECK: - disable = lyxrc.isp_command == "none"; - break; -#ifndef HAVE_LIBAIKSAURUS - case LFUN_THESAURUS_ENTRY: - disable = true; + case LFUN_CUT: + case LFUN_COPY: + if (tli) { + UpdatableInset * in = tli; + if (in->lyxCode() != Inset::TABULAR_CODE) { + in = tli->getFirstLockingInsetOfType(Inset::TABULAR_CODE); + } + if (in && static_cast(in)->hasSelection()) { + disable = false; + break; + } + } + disable = !mathcursor && !view()->getLyXText()->selection.set(); break; -#endif case LFUN_RUNCHKTEX: disable = lyxrc.chktex_command == "none"; break; @@ -419,6 +353,10 @@ FuncStatus LyXFunc::getStatus(kb_action action, disable = !Exporter::IsExportable(buf, "program"); break; + case LFUN_LAYOUT_CHARACTER: + disable = tli && tli->lyxCode() == Inset::ERT_CODE; + break; + case LFUN_LAYOUT_TABULAR: disable = !tli || (tli->lyxCode() != Inset::TABULAR_CODE @@ -432,18 +370,62 @@ FuncStatus LyXFunc::getStatus(kb_action action, break; } + case LFUN_INSET_OPTARG: + disable = (TEXT(false)->cursor.par()->layout()->optionalargs == 0); + break; + case LFUN_TABULAR_FEATURE: - disable = true; + if (mathcursor) { +#if 0 + // FIXME: check temporarily disabled + // valign code + char align = mathcursor->valign(); + if (align == '\0') { + disable = true; + break; + } + if (ev.argument.empty()) { + flag.clear(); + break; + } + if (!contains("tcb", ev.argument[0])) { + disable = true; + break; + } + flag.setOnOff(ev.argument[0] == align); + } else + disable = true; + + char align = mathcursor->halign(); + if (align == '\0') { + disable = true; + break; + } + if (ev.argument.empty()) { + flag.clear(); + break; + } + if (!contains("lcr", ev.argument[0])) { + disable = true; + break; + } + flag.setOnOff(ev.argument[0] == align); +#endif + + disable = !mathcursor->halign(); + break; + } + if (tli) { FuncStatus ret; //ret.disabled(true); if (tli->lyxCode() == Inset::TABULAR_CODE) { ret = static_cast(tli) - ->getStatus(argument); + ->getStatus(ev.argument); } else if (tli->getFirstLockingInsetOfType(Inset::TABULAR_CODE)) { ret = static_cast (tli->getFirstLockingInsetOfType(Inset::TABULAR_CODE)) - ->getStatus(argument); + ->getStatus(ev.argument); } flag |= ret; disable = false; @@ -452,7 +434,7 @@ FuncStatus LyXFunc::getStatus(kb_action action, FuncStatus ret; disable = true; - ret = inset.getStatus(argument); + ret = inset.getStatus(ev.argument); if (ret.onoff(true) || ret.onoff(false)) flag.setOnOff(false); } @@ -473,74 +455,33 @@ FuncStatus LyXFunc::getStatus(kb_action action, disable = !buf->lyxvc.inUse(); break; case LFUN_BOOKMARK_GOTO: - disable = !owner->view()-> - isSavedPosition(strToUnsignedInt(argument)); + disable = !view()-> + isSavedPosition(strToUnsignedInt(ev.argument)); + break; + case LFUN_MERGE_CHANGES: + case LFUN_ACCEPT_CHANGE: + case LFUN_REJECT_CHANGE: + case LFUN_ACCEPT_ALL_CHANGES: + case LFUN_REJECT_ALL_CHANGES: + disable = !buf->params.tracking_changes; break; - - case LFUN_INSET_TOGGLE: { - LyXText * lt = owner->view()->getLyXText(); + LyXText * lt = view()->getLyXText(); disable = !(isEditableInset(lt->getInset()) || (lt->inset_owner && lt->inset_owner->owner() && lt->inset_owner->owner()->isOpen())); break; } - case LFUN_MATH_VALIGN: - if (mathcursor) { - char align = mathcursor->valign(); - if (align == '\0') { - disable = true; - break; - } - if (argument.empty()) { - flag.clear(); - break; - } - if (!contains("tcb", argument[0])) { - disable = true; - break; - } - flag.setOnOff(argument[0] == align); - } else - disable = true; - break; - - case LFUN_MATH_HALIGN: - if (mathcursor) { - char align = mathcursor->halign(); - if (align == '\0') { - disable = true; - break; - } - if (argument.empty()) { - flag.clear(); - break; - } - if (!contains("lcr", argument[0])) { - disable = true; - break; - } - flag.setOnOff(argument[0] == align); - } else - disable = true; + case LFUN_LATEX_LOG: + disable = !IsFileReadable(buf->getLogName().second); break; case LFUN_MATH_MUTATE: - if (tli && (tli->lyxCode() == Inset::MATH_CODE)) { - MathInsetTypes type = mathcursor->formula()->getType(); - if (argument == "inline") { - flag.setOnOff(type == LM_OT_SIMPLE); - } else if (argument == "display") { - flag.setOnOff(type == LM_OT_EQUATION); - } else if (argument == "eqnarray") { - flag.setOnOff(type == LM_OT_EQNARRAY); - } else if (argument == "align") { - flag.setOnOff(type == LM_OT_ALIGN); - } else { - disable = true; - } - } else + if (mathcursor) + //flag.setOnOff(mathcursor->formula()->hullType() == ev.argument); + flag.setOnOff(false); + else disable = true; break; @@ -550,25 +491,17 @@ FuncStatus LyXFunc::getStatus(kb_action action, case LFUN_MATH_LIMITS: case LFUN_MATH_NONUMBER: case LFUN_MATH_NUMBER: + case LFUN_MATH_EXTERN: disable = !mathcursor; break; - // we need to be math mode and a math array for that - // Hack: halign produces non-zero result iff we are in a math array - case LFUN_MATH_ROW_INSERT: - case LFUN_MATH_ROW_DELETE: - case LFUN_MATH_COLUMN_INSERT: - case LFUN_MATH_COLUMN_DELETE: - disable = !mathcursor || !mathcursor->halign(); - break; - default: break; } // the functions which insert insets Inset::Code code = Inset::NO_CODE; - switch (action) { + switch (ev.action) { case LFUN_INSET_ERT: code = Inset::ERT_CODE; break; @@ -578,8 +511,7 @@ FuncStatus LyXFunc::getStatus(kb_action action, case LFUN_INSET_FOOTNOTE: code = Inset::FOOT_CODE; break; - case LFUN_DIALOG_TABULAR_INSERT: - case LFUN_INSET_TABULAR: + case LFUN_TABULAR_INSERT: code = Inset::TABULAR_CODE; break; case LFUN_INSET_EXTERNAL: @@ -595,6 +527,9 @@ FuncStatus LyXFunc::getStatus(kb_action action, case LFUN_INSET_WIDE_FLOAT: code = Inset::FLOAT_CODE; break; + case LFUN_INSET_WRAP: + code = Inset::WRAP_CODE; + break; case LFUN_FLOAT_LIST: code = Inset::FLOAT_LIST_CODE; break; @@ -610,11 +545,14 @@ FuncStatus LyXFunc::getStatus(kb_action action, code = Inset::CAPTION_CODE; break; case LFUN_INSERT_NOTE: - code = Inset::IGNORE_CODE; + code = Inset::NOTE_CODE; break; case LFUN_INSERT_LABEL: code = Inset::LABEL_CODE; break; + case LFUN_INSET_OPTARG: + code = Inset::OPTARG_CODE; + break; case LFUN_REF_INSERT: code = Inset::REF_CODE; break; @@ -626,8 +564,6 @@ FuncStatus LyXFunc::getStatus(kb_action action, code = Inset::BIBTEX_CODE; break; case LFUN_INDEX_INSERT: - case LFUN_INDEX_INSERT_LAST: - case LFUN_INDEX_CREATE: code = Inset::INDEX_CODE; break; case LFUN_INDEX_PRINT: @@ -667,17 +603,16 @@ FuncStatus LyXFunc::getStatus(kb_action action, default: break; } - if (code != Inset::NO_CODE && tli && !tli->insetAllowed(code)) { + if (code != Inset::NO_CODE && tli && !tli->insetAllowed(code)) disable = true; - } if (disable) - flag.disabled(true); + flag.disabled(true); // A few general toggles - switch (action) { + switch (ev.action) { case LFUN_TOOLTIPS_TOGGLE: - flag.setOnOff(owner->getDialogs()->tooltipsEnabled()); + flag.setOnOff(owner->getDialogs().tooltipsEnabled()); break; case LFUN_READ_ONLY_TOGGLE: @@ -689,9 +624,12 @@ FuncStatus LyXFunc::getStatus(kb_action action, case LFUN_SWITCHBUFFER: // toggle on the current buffer, but do not toggle off // the other ones (is that a good idea?) - if (argument == buf->fileName()) + if (ev.argument == buf->fileName()) flag.setOnOff(true); break; + case LFUN_TRACK_CHANGES: + flag.setOnOff(buf->params.tracking_changes); + break; default: break; } @@ -699,7 +637,7 @@ FuncStatus LyXFunc::getStatus(kb_action action, // the font related toggles if (!mathcursor) { LyXFont const & font = TEXT(false)->real_current_font; - switch (action) { + switch (ev.action) { case LFUN_EMPH: flag.setOnOff(font.emph() == LyXFont::ON); break; @@ -721,138 +659,78 @@ FuncStatus LyXFunc::getStatus(kb_action action, default: break; } - } - else { - MathTextCodes tc = mathcursor->getLastCode(); - switch (action) { + } else { + string tc = mathcursor->getLastCode(); + switch (ev.action) { case LFUN_BOLD: - flag.setOnOff(tc == LM_TC_BF); + flag.setOnOff(tc == "mathbf"); break; case LFUN_SANS: - flag.setOnOff(tc == LM_TC_SF); + flag.setOnOff(tc == "mathsf"); break; case LFUN_EMPH: - flag.setOnOff(tc == LM_TC_CAL); + flag.setOnOff(tc == "mathcal"); break; case LFUN_ROMAN: - flag.setOnOff(tc == LM_TC_RM); + flag.setOnOff(tc == "mathrm"); break; case LFUN_CODE: - flag.setOnOff(tc == LM_TC_TT); + flag.setOnOff(tc == "mathtt"); break; case LFUN_NOUN: - flag.setOnOff(tc == LM_TC_BB); + flag.setOnOff(tc == "mathbb"); break; case LFUN_DEFAULT: - flag.setOnOff(tc == LM_TC_VAR); + flag.setOnOff(tc == "mathnormal"); break; default: break; } } - return flag; -} - - -// temporary dispatch method -void LyXFunc::miniDispatch(string const & s) -{ - string s2(frontStrip(strip(s))); - - if (!s2.empty()) { - verboseDispatch(s2, true); + // this one is difficult to get right. As a half-baked + // solution, we consider only the first action of the sequence + if (ev.action == LFUN_SEQUENCE) { + // argument contains ';'-terminated commands + flag = getStatus(lyxaction.LookupFunc(token(ev.argument, ';', 0))); } + + return flag; } -void LyXFunc::verboseDispatch(string const & s, bool show_sc) +void LyXFunc::dispatch(string const & s, bool verbose) { - int action = lyxaction.LookupFunc(frontStrip(s)); + int const action = lyxaction.LookupFunc(s); if (action == LFUN_UNKNOWN_ACTION) { +#if USE_BOOST_FORMAT +boost::format fmt(_("Unknown function (%1$s)")); +fmt % s; +owner->message(fmt.str()); +#else string const msg = string(_("Unknown function (")) - + s + ")"; + + s + ')'; owner->message(msg); - } else { - verboseDispatch(action, show_sc); +#endif + return; } -} - - -void LyXFunc::verboseDispatch(int ac, bool show_sc) -{ - string argument; - kb_action action; - - // get the real action and argument - action = lyxaction.retrieveActionArg(ac, argument); - verboseDispatch(action, argument, show_sc); + dispatch(action, verbose); } - -void LyXFunc::verboseDispatch(kb_action action, - string const & argument, bool show_sc) +void LyXFunc::dispatch(int ac, bool verbose) { - string res = dispatch(action, argument); - - commandshortcut.erase(); - - if (lyxrc.display_shortcuts && show_sc) { - if (action != LFUN_SELFINSERT) { - // Put name of command and list of shortcuts - // for it in minibuffer - string comname = lyxaction.getActionName(action); - - int pseudoaction = action; - bool argsadded = false; - - if (!argument.empty()) { - // the pseudoaction is useful for the bindings - pseudoaction = - lyxaction.searchActionArg(action, - argument); - - if (pseudoaction == LFUN_UNKNOWN_ACTION) { - pseudoaction = action; - } else { - comname += " " + argument; - argsadded = true; - } - } - - string const shortcuts = - toplevel_keymap->findbinding(pseudoaction); - - if (!shortcuts.empty()) { - comname += ": " + shortcuts; - } else if (!argsadded && !argument.empty()) { - comname += " " + argument; - } - - if (!comname.empty()) { - comname = strip(comname); - commandshortcut = "(" + comname + ')'; - } - } - } - - if (res.empty()) { - if (!commandshortcut.empty()) { - owner->getMiniBuffer()->addSet(commandshortcut); - } - } else { - owner->getMiniBuffer()->addSet(' ' + commandshortcut); - } + dispatch(lyxaction.retrieveActionArg(ac), verbose); } -string const LyXFunc::dispatch(kb_action action, string argument) + +void LyXFunc::dispatch(FuncRequest const & ev, bool verbose) { - lyxerr[Debug::ACTION] << "LyXFunc::Dispatch: action[" << action - <<"] arg[" << argument << "]" << endl; + lyxerr[Debug::ACTION] << "LyXFunc::dispatch: action[" << ev.action + <<"] arg[" << ev.argument << ']' << endl; // we have not done anything wrong yet. errorstat = false; @@ -867,12 +745,15 @@ string const LyXFunc::dispatch(kb_action action, string argument) selection_possible = false; - if (owner->view()->available()) - owner->view()->hideCursor(); + if (view()->available()) + view()->hideCursor(); + + string argument = ev.argument; + kb_action action = ev.action; // We cannot use this function here - if (getStatus(action, argument).disabled()) { - lyxerr[Debug::ACTION] << "LyXFunc::Dispatch: " + if (getStatus(ev).disabled()) { + lyxerr[Debug::ACTION] << "LyXFunc::dispatch: " << lyxaction.getActionName(action) << " [" << action << "] is disabled at this location" << endl; @@ -880,83 +761,79 @@ string const LyXFunc::dispatch(kb_action action, string argument) goto exit_with_message; } - if (owner->view()->available() && owner->view()->theLockingInset()) { - UpdatableInset::RESULT result; + if (view()->available() && view()->theLockingInset()) { + Inset::RESULT result; if ((action > 1) || ((action == LFUN_UNKNOWN_ACTION) && (!keyseq.deleted()))) { - UpdatableInset * inset = owner->view()->theLockingInset(); + UpdatableInset * inset = view()->theLockingInset(); #if 1 int inset_x; int dummy_y; - inset->getCursorPos(owner->view(), inset_x, dummy_y); + inset->getCursorPos(view(), inset_x, dummy_y); #endif if ((action == LFUN_UNKNOWN_ACTION) && argument.empty()) { - argument = keyseq.getiso(); + argument = encoded_last_key; } // Undo/Redo is a bit tricky for insets. if (action == LFUN_UNDO) { - owner->view()->menuUndo(); + view()->undo(); goto exit_with_message; } else if (action == LFUN_REDO) { - owner->view()->menuRedo(); + view()->redo(); goto exit_with_message; } else if (((result=inset-> // Hand-over to inset's own dispatch: - localDispatch(owner->view(), action, argument)) == + localDispatch(FuncRequest(view(), action, argument))) == UpdatableInset::DISPATCHED) || (result == UpdatableInset::DISPATCHED_NOUPDATE)) goto exit_with_message; // If UNDISPATCHED, just soldier on else if (result == UpdatableInset::FINISHED) { - if (TEXT()->cursor.par()->isRightToLeftPar(owner->buffer()->params)) { - TEXT()->cursorRight(owner->view()); - moveCursorUpdate(true, false); - owner->showState(); - } - goto exit_with_message; + 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 == UpdatableInset::FINISHED_RIGHT) { - if (!TEXT()->cursor.par()->isRightToLeftPar(owner->buffer()->params)) { - TEXT()->cursorRight(owner->view()); - moveCursorUpdate(true, false); - owner->showState(); - } + TEXT()->cursorRight(view()); + moveCursorUpdate(true, false); + owner->view_state_changed(); goto exit_with_message; } else if (result == UpdatableInset::FINISHED_UP) { if (TEXT()->cursor.irow()->previous()) { #if 1 TEXT()->setCursorFromCoordinates( - owner->view(), TEXT()->cursor.ix() + inset_x, + view(), TEXT()->cursor.ix() + inset_x, TEXT()->cursor.iy() - TEXT()->cursor.irow()->baseline() - 1); TEXT()->cursor.x_fix(TEXT()->cursor.x()); #else - TEXT()->cursorUp(owner->view()); + TEXT()->cursorUp(view()); #endif moveCursorUpdate(true, false); - owner->showState(); + owner->view_state_changed(); } else { - owner->view()->update(TEXT(), BufferView::SELECT|BufferView::FITCUR); + view()->update(TEXT(), BufferView::SELECT|BufferView::FITCUR); } goto exit_with_message; } else if (result == UpdatableInset::FINISHED_DOWN) { if (TEXT()->cursor.irow()->next()) { #if 1 TEXT()->setCursorFromCoordinates( - owner->view(), TEXT()->cursor.ix() + inset_x, + view(), TEXT()->cursor.ix() + inset_x, TEXT()->cursor.iy() - TEXT()->cursor.irow()->baseline() + TEXT()->cursor.irow()->height() + 1); TEXT()->cursor.x_fix(TEXT()->cursor.x()); #else - TEXT()->cursorDown(owner->view()); + TEXT()->cursorDown(view()); #endif } else { - TEXT()->cursorRight(owner->view()); + TEXT()->cursorRight(view()); } moveCursorUpdate(true, false); - owner->showState(); + owner->view_state_changed(); goto exit_with_message; } #warning I am not sure this is still right, please have a look! (Jug 20020417) @@ -966,31 +843,31 @@ string const LyXFunc::dispatch(kb_action action, string argument) case LFUN_UNKNOWN_ACTION: case LFUN_BREAKPARAGRAPH: case LFUN_BREAKLINE: - TEXT()->cursorRight(owner->view()); - owner->view()->setState(); - owner->showState(); + TEXT()->cursorRight(view()); + view()->switchKeyMap(); + owner->view_state_changed(); break; case LFUN_RIGHT: if (!TEXT()->cursor.par()->isRightToLeftPar(owner->buffer()->params)) { - TEXT()->cursorRight(owner->view()); + TEXT()->cursorRight(view()); moveCursorUpdate(true, false); - owner->showState(); + owner->view_state_changed(); } goto exit_with_message; case LFUN_LEFT: if (TEXT()->cursor.par()->isRightToLeftPar(owner->buffer()->params)) { - TEXT()->cursorRight(owner->view()); + TEXT()->cursorRight(view()); moveCursorUpdate(true, false); - owner->showState(); + owner->view_state_changed(); } goto exit_with_message; case LFUN_DOWN: if (TEXT()->cursor.row()->next()) - TEXT()->cursorDown(owner->view()); + TEXT()->cursorDown(view()); else - TEXT()->cursorRight(owner->view()); + TEXT()->cursorRight(view()); moveCursorUpdate(true, false); - owner->showState(); + owner->view_state_changed(); goto exit_with_message; default: break; @@ -1003,26 +880,26 @@ string const LyXFunc::dispatch(kb_action action, string argument) case LFUN_ESCAPE: { - if (!owner->view()->available()) break; + if (!view()->available()) break; // this function should be used always [asierra060396] UpdatableInset * tli = - owner->view()->theLockingInset(); + view()->theLockingInset(); if (tli) { UpdatableInset * lock = tli->getLockingInset(); if (tli == lock) { - owner->view()->unlockInset(tli); - TEXT()->cursorRight(owner->view()); + view()->unlockInset(tli); + TEXT()->cursorRight(view()); moveCursorUpdate(true, false); - owner->showState(); + owner->view_state_changed(); } else { - tli->unlockInsetInInset(owner->view(), + tli->unlockInsetInInset(view(), lock, true); } finishUndo(); // Tell the paragraph dialog that we changed paragraph - owner->getDialogs()->updateParagraph(); + owner->getDialogs().updateParagraph(); } } break; @@ -1039,18 +916,18 @@ string const LyXFunc::dispatch(kb_action action, string argument) } else { searched_string = last_search; } - bool fw = (action == LFUN_WORDFINDBACKWARD); + bool fw = (action == LFUN_WORDFINDFORWARD); if (!searched_string.empty()) { - LyXFind(owner->view(), searched_string, fw); + lyxfind::LyXFind(view(), searched_string, fw); } -// owner->view()->showCursor(); +// view()->showCursor(); } break; case LFUN_PREFIX: { - if (owner->view()->available() && !owner->view()->theLockingInset()) { - owner->view()->update(TEXT(), + if (view()->available() && !view()->theLockingInset()) { + view()->update(TEXT(), BufferView::SELECT|BufferView::FITCUR); } owner->message(keyseq.printOptions()); @@ -1059,20 +936,13 @@ string const LyXFunc::dispatch(kb_action action, string argument) // --- Misc ------------------------------------------- case LFUN_EXEC_COMMAND: - { - vector allCmds; - transform(lyxaction.func_begin(), lyxaction.func_end(), - back_inserter(allCmds), lyx::firster()); - static vector hist; - owner->getMiniBuffer()->getString(MiniBuffer::spaces, - allCmds, hist); - } - break; + owner->focus_command_buffer(); + break; case LFUN_CANCEL: // RVDK_PATCH_5 keyseq.reset(); meta_fake_bit = key_modifier::none; - if (owner->view()->available()) + if (view()->available()) // cancel any selection dispatch(LFUN_MARK_OFF); setMessage(N_("Cancel")); @@ -1095,16 +965,16 @@ string const LyXFunc::dispatch(kb_action action, string argument) break; case LFUN_CENTER: // this is center and redraw. - owner->view()->center(); + view()->center(); break; // --- Menus ----------------------------------------------- case LFUN_MENUNEW: - menuNew(false); + menuNew(argument, false); break; case LFUN_MENUNEWTMPLT: - menuNew(true); + menuNew(argument, true); break; case LFUN_CLOSEBUFFER: @@ -1114,16 +984,24 @@ string const LyXFunc::dispatch(kb_action action, string argument) case LFUN_MENUWRITE: if (!owner->buffer()->isUnnamed()) { ostringstream s1; - s1 << _("Saving document") << ' ' - << MakeDisplayPath(owner->buffer()->fileName() + "..."); - owner->message(s1.str().c_str()); - MenuWrite(owner->view(), owner->buffer()); +#if USE_BOOST_FORMAT + s1 << boost::format(_("Saving document %1$s...")) + % MakeDisplayPath(owner->buffer()->fileName()); +#else + s1 << _("Saving document ") + << MakeDisplayPath(owner->buffer()->fileName()) + << _("..."); +#endif + owner->message(STRCONV(s1.str())); + MenuWrite(view(), owner->buffer()); + s1 << _(" done."); + owner->message(STRCONV(s1.str())); } else - WriteAs(owner->view(), owner->buffer()); + WriteAs(view(), owner->buffer()); break; case LFUN_WRITEAS: - WriteAs(owner->view(), owner->buffer(), argument); + WriteAs(view(), owner->buffer(), argument); break; case LFUN_MENURELOAD: @@ -1147,12 +1025,12 @@ string const LyXFunc::dispatch(kb_action action, string argument) break; case LFUN_MENUPRINT: - owner->getDialogs()->showPrint(); + owner->getDialogs().showPrint(); break; case LFUN_EXPORT: if (argument == "custom") - owner->getDialogs()->showSendto(); + owner->getDialogs().showSendto(); else Exporter::Export(owner->buffer(), argument, false); break; @@ -1186,63 +1064,60 @@ string const LyXFunc::dispatch(kb_action action, string argument) else p.setCmdName("listoftables"); #endif - owner->getDialogs()->createTOC(p.getAsString()); + owner->getDialogs().createTOC(p.getAsString()); break; } - case LFUN_DIALOG_TABULAR_INSERT: - owner->getDialogs()->showTabularCreate(); - break; - case LFUN_AUTOSAVE: - AutoSave(owner->view()); + AutoSave(view()); break; case LFUN_UNDO: - owner->view()->menuUndo(); + view()->undo(); break; case LFUN_REDO: - owner->view()->menuRedo(); + view()->redo(); break; case LFUN_MENUSEARCH: - owner->getDialogs()->showSearch(); + owner->getDialogs().showSearch(); break; case LFUN_REMOVEERRORS: - if (owner->view()->removeAutoInsets()) { - owner->view()->redraw(); - owner->view()->fitCursor(); + if (view()->removeAutoInsets()) { +#warning repaint() or update() or nothing ? + view()->repaint(); + view()->fitCursor(); } break; case LFUN_DEPTH_MIN: - changeDepth(owner->view(), TEXT(false), -1); + changeDepth(view(), TEXT(false), -1); break; case LFUN_DEPTH_PLUS: - changeDepth(owner->view(), TEXT(false), 1); + changeDepth(view(), TEXT(false), 1); break; case LFUN_FREE: - owner->getDialogs()->setUserFreeFont(); + owner->getDialogs().setUserFreeFont(); break; case LFUN_RECONFIGURE: - Reconfigure(owner->view()); + Reconfigure(view()); break; #if 0 case LFUN_FLOATSOPERATE: if (argument == "openfoot") - owner->view()->allFloats(1,0); + view()->allFloats(1,0); else if (argument == "closefoot") - owner->view()->allFloats(0,0); + view()->allFloats(0,0); else if (argument == "openfig") - owner->view()->allFloats(1,1); + view()->allFloats(1,1); else if (argument == "closefig") - owner->view()->allFloats(0,1); + view()->allFloats(0,1); break; #else #ifdef WITH_WARNINGS @@ -1250,11 +1125,11 @@ string const LyXFunc::dispatch(kb_action action, string argument) #endif #endif case LFUN_HELP_ABOUTLYX: - owner->getDialogs()->showAboutlyx(); + owner->getDialogs().showAboutlyx(); break; case LFUN_HELP_TEXINFO: - owner->getDialogs()->showTexinfo(); + owner->getDialogs().showTexinfo(); break; case LFUN_HELP_OPEN: @@ -1264,20 +1139,22 @@ string const LyXFunc::dispatch(kb_action action, string argument) setErrorMessage(N_("Missing argument")); break; } - owner->prohibitInput(); string const fname = i18nLibFileSearch("doc", arg, "lyx"); if (fname.empty()) { lyxerr << "LyX: unable to find documentation file `" << arg << "'. Bad installation?" << endl; - owner->allowInput(); break; } ostringstream str; - str << _("Opening help file") << ' ' - << MakeDisplayPath(fname) << "..."; - owner->message(str.str().c_str()); - owner->view()->buffer(bufferlist.loadLyXFile(fname, false)); - owner->allowInput(); +#if USE_BOOST_FORMAT + str << boost::format(_("Opening help file %1$s...")) + % MakeDisplayPath(fname); +#else + str << _("Opening help file ") + << MakeDisplayPath(fname) << _("..."); +#endif + owner->message(STRCONV(str.str())); + view()->buffer(bufferlist.loadLyXFile(fname, false)); break; } @@ -1319,22 +1196,22 @@ string const LyXFunc::dispatch(kb_action action, string argument) case LFUN_VC_HISTORY: { - owner->getDialogs()->showVCLogFile(); + owner->getDialogs().showVCLogFile(); break; } // --- buffers ---------------------------------------- case LFUN_SWITCHBUFFER: - owner->view()->buffer(bufferlist.getBuffer(argument)); + view()->buffer(bufferlist.getBuffer(argument)); break; case LFUN_FILE_NEW: { // servercmd: argument must be :