/* This file is part of * ====================================================== * * LyX, The Document Processor * * Copyright 1995 Matthias Ettrich * Copyright 1995-2001 The LyX Team. * * ====================================================== */ #include #include "Lsstream.h" #include #include #include #include #include #include #ifdef __GNUG__ #pragma implementation #endif #include "support/lyxalgo.h" #include "version.h" #include "kbmap.h" #include "lyxfunc.h" #include "bufferlist.h" #include "BufferView.h" #include "ColorHandler.h" #include "lyxserver.h" #include "intl.h" #include "lyx_main.h" #include "lyx_cb.h" #include "LyXAction.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" #include "insets/insetlist.h" #include "insets/insettabular.h" #include "insets/insettheorem.h" #include "insets/insetcaption.h" #include "mathed/formulamacro.h" #include "mathed/math_cursor.h" #include "mathed/math_inset.h" #include "minibuffer.h" #include "vspace.h" #include "LyXView.h" #include "lyx_gui_misc.h" #include "support/filetools.h" #include "support/FileInfo.h" #include "support/syscall.h" #include "support/lstrings.h" #include "support/path.h" #include "support/lyxfunctional.h" #include "debug.h" #include "lyxrc.h" #include "lyxtext.h" #include "gettext.h" #include "trans_mgr.h" #include "layout.h" #include "WorkArea.h" #include "bufferview_funcs.h" #include "frontends/FileDialog.h" #include "frontends/Dialogs.h" #include "frontends/Toolbar.h" #include "frontends/Menubar.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" using std::pair; using std::make_pair; using std::endl; using std::find_if; extern BufferList bufferlist; extern LyXServer * lyxserver; extern int greek_kb_flag; extern bool selection_possible; extern void MenuSendto(); 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 LyXTextClass::size_type current_layout; 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 =========================================================== */ // Initialization of static member var bool LyXFunc::show_sc = true; LyXFunc::LyXFunc(LyXView * o) : owner(o) { meta_fake_bit = 0; lyx_dead_action = LFUN_NOACTION; lyx_calling_dead_action = LFUN_NOACTION; setupLocalKeymap(); } inline LyXText * LyXFunc::TEXT(bool flag = true) const { if (flag) return owner->view()->text; return owner->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(); } void LyXFunc::handleKeyFunc(kb_action action) { char c = keyseq.getiso(); if (keyseq.length != -1) c = 0; owner->getIntl()->getTrans() .deadkey(c, get_accent(action).accent, TEXT(false)); // Need to reset, in case the minibuffer calls these // actions keyseq.reset(); keyseq.length = 0; // copied verbatim from do_accent_char owner->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) { 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 << "]" << endl; } // Do nothing if we have nothing (JMarc) if (keysym == NoSymbol) { lyxerr[Debug::KEY] << "Empty kbd action (probably composing)" << endl; return; } // Can we be sure that this will work for all X-Windows // 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) { return; } // 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. // Note how the meta_fake Mod1 bit is OR-ed in and reset afterwards. // Mostly, meta_fake_bit = 0. 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; } } // Dont remove this unless you know what you are doing. meta_fake_bit = 0; if (action == 0) action = LFUN_PREFIX; if (lyxerr.debugging(Debug::KEY)) { string buf; keyseq.print(buf); lyxerr << "Key [action=" << action << "][" << buf << "]" << endl; } // already here we know if it any point in going further // why not return already here if action == -1 and // num_bytes == 0? (Lgb) if (keyseq.length > 1 || keyseq.length < -1) { string buf; keyseq.print(buf); owner->message(buf); } if (action == -1) { // 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 == -1) { owner->message(_("Unknown function.")); return; } } if (action == LFUN_SELFINSERT) { // This is very X dependant. unsigned int c = keysym; switch (c & 0x0000FF00) { // latin 1 byte 3 = 0 case 0x00000000: break; // latin 2 byte 3 = 1 case 0x00000100: // latin 3 byte 3 = 2 case 0x00000200: // latin 4 byte 3 = 3 case 0x00000300: // latin 8 byte 3 = 18 (0x12) case 0x00001200: // latin 9 byte 3 = 19 (0x13) case 0x00001300: c &= 0x000000FF; break; default: c = 0; break; } if (c > 0) argument = static_cast(c); lyxerr[Debug::KEY] << "SelfInsert arg[`" << argument << "']" << endl; } bool tmp_sc = show_sc; show_sc = false; dispatch(action, argument); show_sc = tmp_sc; //return 0; } func_status::value_type LyXFunc::getStatus(int ac) const { return getStatus(ac, string()); } func_status::value_type LyXFunc::getStatus(int ac, string const & not_to_use_arg) const { kb_action action; func_status::value_type flag = func_status::OK; string argument; Buffer * buf = owner->buffer(); if (lyxaction.isPseudoAction(ac)) action = lyxaction.retrieveActionArg(ac, argument); else { action = static_cast(ac); if (!not_to_use_arg.empty()) argument = not_to_use_arg; // exept here } if (action == LFUN_UNKNOWN_ACTION) { setErrorMessage(N_("Unknown action")); return func_status::Unknown; } // Check whether we need a buffer if (!lyxaction.funcHasFlag(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::ReadOnly)) { // no setErrorMessage(N_("Document is read-only")); flag |= func_status::Disabled; } } else { // no setErrorMessage(N_("Command not allowed with" "out any document open")); flag |= func_status::Disabled; return flag; } } // I would really like to avoid having this switch and rather try to // encode this in the function itself. bool disable = false; switch (action) { case LFUN_MENUPRINT: disable = !Exporter::IsExportable(buf, "dvi") || lyxrc.print_command == "none"; break; case LFUN_EXPORT: disable = argument == "fax" && !Exporter::IsExportable(buf, argument); break; case LFUN_UNDO: disable = buf->undostack.empty(); break; case LFUN_REDO: disable = buf->redostack.empty(); break; case LFUN_SPELLCHECK: disable = lyxrc.isp_command == "none"; break; case LFUN_RUNCHKTEX: disable = lyxrc.chktex_command == "none"; break; case LFUN_BUILDPROG: disable = !Exporter::IsExportable(buf, "program"); break; case LFUN_LAYOUT_TABULAR: disable = true; if (owner->view()->theLockingInset()) { disable = (owner->view()->theLockingInset()->lyxCode() != Inset::TABULAR_CODE) && !owner->view()->theLockingInset()->getFirstLockingInsetOfType(Inset::TABULAR_CODE); } break; case LFUN_TABULAR_FEATURE: disable = true; if (owner->view()->theLockingInset()) { func_status::value_type ret = func_status::Disabled; if (owner->view()->theLockingInset()->lyxCode() == Inset::TABULAR_CODE) { ret = static_cast (owner->view()->theLockingInset())-> getStatus(argument); } else if (owner->view()->theLockingInset()->getFirstLockingInsetOfType(Inset::TABULAR_CODE)) { ret = static_cast (owner->view()->theLockingInset()-> getFirstLockingInsetOfType(Inset::TABULAR_CODE))-> getStatus(argument); } flag |= ret; disable = false; } else { static InsetTabular inset(*owner->buffer(), 1, 1); func_status::value_type ret; disable = true; ret = inset.getStatus(argument); if ((ret & func_status::ToggleOn) || (ret & func_status::ToggleOff)) flag |= func_status::ToggleOff; } break; case LFUN_VC_REGISTER: disable = buf->lyxvc.inUse(); break; case LFUN_VC_CHECKIN: disable = !buf->lyxvc.inUse() || buf->isReadonly(); break; case LFUN_VC_CHECKOUT: disable = !buf->lyxvc.inUse() || !buf->isReadonly(); break; case LFUN_VC_REVERT: case LFUN_VC_UNDO: case LFUN_VC_HISTORY: disable = !buf->lyxvc.inUse(); break; case LFUN_BOOKMARK_GOTO: disable = !owner->view()-> isSavedPosition(strToUnsignedInt(argument)); break; case LFUN_INSET_TOGGLE: disable = (TEXT(false)->getInset() == 0); break; case LFUN_MATH_VALIGN: { // I think this test can be simplified (Andre') // mathcursor is != 0 iff we are in math mode //Inset * tli = owner->view()->theLockingInset(); //if (tli && (tli->lyxCode() == Inset::MATH_CODE // || tli->lyxCode() == Inset::MATHMACRO_CODE)) { // if (mathcursor) { char align = mathcursor->valign(); if (align == '\0') { disable = true; break; } if (argument.empty()) { flag = func_status::OK; break; } if (!contains("tcb", argument[0])) { disable = true; break; } if (argument[0] == align) flag |= func_status::ToggleOn; else flag |= func_status::ToggleOff; } else disable = true; break; } case LFUN_MATH_HALIGN: { //Inset * tli = owner->view()->theLockingInset(); //if (tli && (tli->lyxCode() == Inset::MATH_CODE // || tli->lyxCode() == Inset::MATHMACRO_CODE)) { if (mathcursor) { char align = mathcursor->halign(); if (align == '\0') { disable = true; break; } if (argument.empty()) { flag = func_status::OK; break; } if (!contains("lcr", argument[0])) { disable = true; break; } if (argument[0] == align) flag |= func_status::ToggleOn; else flag |= func_status::ToggleOff; } else disable = true; break; } case LFUN_MATH_MUTATE: { Inset * tli = owner->view()->theLockingInset(); if (tli && (tli->lyxCode() == Inset::MATH_CODE)) { MathInsetTypes type = mathcursor->par()->GetType(); func_status::value_type box = func_status::ToggleOff; if (argument == "inline") { if (type == LM_OT_SIMPLE) box = func_status::ToggleOn; } else if (argument == "display") { if (type == LM_OT_EQUATION) box = func_status::ToggleOn; } else if (argument == "eqnarray") { if (type == LM_OT_EQNARRAY) box = func_status::ToggleOn; } else if (argument == "align") { if (type == LM_OT_ALIGN) box = func_status::ToggleOn; } else { box = func_status::OK; disable = true; } flag |= box; } else disable = true; break; } // we just need to be in math mode to enable that case LFUN_MATH_SIZE: case LFUN_MATH_LIMITS: case LFUN_MATH_NONUMBER: case LFUN_MATH_NUMBER: 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) { case LFUN_INSET_TEXT: code = Inset::TEXT_CODE; break; case LFUN_INSET_ERT: code = Inset::ERT_CODE; break; case LFUN_INSET_GRAPHICS: code = Inset::GRAPHICS_CODE; break; case LFUN_INSET_FOOTNOTE: code = Inset::FOOT_CODE; break; case LFUN_INSET_TABULAR: code = Inset::TABULAR_CODE; break; case LFUN_INSET_EXTERNAL: code = Inset::EXTERNAL_CODE; break; case LFUN_INSET_MARGINAL: code = Inset::MARGIN_CODE; break; case LFUN_INSET_MINIPAGE: code = Inset::MINIPAGE_CODE; break; case LFUN_INSET_FLOAT: case LFUN_INSET_WIDE_FLOAT: code = Inset::FLOAT_CODE; break; #if 0 case LFUN_INSET_LIST: code = Inset::LIST_CODE; break; #endif case LFUN_INSET_THEOREM: code = Inset::THEOREM_CODE; break; case LFUN_INSET_CAPTION: code = Inset::CAPTION_CODE; break; case LFUN_INSERT_NOTE: code = Inset::IGNORE_CODE; break; case LFUN_INSERT_LABEL: code = Inset::LABEL_CODE; break; case LFUN_REF_INSERT: code = Inset::REF_CODE; break; case LFUN_CITATION_INSERT: code = Inset::CITE_CODE; break; case LFUN_INSERT_BIBTEX: code = Inset::BIBTEX_CODE; break; case LFUN_INDEX_INSERT: case LFUN_INDEX_INSERT_LAST: code = Inset::INDEX_CODE; break; #if 0 case LFUN_CHILD_INSERT: code = Inset::CHILD_CODE; break; #endif case LFUN_TOC_INSERT: code = Inset::TOC_CODE; break; case LFUN_PARENTINSERT: code = Inset::PARENT_CODE; break; case LFUN_INSERT_URL: code = Inset::URL_CODE; break; default: break; } if (code != Inset::NO_CODE && owner->view()->theLockingInset() && !owner->view()->theLockingInset()->insetAllowed(code)) { disable = true; } if (disable) flag |= func_status::Disabled; // the font related functions func_status::value_type box = func_status::ToggleOff; LyXFont const & font = TEXT(false)->real_current_font; switch (action) { case LFUN_EMPH: if (font.emph() == LyXFont::ON) box = func_status::ToggleOn; break; case LFUN_NOUN: if (font.noun() == LyXFont::ON) box = func_status::ToggleOn; break; case LFUN_BOLD: if (font.series() == LyXFont::BOLD_SERIES) box = func_status::ToggleOn; break; #ifndef NO_LATEX case LFUN_TEX: if (font.latex() == LyXFont::ON) box = func_status::ToggleOn; break; #endif case LFUN_READ_ONLY_TOGGLE: if (buf->isReadonly()) box = func_status::ToggleOn; break; default: box = func_status::OK; break; } flag |= box; return flag; } // temporary dispatch method void LyXFunc::miniDispatch(string const & s) { if (!s.empty()) { dispatch(s); } } string const LyXFunc::dispatch(string const & s) { // Split command string into command and argument string cmd; string line = frontStrip(s); string const arg = strip(frontStrip(split(line, cmd, ' '))); return dispatch(lyxaction.LookupFunc(cmd), arg); } string const LyXFunc::dispatch(int ac, string const & do_not_use_this_arg) { lyxerr[Debug::ACTION] << "LyXFunc::Dispatch: action[" << ac <<"] arg[" << do_not_use_this_arg << "]" << endl; string argument; kb_action action; // we have not done anything wrong yet. errorstat = false; dispatch_buffer.erase(); // if action is a pseudo-action, we need the real action if (lyxaction.isPseudoAction(ac)) { string tmparg; action = static_cast (lyxaction.retrieveActionArg(ac, tmparg)); if (!tmparg.empty()) argument = tmparg; } else { action = static_cast(ac); if (!do_not_use_this_arg.empty()) argument = do_not_use_this_arg; // except here } #ifdef NEW_DISPATCHER // We try do call the most specific dispatcher first: // 1. the lockinginset's dispatch // 2. the bufferview's dispatch // 3. the lyxview's dispatch #endif selection_possible = false; if (owner->view()->available()) owner->view()->hideCursor(); // We cannot use this function here if (getStatus(ac, do_not_use_this_arg) & func_status::Disabled) goto exit_with_message; if (owner->view()->available() && owner->view()->theLockingInset()) { UpdatableInset::RESULT result; if ((action > 1) || ((action == LFUN_UNKNOWN_ACTION) && (keyseq.length >= -1))) { if ((action==LFUN_UNKNOWN_ACTION) && argument.empty()){ argument = keyseq.getiso(); } // Undo/Redo is a bit tricky for insets. if (action == LFUN_UNDO) { #ifdef RETHINK_THIS_FOR_NOW_WE_LEAVE_ALL_UNLOCKED int slx; int sly; UpdatableInset * inset = owner->view()->theLockingInset()->getLockingInset(); int inset_id = inset->id(); inset->getCursorPos(owner->view(), slx, sly); owner->view()->unlockInset(inset); #else owner->view()->unlockInset(owner->view()->theLockingInset()); #endif owner->view()->menuUndo(); #ifdef RETHINK_THIS_FOR_NOW_WE_LEAVE_ALL_UNLOCKED #if 0 if (TEXT()->cursor.par()-> isInset(TEXT()->cursor.pos())) { inset = static_cast( TEXT()->cursor.par()-> getInset(TEXT()-> cursor.pos())); } else { inset = 0; } #else inset = static_cast(owner->view()->buffer()->getInsetFromID(inset_id)); #endif if (inset) inset->edit(owner->view(),slx,sly,0); #endif return string(); } else if (action == LFUN_REDO) { int slx; int sly; UpdatableInset * inset = owner->view()-> theLockingInset(); inset->getCursorPos(owner->view(), slx, sly); owner->view()->unlockInset(inset); owner->view()->menuRedo(); inset = static_cast( TEXT()->cursor.par()-> getInset(TEXT()-> cursor.pos())); if (inset) inset->edit(owner->view(),slx,sly,0); return string(); } else if (((result=owner->view()->theLockingInset()-> localDispatch(owner->view(), action, argument)) == UpdatableInset::DISPATCHED) || (result == UpdatableInset::DISPATCHED_NOUPDATE)) return string(); else { //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(); break; case LFUN_RIGHT: if (!TEXT()->cursor.par()->isRightToLeftPar(owner->buffer()->params)) { TEXT()->cursorRight(owner->view()); moveCursorUpdate(true, false); owner->showState(); } return string(); case LFUN_LEFT: if (TEXT()->cursor.par()->isRightToLeftPar(owner->buffer()->params)) { TEXT()->cursorRight(owner->view()); moveCursorUpdate(true, false); owner->showState(); } return string(); case LFUN_DOWN: if (TEXT()->cursor.row()->next()) TEXT()->cursorDown(owner->view()); else TEXT()->cursorRight(owner->view()); moveCursorUpdate(true, false); owner->showState(); return string(); default: break; } } } } lyx::Assert(action != LFUN_SELECT_FILE_SYNC); switch (action) { case LFUN_ESCAPE: { if (!owner->view()->available()) break; // this function should be used always [asierra060396] UpdatableInset * tli = owner->view()->theLockingInset(); if (tli) { UpdatableInset * lock = tli->getLockingInset(); if (tli == lock) { owner->view()->unlockInset(tli); TEXT()->cursorRight(owner->view()); moveCursorUpdate(true, false); owner->showState(); } else { tli->unlockInsetInInset(owner->view(), lock, true); } } } break; // --- Misc ------------------------------------------- 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); if (!searched_string.empty()) { LyXFind(owner->view(), searched_string, fw); } // owner->view()->showCursor(); } break; case LFUN_PREFIX: { if (owner->view()->available() && !owner->view()->theLockingInset()) { owner->view()->update(TEXT(), BufferView::SELECT|BufferView::FITCUR); } string buf; keyseq.print(buf, true); owner->message(buf); } break; // --- Misc ------------------------------------------- case LFUN_EXEC_COMMAND: { std::vector allCmds; std::transform(lyxaction.func_begin(), lyxaction.func_end(), std::back_inserter(allCmds), lyx::firster()); static std::vector hist; owner->getMiniBuffer()->getString(MiniBuffer::spaces, allCmds, hist); } break; case LFUN_CANCEL: // RVDK_PATCH_5 keyseq.reset(); meta_fake_bit = 0; if (owner->view()->available()) // cancel any selection dispatch(LFUN_MARK_OFF); setMessage(N_("Cancel")); break; case LFUN_META_FAKE: // RVDK_PATCH_5 { meta_fake_bit = Mod1Mask; string buf; keyseq.print(buf, true); setMessage(buf); // RVDK_PATCH_5 } break; case LFUN_READ_ONLY_TOGGLE: if (owner->buffer()->lyxvc.inUse()) { owner->buffer()->lyxvc.toggleReadOnly(); } else { owner->buffer()->setReadonly( !owner->buffer()->isReadonly()); } break; case LFUN_CENTER: // this is center and redraw. owner->view()->center(); break; // --- Menus ----------------------------------------------- case LFUN_MENUNEW: menuNew(false); break; case LFUN_MENUNEWTMPLT: menuNew(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()); } else WriteAs(owner->view(), owner->buffer()); break; case LFUN_WRITEAS: WriteAs(owner->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: Exporter::Export(owner->buffer(), "program", true); break; case LFUN_RUNCHKTEX: MenuRunChktex(owner->buffer()); break; case LFUN_MENUPRINT: owner->getDialogs()->showPrint(); break; case LFUN_EXPORT: if (argument == "custom") MenuSendto(); else Exporter::Export(owner->buffer(), argument, false); break; case LFUN_IMPORT: doImport(argument); break; case LFUN_QUIT: QuitLyX(); break; case LFUN_TOCVIEW: #if 0 case LFUN_LOFVIEW: case LFUN_LOTVIEW: case LFUN_LOAVIEW: #endif { InsetCommandParams p; #if 0 if (action == LFUN_TOCVIEW) #endif p.setCmdName("tableofcontents"); #if 0 else if (action == LFUN_LOAVIEW ) p.setCmdName("listof{algorithm}{List of Algorithms}"); else if (action == LFUN_LOFVIEW) p.setCmdName("listoffigures"); else p.setCmdName("listoftables"); #endif owner->getDialogs()->createTOC(p.getAsString()); break; } case LFUN_DIALOG_TABULAR_INSERT: owner->getDialogs()->showTabularCreate(); break; case LFUN_FIGURE: Figure(); break; case LFUN_AUTOSAVE: AutoSave(owner->view()); break; case LFUN_UNDO: owner->view()->menuUndo(); break; case LFUN_REDO: owner->view()->menuRedo(); break; case LFUN_MENUSEARCH: owner->getDialogs()->showSearch(); break; case LFUN_REMOVEERRORS: if (owner->view()->removeAutoInsets()) { owner->view()->redraw(); owner->view()->fitCursor(TEXT()); } break; case LFUN_DEPTH: changeDepth(owner->view(), TEXT(false), 0); break; case LFUN_DEPTH_MIN: changeDepth(owner->view(), TEXT(false), -1); break; case LFUN_DEPTH_PLUS: changeDepth(owner->view(), TEXT(false), 1); break; case LFUN_FREE: owner->getDialogs()->setUserFreeFont(); break; #ifndef NO_LATEX case LFUN_TEX: Tex(owner->view()); owner->view()->setState(); owner->showState(); break; #endif case LFUN_RECONFIGURE: Reconfigure(owner->view()); break; #if 0 case LFUN_FLOATSOPERATE: if (argument == "openfoot") owner->view()->allFloats(1,0); else if (argument == "closefoot") owner->view()->allFloats(0,0); else if (argument == "openfig") owner->view()->allFloats(1,1); else if (argument == "closefig") owner->view()->allFloats(0,1); break; #else #ifdef WITH_WARNINGS #warning Find another implementation here (or another lyxfunc)! #endif #endif case LFUN_HELP_ABOUTLYX: owner->getDialogs()->showAboutlyx(); break; case LFUN_HELP_COPYRIGHT: case LFUN_HELP_CREDITS: 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(); break; } case LFUN_HELP_VERSION: // --- version control ------------------------------- case LFUN_VC_REGISTER: { if (!owner->buffer()->lyxvc.inUse()) owner->buffer()->lyxvc.registrer(); } break; case LFUN_VC_CHECKIN: { if (owner->buffer()->lyxvc.inUse() && !owner->buffer()->isReadonly()) owner->buffer()->lyxvc.checkIn(); } break; case LFUN_VC_CHECKOUT: { if (owner->buffer()->lyxvc.inUse() && owner->buffer()->isReadonly()) 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(); break; } // --- buffers ---------------------------------------- case LFUN_SWITCHBUFFER: owner->view()->buffer(bufferlist.getBuffer(argument)); break; case LFUN_FILE_NEW: { // servercmd: argument must be :