X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Flyx_main.C;h=7b4b8ce795c6bcff9aa1f72a2aee920498bdfba6;hb=1fa0fb5c67656cacbe3cfe6e8b08dd98cada1f73;hp=d29b23455096cdaf9a50cd2f0e48143b183f80a2;hpb=8e5e95247280998287554937870c44a20fc493c7;p=lyx.git diff --git a/src/lyx_main.C b/src/lyx_main.C index d29b234550..7b4b8ce795 100644 --- a/src/lyx_main.C +++ b/src/lyx_main.C @@ -1,52 +1,84 @@ /** * \file lyx_main.C - * Copyright 1995-2002 the LyX Team - * Read the file COPYING + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. * - * \author unknown + * \author Alfredo Braunstein + * \author Lars Gullik Bjønnes + * \author Jean-Marc Lasgouttes + * \author John Levon + * \author André Pönitz + * + * Full author contact details are available in file CREDITS. */ #include #include -#ifdef __GNUG__ -#pragma implementation -#endif - #include "lyx_main.h" -#include "support/filetools.h" -#include "support/lyxlib.h" -#include "support/os.h" -#include "support/FileInfo.h" -#include "support/path.h" +#include "buffer.h" +#include "buffer_funcs.h" +#include "bufferlist.h" +#include "converter.h" #include "debug.h" +#include "encoding.h" +#include "errorlist.h" +#include "format.h" #include "gettext.h" -#include "lyxlex.h" - -#include "bufferlist.h" -#include "buffer.h" -#include "lyxserver.h" #include "kbmap.h" -#include "lyxfunc.h" -#include "ToolbarDefaults.h" -#include "MenuBackend.h" #include "language.h" #include "lastfiles.h" -#include "encoding.h" -#include "converter.h" +#include "LColor.h" +#include "lyxfunc.h" +#include "lyxlex.h" +#include "lyxrc.h" #include "lyxtextclasslist.h" +#include "lyxserver.h" +#include "MenuBackend.h" +#include "ToolbarBackend.h" + +#include "mathed/math_inset.h" #include "frontends/Alert.h" #include "frontends/lyx_gui.h" +#include "frontends/LyXView.h" -#include +#include "support/FileInfo.h" +#include "support/filetools.h" +#include "support/lyxlib.h" +#include "support/os.h" +#include "support/path.h" +#include "support/path_defines.h" + +#include -#include +#include #include -using std::vector; +using lyx::support::AddName; +using lyx::support::AddPath; +using lyx::support::bformat; +using lyx::support::createDirectory; +using lyx::support::createLyXTmpDir; +using lyx::support::FileInfo; +using lyx::support::FileSearch; +using lyx::support::GetEnv; +using lyx::support::GetEnvPath; +using lyx::support::i18nLibFileSearch; +using lyx::support::LibFileSearch; +using lyx::support::Path; +using lyx::support::rtrim; +using lyx::support::setLyxPaths; +using lyx::support::system_lyxdir; +using lyx::support::user_lyxdir; + +using lyx::support::os::getTmpDir; +using lyx::support::os::setTmpDir; + using std::endl; +using std::string; +using std::vector; #ifndef CXX_GLOBAL_CSTD using std::exit; @@ -54,48 +86,115 @@ using std::signal; using std::system; #endif -extern void LoadLyXFile(string const &); + extern void QuitLyX(); extern LyXServer * lyxserver; -string system_lyxdir; -string build_lyxdir; -string system_tempdir; -string user_lyxdir; - -DebugStream lyxerr; - -boost::scoped_ptr lastfiles; - // This is the global bufferlist object BufferList bufferlist; // convenient to have it here. boost::scoped_ptr toplevel_keymap; +namespace { -LyX::LyX(int & argc, char * argv[]) +void showFileError(string const & error) +{ + Alert::warning(_("Could not read configuration file"), + bformat(_("Error while reading the configuration file\n%1$s.\n" + "Please check your installation."), error)); + exit(EXIT_FAILURE); +} + +} // namespace anon + + +boost::scoped_ptr LyX::singleton_; + +void LyX::exec(int & argc, char * argv[]) +{ + BOOST_ASSERT(!singleton_.get()); + // We must return from this before launching the gui so that + // other parts of the code can access singleton_ through + // LyX::ref and LyX::cref. + singleton_.reset(new LyX); + // Start the real execution loop. + singleton_->priv_exec(argc, argv); +} + + +LyX & LyX::ref() +{ + BOOST_ASSERT(singleton_.get()); + return *singleton_.get(); +} + + +LyX const & LyX::cref() +{ + BOOST_ASSERT(singleton_.get()); + return *singleton_.get(); +} + + +LyX::LyX() + : first_start(false) +{} + + +LastFiles & LyX::lastfiles() +{ + BOOST_ASSERT(lastfiles_.get()); + return *lastfiles_.get(); +} + + +LastFiles const & LyX::lastfiles() const +{ + BOOST_ASSERT(lastfiles_.get()); + return *lastfiles_.get(); +} + + +void LyX::addLyXView(boost::shared_ptr const & lyxview) +{ + views_.push_back(lyxview); +} + + +Buffer const * const LyX::updateInset(InsetBase const * inset) const +{ + if (!inset) + return 0; + + Buffer const * buffer_ptr = 0; + ViewList::const_iterator it = views_.begin(); + ViewList::const_iterator const end = views_.end(); + for (; it != end; ++it) { + Buffer const * ptr = (*it)->updateInset(inset); + if (ptr) + buffer_ptr = ptr; + } + return buffer_ptr; +} + + +void LyX::priv_exec(int & argc, char * argv[]) { // Here we need to parse the command line. At least // we need to parse for "-dbg" and "-help" bool const want_gui = easyParse(argc, argv); - // Global bindings (this must be done as early as possible.) (Lgb) - toplevel_keymap.reset(new kb_keymap); - defaultKeyBindings(toplevel_keymap.get()); - - if (want_gui) { + if (want_gui) lyx_gui::parse_init(argc, argv); - } // check for any spurious extra arguments // other than documents for (int argi = 1; argi < argc ; ++argi) { if (argv[argi][0] == '-') { - lyxerr << _("Wrong command line option `") - << argv[argi] - << _("'. Exiting.") << endl; + lyxerr << bformat(_("Wrong command line option `%1$s'. Exiting."), + argv[argi]) << endl; exit(1); } } @@ -105,48 +204,55 @@ LyX::LyX(int & argc, char * argv[]) init(want_gui); lyxerr[Debug::INIT] << "Initializing LyX::init...done" << endl; - if (want_gui) { + if (want_gui) lyx_gui::parse_lyxrc(); - } + + initMath(); vector files; - for (int argi = argc - 1; argi >= 1; --argi) { + for (int argi = argc - 1; argi >= 1; --argi) files.push_back(argv[argi]); - } - if (first_start) { + if (first_start) files.push_back(i18nLibFileSearch("examples", "splash.lyx")); - } // Execute batch commands if available if (!batch_command.empty()) { + lyxerr[Debug::INIT] << "About to handle -x '" - << batch_command << "'" << endl; + << batch_command << '\'' << endl; Buffer * last_loaded = 0; - vector::iterator it = files.begin(); - vector::iterator end = files.end(); + vector::const_iterator it = files.begin(); + vector::const_iterator end = files.end(); + for (; it != end; ++it) { - last_loaded = bufferlist.loadLyXFile(*it); + // get absolute path of file and add ".lyx" to + // the filename if necessary + string s = FileSearch(string(), *it, "lyx"); + if (s.empty()) { + last_loaded = newFile(*it, string(), true); + } else { + Buffer * buf = bufferlist.newBuffer(s, false); + buf->error.connect(boost::bind(&LyX::printError, this, _1)); + if (loadLyXFile(buf, s)) + last_loaded = buf; + else + bufferlist.release(buf); + } } - files.clear(); - - // no buffer loaded, create one - if (!last_loaded) - last_loaded = bufferlist.newFile("tmpfile", string()); - - bool success = false; - // try to dispatch to last loaded buffer first - bool const dispatched = last_loaded->dispatch(batch_command, &success); - - if (dispatched) { - QuitLyX(); - exit(!success); + if (last_loaded) { + bool success = false; + if (last_loaded->dispatch(batch_command, &success)) { + QuitLyX(); + exit(!success); + } } + files.clear(); // the files are already loaded } lyx_gui::start(batch_command, files); @@ -157,24 +263,42 @@ extern "C" { static void error_handler(int err_sig) { + // Throw away any signals other than the first one received. + static sig_atomic_t handling_error = false; + if (handling_error) + return; + handling_error = true; + + // We have received a signal indicating a fatal error, so + // try and save the data ASAP. + LyX::cref().emergencyCleanup(); + + // These lyxerr calls may or may not work: + + // Signals are asynchronous, so the main program may be in a very + // fragile state when a signal is processed and thus while a signal + // handler function executes. + // In general, therefore, we should avoid performing any + // I/O operations or calling most library and system functions from + // signal handlers. + + // This shouldn't matter here, however, as we've already invoked + // emergencyCleanup. switch (err_sig) { case SIGHUP: - lyxerr << "\nlyx: SIGHUP signal caught" << endl; - break; - case SIGINT: - // no comments + lyxerr << "\nlyx: SIGHUP signal caught\nBye." << endl; break; case SIGFPE: - lyxerr << "\nlyx: SIGFPE signal caught" << endl; + lyxerr << "\nlyx: SIGFPE signal caught\nBye." << endl; break; case SIGSEGV: - lyxerr << "\nlyx: SIGSEGV signal caught" << endl; - lyxerr << - "Sorry, you have found a bug in LyX. " - "Please read the bug-reporting instructions " - "in Help->Introduction and send us a bug report, " - "if necessary. Thanks !" << endl; + lyxerr << "\nlyx: SIGSEGV signal caught\n" + "Sorry, you have found a bug in LyX. " + "Please read the bug-reporting instructions " + "in Help->Introduction and send us a bug report, " + "if necessary. Thanks !\nBye." << endl; break; + case SIGINT: case SIGTERM: // no comments break; @@ -187,18 +311,23 @@ static void error_handler(int err_sig) signal(SIGSEGV, SIG_DFL); signal(SIGTERM, SIG_DFL); - LyX::emergencyCleanup(); - - lyxerr << "Bye." << endl; - if (err_sig!= SIGHUP && - (!GetEnv("LYXDEBUG").empty() || err_sig == SIGSEGV)) - lyx::abort(); + if (err_sig == SIGSEGV || + (err_sig != SIGHUP && !GetEnv("LYXDEBUG").empty())) + lyx::support::abort(); exit(0); } } +void LyX::printError(ErrorItem const & ei) +{ + std::cerr << _("LyX: ") << ei.error + << ':' << ei.description << std::endl; + +} + + void LyX::init(bool gui) { signal(SIGHUP, error_handler); @@ -206,186 +335,9 @@ void LyX::init(bool gui) signal(SIGSEGV, error_handler); signal(SIGINT, error_handler); signal(SIGTERM, error_handler); + // SIGPIPE can be safely ignored. - // - // Determine path of binary - // - - string binpath = os::binpath(); - string binname = os::binname(); - string fullbinname = MakeAbsPath(binname, binpath); - - if (binpath.empty()) { - lyxerr << _("Warning: could not determine path of binary.") - << "\n" - << _("If you have problems, try starting LyX with an absolute path.") - << endl; - } - lyxerr[Debug::INIT] << "Name of binary: " << binname << endl; - lyxerr[Debug::INIT] << "Path of binary: " << binpath << endl; - - // - // Determine system directory. - // - - // Directories are searched in this order: - // 1) -sysdir command line parameter - // 2) LYX_DIR_13x environment variable - // 3) Maybe /TOP_SRCDIR/lib - // 4) /../share// - // 4a) repeat 4 after following the Symlink if is a symbolic link. - // 5) hardcoded lyx_dir - // The directory is checked for the presence of the file - // "chkconfig.ltx", and if that is present, the directory - // is accepted as the system directory. - // If no chkconfig.ltx file is found, a warning is given, - // and the hardcoded lyx_dir is used. - - // If we had a command line switch, system_lyxdir is already set - string searchpath; - if (!system_lyxdir.empty()) - searchpath = MakeAbsPath(system_lyxdir) + ';'; - - string const lyxdir = GetEnvPath("LYX_DIR_13x"); - - if (!lyxdir.empty()) { - lyxerr[Debug::INIT] << "LYX_DIR_13x: " << lyxdir << endl; - searchpath += lyxdir + ';'; - } - - string fullbinpath = binpath; - FileInfo file(fullbinname, true); - if (file.isLink()) { - lyxerr[Debug::INIT] << "binary is a link" << endl; - string link; - if (LyXReadLink(fullbinname, link, true)) { - // Path of binary/../share/name of binary/ - searchpath += NormalizePath(AddPath(binpath, - "../share/") - + OnlyFilename(binname)); - searchpath += ';'; - fullbinpath = link; - binpath = MakeAbsPath(OnlyPath(fullbinpath)); - } - } - - bool followlink; - do { - // Path of binary/../share/name of binary/ - searchpath += NormalizePath(AddPath(binpath, "../share/") + - OnlyFilename(binname)) + ';'; - - // Follow Symlinks - FileInfo file(fullbinpath, true); - followlink = file.isLink(); - if (followlink) { - lyxerr << " directory " << fullbinpath - << " is a link" << endl; - string link; - if (LyXReadLink(fullbinpath, link, true)) { - fullbinpath = link; - binpath = MakeAbsPath(OnlyPath(fullbinpath)); - } - else { - followlink = false; - } - } - } while (followlink); - - // /TOP_SRCDIR/lib - build_lyxdir = MakeAbsPath("../lib", binpath); - if (!FileSearch(build_lyxdir, "lyxrc.defaults").empty()) { - searchpath += MakeAbsPath(AddPath(TOP_SRCDIR, "lib"), - binpath) + ';'; - lyxerr[Debug::INIT] << "Checking whether LyX is run in " - "place... yes" << endl; - } else { - lyxerr[Debug::INIT] - << "Checking whether LyX is run in place... no" - << endl; - build_lyxdir.erase(); - } - - // Hardcoded dir - searchpath += LYX_DIR; - - lyxerr[Debug::INIT] << "System directory search path: " - << searchpath << endl; - - string const filename = "chkconfig.ltx"; - string const temp = FileOpenSearch(searchpath, filename, string()); - system_lyxdir = OnlyPath(temp); - - // Reduce "path/../path" stuff out of system directory - system_lyxdir = NormalizePath(system_lyxdir); - - bool path_shown = false; - - // Warn if environment variable is set, but unusable - if (!lyxdir.empty()) { - if (system_lyxdir != NormalizePath(lyxdir)) { - lyxerr <<_("LYX_DIR_13x environment variable no good.") - << '\n' - << _("System directory set to: ") - << system_lyxdir << endl; - path_shown = true; - } - } - - // Warn the user if we couldn't find "chkconfig.ltx" - if (system_lyxdir == "./") { - lyxerr <<_("LyX Warning! Couldn't determine system directory. ") - <<_("Try the '-sysdir' command line parameter or ") - <<_("set the environment variable LYX_DIR_13x to the " - "LyX system directory ") - << _("containing the file `chkconfig.ltx'.") << endl; - if (!path_shown) { - FileInfo fi(LYX_DIR); - if (!fi.exist()) { - lyxerr << "Couldn't even find the default LYX_DIR." << endl - << "Giving up." << endl; - exit(1); - } - lyxerr << _("Using built-in default ") - << LYX_DIR << _(" but expect problems.") - << endl; - } else { - lyxerr << _("Expect problems.") << endl; - } - system_lyxdir = LYX_DIR; - path_shown = true; - } - - if (!path_shown) - lyxerr[Debug::INIT] << "System directory: '" - << system_lyxdir << '\'' << endl; - - // - // Determine user lyx-dir - // - - // Directories are searched in this order: - // 1) -userdir command line parameter - // 2) LYX_USERDIR_13x environment variable - // 3) $HOME/. - - // If we had a command line switch, user_lyxdir is already set - bool explicit_userdir = true; - if (user_lyxdir.empty()) { - - // LYX_USERDIR_13x environment variable - user_lyxdir = GetEnvPath("LYX_USERDIR_13x"); - - // default behaviour - if (user_lyxdir.empty()) - user_lyxdir = AddPath(GetEnvPath("HOME"), - string(".") + PACKAGE); - explicit_userdir = false; - } - - lyxerr[Debug::INIT] << "User LyX directory: '" - << user_lyxdir << '\'' << endl; + bool const explicit_userdir = setLyxPaths(); // Check that user LyX directory is ok. We don't do that if // running in batch mode. @@ -395,23 +347,23 @@ void LyX::init(bool gui) first_start = false; } - // - // Shine up lyxrc defaults - // + // Disable gui when easyparse says so + lyx_gui::use_gui = gui; - // Default template path: system_dir/templates if (lyxrc.template_path.empty()) { - lyxrc.template_path = AddPath(system_lyxdir, "templates"); + lyxrc.template_path = AddPath(system_lyxdir(), "templates"); } - // Default lastfiles file: $HOME/.lyx/lastfiles if (lyxrc.lastfiles.empty()) { - lyxrc.lastfiles = AddName(user_lyxdir, "lastfiles"); + lyxrc.lastfiles = AddName(user_lyxdir(), "lastfiles"); } - // Disable gui when either lyxrc or easyparse says so - if (!gui) - lyxrc.use_gui = false; + if (lyxrc.roman_font_name.empty()) + lyxrc.roman_font_name = lyx_gui::roman_font_name(); + if (lyxrc.sans_font_name.empty()) + lyxrc.sans_font_name = lyx_gui::sans_font_name(); + if (lyxrc.typewriter_font_name.empty()) + lyxrc.typewriter_font_name = lyx_gui::typewriter_font_name(); // // Read configuration files @@ -423,10 +375,12 @@ void LyX::init(bool gui) system_converters = converters; system_lcolor = lcolor; - // If there is a preferences file we read that instead - // of the old lyxrc file. - if (!readRcFile("preferences")) - readRcFile("lyxrc"); + string prefsfile = "preferences"; + // back compatibility to lyxs < 1.1.6 + if (LibFileSearch(string(), prefsfile).empty()) + prefsfile = "lyxrc"; + if (!LibFileSearch(string(), prefsfile).empty()) + readRcFile(prefsfile); readEncodingsFile("encodings"); readLanguagesFile("languages"); @@ -435,95 +389,101 @@ void LyX::init(bool gui) lyxerr[Debug::INIT] << "Reading layouts..." << endl; LyXSetStyle(); - // Ensure that we have really read a bind file, so that LyX is - // usable. - lyxrc.readBindFileIfNeeded(); - - // Read menus - readUIFile(lyxrc.ui_file); + if (gui) { + // Set up bindings + toplevel_keymap.reset(new kb_keymap); + defaultKeyBindings(toplevel_keymap.get()); + toplevel_keymap->read(lyxrc.bind_file); - // Bind the X dead keys to the corresponding LyX functions if - // necessary. - if (lyxrc.override_x_deadkeys) - deadKeyBindings(toplevel_keymap.get()); + // Read menus + readUIFile(lyxrc.ui_file); + } - if (lyxerr.debugging(Debug::LYXRC)) { + if (lyxerr.debugging(Debug::LYXRC)) lyxrc.print(); + + setTmpDir(createLyXTmpDir(lyxrc.tempdir_path)); + if (getTmpDir().empty()) { + Alert::error(_("Could not create temporary directory"), + bformat(_("Could not create a temporary directory in\n" + "%1$s. Make sure that this\n" + "path exists and is writable and try again."), + lyxrc.tempdir_path)); + // createLyXTmpDir() tries sufficiently hard to create a + // usable temp dir, so the probability to come here is + // close to zero. We therefore don't try to overcome this + // problem with e.g. asking the user for a new path and + // trying again but simply exit. + exit(EXIT_FAILURE); } - os::setTmpDir(CreateLyXTmpDir(lyxrc.tempdir_path)); - system_tempdir = os::getTmpDir(); if (lyxerr.debugging(Debug::INIT)) { - lyxerr << "LyX tmp dir: `" << system_tempdir << '\'' << endl; + lyxerr << "LyX tmp dir: `" << getTmpDir() << '\'' << endl; } lyxerr[Debug::INIT] << "Reading lastfiles `" << lyxrc.lastfiles << "'..." << endl; - lastfiles.reset(new LastFiles(lyxrc.lastfiles, - lyxrc.check_lastfiles, - lyxrc.num_lastfiles)); + lastfiles_.reset(new LastFiles(lyxrc.lastfiles, + lyxrc.check_lastfiles, + lyxrc.num_lastfiles)); } void LyX::defaultKeyBindings(kb_keymap * kbmap) { - kbmap->bind("Right", LFUN_RIGHT); - kbmap->bind("Left", LFUN_LEFT); - kbmap->bind("Up", LFUN_UP); - kbmap->bind("Down", LFUN_DOWN); - - kbmap->bind("Tab", LFUN_TAB); - kbmap->bind("ISO_Left_Tab", LFUN_TAB); // jbl 2001-23-02 + kbmap->bind("Right", FuncRequest(LFUN_RIGHT)); + kbmap->bind("Left", FuncRequest(LFUN_LEFT)); + kbmap->bind("Up", FuncRequest(LFUN_UP)); + kbmap->bind("Down", FuncRequest(LFUN_DOWN)); - kbmap->bind("Home", LFUN_HOME); - kbmap->bind("End", LFUN_END); - kbmap->bind("Prior", LFUN_PRIOR); - kbmap->bind("Next", LFUN_NEXT); + kbmap->bind("Tab", FuncRequest(LFUN_CELL_FORWARD)); + kbmap->bind("ISO_Left_Tab", FuncRequest(LFUN_CELL_FORWARD)); - kbmap->bind("Return", LFUN_BREAKPARAGRAPH); - //kbmap->bind("~C-~S-~M-nobreakspace", LFUN_PROTECTEDSPACE); + kbmap->bind("Home", FuncRequest(LFUN_HOME)); + kbmap->bind("End", FuncRequest(LFUN_END)); + kbmap->bind("Prior", FuncRequest(LFUN_PRIOR)); + kbmap->bind("Next", FuncRequest(LFUN_NEXT)); - kbmap->bind("Delete", LFUN_DELETE); - kbmap->bind("BackSpace", LFUN_BACKSPACE); + kbmap->bind("Return", FuncRequest(LFUN_BREAKPARAGRAPH)); + //kbmap->bind("~C-~S-~M-nobreakspace", FuncRequest(LFUN_PROTECTEDSPACE)); - // sub- and superscript -MV - kbmap->bind("~S-underscore", LFUN_SUBSCRIPT); - kbmap->bind("~S-asciicircum", LFUN_SUPERSCRIPT); + kbmap->bind("Delete", FuncRequest(LFUN_DELETE)); + kbmap->bind("BackSpace", FuncRequest(LFUN_BACKSPACE)); // kbmap->bindings to enable the use of the numeric keypad // e.g. Num Lock set - //kbmap->bind("KP_0", LFUN_SELFINSERT); - //kbmap->bind("KP_Decimal", LFUN_SELFINSERT); - kbmap->bind("KP_Enter", LFUN_BREAKPARAGRAPH); - //kbmap->bind("KP_1", LFUN_SELFINSERT); - //kbmap->bind("KP_2", LFUN_SELFINSERT); - //kbmap->bind("KP_3", LFUN_SELFINSERT); - //kbmap->bind("KP_4", LFUN_SELFINSERT); - //kbmap->bind("KP_5", LFUN_SELFINSERT); - //kbmap->bind("KP_6", LFUN_SELFINSERT); - //kbmap->bind("KP_Add", LFUN_SELFINSERT); - //kbmap->bind("KP_7", LFUN_SELFINSERT); - //kbmap->bind("KP_8", LFUN_SELFINSERT); - //kbmap->bind("KP_9", LFUN_SELFINSERT); - //kbmap->bind("KP_Divide", LFUN_SELFINSERT); - //kbmap->bind("KP_Multiply", LFUN_SELFINSERT); - //kbmap->bind("KP_Subtract", LFUN_SELFINSERT); - kbmap->bind("KP_Right", LFUN_RIGHT); - kbmap->bind("KP_Left", LFUN_LEFT); - kbmap->bind("KP_Up", LFUN_UP); - kbmap->bind("KP_Down", LFUN_DOWN); - kbmap->bind("KP_Home", LFUN_HOME); - kbmap->bind("KP_End", LFUN_END); - kbmap->bind("KP_Prior", LFUN_PRIOR); - kbmap->bind("KP_Next", LFUN_NEXT); - - kbmap->bind("C-Tab", LFUN_TABINSERT); // ale970515 - kbmap->bind("S-Tab", LFUN_SHIFT_TAB); // jug20000522 - kbmap->bind("S-ISO_Left_Tab", LFUN_SHIFT_TAB); // jbl 2001-23-02 + //kbmap->bind("KP_0", FuncRequest(LFUN_SELFINSERT)); + //kbmap->bind("KP_Decimal", FuncRequest(LFUN_SELFINSERT)); + kbmap->bind("KP_Enter", FuncRequest(LFUN_BREAKPARAGRAPH)); + //kbmap->bind("KP_1", FuncRequest(LFUN_SELFINSERT)); + //kbmap->bind("KP_2", FuncRequest(LFUN_SELFINSERT)); + //kbmap->bind("KP_3", FuncRequest(LFUN_SELFINSERT)); + //kbmap->bind("KP_4", FuncRequest(LFUN_SELFINSERT)); + //kbmap->bind("KP_5", FuncRequest(LFUN_SELFINSERT)); + //kbmap->bind("KP_6", FuncRequest(LFUN_SELFINSERT)); + //kbmap->bind("KP_Add", FuncRequest(LFUN_SELFINSERT)); + //kbmap->bind("KP_7", FuncRequest(LFUN_SELFINSERT)); + //kbmap->bind("KP_8", FuncRequest(LFUN_SELFINSERT)); + //kbmap->bind("KP_9", FuncRequest(LFUN_SELFINSERT)); + //kbmap->bind("KP_Divide", FuncRequest(LFUN_SELFINSERT)); + //kbmap->bind("KP_Multiply", FuncRequest(LFUN_SELFINSERT)); + //kbmap->bind("KP_Subtract", FuncRequest(LFUN_SELFINSERT)); + kbmap->bind("KP_Right", FuncRequest(LFUN_RIGHT)); + kbmap->bind("KP_Left", FuncRequest(LFUN_LEFT)); + kbmap->bind("KP_Up", FuncRequest(LFUN_UP)); + kbmap->bind("KP_Down", FuncRequest(LFUN_DOWN)); + kbmap->bind("KP_Home", FuncRequest(LFUN_HOME)); + kbmap->bind("KP_End", FuncRequest(LFUN_END)); + kbmap->bind("KP_Prior", FuncRequest(LFUN_PRIOR)); + kbmap->bind("KP_Next", FuncRequest(LFUN_NEXT)); + + kbmap->bind("C-Tab", FuncRequest(LFUN_CELL_SPLIT)); + kbmap->bind("S-Tab", FuncRequest(LFUN_CELL_BACKWARD)); + kbmap->bind("S-ISO_Left_Tab", FuncRequest(LFUN_CELL_BACKWARD)); } -void LyX::emergencyCleanup() +void LyX::emergencyCleanup() const { // what to do about tmpfiles is non-obvious. we would // like to delete any we find, but our lyxdir might @@ -540,89 +500,84 @@ void LyX::deadKeyBindings(kb_keymap * kbmap) { // bindKeyings for transparent handling of deadkeys // The keysyms are gotten from XFree86 X11R6 - kbmap->bind("~C-~S-~M-dead_acute", LFUN_ACUTE); - kbmap->bind("~C-~S-~M-dead_breve", LFUN_BREVE); - kbmap->bind("~C-~S-~M-dead_caron", LFUN_CARON); - kbmap->bind("~C-~S-~M-dead_cedilla", LFUN_CEDILLA); - kbmap->bind("~C-~S-~M-dead_abovering", LFUN_CIRCLE); - kbmap->bind("~C-~S-~M-dead_circumflex", LFUN_CIRCUMFLEX); - kbmap->bind("~C-~S-~M-dead_abovedot", LFUN_DOT); - kbmap->bind("~C-~S-~M-dead_grave", LFUN_GRAVE); - kbmap->bind("~C-~S-~M-dead_doubleacute", LFUN_HUNG_UMLAUT); - kbmap->bind("~C-~S-~M-dead_macron", LFUN_MACRON); + kbmap->bind("~C-~S-~M-dead_acute", FuncRequest(LFUN_ACUTE)); + kbmap->bind("~C-~S-~M-dead_breve", FuncRequest(LFUN_BREVE)); + kbmap->bind("~C-~S-~M-dead_caron", FuncRequest(LFUN_CARON)); + kbmap->bind("~C-~S-~M-dead_cedilla", FuncRequest(LFUN_CEDILLA)); + kbmap->bind("~C-~S-~M-dead_abovering", FuncRequest(LFUN_CIRCLE)); + kbmap->bind("~C-~S-~M-dead_circumflex", FuncRequest(LFUN_CIRCUMFLEX)); + kbmap->bind("~C-~S-~M-dead_abovedot", FuncRequest(LFUN_DOT)); + kbmap->bind("~C-~S-~M-dead_grave", FuncRequest(LFUN_GRAVE)); + kbmap->bind("~C-~S-~M-dead_doubleacute", FuncRequest(LFUN_HUNG_UMLAUT)); + kbmap->bind("~C-~S-~M-dead_macron", FuncRequest(LFUN_MACRON)); // nothing with this name // kbmap->bind("~C-~S-~M-dead_special_caron", LFUN_SPECIAL_CARON); - kbmap->bind("~C-~S-~M-dead_tilde", LFUN_TILDE); - kbmap->bind("~C-~S-~M-dead_diaeresis", LFUN_UMLAUT); + kbmap->bind("~C-~S-~M-dead_tilde", FuncRequest(LFUN_TILDE)); + kbmap->bind("~C-~S-~M-dead_diaeresis", FuncRequest(LFUN_UMLAUT)); // nothing with this name either... - //kbmap->bind("~C-~S-~M-dead_underbar", LFUN_UNDERBAR); - kbmap->bind("~C-~S-~M-dead_belowdot", LFUN_UNDERDOT); - kbmap->bind("~C-~S-~M-dead_tie", LFUN_TIE); - kbmap->bind("~C-~S-~M-dead_ogonek", LFUN_OGONEK); + //kbmap->bind("~C-~S-~M-dead_underbar", FuncRequest(LFUN_UNDERBAR)); + kbmap->bind("~C-~S-~M-dead_belowdot", FuncRequest(LFUN_UNDERDOT)); + kbmap->bind("~C-~S-~M-dead_tie", FuncRequest(LFUN_TIE)); + kbmap->bind("~C-~S-~M-dead_ogonek",FuncRequest(LFUN_OGONEK)); } void LyX::queryUserLyXDir(bool explicit_userdir) { + string const configure_script = AddName(system_lyxdir(), "configure"); + // Does user directory exist? - FileInfo fileInfo(user_lyxdir); + FileInfo fileInfo(user_lyxdir()); if (fileInfo.isOK() && fileInfo.isDir()) { first_start = false; + FileInfo script(configure_script); + FileInfo defaults(AddName(user_lyxdir(), "lyxrc.defaults")); + if (defaults.isOK() && script.isOK() + && defaults.getModificationTime() < script.getModificationTime()) { + lyxerr << _("LyX: reconfiguring user directory") + << endl; + Path p(user_lyxdir()); + ::system(configure_script.c_str()); + lyxerr << "LyX: " << _("Done!") << endl; + } return; } first_start = !explicit_userdir; - // If the user specified explicitly a directory, ask whether - // to create it (otherwise, always create it) - if (explicit_userdir && - !Alert::askQuestion(_("You have specified an invalid LyX directory."), - _("It is needed to keep your own configuration."), - _("Should I try to set it up for you (recommended)?"))) { - lyxerr << _("Running without personal LyX directory.") << endl; - // No, let's use $HOME instead. - user_lyxdir = GetEnvPath("HOME"); - return; - } - - lyxerr << _("LyX: Creating directory ") << user_lyxdir - << _(" and running configure...") << endl; + lyxerr << bformat(_("LyX: Creating directory %1$s" + " and running configure..."), user_lyxdir()) << endl; - if (!createDirectory(user_lyxdir, 0755)) { + if (!createDirectory(user_lyxdir(), 0755)) { // Failed, let's use $HOME instead. - user_lyxdir = GetEnvPath("HOME"); - lyxerr << _("Failed. Will use ") << user_lyxdir - << _(" instead.") << endl; + user_lyxdir(GetEnvPath("HOME")); + lyxerr << bformat(_("Failed. Will use %1$s instead."), + user_lyxdir()) << endl; return; } // Run configure in user lyx directory - Path p(user_lyxdir); - ::system(AddName(system_lyxdir, "configure").c_str()); + Path p(user_lyxdir()); + ::system(configure_script.c_str()); lyxerr << "LyX: " << _("Done!") << endl; } -bool LyX::readRcFile(string const & name) +void LyX::readRcFile(string const & name) { lyxerr[Debug::INIT] << "About to read " << name << "..." << endl; string const lyxrc_path = LibFileSearch(string(), name); if (!lyxrc_path.empty()) { + lyxerr[Debug::INIT] << "Found " << name << " in " << lyxrc_path << endl; - if (lyxrc.read(lyxrc_path) < 0) { - Alert::alert(_("LyX Warning!"), - _("Error while reading ") + lyxrc_path + ".", - _("Using built-in defaults.")); - return false; - } - return true; - } else { - lyxerr[Debug::INIT] << "Could not find " << name << endl; + + if (lyxrc.read(lyxrc_path) >= 0) + return; } - return false; + showFileError(name); } @@ -632,23 +587,41 @@ void LyX::readUIFile(string const & name) enum Uitags { ui_menuset = 1, ui_toolbar, + ui_toolbars, + ui_include, ui_last }; struct keyword_item uitags[ui_last - 1] = { + { "include", ui_include }, { "menuset", ui_menuset }, - { "toolbar", ui_toolbar } + { "toolbar", ui_toolbar }, + { "toolbars", ui_toolbars } }; + // Ensure that a file is read only once (prevents include loops) + static std::list uifiles; + std::list::const_iterator it = uifiles.begin(); + std::list::const_iterator end = uifiles.end(); + it = std::find(it, end, name); + if (it != end) { + lyxerr[Debug::INIT] << "UI file '" << name + << "' has been read already. " + << "Is this an include loop?" + << endl; + return; + } + lyxerr[Debug::INIT] << "About to read " << name << "..." << endl; string const ui_path = LibFileSearch("ui", name, "ui"); if (ui_path.empty()) { lyxerr[Debug::INIT] << "Could not find " << name << endl; - menubackend.defaults(); + showFileError(name); return; } + uifiles.push_back(name); lyxerr[Debug::INIT] << "Found " << name << " in " << ui_path << endl; @@ -664,12 +637,22 @@ void LyX::readUIFile(string const & name) while (lex.isOK()) { switch (lex.lex()) { + case ui_include: { + lex.next(true); + string const file = lex.getString(); + readUIFile(file); + break; + } case ui_menuset: menubackend.read(lex); break; case ui_toolbar: - toolbardefaults.read(lex); + toolbarbackend.read(lex); + break; + + case ui_toolbars: + toolbarbackend.readToolbars(lex); break; default: @@ -689,8 +672,7 @@ void LyX::readLanguagesFile(string const & name) string const lang_path = LibFileSearch(string(), name); if (lang_path.empty()) { - lyxerr[Debug::INIT] << "Could not find " << name << endl; - languages.setDefaults(); + showFileError(name); return; } languages.read(lang_path); @@ -704,7 +686,7 @@ void LyX::readEncodingsFile(string const & name) string const enc_path = LibFileSearch(string(), name); if (enc_path.empty()) { - lyxerr[Debug::INIT] << "Could not find " << name << endl; + showFileError(name); return; } encodings.read(enc_path); @@ -717,7 +699,7 @@ bool is_gui = true; string batch; /// return the the number of arguments consumed -typedef boost::function cmd_helper; +typedef boost::function cmd_helper; int parse_dbg(string const & arg, string const &) { @@ -726,12 +708,14 @@ int parse_dbg(string const & arg, string const &) Debug::showTags(lyxerr); exit(0); } - lyxerr << _("Setting debug level to ") << arg << endl; + lyxerr << bformat(_("Setting debug level to %1$s"), arg) << endl; + lyxerr.level(Debug::value(arg)); Debug::showLevel(lyxerr, lyxerr.level()); return 1; } + int parse_help(string const &, string const &) { lyxerr << @@ -774,7 +758,7 @@ int parse_sysdir(string const & arg, string const &) lyxerr << _("Missing directory for -sysdir switch") << endl; exit(1); } - system_lyxdir = arg; + system_lyxdir(arg); return 1; } @@ -784,7 +768,7 @@ int parse_userdir(string const & arg, string const &) lyxerr << _("Missing directory for -userdir switch") << endl; exit(1); } - user_lyxdir = arg; + user_lyxdir(arg); return 1; } @@ -825,7 +809,7 @@ int parse_import(string const & type, string const & file) exit(1); } - batch = "buffer-import " + type + " " + file; + batch = "buffer-import " + type + ' ' + file; return 2; }