3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Alfredo Braunstein
7 * \author Lars Gullik Bjønnes
8 * \author Jean-Marc Lasgouttes
9 * \author Angus Leeming
11 * \author André Pönitz
14 * \author Martin Vermeer
15 * \author Jürgen Vigna
17 * Full author contact details are available in file CREDITS.
24 #include "LayoutFile.h"
25 #include "BranchList.h"
26 #include "buffer_funcs.h"
28 #include "BufferList.h"
29 #include "BufferParams.h"
30 #include "BufferView.h"
33 #include "Converter.h"
35 #include "CutAndPaste.h"
36 #include "DispatchResult.h"
38 #include "ErrorList.h"
40 #include "FuncRequest.h"
41 #include "FuncStatus.h"
42 #include "InsetIterator.h"
47 #include "LyXAction.h"
52 #include "Paragraph.h"
53 #include "ParagraphParameters.h"
54 #include "ParIterator.h"
58 #include "SpellChecker.h"
60 #include "insets/InsetBox.h"
61 #include "insets/InsetBranch.h"
62 #include "insets/InsetCommand.h"
63 #include "insets/InsetERT.h"
64 #include "insets/InsetExternal.h"
65 #include "insets/InsetFloat.h"
66 #include "insets/InsetGraphics.h"
67 #include "insets/InsetInclude.h"
68 #include "insets/InsetListings.h"
69 #include "insets/InsetNote.h"
70 #include "insets/InsetPhantom.h"
71 #include "insets/InsetSpace.h"
72 #include "insets/InsetTabular.h"
73 #include "insets/InsetVSpace.h"
74 #include "insets/InsetWrap.h"
76 #include "frontends/alert.h"
77 #include "frontends/Application.h"
78 #include "frontends/KeySymbol.h"
79 #include "frontends/LyXView.h"
80 #include "frontends/Selection.h"
82 #include "support/debug.h"
83 #include "support/environment.h"
84 #include "support/FileName.h"
85 #include "support/filetools.h"
86 #include "support/gettext.h"
87 #include "support/lstrings.h"
88 #include "support/Path.h"
89 #include "support/Package.h"
90 #include "support/Systemcall.h"
91 #include "support/convert.h"
92 #include "support/os.h"
98 using namespace lyx::support;
102 using frontend::LyXView;
104 namespace Alert = frontend::Alert;
109 // This function runs "configure" and then rereads lyx.defaults to
110 // reconfigure the automatic settings.
111 void reconfigure(LyXView * lv, string const & option)
113 // emit message signal.
115 lv->message(_("Running configure..."));
117 // Run configure in user lyx directory
118 PathChanger p(package().user_support());
119 string configure_command = package().configure_command();
120 configure_command += option;
122 int ret = one.startscript(Systemcall::Wait, configure_command);
124 // emit message signal.
126 lv->message(_("Reloading configuration..."));
127 lyxrc.read(libFileSearch(string(), "lyxrc.defaults"));
128 // Re-read packages.lst
129 LaTeXFeatures::getAvailable();
132 Alert::information(_("System reconfiguration failed"),
133 _("The system reconfiguration has failed.\n"
134 "Default textclass is used but LyX may "
135 "not be able to work properly.\n"
136 "Please reconfigure again if needed."));
139 Alert::information(_("System reconfigured"),
140 _("The system has been reconfigured.\n"
141 "You need to restart LyX to make use of any\n"
142 "updated document class specifications."));
146 bool getLocalStatus(Cursor cursor, FuncRequest const & cmd, FuncStatus & status)
148 // Try to fix cursor in case it is broken.
149 cursor.fixIfBroken();
151 // This is, of course, a mess. Better create a new doc iterator and use
152 // this in Inset::getStatus. This might require an additional
153 // BufferView * arg, though (which should be avoided)
154 //Cursor safe = *this;
156 for ( ; cursor.depth(); cursor.pop()) {
157 //lyxerr << "\nCursor::getStatus: cmd: " << cmd << endl << *this << endl;
158 LASSERT(cursor.idx() <= cursor.lastidx(), /**/);
159 LASSERT(cursor.pit() <= cursor.lastpit(), /**/);
160 LASSERT(cursor.pos() <= cursor.lastpos(), /**/);
162 // The inset's getStatus() will return 'true' if it made
163 // a definitive decision on whether it want to handle the
164 // request or not. The result of this decision is put into
165 // the 'status' parameter.
166 if (cursor.inset().getStatus(cursor, cmd, status)) {
175 /** Return the change status at cursor position, taking in account the
176 * status at each level of the document iterator (a table in a deleted
177 * footnote is deleted).
178 * When \param outer is true, the top slice is not looked at.
180 Change::Type lookupChangeType(DocIterator const & dit, bool outer = false)
182 size_t const depth = dit.depth() - (outer ? 1 : 0);
184 for (size_t i = 0 ; i < depth ; ++i) {
185 CursorSlice const & slice = dit[i];
186 if (!slice.inset().inMathed()
187 && slice.pos() < slice.paragraph().size()) {
188 Change::Type const ch = slice.paragraph().lookupChange(slice.pos()).type;
189 if (ch != Change::UNCHANGED)
193 return Change::UNCHANGED;
200 : lyx_view_(0), encoded_last_key(0), meta_fake_bit(NoModifier)
205 void LyXFunc::initKeySequences(KeyMap * kb)
207 keyseq = KeySequence(kb, kb);
208 cancel_meta_seq = KeySequence(kb, kb);
212 void LyXFunc::setLyXView(LyXView * lv)
214 if (lyx_view_ && lyx_view_->currentBufferView() && lyx_view_ != lv)
215 // save current selection to the selection buffer to allow
216 // middle-button paste in another window
217 cap::saveSelection(lyx_view_->currentBufferView()->cursor());
222 void LyXFunc::handleKeyFunc(FuncCode action)
224 char_type c = encoded_last_key;
229 LASSERT(lyx_view_ && lyx_view_->currentBufferView(), /**/);
230 BufferView * bv = lyx_view_->currentBufferView();
231 bv->getIntl().getTransManager().deadkey(
232 c, get_accent(action).accent, bv->cursor().innerText(),
234 // Need to clear, in case the minibuffer calls these
237 // copied verbatim from do_accent_char
238 bv->cursor().resetAnchor();
239 bv->processUpdateFlags(Update::FitCursor);
242 //FIXME: bookmark handling is a frontend issue. This code should be transferred
243 // to GuiView and be GuiView and be window dependent.
244 void LyXFunc::gotoBookmark(unsigned int idx, bool openFile, bool switchToBuffer)
246 LASSERT(lyx_view_, /**/);
247 if (!theSession().bookmarks().isValid(idx))
249 BookmarksSection::Bookmark const & bm = theSession().bookmarks().bookmark(idx);
250 LASSERT(!bm.filename.empty(), /**/);
251 string const file = bm.filename.absFilename();
252 // if the file is not opened, open it.
253 if (!theBufferList().exists(bm.filename)) {
255 dispatch(FuncRequest(LFUN_FILE_OPEN, file));
259 // open may fail, so we need to test it again
260 if (!theBufferList().exists(bm.filename))
263 // bm can be changed when saving
264 BookmarksSection::Bookmark tmp = bm;
266 // Special case idx == 0 used for back-from-back jump navigation
268 dispatch(FuncRequest(LFUN_BOOKMARK_SAVE, "0"));
270 // if the current buffer is not that one, switch to it.
271 if (!lyx_view_->documentBufferView()
272 || lyx_view_->documentBufferView()->buffer().fileName() != tmp.filename) {
275 dispatch(FuncRequest(LFUN_BUFFER_SWITCH, file));
278 // moveToPosition try paragraph id first and then paragraph (pit, pos).
279 if (!lyx_view_->documentBufferView()->moveToPosition(
280 tmp.bottom_pit, tmp.bottom_pos, tmp.top_id, tmp.top_pos))
287 // Cursor jump succeeded!
288 Cursor const & cur = lyx_view_->documentBufferView()->cursor();
289 pit_type new_pit = cur.pit();
290 pos_type new_pos = cur.pos();
291 int new_id = cur.paragraph().id();
293 // if bottom_pit, bottom_pos or top_id has been changed, update bookmark
294 // see http://bugzilla.lyx.org/show_bug.cgi?id=3092
295 if (bm.bottom_pit != new_pit || bm.bottom_pos != new_pos
296 || bm.top_id != new_id) {
297 const_cast<BookmarksSection::Bookmark &>(bm).updatePos(
298 new_pit, new_pos, new_id);
303 void LyXFunc::processKeySym(KeySymbol const & keysym, KeyModifier state)
305 LYXERR(Debug::KEY, "KeySym is " << keysym.getSymbolName());
307 // Do nothing if we have nothing (JMarc)
308 if (!keysym.isOK()) {
309 LYXERR(Debug::KEY, "Empty kbd action (probably composing)");
310 lyx_view_->restartCursor();
314 if (keysym.isModifier()) {
315 LYXERR(Debug::KEY, "isModifier true");
317 lyx_view_->restartCursor();
321 //Encoding const * encoding = lyx_view_->documentBufferView()->cursor().getEncoding();
322 //encoded_last_key = keysym.getISOEncoded(encoding ? encoding->name() : "");
323 // FIXME: encoded_last_key shadows the member variable of the same
324 // name. Is that intended?
325 char_type encoded_last_key = keysym.getUCSEncoded();
327 // Do a one-deep top-level lookup for
328 // cancel and meta-fake keys. RVDK_PATCH_5
329 cancel_meta_seq.reset();
331 FuncRequest func = cancel_meta_seq.addkey(keysym, state);
332 LYXERR(Debug::KEY, "action first set to [" << func.action << ']');
334 // When not cancel or meta-fake, do the normal lookup.
335 // Note how the meta_fake Mod1 bit is OR-ed in and reset afterwards.
336 // Mostly, meta_fake_bit = NoModifier. RVDK_PATCH_5.
337 if ((func.action != LFUN_CANCEL) && (func.action != LFUN_META_PREFIX)) {
338 // remove Caps Lock and Mod2 as a modifiers
339 func = keyseq.addkey(keysym, (state | meta_fake_bit));
340 LYXERR(Debug::KEY, "action now set to [" << func.action << ']');
343 // Dont remove this unless you know what you are doing.
344 meta_fake_bit = NoModifier;
346 // Can this happen now ?
347 if (func.action == LFUN_NOACTION)
348 func = FuncRequest(LFUN_COMMAND_PREFIX);
350 LYXERR(Debug::KEY, " Key [action=" << func.action << "]["
351 << keyseq.print(KeySequence::Portable) << ']');
353 // already here we know if it any point in going further
354 // why not return already here if action == -1 and
355 // num_bytes == 0? (Lgb)
357 if (keyseq.length() > 1)
358 lyx_view_->message(keyseq.print(KeySequence::ForGui));
361 // Maybe user can only reach the key via holding down shift.
362 // Let's see. But only if shift is the only modifier
363 if (func.action == LFUN_UNKNOWN_ACTION && state == ShiftModifier) {
364 LYXERR(Debug::KEY, "Trying without shift");
365 func = keyseq.addkey(keysym, NoModifier);
366 LYXERR(Debug::KEY, "Action now " << func.action);
369 if (func.action == LFUN_UNKNOWN_ACTION) {
370 // Hmm, we didn't match any of the keysequences. See
371 // if it's normal insertable text not already covered
373 if (keysym.isText() && keyseq.length() == 1) {
374 LYXERR(Debug::KEY, "isText() is true, inserting.");
375 func = FuncRequest(LFUN_SELF_INSERT,
376 FuncRequest::KEYBOARD);
378 LYXERR(Debug::KEY, "Unknown, !isText() - giving up");
379 lyx_view_->message(_("Unknown function."));
380 lyx_view_->restartCursor();
385 if (func.action == LFUN_SELF_INSERT) {
386 if (encoded_last_key != 0) {
387 docstring const arg(1, encoded_last_key);
388 dispatch(FuncRequest(LFUN_SELF_INSERT, arg,
389 FuncRequest::KEYBOARD));
390 LYXERR(Debug::KEY, "SelfInsert arg[`" << to_utf8(arg) << "']");
400 FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const
402 //lyxerr << "LyXFunc::getStatus: cmd: " << cmd << endl;
405 /* In LyX/Mac, when a dialog is open, the menus of the
406 application can still be accessed without giving focus to
407 the main window. In this case, we want to disable the menu
408 entries that are buffer or view-related.
410 If this code is moved somewhere else (like in
411 GuiView::getStatus), then several functions will not be
414 frontend::LyXView * lv = 0;
417 && (cmd.origin != FuncRequest::MENU || lyx_view_->hasFocus())) {
419 if (lyx_view_->documentBufferView())
420 buf = &lyx_view_->documentBufferView()->buffer();
423 if (cmd.action == LFUN_NOACTION) {
424 flag.message(from_utf8(N_("Nothing to do")));
425 flag.setEnabled(false);
429 switch (cmd.action) {
430 case LFUN_UNKNOWN_ACTION:
432 flag.setEnabled(false);
439 if (flag.unknown()) {
440 flag.message(from_utf8(N_("Unknown action")));
444 if (!flag.enabled()) {
445 if (flag.message().empty())
446 flag.message(from_utf8(N_("Command disabled")));
450 // Check whether we need a buffer
451 if (!lyxaction.funcHasFlag(cmd.action, LyXAction::NoBuffer) && !buf) {
453 flag.message(from_utf8(N_("Command not allowed with"
454 "out any document open")));
455 flag.setEnabled(false);
459 // I would really like to avoid having this switch and rather try to
460 // encode this in the function itself.
461 // -- And I'd rather let an inset decide which LFUNs it is willing
462 // to handle (Andre')
464 switch (cmd.action) {
466 case LFUN_CITATION_INSERT: {
467 FuncRequest fr(LFUN_INSET_INSERT, "citation");
468 enable = getStatus(fr).enabled();
472 // This could be used for the no-GUI version. The GUI version is handled in
473 // LyXView::getStatus(). See above.
475 case LFUN_BUFFER_WRITE:
476 case LFUN_BUFFER_WRITE_AS: {
477 Buffer * b = theBufferList().getBuffer(FileName(cmd.getArg(0)));
478 enable = b && (b->isUnnamed() || !b->isClean());
483 case LFUN_BUFFER_WRITE_ALL: {
484 // We enable the command only if there are some modified buffers
485 Buffer * first = theBufferList().first();
490 // We cannot use a for loop as the buffer list is a cycle.
496 b = theBufferList().next(b);
497 } while (b != first);
501 case LFUN_BOOKMARK_GOTO: {
502 const unsigned int num = convert<unsigned int>(to_utf8(cmd.argument()));
503 enable = theSession().bookmarks().isValid(num);
507 case LFUN_BOOKMARK_CLEAR:
508 enable = theSession().bookmarks().hasValid();
511 // this one is difficult to get right. As a half-baked
512 // solution, we consider only the first action of the sequence
513 case LFUN_COMMAND_SEQUENCE: {
514 // argument contains ';'-terminated commands
515 string const firstcmd = token(to_utf8(cmd.argument()), ';', 0);
516 FuncRequest func(lyxaction.lookupFunc(firstcmd));
517 func.origin = cmd.origin;
518 flag = getStatus(func);
522 // we want to check if at least one of these is enabled
523 case LFUN_COMMAND_ALTERNATIVES: {
524 // argument contains ';'-terminated commands
525 string arg = to_utf8(cmd.argument());
526 while (!arg.empty()) {
528 arg = split(arg, first, ';');
529 FuncRequest func(lyxaction.lookupFunc(first));
530 func.origin = cmd.origin;
531 flag = getStatus(func);
532 // if this one is enabled, the whole thing is
541 string name = to_utf8(cmd.argument());
542 if (theTopLevelCmdDef().lock(name, func)) {
543 func.origin = cmd.origin;
544 flag = getStatus(func);
545 theTopLevelCmdDef().release(name);
547 // catch recursion or unknown command
548 // definition. all operations until the
549 // recursion or unknown command definition
550 // occurs are performed, so set the state to
557 case LFUN_COMMAND_PREFIX:
559 case LFUN_META_PREFIX:
560 case LFUN_RECONFIGURE:
562 case LFUN_DROP_LAYOUTS_CHOICE:
563 case LFUN_SERVER_GET_FILENAME:
564 case LFUN_SERVER_NOTIFY:
565 case LFUN_SERVER_GOTO_FILE_ROW:
566 case LFUN_CURSOR_FOLLOWS_SCROLLBAR_TOGGLE:
568 case LFUN_PREFERENCES_SAVE:
569 case LFUN_INSET_EDIT:
570 case LFUN_TEXTCLASS_APPLY:
571 case LFUN_TEXTCLASS_LOAD:
572 case LFUN_BUFFER_SAVE_AS_DEFAULT:
573 case LFUN_LAYOUT_MODULES_CLEAR:
574 case LFUN_LAYOUT_MODULE_ADD:
575 case LFUN_LAYOUT_RELOAD:
576 case LFUN_LYXRC_APPLY:
577 // these are handled in our dispatch()
585 if (theApp()->getStatus(cmd, flag))
588 // Does the view know something?
593 if (lv->getStatus(cmd, flag))
596 BufferView * bv = lv->currentBufferView();
597 BufferView * doc_bv = lv->documentBufferView();
598 // If we do not have a BufferView, then other functions are disabled
603 // Is this a function that acts on inset at point?
604 Inset * inset = bv->cursor().nextInset();
605 if (lyxaction.funcHasFlag(cmd.action, LyXAction::AtPoint)
606 && inset && inset->getStatus(bv->cursor(), cmd, flag))
609 bool decided = getLocalStatus(bv->cursor(), cmd, flag);
611 // try the BufferView
612 decided = bv->getStatus(cmd, flag);
615 decided = bv->buffer().getStatus(cmd, flag);
616 if (!decided && doc_bv)
617 // try the Document Buffer
618 decided = doc_bv->buffer().getStatus(cmd, flag);
622 flag.setEnabled(false);
624 // Can we use a readonly buffer?
625 if (buf && buf->isReadonly()
626 && !lyxaction.funcHasFlag(cmd.action, LyXAction::ReadOnly)
627 && !lyxaction.funcHasFlag(cmd.action, LyXAction::NoBuffer)) {
628 flag.message(from_utf8(N_("Document is read-only")));
629 flag.setEnabled(false);
632 // Are we in a DELETED change-tracking region?
633 if (lyx_view_ && lyx_view_->documentBufferView()
634 && (lookupChangeType(lyx_view_->documentBufferView()->cursor(), true)
636 && !lyxaction.funcHasFlag(cmd.action, LyXAction::ReadOnly)
637 && !lyxaction.funcHasFlag(cmd.action, LyXAction::NoBuffer)) {
638 flag.message(from_utf8(N_("This portion of the document is deleted.")));
639 flag.setEnabled(false);
642 // the default error message if we disable the command
643 if (!flag.enabled() && flag.message().empty())
644 flag.message(from_utf8(N_("Command disabled")));
652 bool loadLayoutFile(string const & name, string const & buf_path)
654 if (!LayoutFileList::get().haveClass(name)) {
655 lyxerr << "Document class \"" << name
656 << "\" does not exist."
661 LayoutFile & tc = LayoutFileList::get()[name];
662 if (!tc.load(buf_path)) {
663 docstring s = bformat(_("The document class %1$s "
664 "could not be loaded."), from_utf8(name));
665 Alert::error(_("Could not load class"), s);
672 void actOnUpdatedPrefs(LyXRC const & lyxrc_orig, LyXRC const & lyxrc_new);
677 void LyXFunc::dispatch(FuncRequest const & cmd)
679 string const argument = to_utf8(cmd.argument());
680 FuncCode const action = cmd.action;
682 LYXERR(Debug::ACTION, "\nLyXFunc::dispatch: cmd: " << cmd);
683 //lyxerr << "LyXFunc::dispatch: cmd: " << cmd << endl;
685 // we have not done anything wrong yet.
687 dispatch_buffer.erase();
689 // redraw the screen at the end (first of the two drawing steps).
690 //This is done unless explicitely requested otherwise
691 Update::flags updateFlags = Update::FitCursor;
693 FuncStatus const flag = getStatus(cmd);
694 if (!flag.enabled()) {
695 // We cannot use this function here
696 LYXERR(Debug::ACTION, "LyXFunc::dispatch: "
697 << lyxaction.getActionName(action)
698 << " [" << action << "] is disabled at this location");
699 setErrorMessage(flag.message());
701 lyx_view_->restartCursor();
704 if (lyx_view_ && lyx_view_->currentBufferView())
705 buffer = &lyx_view_->currentBufferView()->buffer();
708 case LFUN_COMMAND_PREFIX:
709 LASSERT(lyx_view_, /**/);
710 lyx_view_->message(keyseq.printOptions(true));
714 LASSERT(lyx_view_ && lyx_view_->currentBufferView(), /**/);
716 meta_fake_bit = NoModifier;
718 // cancel any selection
719 dispatch(FuncRequest(LFUN_MARK_OFF));
720 setMessage(from_ascii(N_("Cancel")));
723 case LFUN_META_PREFIX:
724 meta_fake_bit = AltModifier;
725 setMessage(keyseq.print(KeySequence::ForGui));
728 // --- Menus -----------------------------------------------
729 case LFUN_RECONFIGURE:
730 // argument is any additional parameter to the configure.py command
731 reconfigure(lyx_view_, argument);
734 case LFUN_HELP_OPEN: {
736 theApp()->dispatch(FuncRequest(LFUN_WINDOW_NEW));
737 string const arg = argument;
739 setErrorMessage(from_utf8(N_("Missing argument")));
742 FileName fname = i18nLibFileSearch("doc", arg, "lyx");
744 fname = i18nLibFileSearch("examples", arg, "lyx");
747 lyxerr << "LyX: unable to find documentation file `"
748 << arg << "'. Bad installation?" << endl;
751 lyx_view_->message(bformat(_("Opening help file %1$s..."),
752 makeDisplayPath(fname.absFilename())));
753 Buffer * buf = lyx_view_->loadDocument(fname, false);
756 lyx_view_->setBuffer(buf);
757 buf->errors("Parse");
759 updateFlags = Update::None;
763 // --- lyxserver commands ----------------------------
764 case LFUN_SERVER_GET_FILENAME:
765 LASSERT(lyx_view_ && buffer, /**/);
766 setMessage(from_utf8(buffer->absFileName()));
767 LYXERR(Debug::INFO, "FNAME["
768 << buffer->absFileName() << ']');
771 case LFUN_SERVER_NOTIFY:
772 dispatch_buffer = keyseq.print(KeySequence::Portable);
773 theServer().notifyClient(to_utf8(dispatch_buffer));
776 case LFUN_SERVER_GOTO_FILE_ROW: {
777 LASSERT(lyx_view_, /**/);
780 istringstream is(argument);
781 is >> file_name >> row;
782 file_name = os::internal_path(file_name);
785 string const abstmp = package().temp_dir().absFilename();
786 string const realtmp = package().temp_dir().realPath();
787 // We have to use os::path_prefix_is() here, instead of
788 // simply prefixIs(), because the file name comes from
789 // an external application and may need case adjustment.
790 if (os::path_prefix_is(file_name, abstmp, os::CASE_ADJUSTED)
791 || os::path_prefix_is(file_name, realtmp, os::CASE_ADJUSTED)) {
792 // Needed by inverse dvi search. If it is a file
793 // in tmpdir, call the apropriated function.
794 // If tmpdir is a symlink, we may have the real
795 // path passed back, so we correct for that.
796 if (!prefixIs(file_name, abstmp))
797 file_name = subst(file_name, realtmp, abstmp);
798 buf = theBufferList().getBufferFromTmp(file_name);
800 // Must replace extension of the file to be .lyx
802 FileName const s = fileSearch(string(), changeExtension(file_name, ".lyx"), "lyx");
803 // Either change buffer or load the file
804 if (theBufferList().exists(s))
805 buf = theBufferList().getBuffer(s);
806 else if (s.exists()) {
807 buf = lyx_view_->loadDocument(s);
810 lyx_view_->message(bformat(
811 _("File does not exist: %1$s"),
812 makeDisplayPath(file_name)));
816 updateFlags = Update::None;
821 lyx_view_->setBuffer(buf);
822 lyx_view_->documentBufferView()->setCursorFromRow(row);
824 buf->errors("Parse");
825 updateFlags = Update::FitCursor;
830 case LFUN_DIALOG_SHOW_NEW_INSET: {
831 LASSERT(lyx_view_, /**/);
832 string const name = cmd.getArg(0);
833 InsetCode code = insetCode(name);
834 string data = trim(to_utf8(cmd.argument()).substr(name.size()));
835 bool insetCodeOK = true;
842 case NOMENCL_PRINT_CODE:
845 case HYPERLINK_CODE: {
846 InsetCommandParams p(code);
847 data = InsetCommand::params2string(name, p);
851 // data is the include type: one of "include",
852 // "input", "verbatiminput" or "verbatiminput*"
854 // default type is requested
856 InsetCommandParams p(INCLUDE_CODE, data);
857 data = InsetCommand::params2string("include", p);
861 // \c data == "Boxed" || "Frameless" etc
862 InsetBoxParams p(data);
863 data = InsetBox::params2string(p);
868 data = InsetBranch::params2string(p);
872 InsetCommandParams p(CITE_CODE);
873 data = InsetCommand::params2string(name, p);
877 data = InsetERT::params2string(InsetCollapsable::Open);
880 case EXTERNAL_CODE: {
881 InsetExternalParams p;
882 data = InsetExternal::params2string(p, *buffer);
887 data = InsetFloat::params2string(p);
890 case LISTINGS_CODE: {
891 InsetListingsParams p;
892 data = InsetListings::params2string(p);
895 case GRAPHICS_CODE: {
896 InsetGraphicsParams p;
897 data = InsetGraphics::params2string(p, *buffer);
902 data = InsetNote::params2string(p);
906 InsetPhantomParams p;
907 data = InsetPhantom::params2string(p);
912 data = InsetSpace::params2string(p);
917 data = InsetVSpace::params2string(space);
922 data = InsetWrap::params2string(p);
926 lyxerr << "Inset type '" << name <<
927 "' not recognized in LFUN_DIALOG_SHOW_NEW_INSET" << endl;
930 } // end switch(code)
932 dispatch(FuncRequest(LFUN_DIALOG_SHOW, name + " " + data));
936 case LFUN_CITATION_INSERT: {
937 LASSERT(lyx_view_, /**/);
938 if (!argument.empty()) {
939 // we can have one optional argument, delimited by '|'
940 // citation-insert <key>|<text_before>
941 // this should be enhanced to also support text_after
942 // and citation style
943 string arg = argument;
945 if (contains(argument, "|")) {
946 arg = token(argument, '|', 0);
947 opt1 = token(argument, '|', 1);
949 InsetCommandParams icp(CITE_CODE);
950 icp["key"] = from_utf8(arg);
952 icp["before"] = from_utf8(opt1);
953 string icstr = InsetCommand::params2string("citation", icp);
954 FuncRequest fr(LFUN_INSET_INSERT, icstr);
957 dispatch(FuncRequest(LFUN_DIALOG_SHOW_NEW_INSET, "citation"));
961 case LFUN_CURSOR_FOLLOWS_SCROLLBAR_TOGGLE:
962 LASSERT(lyx_view_, /**/);
963 lyxrc.cursor_follows_scrollbar = !lyxrc.cursor_follows_scrollbar;
969 string rest = split(argument, countstr, ' ');
970 istringstream is(countstr);
973 //lyxerr << "repeat: count: " << count << " cmd: " << rest << endl;
974 for (int i = 0; i < count; ++i)
975 dispatch(lyxaction.lookupFunc(rest));
979 case LFUN_COMMAND_SEQUENCE: {
980 // argument contains ';'-terminated commands
981 string arg = argument;
982 if (theBufferList().isLoaded(buffer))
983 buffer->undo().beginUndoGroup();
984 while (!arg.empty()) {
986 arg = split(arg, first, ';');
987 FuncRequest func(lyxaction.lookupFunc(first));
988 func.origin = cmd.origin;
991 if (theBufferList().isLoaded(buffer))
992 buffer->undo().endUndoGroup();
996 case LFUN_COMMAND_ALTERNATIVES: {
997 // argument contains ';'-terminated commands
998 string arg = argument;
999 while (!arg.empty()) {
1001 arg = split(arg, first, ';');
1002 FuncRequest func(lyxaction.lookupFunc(first));
1003 func.origin = cmd.origin;
1004 FuncStatus stat = getStatus(func);
1005 if (stat.enabled()) {
1015 if (theTopLevelCmdDef().lock(argument, func)) {
1016 func.origin = cmd.origin;
1018 theTopLevelCmdDef().release(argument);
1020 if (func.action == LFUN_UNKNOWN_ACTION) {
1021 // unknown command definition
1022 lyxerr << "Warning: unknown command definition `"
1026 // recursion detected
1027 lyxerr << "Warning: Recursion in the command definition `"
1028 << argument << "' detected"
1035 case LFUN_PREFERENCES_SAVE: {
1036 lyxrc.write(makeAbsPath("preferences",
1037 package().user_support().absFilename()),
1042 case LFUN_BUFFER_SAVE_AS_DEFAULT: {
1043 string const fname =
1044 addName(addPath(package().user_support().absFilename(), "templates/"),
1046 Buffer defaults(fname);
1048 istringstream ss(argument);
1051 int const unknown_tokens = defaults.readHeader(lex);
1053 if (unknown_tokens != 0) {
1054 lyxerr << "Warning in LFUN_BUFFER_SAVE_AS_DEFAULT!\n"
1055 << unknown_tokens << " unknown token"
1056 << (unknown_tokens == 1 ? "" : "s")
1060 if (defaults.writeFile(FileName(defaults.absFileName())))
1061 setMessage(bformat(_("Document defaults saved in %1$s"),
1062 makeDisplayPath(fname)));
1064 setErrorMessage(from_ascii(N_("Unable to save document defaults")));
1068 case LFUN_LAYOUT_MODULES_CLEAR: {
1069 LASSERT(lyx_view_ && lyx_view_->documentBufferView(), /**/);
1070 DocumentClass const * const oldClass = buffer->params().documentClassPtr();
1071 lyx_view_->documentBufferView()->cursor().recordUndoFullDocument();
1072 buffer->params().clearLayoutModules();
1073 buffer->params().makeDocumentClass();
1074 updateLayout(oldClass, buffer);
1075 updateFlags = Update::Force | Update::FitCursor;
1079 case LFUN_LAYOUT_MODULE_ADD: {
1080 LASSERT(lyx_view_ && lyx_view_->documentBufferView(), /**/);
1081 BufferParams const & params = buffer->params();
1082 if (!params.moduleCanBeAdded(argument)) {
1083 LYXERR0("Module `" << argument <<
1084 "' cannot be added due to failed requirements or "
1085 "conflicts with installed modules.");
1088 DocumentClass const * const oldClass = params.documentClassPtr();
1089 lyx_view_->documentBufferView()->cursor().recordUndoFullDocument();
1090 buffer->params().addLayoutModule(argument);
1091 buffer->params().makeDocumentClass();
1092 updateLayout(oldClass, buffer);
1093 updateFlags = Update::Force | Update::FitCursor;
1097 case LFUN_TEXTCLASS_APPLY: {
1098 LASSERT(lyx_view_ && lyx_view_->documentBufferView(), /**/);
1100 if (!loadLayoutFile(argument, buffer->temppath()) &&
1101 !loadLayoutFile(argument, buffer->filePath()))
1104 LayoutFile const * old_layout = buffer->params().baseClass();
1105 LayoutFile const * new_layout = &(LayoutFileList::get()[argument]);
1107 if (old_layout == new_layout)
1111 //Save the old, possibly modular, layout for use in conversion.
1112 DocumentClass const * const oldDocClass =
1113 buffer->params().documentClassPtr();
1114 lyx_view_->documentBufferView()->cursor().recordUndoFullDocument();
1115 buffer->params().setBaseClass(argument);
1116 buffer->params().makeDocumentClass();
1117 updateLayout(oldDocClass, buffer);
1118 updateFlags = Update::Force | Update::FitCursor;
1122 case LFUN_LAYOUT_RELOAD: {
1123 LASSERT(lyx_view_, /**/);
1124 DocumentClass const * const oldClass = buffer->params().documentClassPtr();
1125 LayoutFileIndex bc = buffer->params().baseClassID();
1126 LayoutFileList::get().reset(bc);
1127 buffer->params().setBaseClass(bc);
1128 buffer->params().makeDocumentClass();
1129 updateLayout(oldClass, buffer);
1130 updateFlags = Update::Force | Update::FitCursor;
1134 case LFUN_TEXTCLASS_LOAD:
1135 loadLayoutFile(argument, buffer->temppath()) ||
1136 loadLayoutFile(argument, buffer->filePath());
1139 case LFUN_LYXRC_APPLY: {
1140 // reset active key sequences, since the bindings
1141 // are updated (bug 6064)
1143 LyXRC const lyxrc_orig = lyxrc;
1145 istringstream ss(argument);
1146 bool const success = lyxrc.read(ss) == 0;
1149 lyxerr << "Warning in LFUN_LYXRC_APPLY!\n"
1150 << "Unable to read lyxrc data"
1155 actOnUpdatedPrefs(lyxrc_orig, lyxrc);
1159 theApp()->resetGui();
1161 /// We force the redraw in any case because there might be
1162 /// some screen font changes.
1163 /// FIXME: only the current view will be updated. the Gui
1164 /// class is able to furnish the list of views.
1165 updateFlags = Update::Force;
1169 case LFUN_BOOKMARK_GOTO:
1170 // go to bookmark, open unopened file and switch to buffer if necessary
1171 gotoBookmark(convert<unsigned int>(to_utf8(cmd.argument())), true, true);
1172 updateFlags = Update::FitCursor;
1175 case LFUN_BOOKMARK_CLEAR:
1176 theSession().bookmarks().clear();
1180 LASSERT(theApp(), /**/);
1181 // Let the frontend dispatch its own actions.
1182 if (theApp()->dispatch(cmd))
1183 // Nothing more to do.
1186 // Everything below is only for active lyx_view_
1190 // Start an undo group. This may be needed for
1191 // some stuff like inset-apply on labels.
1192 if (theBufferList().isLoaded(buffer))
1193 buffer->undo().beginUndoGroup();
1195 // Let the current LyXView dispatch its own actions.
1196 if (lyx_view_->dispatch(cmd)) {
1197 if (lyx_view_->currentBufferView()) {
1198 updateFlags = lyx_view_->currentBufferView()->cursor().result().update();
1199 if (theBufferList().isLoaded(buffer))
1200 buffer->undo().endUndoGroup();
1205 LASSERT(lyx_view_->currentBufferView(), /**/);
1207 // Let the current BufferView dispatch its own actions.
1208 if (lyx_view_->currentBufferView()->dispatch(cmd)) {
1209 // The BufferView took care of its own updates if needed.
1210 updateFlags = Update::None;
1211 if (theBufferList().isLoaded(buffer))
1212 buffer->undo().endUndoGroup();
1216 // OK, so try the Buffer itself
1218 BufferView * bv = lyx_view_->currentBufferView();
1219 bv->buffer().dispatch(cmd, dr);
1220 if (dr.dispatched()) {
1221 updateFlags = dr.update();
1224 // OK, so try with the document Buffer.
1225 BufferView * doc_bv = lyx_view_->documentBufferView();
1227 buffer = &(doc_bv->buffer());
1228 buffer->dispatch(cmd, dr);
1229 if (dr.dispatched()) {
1230 updateFlags = dr.update();
1235 // Is this a function that acts on inset at point?
1236 Inset * inset = bv->cursor().nextInset();
1237 if (lyxaction.funcHasFlag(action, LyXAction::AtPoint)
1239 bv->cursor().result().dispatched(true);
1240 bv->cursor().result().update(Update::FitCursor | Update::Force);
1241 FuncRequest tmpcmd = cmd;
1242 inset->dispatch(bv->cursor(), tmpcmd);
1243 if (bv->cursor().result().dispatched()) {
1244 updateFlags = bv->cursor().result().update();
1249 // Let the current Cursor dispatch its own actions.
1250 Cursor old = bv->cursor();
1251 bv->cursor().getPos(cursorPosBeforeDispatchX_,
1252 cursorPosBeforeDispatchY_);
1253 bv->cursor().dispatch(cmd);
1255 // notify insets we just left
1256 if (bv->cursor() != old) {
1258 bool badcursor = notifyCursorLeavesOrEnters(old, bv->cursor());
1260 bv->cursor().fixIfBroken();
1263 if (theBufferList().isLoaded(buffer))
1264 buffer->undo().endUndoGroup();
1266 // update completion. We do it here and not in
1267 // processKeySym to avoid another redraw just for a
1268 // changed inline completion
1269 if (cmd.origin == FuncRequest::KEYBOARD) {
1270 if (cmd.action == LFUN_SELF_INSERT
1271 || (cmd.action == LFUN_ERT_INSERT && bv->cursor().inMathed()))
1272 lyx_view_->updateCompletion(bv->cursor(), true, true);
1273 else if (cmd.action == LFUN_CHAR_DELETE_BACKWARD)
1274 lyx_view_->updateCompletion(bv->cursor(), false, true);
1276 lyx_view_->updateCompletion(bv->cursor(), false, false);
1279 updateFlags = bv->cursor().result().update();
1282 // if we executed a mutating lfun, mark the buffer as dirty
1283 if (theBufferList().isLoaded(buffer) && flag.enabled()
1284 && !lyxaction.funcHasFlag(action, LyXAction::NoBuffer)
1285 && !lyxaction.funcHasFlag(action, LyXAction::ReadOnly))
1286 buffer->markDirty();
1288 if (lyx_view_ && lyx_view_->currentBufferView()) {
1289 // BufferView::update() updates the ViewMetricsInfo and
1290 // also initializes the position cache for all insets in
1291 // (at least partially) visible top-level paragraphs.
1292 // We will redraw the screen only if needed.
1293 lyx_view_->currentBufferView()->processUpdateFlags(updateFlags);
1295 // Do we have a selection?
1296 theSelection().haveSelection(
1297 lyx_view_->currentBufferView()->cursor().selection());
1300 lyx_view_->restartCursor();
1304 // Some messages may already be translated, so we cannot use _()
1305 sendDispatchMessage(translateIfPossible(getMessage()), cmd);
1310 void LyXFunc::sendDispatchMessage(docstring const & msg, FuncRequest const & cmd)
1312 const bool verbose = (cmd.origin == FuncRequest::MENU
1313 || cmd.origin == FuncRequest::TOOLBAR
1314 || cmd.origin == FuncRequest::COMMANDBUFFER);
1316 if (cmd.action == LFUN_SELF_INSERT || !verbose) {
1317 LYXERR(Debug::ACTION, "dispatch msg is " << to_utf8(msg));
1319 lyx_view_->message(msg);
1323 docstring dispatch_msg = msg;
1324 if (!dispatch_msg.empty())
1325 dispatch_msg += ' ';
1327 docstring comname = from_utf8(lyxaction.getActionName(cmd.action));
1329 bool argsadded = false;
1331 if (!cmd.argument().empty()) {
1332 if (cmd.action != LFUN_UNKNOWN_ACTION) {
1333 comname += ' ' + cmd.argument();
1338 docstring const shortcuts = theTopLevelKeymap().printBindings(cmd, KeySequence::ForGui);
1340 if (!shortcuts.empty())
1341 comname += ": " + shortcuts;
1342 else if (!argsadded && !cmd.argument().empty())
1343 comname += ' ' + cmd.argument();
1345 if (!comname.empty()) {
1346 comname = rtrim(comname);
1347 dispatch_msg += '(' + rtrim(comname) + ')';
1350 LYXERR(Debug::ACTION, "verbose dispatch msg " << to_utf8(dispatch_msg));
1351 if (!dispatch_msg.empty())
1352 lyx_view_->message(dispatch_msg);
1356 // Each "lyx_view_" should have it's own message method. lyxview and
1357 // the minibuffer would use the minibuffer, but lyxserver would
1358 // send an ERROR signal to its client. Alejandro 970603
1359 // This function is bit problematic when it comes to NLS, to make the
1360 // lyx servers client be language indepenent we must not translate
1361 // strings sent to this func.
1362 void LyXFunc::setErrorMessage(docstring const & m) const
1364 dispatch_buffer = m;
1369 void LyXFunc::setMessage(docstring const & m) const
1371 dispatch_buffer = m;
1375 docstring LyXFunc::viewStatusMessage()
1377 // When meta-fake key is pressed, show the key sequence so far + "M-".
1379 return keyseq.print(KeySequence::ForGui) + "M-";
1381 // Else, when a non-complete key sequence is pressed,
1382 // show the available options.
1383 if (keyseq.length() > 0 && !keyseq.deleted())
1384 return keyseq.printOptions(true);
1386 LASSERT(lyx_view_, /**/);
1387 if (!lyx_view_->currentBufferView())
1388 return _("Welcome to LyX!");
1390 return lyx_view_->currentBufferView()->cursor().currentState();
1394 bool LyXFunc::wasMetaKey() const
1396 return (meta_fake_bit != NoModifier);
1400 void LyXFunc::updateLayout(DocumentClass const * const oldlayout, Buffer * buf)
1402 lyx_view_->message(_("Converting document to new document class..."));
1404 StableDocIterator backcur(lyx_view_->currentBufferView()->cursor());
1405 ErrorList & el = buf->errorList("Class Switch");
1406 cap::switchBetweenClasses(
1407 oldlayout, buf->params().documentClassPtr(),
1408 static_cast<InsetText &>(buf->inset()), el);
1410 lyx_view_->currentBufferView()->setCursor(backcur.asDocIterator(buf));
1412 buf->errors("Class Switch");
1413 buf->updateLabels();
1419 void actOnUpdatedPrefs(LyXRC const & lyxrc_orig, LyXRC const & lyxrc_new)
1421 // Why the switch you might ask. It is a trick to ensure that all
1422 // the elements in the LyXRCTags enum is handled. As you can see
1423 // there are no breaks at all. So it is just a huge fall-through.
1424 // The nice thing is that we will get a warning from the compiler
1425 // if we forget an element.
1426 LyXRC::LyXRCTags tag = LyXRC::RC_LAST;
1428 case LyXRC::RC_ACCEPT_COMPOUND:
1429 case LyXRC::RC_ALT_LANG:
1430 case LyXRC::RC_PLAINTEXT_LINELEN:
1431 case LyXRC::RC_PLAINTEXT_ROFF_COMMAND:
1432 case LyXRC::RC_AUTOCORRECTION_MATH:
1433 case LyXRC::RC_AUTOREGIONDELETE:
1434 case LyXRC::RC_AUTORESET_OPTIONS:
1435 case LyXRC::RC_AUTOSAVE:
1436 case LyXRC::RC_AUTO_NUMBER:
1437 case LyXRC::RC_BACKUPDIR_PATH:
1438 case LyXRC::RC_BIBTEX_ALTERNATIVES:
1439 case LyXRC::RC_BIBTEX_COMMAND:
1440 case LyXRC::RC_BINDFILE:
1441 case LyXRC::RC_CHECKLASTFILES:
1442 case LyXRC::RC_COMPLETION_CURSOR_TEXT:
1443 case LyXRC::RC_COMPLETION_INLINE_DELAY:
1444 case LyXRC::RC_COMPLETION_INLINE_DOTS:
1445 case LyXRC::RC_COMPLETION_INLINE_MATH:
1446 case LyXRC::RC_COMPLETION_INLINE_TEXT:
1447 case LyXRC::RC_COMPLETION_POPUP_AFTER_COMPLETE:
1448 case LyXRC::RC_COMPLETION_POPUP_DELAY:
1449 case LyXRC::RC_COMPLETION_POPUP_MATH:
1450 case LyXRC::RC_COMPLETION_POPUP_TEXT:
1451 case LyXRC::RC_USELASTFILEPOS:
1452 case LyXRC::RC_LOADSESSION:
1453 case LyXRC::RC_CHKTEX_COMMAND:
1454 case LyXRC::RC_CONVERTER:
1455 case LyXRC::RC_CONVERTER_CACHE_MAXAGE:
1456 case LyXRC::RC_COPIER:
1457 case LyXRC::RC_CURSOR_FOLLOWS_SCROLLBAR:
1458 case LyXRC::RC_SCROLL_BELOW_DOCUMENT:
1459 case LyXRC::RC_DATE_INSERT_FORMAT:
1460 case LyXRC::RC_DEFAULT_LANGUAGE:
1461 case LyXRC::RC_GUI_LANGUAGE:
1462 case LyXRC::RC_DEFAULT_PAPERSIZE:
1463 case LyXRC::RC_DEFAULT_VIEW_FORMAT:
1464 case LyXRC::RC_DEFFILE:
1465 case LyXRC::RC_DIALOGS_ICONIFY_WITH_MAIN:
1466 case LyXRC::RC_DISPLAY_GRAPHICS:
1467 case LyXRC::RC_DOCUMENTPATH:
1468 if (lyxrc_orig.document_path != lyxrc_new.document_path) {
1469 FileName path(lyxrc_new.document_path);
1470 if (path.exists() && path.isDirectory())
1471 package().document_dir() = FileName(lyxrc.document_path);
1473 case LyXRC::RC_EDITOR_ALTERNATIVES:
1474 case LyXRC::RC_ESC_CHARS:
1475 case LyXRC::RC_EXAMPLEPATH:
1476 case LyXRC::RC_FONT_ENCODING:
1477 case LyXRC::RC_FORMAT:
1478 case LyXRC::RC_GROUP_LAYOUTS:
1479 case LyXRC::RC_HUNSPELLDIR_PATH:
1480 case LyXRC::RC_INDEX_ALTERNATIVES:
1481 case LyXRC::RC_INDEX_COMMAND:
1482 case LyXRC::RC_JBIBTEX_COMMAND:
1483 case LyXRC::RC_JINDEX_COMMAND:
1484 case LyXRC::RC_NOMENCL_COMMAND:
1485 case LyXRC::RC_INPUT:
1486 case LyXRC::RC_KBMAP:
1487 case LyXRC::RC_KBMAP_PRIMARY:
1488 case LyXRC::RC_KBMAP_SECONDARY:
1489 case LyXRC::RC_LABEL_INIT_LENGTH:
1490 case LyXRC::RC_LANGUAGE_AUTO_BEGIN:
1491 case LyXRC::RC_LANGUAGE_AUTO_END:
1492 case LyXRC::RC_LANGUAGE_COMMAND_BEGIN:
1493 case LyXRC::RC_LANGUAGE_COMMAND_END:
1494 case LyXRC::RC_LANGUAGE_COMMAND_LOCAL:
1495 case LyXRC::RC_LANGUAGE_GLOBAL_OPTIONS:
1496 case LyXRC::RC_LANGUAGE_PACKAGE:
1497 case LyXRC::RC_LANGUAGE_USE_BABEL:
1498 case LyXRC::RC_MAC_LIKE_WORD_MOVEMENT:
1499 case LyXRC::RC_MACRO_EDIT_STYLE:
1500 case LyXRC::RC_MAKE_BACKUP:
1501 case LyXRC::RC_MARK_FOREIGN_LANGUAGE:
1502 case LyXRC::RC_MOUSE_WHEEL_SPEED:
1503 case LyXRC::RC_NUMLASTFILES:
1504 case LyXRC::RC_PARAGRAPH_MARKERS:
1505 case LyXRC::RC_PATH_PREFIX:
1506 if (lyxrc_orig.path_prefix != lyxrc_new.path_prefix) {
1507 prependEnvPath("PATH", lyxrc.path_prefix);
1509 case LyXRC::RC_PERS_DICT:
1510 case LyXRC::RC_PREVIEW:
1511 case LyXRC::RC_PREVIEW_HASHED_LABELS:
1512 case LyXRC::RC_PREVIEW_SCALE_FACTOR:
1513 case LyXRC::RC_PRINTCOLLCOPIESFLAG:
1514 case LyXRC::RC_PRINTCOPIESFLAG:
1515 case LyXRC::RC_PRINTER:
1516 case LyXRC::RC_PRINTEVENPAGEFLAG:
1517 case LyXRC::RC_PRINTEXSTRAOPTIONS:
1518 case LyXRC::RC_PRINTFILEEXTENSION:
1519 case LyXRC::RC_PRINTLANDSCAPEFLAG:
1520 case LyXRC::RC_PRINTODDPAGEFLAG:
1521 case LyXRC::RC_PRINTPAGERANGEFLAG:
1522 case LyXRC::RC_PRINTPAPERDIMENSIONFLAG:
1523 case LyXRC::RC_PRINTPAPERFLAG:
1524 case LyXRC::RC_PRINTREVERSEFLAG:
1525 case LyXRC::RC_PRINTSPOOL_COMMAND:
1526 case LyXRC::RC_PRINTSPOOL_PRINTERPREFIX:
1527 case LyXRC::RC_PRINTTOFILE:
1528 case LyXRC::RC_PRINTTOPRINTER:
1529 case LyXRC::RC_PRINT_ADAPTOUTPUT:
1530 case LyXRC::RC_PRINT_COMMAND:
1531 case LyXRC::RC_RTL_SUPPORT:
1532 case LyXRC::RC_SCREEN_DPI:
1533 case LyXRC::RC_SCREEN_FONT_ROMAN:
1534 case LyXRC::RC_SCREEN_FONT_ROMAN_FOUNDRY:
1535 case LyXRC::RC_SCREEN_FONT_SANS:
1536 case LyXRC::RC_SCREEN_FONT_SANS_FOUNDRY:
1537 case LyXRC::RC_SCREEN_FONT_SCALABLE:
1538 case LyXRC::RC_SCREEN_FONT_SIZES:
1539 case LyXRC::RC_SCREEN_FONT_TYPEWRITER:
1540 case LyXRC::RC_SCREEN_FONT_TYPEWRITER_FOUNDRY:
1541 case LyXRC::RC_GEOMETRY_SESSION:
1542 case LyXRC::RC_SCREEN_ZOOM:
1543 case LyXRC::RC_SERVERPIPE:
1544 case LyXRC::RC_SET_COLOR:
1545 case LyXRC::RC_SHOW_BANNER:
1546 case LyXRC::RC_OPEN_BUFFERS_IN_TABS:
1547 case LyXRC::RC_SPELL_COMMAND:
1548 case LyXRC::RC_SPELLCHECKER:
1549 case LyXRC::RC_SPELLCHECK_CONTINUOUSLY:
1550 case LyXRC::RC_SPLITINDEX_COMMAND:
1551 case LyXRC::RC_TEMPDIRPATH:
1552 case LyXRC::RC_TEMPLATEPATH:
1553 case LyXRC::RC_TEX_ALLOWS_SPACES:
1554 case LyXRC::RC_TEX_EXPECTS_WINDOWS_PATHS:
1555 if (lyxrc_orig.windows_style_tex_paths != lyxrc_new.windows_style_tex_paths) {
1556 os::windows_style_tex_paths(lyxrc_new.windows_style_tex_paths);
1558 case LyXRC::RC_THESAURUSDIRPATH:
1559 case LyXRC::RC_UIFILE:
1560 case LyXRC::RC_USER_EMAIL:
1561 case LyXRC::RC_USER_NAME:
1562 case LyXRC::RC_USETEMPDIR:
1563 case LyXRC::RC_USE_ALT_LANG:
1564 case LyXRC::RC_USE_CONVERTER_CACHE:
1565 case LyXRC::RC_USE_ESC_CHARS:
1566 case LyXRC::RC_USE_INP_ENC:
1567 case LyXRC::RC_USE_PERS_DICT:
1568 case LyXRC::RC_USE_TOOLTIP:
1569 case LyXRC::RC_USE_PIXMAP_CACHE:
1570 case LyXRC::RC_USE_SPELL_LIB:
1571 case LyXRC::RC_VIEWDVI_PAPEROPTION:
1572 case LyXRC::RC_SORT_LAYOUTS:
1573 case LyXRC::RC_FULL_SCREEN_LIMIT:
1574 case LyXRC::RC_FULL_SCREEN_SCROLLBAR:
1575 case LyXRC::RC_FULL_SCREEN_MENUBAR:
1576 case LyXRC::RC_FULL_SCREEN_TABBAR:
1577 case LyXRC::RC_FULL_SCREEN_TOOLBARS:
1578 case LyXRC::RC_FULL_SCREEN_WIDTH:
1579 case LyXRC::RC_VISUAL_CURSOR:
1580 case LyXRC::RC_VIEWER:
1581 case LyXRC::RC_VIEWER_ALTERNATIVES:
1582 case LyXRC::RC_LAST: