X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Flyxfunc.C;h=b74ad0e369fee3580d5d2dcd0d38b8762fa5a2a8;hb=5d3718cad2a2ef6a4d6a495054ab0705ba27b6b5;hp=a7e0443845b04c4b02753a4a17427ffdc210e1d7;hpb=dcebc194f4b80b17b7fba5166e53f9dee889611e;p=lyx.git diff --git a/src/lyxfunc.C b/src/lyxfunc.C index a7e0443845..b74ad0e369 100644 --- a/src/lyxfunc.C +++ b/src/lyxfunc.C @@ -1,8 +1,8 @@ /* This file is part of - * ====================================================== - * + * ====================================================== + * * LyX, The Document Processor - * + * * Copyright 1995 Matthias Ettrich * Copyright 1995-2001 The LyX Team. * @@ -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 "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 "frontends/LyXView.h" +#include "frontends/lyx_gui.h" #include "vspace.h" -#include "LyXView.h" #include "FloatList.h" #include "converter.h" #include "exporter.h" #include "importer.h" -#include "FontLoader.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,17 +66,18 @@ #include "support/path.h" #include "support/lyxfunctional.h" +#include "BoostFormat.h" + #include #include #include #include -#include -#include - +#include +#include using std::pair; -using std::make_pair; +using std::make_pair; using std::endl; using std::find_if; using std::vector; @@ -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 = 0; - lyx_dead_action = LFUN_NOACTION; - lyx_calling_dead_action = LFUN_NOACTION; } @@ -175,116 +110,94 @@ 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(); - } - owner->view()->update(TEXT(flag), BufferView::SELECT|BufferView::FITCUR); - owner->view()->showCursor(); - - /* ---> Everytime the cursor is moved, show the current font state. */ - // should this too me moved out of this func? - owner->view()->setState(); + TEXT(flag)->setSelection(view()); + if (TEXT(flag)->isTopLevel()) + view()->toggleToggle(); + } + view()->update(TEXT(flag), BufferView::SELECT|BufferView::FITCUR); + view()->showCursor(); + + 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, unsigned int 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 << "] State is [" - << state << "]" + << 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 - &(ShiftMask|ControlMask - |Mod1Mask)); - if (lyxerr.debugging(Debug::KEY)) { - lyxerr << "action first set to [" << action << "]" << endl; - } - - // When not cancel or meta-fake, do the normal lookup. + int action = cancel_meta_seq.addkey(keysym, state); + 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 = 0. RVDK_PATCH_5. + // Mostly, meta_fake_bit = key_modifier::none. RVDK_PATCH_5. if ((action != LFUN_CANCEL) && (action != LFUN_META_FAKE)) { - if (lyxerr.debugging(Debug::KEY)) { - lyxerr << "meta_fake_bit is [" - << meta_fake_bit << "]" << endl; - } // remove Caps Lock and Mod2 as a modifiers - action = keyseq.addkey(keysym, - (state | meta_fake_bit) - &(ShiftMask|ControlMask - |Mod1Mask)); - if (lyxerr.debugging(Debug::KEY)) { - lyxerr << "action now set to [" - << action << "]" << endl; - } + action = keyseq.addkey(keysym, (state | meta_fake_bit)); + lyxerr[Debug::KEY] << "action now set to [" + << action << ']' << endl; } + // Dont remove this unless you know what you are doing. - meta_fake_bit = 0; - - // can this happen now ? + meta_fake_bit = key_modifier::none; + + // can this happen now ? if (action == LFUN_NOACTION) { action = LFUN_PREFIX; } @@ -292,7 +205,7 @@ void LyXFunc::processKeySym(KeySym keysym, unsigned int state) if (lyxerr.debugging(Debug::KEY)) { lyxerr << "Key [action=" << action << "][" - << keyseq.print() << "]" + << keyseq.print() << ']' << endl; } @@ -304,72 +217,88 @@ void LyXFunc::processKeySym(KeySym keysym, unsigned int state) owner->message(keyseq.print()); } + + // 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 (action == LFUN_UNKNOWN_ACTION) { - // It is unknown, but what if we remove all - // the modifiers? (Lgb) - action = keyseq.addkey(keysym, 0); - - if (lyxerr.debugging(Debug::KEY)) { - lyxerr << "Removing modifiers...\n" - << "Action now set to [" - << action << "]" << endl; - } - 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; - - c = kb_keymap::getiso(c); - - if (c > 0) - argument = static_cast(c); - - dispatch(LFUN_SELFINSERT, argument); - lyxerr[Debug::KEY] << "SelfInsert arg[`" + if (encoded_last_key != 0) { + string arg; + arg += encoded_last_key; + + dispatch(FuncRequest(view(), LFUN_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_UNKNOWN_ACTION) { + + if (ev.action == LFUN_NOACTION) { + setStatusMessage(N_("Nothing to do")); + return flag.disabled(true); + } + + 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, + if (buf->isReadonly() && + !lyxaction.funcHasFlag(ev.action, LyXAction::ReadOnly)) { // no setStatusMessage(N_("Document is read-only")); @@ -383,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) { + bool disable = false; + 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(); @@ -403,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; @@ -418,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 @@ -431,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; @@ -451,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); } @@ -472,104 +455,55 @@ 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(); - disable = !(isEditableInset(lt->getInset()) - || (lt->inset_owner + LyXText * lt = view()->getLyXText(); + disable = !(isEditableInset(lt->getInset()) + || (lt->inset_owner && lt->inset_owner->owner() - && lt->inset_owner->owner()->isOpen())); + && 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 + case LFUN_MATH_MUTATE: + if (mathcursor) + //flag.setOnOff(mathcursor->formula()->hullType() == ev.argument); + flag.setOnOff(false); + else disable = true; break; // we just need to be in math mode to enable that - case LFUN_MATH_SIZE: + case LFUN_MATH_SIZE: case LFUN_MATH_SPACE: - case LFUN_MATH_LIMITS: - case LFUN_MATH_NONUMBER: + 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; + code = Inset::ERT_CODE; break; case LFUN_INSET_GRAPHICS: code = Inset::GRAPHICS_CODE; @@ -577,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: @@ -594,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; @@ -609,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; @@ -625,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: @@ -656,23 +593,26 @@ FuncStatus LyXFunc::getStatus(kb_action action, case LFUN_MENU_SEPARATOR: case LFUN_LDOTS: case LFUN_END_OF_SENTENCE: - case LFUN_PROTECTEDSPACE: code = Inset::SPECIALCHAR_CODE; break; + case LFUN_PROTECTEDSPACE: + // slight hack: we know this is allowed in math mode + if (!mathcursor) + code = Inset::SPECIALCHAR_CODE; + break; 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: @@ -683,10 +623,13 @@ FuncStatus LyXFunc::getStatus(kb_action action, break; 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()) + // the other ones (is that a good idea?) + if (ev.argument == buf->fileName()) flag.setOnOff(true); break; + case LFUN_TRACK_CHANGES: + flag.setOnOff(buf->params.tracking_changes); + break; default: break; } @@ -694,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; @@ -716,141 +659,81 @@ 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); - } -} - - -void LyXFunc::verboseDispatch(int ac, bool show_sc) -{ - string argument; - kb_action action; - - // get the real action and argument - action = lyxaction.retrieveActionArg(ac, argument); +#endif + return; + } - 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; + // we have not done anything wrong yet. + errorstat = false; dispatch_buffer.erase(); #ifdef NEW_DISPATCHER @@ -862,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; @@ -875,89 +761,113 @@ 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 = view()->theLockingInset(); +#if 1 + int inset_x; + int 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=owner->view()->theLockingInset()-> + } else if (((result=inset-> // Hand-over to inset's own dispatch: - localDispatch(owner->view(), action, argument)) == - UpdatableInset::DISPATCHED) || - (result == UpdatableInset::DISPATCHED_NOUPDATE)) + 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.row()->previous()) { - TEXT()->cursorUp(owner->view()); + if (TEXT()->cursor.irow()->previous()) { +#if 1 + TEXT()->setCursorFromCoordinates( + view(), TEXT()->cursor.ix() + inset_x, + TEXT()->cursor.iy() - + TEXT()->cursor.irow()->baseline() - 1); + TEXT()->cursor.x_fix(TEXT()->cursor.x()); +#else + TEXT()->cursorUp(view()); +#endif moveCursorUpdate(true, false); - owner->showState(); + owner->view_state_changed(); + } else { + view()->update(TEXT(), BufferView::SELECT|BufferView::FITCUR); } goto exit_with_message; } else if (result == UpdatableInset::FINISHED_DOWN) { - if (TEXT()->cursor.row()->next()) - TEXT()->cursorDown(owner->view()); - else - TEXT()->cursorRight(owner->view()); + if (TEXT()->cursor.irow()->next()) { +#if 1 + TEXT()->setCursorFromCoordinates( + 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(view()); +#endif + } else { + TEXT()->cursorRight(view()); + } moveCursorUpdate(true, false); - owner->showState(); + owner->view_state_changed(); goto exit_with_message; - } else { + } +#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: - 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: + 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; @@ -970,52 +880,54 @@ 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(); } } break; - + // --- Misc ------------------------------------------- - case LFUN_WORDFINDFORWARD : + case LFUN_WORDFINDFORWARD : case LFUN_WORDFINDBACKWARD : { static string last_search; string searched_string; - + if (!argument.empty()) { last_search = argument; searched_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()); @@ -1024,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 = 0; - if (owner->view()->available()) + meta_fake_bit = key_modifier::none; + if (view()->available()) // cancel any selection dispatch(LFUN_MARK_OFF); setMessage(N_("Cancel")); @@ -1045,10 +950,10 @@ string const LyXFunc::dispatch(kb_action action, string argument) case LFUN_META_FAKE: // RVDK_PATCH_5 { - meta_fake_bit = Mod1Mask; + meta_fake_bit = key_modifier::alt; setMessage(keyseq.print()); } - break; + break; case LFUN_READ_ONLY_TOGGLE: if (owner->buffer()->lyxvc.inUse()) { @@ -1058,66 +963,74 @@ string const LyXFunc::dispatch(kb_action action, string argument) !owner->buffer()->isReadonly()); } 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: closeBuffer(); break; - + 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: reloadBuffer(); break; - + case LFUN_UPDATE: Exporter::Export(owner->buffer(), argument, true); break; - + case LFUN_PREVIEW: Exporter::Preview(owner->buffer(), argument); break; - case LFUN_BUILDPROG: + case LFUN_BUILDPROG: Exporter::Export(owner->buffer(), "program", true); break; - case LFUN_RUNCHKTEX: + case LFUN_RUNCHKTEX: MenuRunChktex(owner->buffer()); 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; @@ -1125,11 +1038,11 @@ string const LyXFunc::dispatch(kb_action action, string argument) case LFUN_IMPORT: doImport(argument); break; - + case LFUN_QUIT: QuitLyX(); break; - + case LFUN_TOCVIEW: #if 0 case LFUN_LOFVIEW: @@ -1151,67 +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: - changeDepth(owner->view(), TEXT(false), 0); - 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 @@ -1219,36 +1125,38 @@ 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: + case LFUN_HELP_OPEN: { string const arg = argument; if (arg.empty()) { 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; - } + } // --- version control ------------------------------- case LFUN_VC_REGISTER: @@ -1257,7 +1165,7 @@ string const LyXFunc::dispatch(kb_action action, string argument) owner->buffer()->lyxvc.registrer(); } break; - + case LFUN_VC_CHECKIN: { if (owner->buffer()->lyxvc.inUse() @@ -1265,7 +1173,7 @@ string const LyXFunc::dispatch(kb_action action, string argument) owner->buffer()->lyxvc.checkIn(); } break; - + case LFUN_VC_CHECKOUT: { if (owner->buffer()->lyxvc.inUse() @@ -1273,92 +1181,91 @@ string const LyXFunc::dispatch(kb_action action, string argument) owner->buffer()->lyxvc.checkOut(); } break; - + case LFUN_VC_REVERT: { owner->buffer()->lyxvc.revert(); } break; - + case LFUN_VC_UNDO: { owner->buffer()->lyxvc.undoLast(); } break; - + case LFUN_VC_HISTORY: { - owner->getDialogs()->showVCLogFile(); + owner->getDialogs().showVCLogFile(); break; } - + // --- buffers ---------------------------------------- - case LFUN_SWITCHBUFFER: - owner->view()->buffer(bufferlist.getBuffer(argument)); + case LFUN_SWITCHBUFFER: + view()->buffer(bufferlist.getBuffer(argument)); break; case LFUN_FILE_NEW: { // servercmd: argument must be :