]> git.lyx.org Git - lyx.git/blobdiff - src/LyX.cpp
Update the GuiLabel view when the document is read-only. Also disable the text field.
[lyx.git] / src / LyX.cpp
index fc335f4eb0df9ac487142d9db20aed3c00983c90..7b5c07636f00556e3b9fa21e5d44ecc3a9424b2c 100644 (file)
@@ -4,10 +4,10 @@
  * Licence details can be found in the file COPYING.
  *
  * \author Alfredo Braunstein
- * \author Lars Gullik Bjønnes
+ * \author Lars Gullik Bjønnes
  * \author Jean-Marc Lasgouttes
  * \author John Levon
- * \author André Pönitz
+ * \author André Pönitz
  *
  * Full author contact details are available in file CREDITS.
  */
 
 #include "LyX.h"
 
-#include "LayoutFile.h"
+#include "AspellChecker.h"
 #include "Buffer.h"
 #include "BufferList.h"
 #include "CmdDef.h"
-#include "Color.h"
+#include "ColorSet.h"
 #include "ConverterCache.h"
 #include "Converter.h"
 #include "CutAndPaste.h"
 #include "ErrorList.h"
 #include "Format.h"
 #include "FuncStatus.h"
+#include "HunspellChecker.h"
 #include "KeyMap.h"
 #include "Language.h"
+#include "LayoutFile.h"
 #include "Lexer.h"
 #include "LyXAction.h"
 #include "LyXFunc.h"
 #include "Server.h"
 #include "ServerSocket.h"
 #include "Session.h"
-#include "ToolbarBackend.h"
 
 #include "frontends/alert.h"
 #include "frontends/Application.h"
 
+#include "graphics/Previews.h"
+
 #include "support/lassert.h"
 #include "support/debug.h"
 #include "support/environment.h"
@@ -116,17 +119,23 @@ void reconfigureUserLyXDir()
 
 } // namespace anon
 
-
 /// The main application class private implementation.
 struct LyX::Impl
 {
-       Impl()
+       Impl() : spell_checker_(0), aspell_checker_(0), hunspell_checker_(0)
        {
                // Set the default User Interface language as soon as possible.
                // The language used will be derived from the environment
                // variables.
                messages_["GUI"] = Messages();
        }
+
+       ~Impl()
+       {
+               delete aspell_checker_;
+               delete hunspell_checker_;
+       }
+
        /// our function handler
        LyXFunc lyxfunc_;
        ///
@@ -164,7 +173,16 @@ struct LyX::Impl
        /// has this user started lyx for the first time?
        bool first_start;
        /// the parsed command line batch command if any
-       string batch_command;
+       vector<string> batch_commands;
+
+       ///
+       graphics::Previews preview_;
+       ///
+       SpellChecker * spell_checker_;
+       ///
+       SpellChecker * aspell_checker_;
+       ///
+       SpellChecker * hunspell_checker_;
 };
 
 ///
@@ -179,11 +197,12 @@ frontend::Application * theApp()
 
 LyX::~LyX()
 {
+       singleton_ = 0;
        delete pimpl_;
 }
 
 
-void LyX::exit(int exit_code) const
+void lyx_exit(int exit_code)
 {
        if (exit_code)
                // Something wrong happened so better save everything, just in
@@ -203,20 +222,6 @@ void LyX::exit(int exit_code) const
 }
 
 
-LyX & LyX::ref()
-{
-       LASSERT(singleton_, /**/);
-       return *singleton_;
-}
-
-
-LyX const & LyX::cref()
-{
-       LASSERT(singleton_, /**/);
-       return *singleton_;
-}
-
-
 LyX::LyX()
        : first_start(false)
 {
@@ -225,105 +230,7 @@ LyX::LyX()
 }
 
 
-BufferList & LyX::bufferList()
-{
-       return pimpl_->buffer_list_;
-}
-
-
-BufferList const & LyX::bufferList() const
-{
-       return pimpl_->buffer_list_;
-}
-
-
-Session & LyX::session()
-{
-       LASSERT(pimpl_->session_.get(), /**/);
-       return *pimpl_->session_.get();
-}
-
-
-Session const & LyX::session() const
-{
-       LASSERT(pimpl_->session_.get(), /**/);
-       return *pimpl_->session_.get();
-}
-
-
-LyXFunc & LyX::lyxFunc()
-{
-       return pimpl_->lyxfunc_;
-}
-
-
-LyXFunc const & LyX::lyxFunc() const
-{
-       return pimpl_->lyxfunc_;
-}
-
-
-Server & LyX::server()
-{
-       LASSERT(pimpl_->lyx_server_.get(), /**/);
-       return *pimpl_->lyx_server_.get();
-}
-
-
-Server const & LyX::server() const
-{
-       LASSERT(pimpl_->lyx_server_.get(), /**/);
-       return *pimpl_->lyx_server_.get();
-}
-
-
-ServerSocket & LyX::socket()
-{
-       LASSERT(pimpl_->lyx_socket_.get(), /**/);
-       return *pimpl_->lyx_socket_.get();
-}
-
-
-ServerSocket const & LyX::socket() const
-{
-       LASSERT(pimpl_->lyx_socket_.get(), /**/);
-       return *pimpl_->lyx_socket_.get();
-}
-
-
-frontend::Application & LyX::application()
-{
-       LASSERT(pimpl_->application_.get(), /**/);
-       return *pimpl_->application_.get();
-}
-
-
-frontend::Application const & LyX::application() const
-{
-       LASSERT(pimpl_->application_.get(), /**/);
-       return *pimpl_->application_.get();
-}
-
-
-CmdDef & LyX::topLevelCmdDef()
-{
-       return pimpl_->toplevel_cmddef_;
-}
-
-
-Converters & LyX::converters()
-{
-       return pimpl_->converters_;
-}
-
-
-Converters & LyX::systemConverters()
-{
-       return pimpl_->system_converters_;
-}
-
-
-Messages & LyX::getMessages(string const & language)
+Messages & LyX::messages(string const & language)
 {
        map<string, Messages>::iterator it = pimpl_->messages_.find(language);
 
@@ -338,15 +245,22 @@ Messages & LyX::getMessages(string const & language)
 }
 
 
-Messages & LyX::getGuiMessages()
-{
-       return pimpl_->messages_["GUI"];
-}
-
-
-void LyX::setGuiLanguage(string const & language)
+void setRcGuiLanguage()
 {
-       pimpl_->messages_["GUI"] = Messages(language);
+       LASSERT(singleton_, /**/);
+       if (lyxrc.gui_language == "auto")
+               return;
+       Language const * language = languages.getLanguage(lyxrc.gui_language);
+       if (language) {
+               LYXERR(Debug::LOCALE, "Setting LANGUAGE to " << language->code());
+               if (!setEnv("LANGUAGE", language->code()))
+                       LYXERR(Debug::LOCALE, "\t... failed!");
+       }
+       LYXERR(Debug::LOCALE, "Setting LC_ALL to en_US");
+       if (!setEnv("LC_ALL", "en_US"))
+               LYXERR(Debug::LOCALE, "\t... failed!");
+       Messages::init();
+       singleton_->pimpl_->messages_["GUI"] = Messages();
 }
 
 
@@ -363,7 +277,7 @@ int LyX::exec(int & argc, char * argv[])
        } catch (ExceptionMessage const & message) {
                if (message.type_ == ErrorException) {
                        Alert::error(message.title_, message.details_);
-                       exit(1);
+                       lyx_exit(1);
                } else if (message.type_ == WarningException) {
                        Alert::warning(message.title_, message.details_);
                }
@@ -381,11 +295,12 @@ int LyX::exec(int & argc, char * argv[])
                        return exit_status;
                }
 
-               loadFiles();
+               // this is correct, since return values are inverted.
+               exit_status = !loadFiles();
 
-               if (pimpl_->batch_command.empty() || pimpl_->buffer_list_.empty()) {
+               if (pimpl_->batch_commands.empty() || pimpl_->buffer_list_.empty()) {
                        prepareExit();
-                       return EXIT_SUCCESS;
+                       return exit_status;
                }
 
                BufferList::iterator begin = pimpl_->buffer_list_.begin();
@@ -395,9 +310,14 @@ int LyX::exec(int & argc, char * argv[])
                        Buffer * buf = *I;
                        if (buf != buf->masterBuffer())
                                continue;
-                       bool success = false;
-                       buf->dispatch(pimpl_->batch_command, &success);
-                       final_success |= success;
+                       vector<string>::const_iterator bcit  = pimpl_->batch_commands.begin();
+                       vector<string>::const_iterator bcend = pimpl_->batch_commands.end();
+                       DispatchResult dr;
+                       for (; bcit != bcend; bcit++) {
+                               LYXERR(Debug::ACTION, "Buffer::dispatch: cmd: " << *bcit);
+                               buf->dispatch(*bcit, dr);
+                               final_success |= !dr.error();
+                       }
                }
                prepareExit();
                return !final_success;
@@ -406,6 +326,10 @@ int LyX::exec(int & argc, char * argv[])
        // Let the frontend parse and remove all arguments that it knows
        pimpl_->application_.reset(createApplication(argc, argv));
 
+       // Reestablish our defaults, as Qt overwrites them
+       // after createApplication()
+       locale_init();
+
        // Parse and remove all known arguments in the LyX singleton
        // Give an error for all remaining ones.
        int exit_status = init(argc, argv);
@@ -416,7 +340,7 @@ int LyX::exec(int & argc, char * argv[])
                prepareExit();
                return exit_status;
        }
-
        // FIXME
        /* Create a CoreApplication class that will provide the main event loop
        * and the socket callback registering. With Qt4, only QtCore
@@ -445,6 +369,9 @@ void LyX::prepareExit()
        cap::clearCutStack();
        cap::clearSelection();
 
+       // Write the index file of the converter cache
+       ConverterCache::get().writeIndex();
+
        // close buffers first
        pimpl_->buffer_list_.closeAll();
 
@@ -459,14 +386,21 @@ void LyX::prepareExit()
 
        // do any other cleanup procedures now
        if (package().temp_dir() != package().system_temp_dir()) {
-               LYXERR(Debug::INFO, "Deleting tmp dir "
-                                   << package().temp_dir().absFilename());
-
-               if (!package().temp_dir().destroyDirectory()) {
+               string const abs_tmpdir = package().temp_dir().absFilename();
+               if (!contains(package().temp_dir().absFilename(), "lyx_tmpdir")) {
                        docstring const msg =
-                               bformat(_("Unable to remove the temporary directory %1$s"),
-                               from_utf8(package().temp_dir().absFilename()));
-                       Alert::warning(_("Unable to remove temporary directory"), msg);
+                               bformat(_("%1$s does not appear like a LyX created temporary directory."),
+                               from_utf8(abs_tmpdir));
+                       Alert::warning(_("Cannot remove temporary directory"), msg);
+               } else {
+                       LYXERR(Debug::INFO, "Deleting tmp dir "
+                               << package().temp_dir().absFilename());
+                       if (!package().temp_dir().destroyDirectory()) {
+                               docstring const msg =
+                                       bformat(_("Unable to remove the temporary directory %1$s"),
+                                       from_utf8(package().temp_dir().absFilename()));
+                               Alert::warning(_("Unable to remove temporary directory"), msg);
+                       }
                }
        }
 
@@ -520,19 +454,10 @@ int LyX::init(int & argc, char * argv[])
 }
 
 
-void LyX::addFileToLoad(string const & fname)
-{
-       vector<string>::const_iterator cit = find(
-               pimpl_->files_to_load_.begin(), pimpl_->files_to_load_.end(),
-               fname);
-
-       if (cit == pimpl_->files_to_load_.end())
-               pimpl_->files_to_load_.push_back(fname);
-}
-
-
-void LyX::loadFiles()
+bool LyX::loadFiles()
 {
+       LASSERT(!use_gui, /**/);
+       bool success = true;
        vector<string>::const_iterator it = pimpl_->files_to_load_.begin();
        vector<string>::const_iterator end = pimpl_->files_to_load_.end();
 
@@ -552,13 +477,23 @@ void LyX::loadFiles()
                                for_each(el.begin(), el.end(),
                                boost::bind(&LyX::printError, this, _1));
                }
-               else
+               else {
                        pimpl_->buffer_list_.release(buf);
+                       success = false;
+               }
        }
+       return success;
+}
+
+
+void execBatchCommands()
+{
+       LASSERT(singleton_, /**/);
+       singleton_->execCommands();
 }
 
 
-void LyX::execBatchCommands()
+void LyX::execCommands()
 {
        // The advantage of doing this here is that the event loop
        // is already started. So any need for interaction will be
@@ -566,15 +501,15 @@ void LyX::execBatchCommands()
 
        // if reconfiguration is needed.
        while (LayoutFileList::get().empty()) {
-           switch (Alert::prompt(
-                   _("No textclass is found"),
-                   _("LyX cannot continue because no textclass is found. "
-                     "You can either reconfigure normally, or reconfigure using "
-                     "default textclasses, or quit LyX."),
-                   0, 2,
-                   _("&Reconfigure"),
-                   _("&Use Default"),
-                   _("&Exit LyX")))
+               switch (Alert::prompt(
+                       _("No textclass is found"),
+                       _("LyX cannot continue because no textclass is found. "
+                               "You can either reconfigure normally, or reconfigure using "
+                               "default textclasses, or quit LyX."),
+                       0, 2,
+                       _("&Reconfigure"),
+                       _("&Use Default"),
+                       _("&Exit LyX")))
                {
                case 0:
                        // regular reconfigure
@@ -603,17 +538,19 @@ void LyX::execBatchCommands()
                }
                // clear this list to save a few bytes of RAM
                pimpl_->files_to_load_.clear();
-       }
-       else
+       } else
                pimpl_->application_->restoreGuiSession();
 
        // Execute batch commands if available
-       if (pimpl_->batch_command.empty())
+       if (pimpl_->batch_commands.empty())
                return;
 
-       LYXERR(Debug::INIT, "About to handle -x '" << pimpl_->batch_command << '\'');
-
-       pimpl_->lyxfunc_.dispatch(lyxaction.lookupFunc(pimpl_->batch_command));
+       vector<string>::const_iterator bcit  = pimpl_->batch_commands.begin();
+       vector<string>::const_iterator bcend = pimpl_->batch_commands.end();
+       for (; bcit != bcend; bcit++) {
+               LYXERR(Debug::INIT, "About to handle -x '" << *bcit << '\'');
+               pimpl_->lyxfunc_.dispatch(lyxaction.lookupFunc(*bcit));
+       }
 }
 
 
@@ -624,7 +561,7 @@ The SIGHUP signal does not exist on Windows and does not need to be handled.
 
 Windows handles SIGFPE and SIGSEGV signals as expected.
 
-Cntl+C interrupts (mapped to SIGINT by Windows' POSIX compatability layer)
+Ctrl+C interrupts (mapped to SIGINT by Windows' POSIX compatability layer)
 cause a new thread to be spawned. This may well result in unexpected
 behaviour by the single-threaded LyX.
 
@@ -659,7 +596,7 @@ static void error_handler(int err_sig)
 
        // We have received a signal indicating a fatal error, so
        // try and save the data ASAP.
-       LyX::cref().emergencyCleanup();
+       emergencyCleanup();
 
        // These lyxerr calls may or may not work:
 
@@ -756,7 +693,7 @@ bool LyX::init()
                return false;
 
        // Set the language defined by the distributor.
-       //setGuiLanguage(lyxrc.gui_language);
+       setRcGuiLanguage();
 
        // Set the PATH correctly.
 #if !defined (USE_POSIX_PACKAGING)
@@ -787,6 +724,9 @@ bool LyX::init()
        // Read lyxrc.dist again to be able to override viewer auto-detection.
        readRcFile("lyxrc.dist");
 
+       // Set again the language defined by the distributor.
+       setRcGuiLanguage();
+
        system_lyxrc = lyxrc;
        system_formats = formats;
        pimpl_->system_converters_ = pimpl_->converters_;
@@ -802,20 +742,20 @@ bool LyX::init()
        if (!readLanguagesFile("languages"))
                return false;
 
+       // Set the language defined by the user.
+       setRcGuiLanguage();
+
        // Load the layouts
        LYXERR(Debug::INIT, "Reading layouts...");
        if (!LyXSetStyle())
                return false;
        //...and the modules
-       moduleList.load();
+       theModuleList.read();
 
        // read keymap and ui files in batch mode as well
        // because InsetInfo needs to know these to produce
        // the correct output
 
-       // Set the language defined by the user.
-       //setGuiLanguage(lyxrc.gui_language);
-
        // Set up command definitions
        pimpl_->toplevel_cmddef_.read(lyxrc.def_file);
 
@@ -823,13 +763,7 @@ bool LyX::init()
        pimpl_->toplevel_keymap_.read("site");
        pimpl_->toplevel_keymap_.read(lyxrc.bind_file);
        // load user bind file user.bind
-       pimpl_->toplevel_keymap_.read("user");
-
-       pimpl_->lyxfunc_.initKeySequences(&pimpl_->toplevel_keymap_);
-
-       // Read menus
-       if (use_gui && !readUIFile(lyxrc.ui_file))
-               return false;
+       pimpl_->toplevel_keymap_.read("user", 0, KeyMap::MissingOK);
 
        if (lyxerr.debugging(Debug::LYXRC))
                lyxrc.print();
@@ -842,12 +776,12 @@ bool LyX::init()
        if (document_path.exists() && document_path.isDirectory())
                package().document_dir() = document_path;
 
-       package().temp_dir() = createLyXTmpDir(FileName(lyxrc.tempdir_path));
+       package().set_temp_dir(createLyXTmpDir(FileName(lyxrc.tempdir_path)));
        if (package().temp_dir().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."),
+                                                      "\"%1$s\"\n"
+                                                          "Make sure that this path exists and is writable and try again."),
                                     from_utf8(lyxrc.tempdir_path)));
                // createLyXTmpDir() tries sufficiently hard to create a
                // usable temp dir, so the probability to come here is
@@ -866,29 +800,24 @@ bool LyX::init()
        // This must happen after package initialization and after lyxrc is
        // read, therefore it can't be done by a static object.
        ConverterCache::init();
-       
-       // init the global menubar on Mac. This must be done after the session
-       // was recovered to know the "last files".
-       if (use_gui)
-               theApp()->initGlobalMenu();
-       
+               
        return true;
 }
 
 
-void LyX::emergencyCleanup() const
+void 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
 
-       pimpl_->buffer_list_.emergencyWriteAll();
+       singleton_->pimpl_->buffer_list_.emergencyWriteAll();
        if (use_gui) {
-               if (pimpl_->lyx_server_)
-                       pimpl_->lyx_server_->emergencyCleanup();
-               pimpl_->lyx_server_.reset();
-               pimpl_->lyx_socket_.reset();
+               if (singleton_->pimpl_->lyx_server_)
+                       singleton_->pimpl_->lyx_server_->emergencyCleanup();
+               singleton_->pimpl_->lyx_server_.reset();
+               singleton_->pimpl_->lyx_socket_.reset();
        }
 }
 
@@ -976,100 +905,6 @@ bool LyX::readRcFile(string const & name)
        return true;
 }
 
-
-// Read the ui file `name'
-bool LyX::readUIFile(string const & name, bool include)
-{
-       enum {
-               ui_menuset = 1,
-               ui_toolbars,
-               ui_toolbarset,
-               ui_include,
-               ui_last
-       };
-
-       LexerKeyword uitags[] = {
-               { "include", ui_include },
-               { "menuset", ui_menuset },
-               { "toolbars", ui_toolbars },
-               { "toolbarset", ui_toolbarset }
-       };
-
-       // Ensure that a file is read only once (prevents include loops)
-       static list<string> uifiles;
-       list<string>::const_iterator it  = uifiles.begin();
-       list<string>::const_iterator end = uifiles.end();
-       it = find(it, end, name);
-       if (it != end) {
-               LYXERR(Debug::INIT, "UI file '" << name << "' has been read already. "
-                                   << "Is this an include loop?");
-               return false;
-       }
-
-       LYXERR(Debug::INIT, "About to read " << name << "...");
-
-
-       FileName ui_path;
-       if (include) {
-               ui_path = libFileSearch("ui", name, "inc");
-               if (ui_path.empty())
-                       ui_path = libFileSearch("ui",
-                                               changeExtension(name, "inc"));
-       }
-       else
-               ui_path = libFileSearch("ui", name, "ui");
-
-       if (ui_path.empty()) {
-               LYXERR(Debug::INIT, "Could not find " << name);
-               showFileError(name);
-               return false;
-       }
-
-       uifiles.push_back(name);
-
-       LYXERR(Debug::INIT, "Found " << name << " in " << ui_path);
-       Lexer lex(uitags);
-       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_include: {
-                       lex.next(true);
-                       string const file = lex.getString();
-                       if (!readUIFile(file, true))
-                               return false;
-                       break;
-               }
-               case ui_menuset:
-                       theApp()->readMenus(lex);
-                       break;
-
-               case ui_toolbarset:
-                       toolbarbackend.readToolbars(lex);
-                       break;
-
-               case ui_toolbars:
-                       toolbarbackend.readToolbarSettings(lex);
-                       break;
-
-               default:
-                       if (!rtrim(lex.getString()).empty())
-                               lex.printError("LyX::ReadUIFile: "
-                                              "Unknown menu tag: `$$Token'");
-                       break;
-               }
-       }
-       return true;
-}
-
-
 // Read the languages file `name'
 bool LyX::readLanguagesFile(string const & name)
 {
@@ -1110,12 +945,10 @@ bool LyX::readEncodingsFile(string const & enc_name,
 
 namespace {
 
-string batch;
-
 /// return the the number of arguments consumed
-typedef boost::function<int(string const &, string const &)> cmd_helper;
+typedef boost::function<int(string const &, string const &, string &)> cmd_helper;
 
-int parse_dbg(string const & arg, string const &)
+int parse_dbg(string const & arg, string const &, string &)
 {
        if (arg.empty()) {
                lyxerr << to_utf8(_("List of supported debug flags:")) << endl;
@@ -1124,13 +957,13 @@ int parse_dbg(string const & arg, string const &)
        }
        lyxerr << to_utf8(bformat(_("Setting debug level to %1$s"), from_utf8(arg))) << endl;
 
-       lyxerr.level(Debug::value(arg));
+       lyxerr.setLevel(Debug::value(arg));
        Debug::showLevel(lyxerr, lyxerr.level());
        return 1;
 }
 
 
-int parse_help(string const &, string const &)
+int parse_help(string const &, string const &, string &)
 {
        lyxerr <<
                to_utf8(_("Usage: lyx [ command line switches ] [ name.lyx ... ]\n"
@@ -1148,9 +981,11 @@ int parse_help(string const &, string const &)
                  "                  where fmt is the export format of choice.\n"
                  "                  Look on Tools->Preferences->File formats->Format\n"
                  "                  to get an idea which parameters should be passed.\n"
+                 "                  Note that the order of -e and -x switches matters.\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--batch         execute commands and exit\n"
                  "\t-version        summarize version and build info\n"
                               "Check the LyX man page for more details.")) << endl;
        exit(0);
@@ -1158,7 +993,7 @@ int parse_help(string const &, string const &)
 }
 
 
-int parse_version(string const &, string const &)
+int parse_version(string const &, string const &, string &)
 {
        lyxerr << "LyX " << lyx_version
               << " (" << lyx_release_date << ")" << endl;
@@ -1170,7 +1005,7 @@ int parse_version(string const &, string const &)
 }
 
 
-int parse_sysdir(string const & arg, string const &)
+int parse_sysdir(string const & arg, string const &, string &)
 {
        if (arg.empty()) {
                Alert::error(_("No system directory"),
@@ -1182,7 +1017,7 @@ int parse_sysdir(string const & arg, string const &)
 }
 
 
-int parse_userdir(string const & arg, string const &)
+int parse_userdir(string const & arg, string const &, string &)
 {
        if (arg.empty()) {
                Alert::error(_("No user directory"),
@@ -1194,7 +1029,7 @@ int parse_userdir(string const & arg, string const &)
 }
 
 
-int parse_execute(string const & arg, string const &)
+int parse_execute(string const & arg, string const &, string & batch)
 {
        if (arg.empty()) {
                Alert::error(_("Incomplete command"),
@@ -1206,7 +1041,7 @@ int parse_execute(string const & arg, string const &)
 }
 
 
-int parse_export(string const & type, string const &)
+int parse_export(string const & type, string const &, string & batch)
 {
        if (type.empty()) {
                lyxerr << to_utf8(_("Missing file type [eg latex, ps...] after "
@@ -1219,7 +1054,7 @@ int parse_export(string const & type, string const &)
 }
 
 
-int parse_import(string const & type, string const & file)
+int parse_import(string const & type, string const & file, string & batch)
 {
        if (type.empty()) {
                lyxerr << to_utf8(_("Missing file type [eg latex, ps...] after "
@@ -1236,16 +1071,19 @@ int parse_import(string const & type, string const & file)
 }
 
 
-int parse_geometry(string const & arg1, string const &)
+int parse_geometry(string const & arg1, string const &, string &)
 {
        geometryArg = arg1;
-#if defined(_WIN32) || (defined(__CYGWIN__) && defined(X_DISPLAY_MISSING))
-       // remove also the arg
-       return 1;
-#else
-       // don't remove "-geometry"
+       // don't remove "-geometry", it will be pruned out later in the
+       // frontend if need be.
        return -1;
-#endif
+}
+
+
+int parse_batch(string const &, string const &, string &) 
+{
+       use_gui = false;
+       return 0;
 }
 
 
@@ -1270,6 +1108,7 @@ void LyX::easyParse(int & argc, char * argv[])
        cmdmap["-i"] = parse_import;
        cmdmap["--import"] = parse_import;
        cmdmap["-geometry"] = parse_geometry;
+       cmdmap["--batch"] = parse_batch;
 
        for (int i = 1; i < argc; ++i) {
                map<string, cmd_helper>::const_iterator it
@@ -1284,7 +1123,10 @@ void LyX::easyParse(int & argc, char * argv[])
                string const arg2 =
                        (i + 2 < argc) ? to_utf8(from_local8bit(argv[i + 2])) : string();
 
-               int const remove = 1 + it->second(arg, arg2);
+               string batch;
+               int const remove = 1 + it->second(arg, arg2, batch);
+               if (!batch.empty())
+                       pimpl_->batch_commands.push_back(batch);
 
                // Now, remove used arguments by shifting
                // the following ones remove places down.
@@ -1295,32 +1137,34 @@ void LyX::easyParse(int & argc, char * argv[])
                        --i;
                }
        }
-
-       pimpl_->batch_command = batch;
 }
 
 
 FuncStatus getStatus(FuncRequest const & action)
 {
-       return LyX::ref().lyxFunc().getStatus(action);
+       LASSERT(singleton_, /**/);
+       return singleton_->pimpl_->lyxfunc_.getStatus(action);
 }
 
 
 void dispatch(FuncRequest const & action)
 {
-       LyX::ref().lyxFunc().dispatch(action);
+       LASSERT(singleton_, /**/);
+       singleton_->pimpl_->lyxfunc_.dispatch(action);
 }
 
 
 BufferList & theBufferList()
 {
-       return LyX::ref().bufferList();
+       LASSERT(singleton_, /**/);
+       return singleton_->pimpl_->buffer_list_;
 }
 
 
 LyXFunc & theLyXFunc()
 {
-       return LyX::ref().lyxFunc();
+       LASSERT(singleton_, /**/);
+       return singleton_->pimpl_->lyxfunc_;
 }
 
 
@@ -1328,7 +1172,8 @@ Server & theServer()
 {
        // FIXME: this should not be use_gui dependent
        LASSERT(use_gui, /**/);
-       return LyX::ref().server();
+       LASSERT(singleton_, /**/);
+       return *singleton_->pimpl_->lyx_server_.get();
 }
 
 
@@ -1336,61 +1181,122 @@ ServerSocket & theServerSocket()
 {
        // FIXME: this should not be use_gui dependent
        LASSERT(use_gui, /**/);
-       return LyX::ref().socket();
+       LASSERT(singleton_, /**/);
+       return *singleton_->pimpl_->lyx_socket_.get();
 }
 
 
 KeyMap & theTopLevelKeymap()
 {
-       return LyX::ref().pimpl_->toplevel_keymap_;
+       LASSERT(singleton_, /**/);
+       return singleton_->pimpl_->toplevel_keymap_;
 }
 
 
 Converters & theConverters()
 {
-       return  LyX::ref().converters();
+       LASSERT(singleton_, /**/);
+       return  singleton_->pimpl_->converters_;
 }
 
 
 Converters & theSystemConverters()
 {
-       return  LyX::ref().systemConverters();
+       LASSERT(singleton_, /**/);
+       return  singleton_->pimpl_->system_converters_;
 }
 
 
 Movers & theMovers()
 {
-       return  LyX::ref().pimpl_->movers_;
+       LASSERT(singleton_, /**/);
+       return singleton_->pimpl_->movers_;
 }
 
 
 Mover const & getMover(string  const & fmt)
 {
-       return  LyX::ref().pimpl_->movers_(fmt);
+       LASSERT(singleton_, /**/);
+       return singleton_->pimpl_->movers_(fmt);
 }
 
 
 void setMover(string const & fmt, string const & command)
 {
-       LyX::ref().pimpl_->movers_.set(fmt, command);
+       LASSERT(singleton_, /**/);
+       singleton_->pimpl_->movers_.set(fmt, command);
 }
 
 
 Movers & theSystemMovers()
 {
-       return  LyX::ref().pimpl_->system_movers_;
+       LASSERT(singleton_, /**/);
+       return singleton_->pimpl_->system_movers_;
 }
 
 
 Messages & getMessages(string const & language)
 {
-       return LyX::ref().getMessages(language);
+       LASSERT(singleton_, /**/);
+       return singleton_->messages(language);
 }
 
 
 Messages & getGuiMessages()
 {
-       return LyX::ref().getGuiMessages();
+       LASSERT(singleton_, /**/);
+       return singleton_->pimpl_->messages_["GUI"];
+}
+
+
+graphics::Previews & thePreviews()
+{
+       LASSERT(singleton_, /**/);
+       return singleton_->pimpl_->preview_;
+}
+
+
+Session & theSession()
+{
+       LASSERT(singleton_, /**/);
+       return *singleton_->pimpl_->session_.get();
+}
+
+
+CmdDef & theTopLevelCmdDef()
+{
+       LASSERT(singleton_, /**/);
+       return singleton_->pimpl_->toplevel_cmddef_;
+}
+
+
+SpellChecker * theSpellChecker()
+{
+       if (!singleton_->pimpl_->spell_checker_)
+               setSpellChecker();
+       return singleton_->pimpl_->spell_checker_;
+}
+
+
+void setSpellChecker()
+{
+#if defined(USE_ASPELL)
+       if (lyxrc.spellchecker == "aspell") {
+               if (!singleton_->pimpl_->aspell_checker_)
+                       singleton_->pimpl_->aspell_checker_ = new AspellChecker();
+               singleton_->pimpl_->spell_checker_ = singleton_->pimpl_->aspell_checker_;
+               return;
+       }
+#endif
+#if defined(USE_HUNSPELL)
+       if (lyxrc.spellchecker == "hunspell") {
+               if (!singleton_->pimpl_->hunspell_checker_)
+                       singleton_->pimpl_->hunspell_checker_ = new HunspellChecker();
+               singleton_->pimpl_->spell_checker_ = singleton_->pimpl_->hunspell_checker_;
+               return;
+       }
+#endif
+       singleton_->pimpl_->spell_checker_ = 0;
 }
 
 } // namespace lyx