X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Flyxfunc.C;h=56a79f8ab69411f947b543d983fbac3ece7bace4;hb=37e82a546392d43f787826b85481a11f2a27af15;hp=fe575daf3cb615146901500da8e2ef63337da889;hpb=eddeb13d2db36b5ef06458a891b14f4c1380beb7;p=lyx.git diff --git a/src/lyxfunc.C b/src/lyxfunc.C index fe575daf3c..56a79f8ab6 100644 --- a/src/lyxfunc.C +++ b/src/lyxfunc.C @@ -76,20 +76,21 @@ #include "frontends/LyXKeySym.h" #include "frontends/LyXView.h" #include "frontends/Menubar.h" -#include "frontends/Toolbar.h" +#include "frontends/Toolbars.h" +#include "support/filefilterlist.h" #include "support/FileInfo.h" #include "support/filetools.h" #include "support/forkedcontr.h" -#include "support/globbing.h" #include "support/lstrings.h" #include "support/path.h" #include "support/path_defines.h" #include "support/systemcall.h" #include "support/tostr.h" -#include "support/std_sstream.h" #include "support/os.h" +#include + using bv_funcs::freefont2string; using lyx::support::AddName; @@ -128,6 +129,8 @@ using std::pair; using std::string; using std::istringstream; +namespace biblio = lyx::biblio; + extern BufferList bufferlist; extern LyXServer * lyxserver; @@ -269,11 +272,21 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const { //lyxerr << "LyXFunc::getStatus: cmd: " << cmd << endl; FuncStatus flag; - Buffer * buf = owner->buffer(); LCursor & cur = view()->cursor(); + /* In LyX/Mac, when a dialog is open, the menus of the + application can still be accessed without giving focus to + the main window. In this case, we want to disable the menu + entries that are buffer-related. + */ + Buffer * buf; + if (cmd.origin == FuncRequest::UI && !owner->hasFocus()) + buf = 0; + else + buf = owner->buffer(); + if (cmd.action == LFUN_NOACTION) { - setStatusMessage(N_("Nothing to do")); + flag.message(N_("Nothing to do")); flag.enabled(false); return flag; } @@ -291,17 +304,19 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const } if (flag.unknown()) { - setStatusMessage(N_("Unknown action")); + flag.message(N_("Unknown action")); return flag; } // the default error message if we disable the command - setStatusMessage(N_("Command disabled")); + flag.message(N_("Command disabled")); + if (!flag.enabled()) + return flag; // Check whether we need a buffer if (!lyxaction.funcHasFlag(cmd.action, LyXAction::NoBuffer) && !buf) { // no, exit directly - setStatusMessage(N_("Command not allowed with" + flag.message(N_("Command not allowed with" "out any document open")); flag.enabled(false); return flag; @@ -328,20 +343,10 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const flag.setOnOff(true); break; - case LFUN_TRACK_CHANGES: - flag.setOnOff(buf->params().tracking_changes); - break; - case LFUN_EXPORT: enable = cmd.argument == "custom" || Exporter::IsExportable(*buf, cmd.argument); break; - case LFUN_UNDO: - enable = !buf->undostack().empty(); - break; - case LFUN_REDO: - enable = !buf->redostack().empty(); - break; case LFUN_CUT: case LFUN_COPY: enable = cur.selection(); @@ -380,17 +385,7 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const case LFUN_MENURELOAD: enable = !buf->isUnnamed() && !buf->isClean(); break; - case LFUN_BOOKMARK_GOTO: - enable = view()->isSavedPosition(strToUnsignedInt(cmd.argument)); - break; - case LFUN_MERGE_CHANGES: - case LFUN_ACCEPT_CHANGE: - case LFUN_REJECT_CHANGE: - case LFUN_ACCEPT_ALL_CHANGES: - case LFUN_REJECT_ALL_CHANGES: - enable = buf && buf->params().tracking_changes; - break; case LFUN_INSET_SETTINGS: { enable = false; @@ -401,27 +396,27 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const if (!inset) break; - InsetOld::Code code = inset->lyxCode(); + InsetBase::Code code = inset->lyxCode(); switch (code) { - case InsetOld::TABULAR_CODE: + case InsetBase::TABULAR_CODE: enable = cmd.argument == "tabular"; break; - case InsetOld::ERT_CODE: + case InsetBase::ERT_CODE: enable = cmd.argument == "ert"; break; - case InsetOld::FLOAT_CODE: + case InsetBase::FLOAT_CODE: enable = cmd.argument == "float"; break; - case InsetOld::WRAP_CODE: + case InsetBase::WRAP_CODE: enable = cmd.argument == "wrap"; break; - case InsetOld::NOTE_CODE: + case InsetBase::NOTE_CODE: enable = cmd.argument == "note"; break; - case InsetOld::BRANCH_CODE: + case InsetBase::BRANCH_CODE: enable = cmd.argument == "branch"; break; - case InsetOld::BOX_CODE: + case InsetBase::BOX_CODE: enable = cmd.argument == "box"; break; default: @@ -436,13 +431,13 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const enable = name == "aboutlyx" || name == "file" || name == "forks" - || name == "preferences" + || name == "prefs" || name == "texinfo"; else if (name == "print") enable = Exporter::IsExportable(*buf, "dvi") && lyxrc.print_command != "none"; else if (name == "character") - enable = cur.inset().lyxCode() != InsetOld::ERT_CODE; + enable = cur.inset().lyxCode() != InsetBase::ERT_CODE; else if (name == "vclog") enable = buf->lyxvc().inUse(); else if (name == "latexlog") @@ -450,6 +445,23 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const break; } + case LFUN_DIALOG_UPDATE: { + string const name = cmd.getArg(0); + if (!buf) + enable = name == "prefs"; + break; + } + + // this one is difficult to get right. As a half-baked + // solution, we consider only the first action of the sequence + case LFUN_SEQUENCE: { + // argument contains ';'-terminated commands + string const firstcmd = token(cmd.argument, ';', 0); + FuncRequest func(lyxaction.lookupFunc(firstcmd)); + func.origin = cmd.origin; + flag = getStatus(func); + } + case LFUN_MENUNEW: case LFUN_MENUNEWTMPLT: case LFUN_WORDFINDFORWARD: @@ -479,7 +491,6 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const case LFUN_GOTO_PARAGRAPH: case LFUN_DIALOG_SHOW_NEW_INSET: case LFUN_DIALOG_SHOW_NEXT_INSET: - case LFUN_DIALOG_UPDATE: case LFUN_DIALOG_HIDE: case LFUN_DIALOG_DISCONNECT_INSET: case LFUN_CHILDOPEN: @@ -491,27 +502,28 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const case LFUN_REPEAT: case LFUN_EXPORT_CUSTOM: case LFUN_PRINT: - case LFUN_SEQUENCE: case LFUN_SAVEPREFERENCES: case LFUN_SCREEN_FONT_UPDATE: case LFUN_SET_COLOR: case LFUN_MESSAGE: case LFUN_EXTERNAL_EDIT: - case LFUN_FILE_INSERT: - case LFUN_FILE_INSERT_ASCII: - case LFUN_FILE_INSERT_ASCII_PARA: + case LFUN_GRAPHICS_EDIT: case LFUN_ALL_INSETS_TOGGLE: case LFUN_LANGUAGE_BUFFER: case LFUN_TEXTCLASS_APPLY: case LFUN_TEXTCLASS_LOAD: case LFUN_SAVE_AS_DEFAULT: case LFUN_BUFFERPARAMS_APPLY: - + case LFUN_LYXRC_APPLY: + case LFUN_NEXTBUFFER: + case LFUN_PREVIOUSBUFFER: // these are handled in our dispatch() break; default: - cur.getStatus(cmd, flag); + + if (!cur.getStatus(cmd, flag)) + flag = view()->getStatus(cmd); } if (!enable) @@ -521,10 +533,11 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const if (buf && buf->isReadonly() && !lyxaction.funcHasFlag(cmd.action, LyXAction::ReadOnly) && !lyxaction.funcHasFlag(cmd.action, LyXAction::NoBuffer)) { - setStatusMessage(N_("Document is read-only")); + flag.message(N_("Document is read-only")); flag.enabled(false); } + //lyxerr << "LyXFunc::getStatus: got: " << flag.enabled() << endl; return flag; } @@ -551,19 +564,44 @@ bool ensureBufferClean(BufferView * bv) return buf.isClean(); } + void showPrintError(string const & name) { - string str = bformat(_("Could not print the document %1$s.\n" - "Check that your printer is set up correctly."), - MakeDisplayPath(name, 50)); - Alert::error(_("Print document failed"), str); + string str = bformat(_("Could not print the document %1$s.\n" + "Check that your printer is set up correctly."), + MakeDisplayPath(name, 50)); + Alert::error(_("Print document failed"), str); +} + + +void loadTextclass(string const & name) +{ + std::pair const tc_pair = + textclasslist.NumberOfClass(name); + + if (!tc_pair.first) { + lyxerr << "Document class \"" << name + << "\" does not exist." + << std::endl; + return; + } + + lyx::textclass_type const tc = tc_pair.second; + + if (!textclasslist[tc].load()) { + string s = bformat(_("The document could not be converted\n" + "into the document class %1$s."), + textclasslist[tc].name()); + Alert::error(_("Could not change class"), s); + } } } //namespace anon -void LyXFunc::dispatch(FuncRequest const & cmd, bool verbose) +void LyXFunc::dispatch(FuncRequest const & cmd) { + BOOST_ASSERT(view()); string const argument = cmd.argument; kb_action const action = cmd.action; @@ -575,14 +613,16 @@ void LyXFunc::dispatch(FuncRequest const & cmd, bool verbose) dispatch_buffer.erase(); selection_possible = false; - // We cannot use this function here - if (!getStatus(cmd).enabled()) { + bool update = true; + + FuncStatus const flag = getStatus(cmd); + if (!flag.enabled()) { + // We cannot use this function here lyxerr[Debug::ACTION] << "LyXFunc::dispatch: " << lyxaction.getActionName(action) << " [" << action << "] is disabled at this location" << endl; - setErrorMessage(getStatusMessage()); - + setErrorMessage(flag.message()); } else { if (view()->available()) @@ -617,6 +657,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd, bool verbose) break; case LFUN_EXEC_COMMAND: + owner->getToolbars().display("minibuffer", true); owner->focus_command_buffer(); break; @@ -931,6 +972,14 @@ void LyXFunc::dispatch(FuncRequest const & cmd, bool verbose) view()->setBuffer(bufferlist.getBuffer(argument)); break; + case LFUN_NEXTBUFFER: + view()->setBuffer(bufferlist.next(view()->buffer())); + break; + + case LFUN_PREVIOUSBUFFER: + view()->setBuffer(bufferlist.previous(view()->buffer())); + break; + case LFUN_FILE_NEW: NewFile(view(), argument); break; @@ -940,7 +989,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd, bool verbose) break; case LFUN_DROP_LAYOUTS_CHOICE: - owner->getToolbar().openLayoutList(); + owner->getToolbars().openLayoutList(); break; case LFUN_MENU_OPEN_BY_NAME: @@ -1024,14 +1073,6 @@ void LyXFunc::dispatch(FuncRequest const & cmd, bool verbose) if (!data.empty()) owner->getDialogs().show("character", data); } - else if (name == "document") - owner->getDialogs().showDocument(); - else if (name == "preamble") - owner->getDialogs().showPreamble(); - else if (name == "preferences") - owner->getDialogs().showPreferences(); - else if (name == "spellchecker") - owner->getDialogs().showSpellchecker(); else if (name == "latexlog") { pair const logfile = @@ -1119,6 +1160,8 @@ void LyXFunc::dispatch(FuncRequest const & cmd, bool verbose) inset->dispatch(view()->cursor(), fr); } else if (name == "paragraph") { dispatch(FuncRequest(LFUN_PARAGRAPH_UPDATE)); + } else if (name == "prefs") { + owner->getDialogs().update(name, string()); } break; } @@ -1182,18 +1225,22 @@ void LyXFunc::dispatch(FuncRequest const & cmd, bool verbose) break; } - case LFUN_SEQUENCE: + case LFUN_SEQUENCE: { // argument contains ';'-terminated commands - while (!argument.empty()) { + string arg = argument; + while (!arg.empty()) { string first; - string rest = split(argument, first, ';'); - dispatch(lyxaction.lookupFunc(rest)); + arg = split(arg, first, ';'); + FuncRequest func(lyxaction.lookupFunc(first)); + func.origin = cmd.origin; + dispatch(func); } break; + } case LFUN_SAVEPREFERENCES: { Path p(user_lyxdir()); - lyxrc.write("preferences"); + lyxrc.write("preferences", false); break; } @@ -1253,8 +1300,9 @@ void LyXFunc::dispatch(FuncRequest const & cmd, bool verbose) break; } - case LFUN_BREAKLINE: { -#warning swallow 'Return' if the minibuffer is focused. But how? + case LFUN_GRAPHICS_EDIT: { + FuncRequest fr(action, argument); + InsetGraphics().dispatch(view()->cursor(), fr); break; } @@ -1272,12 +1320,8 @@ void LyXFunc::dispatch(FuncRequest const & cmd, bool verbose) InsetIterator const end = inset_iterator_end(inset); for (; it != end; ++it) { if (inset_code == InsetBase::NO_CODE - || inset_code == it->lyxCode()) { + || inset_code == it->lyxCode()) it->dispatch(cur, fr); - if (&cur.inset() == &*it - && cur.disp_.dispatched()) - cur.pop(); - } } break; } @@ -1297,7 +1341,36 @@ void LyXFunc::dispatch(FuncRequest const & cmd, bool verbose) break; } + case LFUN_SAVE_AS_DEFAULT: { + string const fname = + AddName(AddPath(user_lyxdir(), "templates/"), + "defaults.lyx"); + Buffer defaults(fname); + + istringstream ss(argument); + LyXLex lex(0,0); + lex.setStream(ss); + int const unknown_tokens = defaults.readHeader(lex); + + if (unknown_tokens != 0) { + lyxerr << "Warning in LFUN_SAVE_AS_DEFAULT!\n" + << unknown_tokens << " unknown token" + << (unknown_tokens == 1 ? "" : "s") + << endl; + } + + if (defaults.writeFile(defaults.fileName())) + setMessage(_("Document defaults saved in ") + + MakeDisplayPath(fname)); + else + setErrorMessage(_("Unable to save document defaults")); + break; + } + case LFUN_BUFFERPARAMS_APPLY: { + biblio::CiteEngine const engine = + owner->buffer()->params().cite_engine; + istringstream ss(argument); LyXLex lex(0,0); lex.setStream(ss); @@ -1310,6 +1383,18 @@ void LyXFunc::dispatch(FuncRequest const & cmd, bool verbose) << (unknown_tokens == 1 ? "" : "s") << endl; } + if (engine == owner->buffer()->params().cite_engine) + break; + + LCursor & cur = view()->cursor(); + FuncRequest fr(LFUN_INSET_REFRESH); + + InsetBase & inset = owner->buffer()->inset(); + InsetIterator it = inset_iterator_begin(inset); + InsetIterator const end = inset_iterator_end(inset); + for (; it != end; ++it) + if (it->lyxCode() == InsetBase::CITE_CODE) + it->dispatch(cur, fr); break; } @@ -1319,7 +1404,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd, bool verbose) lyx::textclass_type const old_class = buffer->params().textclass; - dispatch(FuncRequest(LFUN_TEXTCLASS_LOAD, argument)); + loadTextclass(argument); std::pair const tc_pair = textclasslist.NumberOfClass(argument); @@ -1332,9 +1417,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd, bool verbose) // nothing to do break; - owner->message( - _("Converting document to new document class...")); - + owner->message(_("Converting document to new document class...")); ErrorList el; lyx::cap::SwitchLayoutsBetweenClasses( old_class, new_class, @@ -1345,43 +1428,39 @@ void LyXFunc::dispatch(FuncRequest const & cmd, bool verbose) break; } - case LFUN_TEXTCLASS_LOAD: { - std::pair const tc_pair = - textclasslist.NumberOfClass(argument); - - if (!tc_pair.first) { - lyxerr << "Document class \"" << argument - << "\" does not exist." - << std::endl; - break; - } - - lyx::textclass_type const tc = tc_pair.second; - - bool const success = textclasslist[tc].load(); - if (success) - break; + case LFUN_TEXTCLASS_LOAD: + loadTextclass(argument); + break; - string s = bformat(_("The document could not be converted\n" - "into the document class %1$s."), - textclasslist[tc].name()); - Alert::error(_("Could not change class"), s); + case LFUN_LYXRC_APPLY: { + istringstream ss(argument); + bool const success = lyxrc.read(ss) == 0; + if (!success) { + lyxerr << "Warning in LFUN_LYXRC_APPLY!\n" + << "Unable to read lyxrc data" + << endl; + } break; } default: { - DispatchResult res = view()->cursor().dispatch(cmd); - if (!res.dispatched()); - view()->dispatch(cmd); + update = false; + view()->cursor().dispatch(cmd); + if (view()->cursor().result().dispatched()) + update |= view()->cursor().result().update(); + else + update |= view()->dispatch(cmd); break; } } if (view()->available()) { - view()->fitCursor(); - view()->update(); - view()->cursor().updatePos(); + // Redraw screen unless explicitly told otherwise. + // This also initializes the position cache for all insets + // in (at least partially) visible top-level paragraphs. + view()->update(true, update); + // if we executed a mutating lfun, mark the buffer as dirty if (getStatus(cmd).enabled() && !lyxaction.funcHasFlag(cmd.action, LyXAction::NoBuffer) @@ -1391,17 +1470,19 @@ void LyXFunc::dispatch(FuncRequest const & cmd, bool verbose) if (view()->cursor().inTexted()) { view()->owner()->updateLayoutChoice(); - sendDispatchMessage(getMessage(), cmd, verbose); } } + sendDispatchMessage(getMessage(), cmd); } -void LyXFunc::sendDispatchMessage(string const & msg, - FuncRequest const & cmd, bool verbose) +void LyXFunc::sendDispatchMessage(string const & msg, FuncRequest const & cmd) { owner->updateMenubar(); - owner->updateToolbar(); + owner->updateToolbars(); + + const bool verbose = (cmd.origin == FuncRequest::UI + || cmd.origin == FuncRequest::COMMANDBUFFER); if (cmd.action == LFUN_SELFINSERT || !verbose) { lyxerr[Debug::ACTION] << "dispatch msg is " << msg << endl; @@ -1425,7 +1506,7 @@ void LyXFunc::sendDispatchMessage(string const & msg, } } - string const shortcuts = toplevel_keymap->findbinding(cmd); + string const shortcuts = toplevel_keymap->printbindings(cmd); if (!shortcuts.empty()) { comname += ": " + shortcuts; @@ -1691,12 +1772,6 @@ void LyXFunc::setMessage(string const & m) const } -void LyXFunc::setStatusMessage(string const & m) const -{ - status_buffer = m; -} - - string const LyXFunc::viewStatusMessage() { // When meta-fake key is pressed, show the key sequence so far + "M-".