X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Flyx_main.C;h=84378364bcb54d74483b7e37c7e24688723855fe;hb=ebfcf1c0e72288b7131607af0330500c8739cead;hp=37a7e05dc217c838f552df71c635fcd6a0ff1f67;hpb=e6d063c4317b298bd4f14a4b15f97d37f2291c17;p=lyx.git diff --git a/src/lyx_main.C b/src/lyx_main.C index 37a7e05dc2..84378364bc 100644 --- a/src/lyx_main.C +++ b/src/lyx_main.C @@ -13,6 +13,10 @@ #include #include +#ifdef __GNUG__ +#pragma implementation +#endif + #include "version.h" #include "lyx_main.h" #include "lyx_gui.h" @@ -31,10 +35,14 @@ #include "layout.h" #include "gettext.h" #include "kbmap.h" +#include "MenuBackend.h" +#include "ToolbarDefaults.h" +#include "lyxlex.h" using std::endl; extern void LoadLyXFile(string const &); +extern void QuitLyX(); string system_lyxdir; string build_lyxdir; @@ -69,18 +77,26 @@ LyX::LyX(int * argc, char * 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); - } - + defaultKeyBindings(toplevel_keymap); + // 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); 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); @@ -89,9 +105,6 @@ LyX::LyX(int * argc, char * argv[]) 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) lyxerr[Debug::INFO] << "Opening document..." << endl; else if ((*argc) > 2) @@ -108,7 +121,7 @@ LyX::LyX(int * argc, char * argv[]) if (first_start) { string splash = i18nLibFileSearch("examples", "splash.lyx"); - lyxerr.debug() << "Opening splash document " + lyxerr[Debug::INIT] << "Opening splash document " << splash << "..." << endl; Buffer * loadb = bufferlist.loadLyXFile(splash); if (loadb != 0) { @@ -117,14 +130,15 @@ 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()) { - lyxerr << "About to handle -x '" << batch_command << "'" << endl; + lyxerr << "About to handle -x '" + << batch_command << "'" << endl; // no buffer loaded, create one if (!last_loaded) @@ -137,6 +151,7 @@ LyX::LyX(int * argc, char * argv[]) // Maybe we could do something more clever than aborting... if (dispatched) { lyxerr << "We are done!" << endl; + QuitLyX(); return; } @@ -248,7 +263,7 @@ 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; @@ -325,12 +340,30 @@ void LyX::init(int */*argc*/, char **argv, bool gui) // Determine user lyx-dir // - user_lyxdir = AddPath(GetEnvPath("HOME"), string(".") + PACKAGE); + // 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; + } + lyxerr[Debug::INIT] << "User LyX directory: '" << user_lyxdir << '\'' << endl; // Check that user LyX directory is ok. - queryUserLyXDir(); + queryUserLyXDir(explicit_userdir); // // Load the layouts first @@ -360,7 +393,7 @@ void LyX::init(int */*argc*/, char **argv, bool gui) // 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 " + lyxerr[Debug::INIT] << "DPI setting detected to be " << lyxrc.dpi + 0.5 << endl; } else { lyxrc.dpi = 1; // I hope this is safe @@ -371,13 +404,25 @@ void LyX::init(int */*argc*/, char **argv, bool gui) // ReadRcFile("lyxrc.defaults"); - ReadRcFile("lyxrc"); +// system_lyxrc = lyxrc; + // If there is a preferences file we read that instead + // of the old lyxrc file. + if (!ReadRcFile("preferences")) + ReadRcFile("lyxrc"); // Ensure that we have really read a bind file, so that LyX is // usable. if (!lyxrc.hasBindFile) lyxrc.ReadBindFile(); + // 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); + if (lyxerr.debugging(Debug::LYXRC)) { lyxrc.print(); } @@ -401,10 +446,86 @@ void LyX::init(int */*argc*/, char **argv, bool gui) // lyxserver = new LyXServer; } +// 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("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); + + // 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_SELFINSERT); + 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); + + /* Most self-insert keys are handled in the 'default:' section of + * WorkAreaKeyPress - so we don't have to define them all. + * However keys explicit decleared as self-insert are + * handled seperatly (LFUN_SELFINSERT.) Lgb. */ + + kbmap->bind("C-Tab", LFUN_TABINSERT); // ale970515 + kbmap->bind("S-Tab", LFUN_SHIFT_TAB); // jug20000522 +} + +// 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); @@ -416,7 +537,11 @@ void LyX::queryUserLyXDir() } // Nope - if (!AskQuestion(_("You don't have a personal LyX directory."), + // Different wording if the user specifically requested a directory + if (!AskQuestion( explicit_userdir + ? _("You have specified an invalid LyX directory.") + : _("You don't have a personal 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; @@ -440,13 +565,13 @@ 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; @@ -458,9 +583,66 @@ void LyX::ReadRcFile(string const & name) WriteAlert(_("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 ui_path = LibFileSearch("ui", name, "ui"); + + if (ui_path.empty()) { + lyxerr[Debug::INIT] << "Could not find " << name << endl; + 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: + lex.printError("LyX::ReadUFile: " + "Unknown menu tag: `$$Token'"); + break; + } + } } @@ -480,22 +662,20 @@ void commandLineHelp() 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-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" "Check the LyX man page for more options.") << endl; } - bool LyX::easyParse(int * argc, char * argv[]) { bool gui = true; + int removeargs = 0; // used when options are read for(int i = 1; i < *argc; ++i) { string arg = argv[i]; @@ -503,13 +683,7 @@ bool LyX::easyParse(int * argc, char * argv[]) 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; @@ -521,18 +695,26 @@ bool LyX::easyParse(int * argc, char * argv[]) 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 - lyxerr << _("Missing directory for -sysdir switch!") + 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); } @@ -546,14 +728,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; @@ -565,41 +740,19 @@ 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; } - else if (arg == "--import") { if (i + 1 < *argc) { string type(argv[i+1]); string file(argv[i+2]); - - (*argc) -= 3; - for (int j = i; j < (*argc); ++j) - argv[j] = argv[j + 3]; - --i; // After shift, check this number again. + removeargs = 3; batch_command = "buffer-import " + type + " " + file; lyxerr << "batch_command: " @@ -610,6 +763,17 @@ bool LyX::easyParse(int * argc, char * argv[]) "ps...] after ") << arg << _(" switch!") << endl; } + + 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; + } + } return gui; @@ -652,7 +816,8 @@ void error_handler(int err_sig) bufferlist.emergencyWriteAll(); lyxerr << "Bye." << endl; - if(err_sig!= SIGHUP && (!GetEnv("LYXDEBUG").empty() || err_sig == SIGSEGV)) + if(err_sig!= SIGHUP && + (!GetEnv("LYXDEBUG").empty() || err_sig == SIGSEGV)) lyx::abort(); exit(0); }