X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Flyx_main.C;h=879e9c2df6560862ac6feee6ae955ed82ad59053;hb=37e82a546392d43f787826b85481a11f2a27af15;hp=f9b845e70e8852e5461f0d74c17a96600f44d387;hpb=44cd0fc9a1687cc63911c7f98d978594458e7813;p=lyx.git diff --git a/src/lyx_main.C b/src/lyx_main.C index f9b845e70e..879e9c2df6 100644 --- a/src/lyx_main.C +++ b/src/lyx_main.C @@ -36,10 +36,14 @@ #include "lyxtextclasslist.h" #include "lyxserver.h" #include "MenuBackend.h" +#include "mover.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" @@ -57,7 +61,7 @@ using lyx::support::AddName; using lyx::support::AddPath; using lyx::support::bformat; using lyx::support::createDirectory; -using lyx::support::CreateLyXTmpDir; +using lyx::support::createLyXTmpDir; using lyx::support::FileInfo; using lyx::support::FileSearch; using lyx::support::GetEnv; @@ -70,7 +74,8 @@ using lyx::support::setLyxPaths; using lyx::support::system_lyxdir; using lyx::support::user_lyxdir; -namespace os = lyx::support::os; +using lyx::support::os::getTmpDir; +using lyx::support::os::setTmpDir; using std::endl; using std::string; @@ -87,8 +92,6 @@ extern void QuitLyX(); extern LyXServer * lyxserver; -boost::scoped_ptr lastfiles; - // This is the global bufferlist object BufferList bufferlist; @@ -105,19 +108,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::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); } -LyX::LyX(int & argc, char * argv[]) + +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); @@ -139,6 +208,8 @@ LyX::LyX(int & argc, char * argv[]) if (want_gui) lyx_gui::parse_lyxrc(); + initMath(); + vector files; for (int argi = argc - 1; argi >= 1; --argi) @@ -193,24 +264,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; @@ -223,11 +312,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); } @@ -250,6 +336,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(); @@ -287,6 +374,7 @@ void LyX::init(bool gui) system_lyxrc = lyxrc; system_formats = formats; system_converters = converters; + system_movers = movers; system_lcolor = lcolor; string prefsfile = "preferences"; @@ -316,16 +404,30 @@ 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)); } @@ -350,10 +452,6 @@ void LyX::defaultKeyBindings(kb_keymap * kbmap) kbmap->bind("Delete", FuncRequest(LFUN_DELETE)); kbmap->bind("BackSpace", FuncRequest(LFUN_BACKSPACE)); - // sub- and superscript -MV - kbmap->bind("~S-underscore", FuncRequest(LFUN_SUBSCRIPT)); - kbmap->bind("~S-asciicircum", FuncRequest(LFUN_SUPERSCRIPT)); - // kbmap->bindings to enable the use of the numeric keypad // e.g. Num Lock set //kbmap->bind("KP_0", FuncRequest(LFUN_SELFINSERT)); @@ -387,7 +485,7 @@ void LyX::defaultKeyBindings(kb_keymap * kbmap) } -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