X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Flyx_main.C;h=ecb5e296634089d5907f8b0e8e22e7bd8b6a2acf;hb=98c966c64594611e469313314abd1e59524adb4a;hp=cc5e5d1a7ccfe8a15be69df252727f3610fd2625;hpb=7670f99a2354be6d3845254ac3ae64c2e2db1977;p=lyx.git diff --git a/src/lyx_main.C b/src/lyx_main.C index cc5e5d1a7c..ecb5e29663 100644 --- a/src/lyx_main.C +++ b/src/lyx_main.C @@ -1,38 +1,61 @@ /* This file is part of - * ====================================================== - * + * ====================================================== + * * LyX, The Document Processor - * + * * Copyright 1995 Matthias Ettrich - * Copyright 1995-2000 The LyX Team. + * Copyright 1995-2001 The LyX Team. * * ====================================================== */ #include +#include -#include -#include +#ifdef __GNUG__ +#pragma implementation +#endif -#include "version.h" #include "lyx_main.h" #include "lyx_gui.h" -#include "lyx_gui_misc.h" +#include "LyXView.h" +#include "lyxfunc.h" #include "lyxrc.h" -#include "support/path.h" -#include "support/filetools.h" +#include "buffer.h" #include "bufferlist.h" #include "debug.h" -#include "support/FileInfo.h" #include "lastfiles.h" #include "intl.h" #include "lyxserver.h" -#include "layout.h" +//#include "layout.h" +#include "lyxtextclasslist.h" #include "gettext.h" #include "kbmap.h" +#include "MenuBackend.h" +#include "ToolbarDefaults.h" +#include "lyxlex.h" +#include "encoding.h" +#include "converter.h" +#include "language.h" + +#include "frontends/Alert.h" +#include "frontends/GUIRunTime.h" + +#include "support/path.h" +#include "support/filetools.h" +#include "support/FileInfo.h" +#include "support/os.h" + +#include +#include using std::endl; +#ifndef CXX_GLOBAL_CSTD +using std::signal; +#endif + extern void LoadLyXFile(string const &); +extern void QuitLyX(); string system_lyxdir; string build_lyxdir; @@ -42,7 +65,7 @@ string user_lyxdir; // Default $HOME/.lyx // Should this be kept global? Asger says Yes. DebugStream lyxerr; -LastFiles * lastfiles; +boost::scoped_ptr lastfiles; // This is the global bufferlist object BufferList bufferlist; @@ -52,45 +75,46 @@ LyXServer * lyxserver = 0; bool finished = false; // flag, that we are quitting the program // convenient to have it here. -kb_keymap * toplevel_keymap; +boost::scoped_ptr toplevel_keymap; LyX::LyX(int * argc, char * argv[]) { - // Prevent crash with --help - lyxGUI = 0; - lastfiles = 0; - // Here we need to parse the command line. At least // we need to parse for "-dbg" and "-help" bool gui = easyParse(argc, argv); // Global bindings (this must be done as early as possible.) (Lgb) - toplevel_keymap = new kb_keymap; - // Fill the toplevel_keymap with some defaults - for (LyXRC::Bindings::const_iterator cit = lyxrc.bindings.begin(); - cit != lyxrc.bindings.end(); ++cit) { - toplevel_keymap->bind((*cit).first.c_str(), (*cit).second); - } + toplevel_keymap.reset(new kb_keymap); + defaultKeyBindings(toplevel_keymap.get()); // Make the GUI object, and let it take care of the // command line arguments that concerns it. lyxerr[Debug::INIT] << "Initializing LyXGUI..." << endl; - lyxGUI = new LyXGUI(this, argc, argv, gui); + lyxGUI.reset(new LyXGUI(this, argc, argv, gui)); lyxerr[Debug::INIT] << "Initializing LyXGUI...done" << endl; + // Now the GUI and LyX have taken care of their arguments, so + // the only thing left on the command line should be + // filenames. Let's check anyway. + for (int argi = 1; argi < *argc ; ++argi) { + if (argv[argi][0] == '-') { + lyxerr << _("Wrong command line option `") + << argv[argi] + << _("'. Exiting.") << endl; + exit(0); + } + } + // Initialization of LyX (reads lyxrc and more) lyxerr[Debug::INIT] << "Initializing LyX::init..." << endl; - init(argc, argv, gui); + init(gui); lyxerr[Debug::INIT] << "Initializing LyX::init...done" << endl; lyxGUI->init(); // Load the files specified in the command line. - // Now the GUI and LyX have taken care of their arguments, so - // the only thing left on the command line should be - // filenames. - if ((*argc) == 2) + if ((*argc) == 2) lyxerr[Debug::INFO] << "Opening document..." << endl; else if ((*argc) > 2) lyxerr[Debug::INFO] << "Opening documents..." << endl; @@ -105,8 +129,9 @@ LyX::LyX(int * argc, char * argv[]) } if (first_start) { - string splash = i18nLibFileSearch("examples", "splash.lyx"); - lyxerr.debug() << "Opening splash document " + string const splash = + i18nLibFileSearch("examples", "splash.lyx"); + lyxerr[Debug::INIT] << "Opening splash document " << splash << "..." << endl; Buffer * loadb = bufferlist.loadLyXFile(splash); if (loadb != 0) { @@ -115,21 +140,38 @@ LyX::LyX(int * argc, char * argv[]) } if (last_loaded != 0) { - lyxerr.debug() << "Yes we loaded some files." << endl; + lyxerr[Debug::INIT] << "Yes we loaded some files." << endl; if (lyxrc.use_gui) lyxGUI->regBuf(last_loaded); } // Execute batch commands if available - if (!batch_command.empty() && last_loaded) { - lyxerr << "About to handle -x '" << batch_command << "'" << endl; - //Buffer buffer("Script Buffer"); - //buffer.Dispatch(batch_command); - last_loaded->Dispatch(batch_command); - lyxerr << "We are done!" << endl; - return; // Maybe we could do something more clever than aborting.. + if (!batch_command.empty()) { + lyxerr << "About to handle -x '" + << batch_command << "'" << endl; + + // no buffer loaded, create one + if (!last_loaded) + last_loaded = bufferlist.newFile("tmpfile", string()); + + // try to dispatch to last loaded buffer first + bool dispatched = last_loaded->dispatch(batch_command); + + // if this was successful, return. + // Maybe we could do something more clever than aborting... + if (dispatched) { + lyxerr << "We are done!" << endl; + QuitLyX(); + return; + } + + // otherwise, let the GUI handle the batch command + lyxGUI->regBuf(last_loaded); + lyxGUI->getLyXView()->getLyXFunc()->verboseDispatch(batch_command, false); + + // fall through... } - + // Let the ball begin... lyxGUI->runTime(); } @@ -138,14 +180,57 @@ LyX::LyX(int * argc, char * argv[]) // A destructor is always necessary (asierra-970604) LyX::~LyX() { - delete lastfiles; - delete lyxGUI; } -extern "C" void error_handler(int err_sig); +extern "C" { -void LyX::init(int */*argc*/, char **argv, bool gui) +static +void error_handler(int err_sig) +{ + switch (err_sig) { + case SIGHUP: + lyxerr << "\nlyx: SIGHUP signal caught" << endl; + break; + case SIGINT: + // no comments + break; + case SIGFPE: + lyxerr << "\nlyx: SIGFPE signal caught" << 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; + break; + case SIGTERM: + // no comments + break; + } + + // Deinstall the signal handlers + signal(SIGHUP, SIG_DFL); + signal(SIGINT, SIG_DFL); + signal(SIGFPE, SIG_DFL); + 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(); + exit(0); +} + +} + + +void LyX::init(bool gui) { // Install the signal handlers signal(SIGHUP, error_handler); @@ -158,28 +243,9 @@ void LyX::init(int */*argc*/, char **argv, bool gui) // Determine path of binary // - string fullbinpath; - string binpath = subst(argv[0], '\\', '/'); - string binname = OnlyFilename(argv[0]); - // Sorry for system specific code. (SMiyata) - if (suffixIs(binname, ".exe")) - binname.erase(binname.length()-4, string::npos); - - binpath = ExpandPath(binpath); // This expands ./ and ~/ - - if (!AbsolutePath(binpath)) { - string binsearchpath = GetEnvPath("PATH"); - // This will make "src/lyx" work always :-) - binsearchpath += ";."; - binpath = FileOpenSearch(binsearchpath, argv[0]); - } - - fullbinpath = binpath; - binpath = MakeAbsPath(OnlyPath(binpath)); - - // In case we are running in place and compiled with shared libraries - if (suffixIs(binpath, "/.libs/")) - binpath.erase(binpath.length()-6, string::npos); + string binpath = os::binpath(); + string binname = os::binname(); + string fullbinname = MakeAbsPath(binname, binpath); if (binpath.empty()) { lyxerr << _("Warning: could not determine path of binary.") @@ -187,6 +253,7 @@ void LyX::init(int */*argc*/, char **argv, bool gui) << _("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; // @@ -213,13 +280,52 @@ void LyX::init(int */*argc*/, char **argv, bool gui) searchpath= MakeAbsPath(system_lyxdir) + ';'; // LYX_DIR_11x environment variable - string lyxdir = GetEnvPath("LYX_DIR_11x"); - + string const lyxdir = GetEnvPath("LYX_DIR_11x"); + if (!lyxdir.empty()) { lyxerr[Debug::INIT] << "LYX_DIR_11x: " << 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)) { + // 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)) { + 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()) { @@ -231,30 +337,9 @@ void LyX::init(int */*argc*/, char **argv, bool gui) lyxerr[Debug::INIT] << "Checking whether LyX is run in place... no" << endl; - build_lyxdir.clear(); + build_lyxdir.erase(); } - 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) { - string Link; - if (LyXReadLink(fullbinpath, Link)) { - fullbinpath = Link; - binpath = MakeAbsPath(OnlyPath(fullbinpath)); - } - else { - FollowLink = false; - } - } - } while (FollowLink); - // Hardcoded dir searchpath += LYX_DIR; @@ -263,7 +348,7 @@ void LyX::init(int */*argc*/, char **argv, bool gui) << searchpath << endl; string const filename = "chkconfig.ltx"; - string temp = FileOpenSearch(searchpath, filename, string()); + string const temp = FileOpenSearch(searchpath, filename, string()); system_lyxdir = OnlyPath(temp); // Reduce "path/../path" stuff out of system directory @@ -276,7 +361,7 @@ void LyX::init(int */*argc*/, char **argv, bool gui) if (system_lyxdir != NormalizePath(lyxdir)) { lyxerr <<_("LYX_DIR_11x environment variable no good.") << '\n' - << _("System directory set to: ") + << _("System directory set to: ") << system_lyxdir << endl; path_shown = true; } @@ -284,67 +369,89 @@ void LyX::init(int */*argc*/, char **argv, bool gui) // 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") + lyxerr <<_("LyX Warning! Couldn't determine system directory. ") + <<_("Try the '-sysdir' command line parameter or ") <<_("set the environment variable LYX_DIR_11x to the " - "LyX system directory") + "LyX system directory ") << _("containing the file `chkconfig.ltx'.") << endl; - if (!path_shown) - lyxerr << _("Using built-in default ") + 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 + } else { lyxerr << _("Expect problems.") << endl; + } system_lyxdir = LYX_DIR; path_shown = true; } - // Report the system directory if debugging is on if (!path_shown) lyxerr[Debug::INIT] << "System directory: '" - << system_lyxdir << '\'' << endl; + << system_lyxdir << '\'' << endl; // // Determine user lyx-dir // - - user_lyxdir = AddPath(GetEnvPath("HOME"), string(".") + PACKAGE); - lyxerr[Debug::INIT] << "User LyX directory: '" - << user_lyxdir << '\'' << endl; - // Check that user LyX directory is ok. - queryUserLyXDir(); + // Directories are searched in this order: + // 1) -userdir command line parameter + // 2) LYX_USERDIR_11x 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_11x environment variable + user_lyxdir = GetEnvPath("LYX_USERDIR_11x"); + + // default behaviour + if (user_lyxdir.empty()) + user_lyxdir = AddPath(GetEnvPath("HOME"), + string(".") + PACKAGE); + explicit_userdir = false; + } - // - // Load the layouts first - // + lyxerr[Debug::INIT] << "User LyX directory: '" + << user_lyxdir << '\'' << endl; - lyxerr[Debug::INIT] << "Reading layouts..." << endl; - LyXSetStyle(); + // Check that user LyX directory is ok. We don't do that if + // running in batch mode. + if (gui) { + queryUserLyXDir(explicit_userdir); + } else { + first_start = false; + } // // Shine up lyxrc defaults // // Default template path: system_dir/templates - if (lyxrc.template_path.empty()){ + if (lyxrc.template_path.empty()) { lyxrc.template_path = AddPath(system_lyxdir, "templates"); } - + // Default lastfiles file: $HOME/.lyx/lastfiles - if (lyxrc.lastfiles.empty()){ + if (lyxrc.lastfiles.empty()) { lyxrc.lastfiles = AddName(user_lyxdir, "lastfiles"); } // Disable gui when either lyxrc or easyparse says so if (!gui) lyxrc.use_gui = false; - - // Calculate screen dpi as average of x-DPI and y-DPI: + + // Calculate screen dpi as average of x-DPI and y-DPI: if (lyxrc.use_gui) { - lyxrc.dpi = getScreenDPI(); - lyxerr[Debug::INFO] << "DPI setting detected to be " - << lyxrc.dpi + 0.5 << endl; + lyxrc.dpi = GUIRunTime::getScreenDPI(); + lyxerr[Debug::INIT] << "DPI setting detected to be " + << lyxrc.dpi + 0.5 << endl; } else { lyxrc.dpi = 1; // I hope this is safe } @@ -353,30 +460,55 @@ void LyX::init(int */*argc*/, char **argv, bool gui) // Read configuration files // - ReadRcFile("lyxrc.defaults"); - ReadRcFile("lyxrc"); + readRcFile("lyxrc.defaults"); + system_lyxrc = lyxrc; + system_formats = formats; + 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"); + + // Read encodings + readEncodingsFile("encodings"); + // Read languages + readLanguagesFile("languages"); + + // Load the layouts + lyxerr[Debug::INIT] << "Reading layouts..." << endl; + LyXSetStyle(); // Ensure that we have really read a bind file, so that LyX is // usable. - if (!lyxrc.hasBindFile) - lyxrc.ReadBindFile(); + lyxrc.readBindFileIfNeeded(); + + // Read menus + readUIFile(lyxrc.ui_file); + + // Bind the X dead keys to the corresponding LyX functions if + // necessary. + if (lyxrc.override_x_deadkeys) + deadKeyBindings(toplevel_keymap.get()); if (lyxerr.debugging(Debug::LYXRC)) { lyxrc.print(); } - // Create temp directory - system_tempdir = CreateLyXTmpDir(lyxrc.tempdir_path); + // Create temp directory + os::setTmpDir(CreateLyXTmpDir(lyxrc.tempdir_path)); + system_tempdir = os::getTmpDir(); if (lyxerr.debugging(Debug::INIT)) { lyxerr << "LyX tmp dir: `" << system_tempdir << '\'' << endl; } // load the lastfiles mini-database lyxerr[Debug::INIT] << "Reading lastfiles `" - << lyxrc.lastfiles << "'..." << endl; - lastfiles = new LastFiles(lyxrc.lastfiles, - lyxrc.check_lastfiles, - lyxrc.num_lastfiles); + << lyxrc.lastfiles << "'..." << endl; + lastfiles.reset(new LastFiles(lyxrc.lastfiles, + lyxrc.check_lastfiles, + lyxrc.num_lastfiles)); // start up the lyxserver. (is this a bit early?) (Lgb) // 0.12 this will be way to early, we need the GUI to be initialized @@ -385,9 +517,108 @@ void LyX::init(int */*argc*/, char **argv, bool gui) } +// These are the default bindings known to LyX +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("Home", LFUN_HOME); + kbmap->bind("End", LFUN_END); + kbmap->bind("Prior", LFUN_PRIOR); + kbmap->bind("Next", LFUN_NEXT); + + kbmap->bind("Return", LFUN_BREAKPARAGRAPH); + //kbmap->bind("~C-~S-~M-nobreakspace", LFUN_PROTECTEDSPACE); + + kbmap->bind("Delete", LFUN_DELETE); + kbmap->bind("BackSpace", LFUN_BACKSPACE); + + // sub- and superscript -MV + kbmap->bind("~S-underscore", LFUN_SUBSCRIPT); + kbmap->bind("~S-asciicircum", LFUN_SUPERSCRIPT); + + // 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 +} + + +void LyX::emergencyCleanup() +{ + // what to do about tmpfiles is non-obvious. we would + // like to delete any we find, but our lyxdir might + // contain documents etc. which might be helpful on + // a crash + + bufferlist.emergencyWriteAll(); + if (lyxserver) + lyxserver->emergencyCleanup(); +} + + +// LyX can optionally take over the handling of deadkeys +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); + // 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); + // 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); +} + + // This one is not allowed to use anything on the main form, since that // one does not exist yet. (Asger) -void LyX::queryUserLyXDir() +void LyX::queryUserLyXDir(bool explicit_userdir) { // Does user directory exist? FileInfo fileInfo(user_lyxdir); @@ -395,11 +626,13 @@ void LyX::queryUserLyXDir() first_start = false; return; } else { - first_start = true; + first_start = !explicit_userdir; } - - // Nope - if (!AskQuestion(_("You don't have a personal LyX directory."), + + // If the user specified explicitely 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; @@ -423,30 +656,122 @@ void LyX::queryUserLyXDir() // Run configure in user lyx directory Path p(user_lyxdir); - system(AddName(system_lyxdir, "configure").c_str()); + ::system(AddName(system_lyxdir, "configure").c_str()); lyxerr << "LyX: " << _("Done!") << endl; } // Read the rc file `name' -void LyX::ReadRcFile(string const & name) +bool LyX::readRcFile(string const & name) { lyxerr[Debug::INIT] << "About to read " << name << "..." << endl; - - string lyxrc_path = LibFileSearch(string(), name); - if (!lyxrc_path.empty()){ - lyxerr[Debug::INIT] << "Found " << name + + 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) { - WriteAlert(_("LyX Warning!"), - _("Error while reading ")+lyxrc_path+".", + 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; + } + + return false; +} + + +// Read the ui file `name' +void LyX::readUIFile(string const & name) +{ + enum Uitags { + ui_menuset = 1, + ui_toolbar, + ui_last + }; + + struct keyword_item uitags[ui_last-1] = { + { "menuset", ui_menuset }, + { "toolbar", ui_toolbar } + }; + + 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(); + return; + } + + lyxerr[Debug::INIT] << "Found " << name + << " in " << ui_path << endl; + LyXLex lex(uitags, ui_last - 1); + lex.setFile(ui_path); + if (!lex.isOK()) { + lyxerr << "Unable to set LyXLeX for ui file: " << ui_path + << endl; + } + + if (lyxerr.debugging(Debug::PARSER)) + lex.printTable(lyxerr); + + while (lex.isOK()) { + switch (lex.lex()) { + case ui_menuset: + menubackend.read(lex); + break; + + case ui_toolbar: + toolbardefaults.read(lex); + break; + + default: + if (!strip(lex.getString()).empty()) + lex.printError("LyX::ReadUIFile: " + "Unknown menu tag: `$$Token'"); + break; } - } else - lyxerr[Debug::INIT] << "Could not find " << name << endl; + } +} + + +// Read the languages file `name' +void LyX::readLanguagesFile(string const & name) +{ + lyxerr[Debug::INIT] << "About to read " << name << "..." << endl; + + string const lang_path = LibFileSearch(string(), name); + if (lang_path.empty()) { + lyxerr[Debug::INIT] << "Could not find " << name << endl; + languages.setDefaults(); + return; + } + languages.read(lang_path); +} + + +// Read the encodings file `name' +void LyX::readEncodingsFile(string const & name) +{ + lyxerr[Debug::INIT] << "About to read " << name << "..." << endl; + + string const enc_path = LibFileSearch(string(), name); + if (enc_path.empty()) { + lyxerr[Debug::INIT] << "Could not find " << name << endl; + return; + } + encodings.read(enc_path); } +namespace { + // Set debugging level and report result to user void setDebuggingLevel(string const & dbgLevel) { @@ -459,66 +784,92 @@ void setDebuggingLevel(string const & dbgLevel) // Give command line help void commandLineHelp() { - lyxerr << "LyX " LYX_VERSION << " of " LYX_RELEASE << endl; lyxerr << _("Usage: lyx [ command line switches ] [ name.lyx ... ]\n" "Command line switches (case sensitive):\n" - "\t-help summarize LyX usage\n" - "\t-sysdir x try to set system directory to x\n" - "\t-width x set the width of the main window\n" - "\t-height y set the height of the main window\n" - "\t-xpos x set the x position of the main window\n" - "\t-ypos y set the y position of the main window\n" - "\t-dbg feature[,feature]...\n" - " select the features to debug.\n" - " Type `lyx -dbg' to see the list of features\n" - "Check the LyX man page for more options.") << endl; + "\t-help summarize LyX usage\n" + "\t-userdir dir try to set user directory to dir\n" + "\t-sysdir dir try to set system directory to dir\n" + "\t-geometry WxH+X+Y set geometry of the main window\n" + "\t-dbg feature[,feature]...\n" + " select the features to debug.\n" + " Type `lyx -dbg' to see the list of features\n" + "\t-x [--execute] command\n" + " where command is a lyx command.\n" + "\t-e [--export] fmt\n" + " where fmt is the export format of choice.\n" + "\t-i [--import] fmt file.xxx\n" + " where fmt is the import format of choice\n" + " and file.xxx is the file to be imported.\n" + "\t-version summarize version and build info\n" + "Check the LyX man page for more details.") << endl; } +// Give command line version information +void commandLineVersionInfo() +{ + lyxerr << "LyX " << lyx_version + << " of " << lyx_release_date << endl; + lyxerr << "Built on " << __DATE__ << ", " << __TIME__ << endl; + + lyxerr << lyx_version_info << endl; +} + + +} // namespace anon + bool LyX::easyParse(int * argc, char * argv[]) { bool gui = true; - for(int i = 1; i < *argc; ++i) { + int removeargs = 0; // used when options are read + for (int i = 1; i < *argc; ++i) { string arg = argv[i]; // Check for -dbg int if (arg == "-dbg") { if (i + 1 < *argc) { setDebuggingLevel(argv[i + 1]); - - // Now, remove these two arguments by shifting - // the following two places down. - (*argc) -= 2; - for (int j = i; j < (*argc); ++j) - argv[j] = argv[j + 2]; - --i; // After shift, check this number again. + removeargs = 2; } else { lyxerr << _("List of supported debug flags:") << endl; Debug::showTags(lyxerr); exit(0); } - } + } // Check for "-sysdir" else if (arg == "-sysdir") { if (i + 1 < *argc) { system_lyxdir = argv[i + 1]; - - // Now, remove these two arguments by shifting - // the following two places down. - (*argc) -= 2; - for (int j= i; j < (*argc); ++j) - argv[j] = argv[j + 2]; - --i; // After shift, check this number again. - } else + removeargs = 2; + } else { lyxerr << _("Missing directory for -sysdir switch!") << endl; + exit(0); + } + } + // Check for "-userdir" + else if (arg == "-userdir") { + if (i + 1 < *argc) { + user_lyxdir = argv[i + 1]; + removeargs = 2; + } else { + lyxerr << _("Missing directory for -userdir switch!") + << endl; + exit(0); + } + } // Check for --help or -help - } else if (arg == "--help" || arg == "-help") { + else if (arg == "--help" || arg == "-help") { commandLineHelp(); exit(0); - } + } + // Check for --version or -version + else if (arg == "--version" || arg == "-version") { + commandLineVersionInfo(); + exit(0); + } // Check for "-nw": No XWindows as for emacs this should // give a LyX that could be used in a terminal window. //else if (arg == "-nw") { @@ -529,14 +880,7 @@ bool LyX::easyParse(int * argc, char * argv[]) else if (arg == "-x" || arg == "--execute") { if (i + 1 < *argc) { batch_command = string(argv[i + 1]); - - // Now, remove these two arguments by shifting - // the following two places down. - (*argc) -= 2; - for (int j = i; j < (*argc); ++j) - argv[j] = argv[j + 2]; - --i; // After shift, check this number again. - + removeargs = 2; } else lyxerr << _("Missing command string after -x switch!") << endl; @@ -548,73 +892,41 @@ bool LyX::easyParse(int * argc, char * argv[]) else if (arg == "-e" || arg == "--export") { if (i + 1 < *argc) { string type(argv[i+1]); - - (*argc) -= 2; - for (int j = i; j < (*argc); ++j) - argv[j] = argv[j + 2]; - --i; // After shift, check this number again. - - if (type == "tex") - type = "latex"; - else if (type == "ps") - type = "postscript"; - else if (type == "text" || type == "txt") - type = "ascii"; - - if (type == "latex" || type == "postscript" - || type == "ascii" || type == "html") - batch_command = "buffer-export " + type; - else - lyxerr << _("Unknown file type '") - << type << _("' after ") - << arg << _(" switch!") << endl; + removeargs = 2; + batch_command = "buffer-export " + type; + gui = false; } else lyxerr << _("Missing file type [eg latex, " "ps...] after ") << arg << _(" switch!") << endl; } - } - return gui; -} + else if (arg == "-i" || arg == "--import") { + if (i + 1 < *argc) { + string const type(argv[i+1]); + string const file(argv[i+2]); + removeargs = 3; + batch_command = "buffer-import " + type + " " + file; + lyxerr << "batch_command: " + << batch_command << endl; -extern "C" -void error_handler(int err_sig) -{ - switch (err_sig) { - case SIGHUP: - lyxerr << "\nlyx: SIGHUP signal caught" << endl; - break; - case SIGINT: - // no comments - break; - case SIGFPE: - lyxerr << "\nlyx: SIGFPE signal caught" << endl; - break; - case SIGSEGV: - lyxerr << "\nlyx: SIGSEGV signal caught" << endl; - lyxerr << - "Sorry, you have found a bug in LyX." - " If possible, please read 'Known bugs'\n" - "under the Help menu and then send us " - "a full bug report. Thanks!" << endl; - break; - case SIGTERM: - // no comments - break; - } - - // Deinstall the signal handlers - signal(SIGHUP, SIG_DFL); - signal(SIGINT, SIG_DFL); - signal(SIGFPE, SIG_DFL); - signal(SIGSEGV, SIG_DFL); - signal(SIGTERM, SIG_DFL); + } else + lyxerr << _("Missing type [eg latex, " + "ps...] after ") + << arg << _(" switch!") << endl; + } - bufferlist.emergencyWriteAll(); + if (removeargs > 0) { + // Now, remove used arguments by shifting + // the following ones removeargs places down. + (*argc) -= removeargs; + for (int j = i; j < (*argc); ++j) + argv[j] = argv[j + removeargs]; + --i; // After shift, check this number again. + removeargs = 0; + } - lyxerr << "Bye." << endl; - if(err_sig!= SIGHUP && (!GetEnv("LYXDEBUG").empty() || err_sig == SIGSEGV)) - lyx::abort(); - exit(0); + } + + return gui; }