X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Flyx_main.C;h=7b4b8ce795c6bcff9aa1f72a2aee920498bdfba6;hb=1fa0fb5c67656cacbe3cfe6e8b08dd98cada1f73;hp=5aa42b2e9198848bf798a948186742cb42fa197e;hpb=ecaf48dc268f677363d81ba4c04572c44ae712f3;p=lyx.git diff --git a/src/lyx_main.C b/src/lyx_main.C index 5aa42b2e91..7b4b8ce795 100644 --- a/src/lyx_main.C +++ b/src/lyx_main.C @@ -29,6 +29,7 @@ #include "kbmap.h" #include "language.h" #include "lastfiles.h" +#include "LColor.h" #include "lyxfunc.h" #include "lyxlex.h" #include "lyxrc.h" @@ -37,8 +38,11 @@ #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 "support/FileInfo.h" #include "support/filetools.h" @@ -50,11 +54,31 @@ #include #include +#include + +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 namespace lyx::support; - -using std::vector; using std::endl; +using std::string; +using std::vector; #ifndef CXX_GLOBAL_CSTD using std::exit; @@ -62,14 +86,11 @@ using std::signal; using std::system; #endif + extern void QuitLyX(); extern LyXServer * lyxserver; -DebugStream lyxerr; - -boost::scoped_ptr lastfiles; - // This is the global bufferlist object BufferList bufferlist; @@ -86,19 +107,85 @@ void showFileError(string const & 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(int & argc, char * 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); - // set the DisplayTranslator only once; should that be done here?? - // if this should not be in this file, please also remove - // #include "graphics/GraphicsTypes.h" at the top -- Rob Lahaye. - lyx::graphics::setDisplayTranslator(); - if (want_gui) lyx_gui::parse_init(argc, argv); @@ -117,12 +204,14 @@ 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) @@ -148,7 +237,7 @@ LyX::LyX(int & argc, char * argv[]) } else { Buffer * buf = bufferlist.newBuffer(s, false); buf->error.connect(boost::bind(&LyX::printError, this, _1)); - if (loadLyXFile(buf, s)) + if (loadLyXFile(buf, s)) last_loaded = buf; else bufferlist.release(buf); @@ -162,7 +251,7 @@ LyX::LyX(int & argc, char * argv[]) QuitLyX(); exit(!success); } - } + } files.clear(); // the files are already loaded } @@ -174,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; @@ -204,11 +311,8 @@ 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)) + if (err_sig == SIGSEGV || + (err_sig != SIGHUP && !GetEnv("LYXDEBUG").empty())) lyx::support::abort(); exit(0); } @@ -231,6 +335,7 @@ void LyX::init(bool gui) signal(SIGSEGV, error_handler); signal(SIGINT, error_handler); signal(SIGTERM, error_handler); + // SIGPIPE can be safely ignored. bool const explicit_userdir = setLyxPaths(); @@ -297,78 +402,88 @@ void LyX::init(bool gui) if (lyxerr.debugging(Debug::LYXRC)) lyxrc.print(); - os::setTmpDir(CreateLyXTmpDir(lyxrc.tempdir_path)); + 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); + } + if (lyxerr.debugging(Debug::INIT)) { - lyxerr << "LyX tmp dir: `" << os::getTmpDir() << '\'' << 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_CELL_FORWARD); - kbmap->bind("ISO_Left_Tab", LFUN_CELL_FORWARD); // 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_CELL_SPLIT); // ale970515 - kbmap->bind("S-Tab", LFUN_CELL_BACKWARD); // jug20000522 - kbmap->bind("S-ISO_Left_Tab", LFUN_CELL_BACKWARD); // 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 @@ -385,25 +500,25 @@ 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)); }