#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"
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;
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;
extern LyXServer * lyxserver;
-boost::scoped_ptr<LastFiles> lastfiles;
-
// This is the global bufferlist object
BufferList bufferlist;
exit(EXIT_FAILURE);
}
+} // namespace anon
+
+
+boost::scoped_ptr<LyX> 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(int & argc, char * argv[])
+
+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<LyXView> 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);
if (want_gui)
lyx_gui::parse_lyxrc();
+ initMath();
+
vector<string> files;
for (int argi = argc - 1; argi >= 1; --argi)
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;
- case SIGPIPE:
- // This will be received if lyx tries to write to a socket
- // whose reading end was closed. It can safely be ignored,
- // as in this case the ::write() system call will return -1
- // and errno will be set to EPIPE
- return;
- //break;
}
// Deinstall the signal handlers
signal(SIGFPE, SIG_DFL);
signal(SIGSEGV, SIG_DFL);
signal(SIGTERM, SIG_DFL);
- signal(SIGPIPE, 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);
}
signal(SIGSEGV, error_handler);
signal(SIGINT, error_handler);
signal(SIGTERM, error_handler);
- signal(SIGPIPE, error_handler);
+ // SIGPIPE can be safely ignored.
bool const explicit_userdir = setLyxPaths();
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));
}
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));
}
-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