]> git.lyx.org Git - lyx.git/blobdiff - src/LyX.cpp
adjust
[lyx.git] / src / LyX.cpp
index 6e6d64502f42362d898fc21af4aa07155db7561a..81acf9f6cf3f5ae5423d3a3c59898fa27f58aaa6 100644 (file)
@@ -22,6 +22,7 @@
 #include "buffer_funcs.h"
 #include "BufferList.h"
 #include "Converter.h"
+#include "CutAndPaste.h"
 #include "debug.h"
 #include "Encoding.h"
 #include "ErrorList.h"
 #include "Language.h"
 #include "Session.h"
 #include "Color.h"
-#include "callback.h"
 #include "LyXAction.h"
 #include "LyXFunc.h"
 #include "Lexer.h"
 #include "LyXRC.h"
-#include "LyXServer.h"
-#include "LyXServerSocket.h"
-#include "LyXTextClassList.h"
+#include "ModuleList.h"
+#include "Server.h"
+#include "ServerSocket.h"
+#include "TextClassList.h"
 #include "MenuBackend.h"
 #include "Messages.h"
 #include "Mover.h"
@@ -46,6 +47,7 @@
 
 #include "frontends/alert.h"
 #include "frontends/Application.h"
+#include "frontends/Dialogs.h"
 #include "frontends/Gui.h"
 #include "frontends/LyXView.h"
 
 #include <boost/bind.hpp>
 #include <boost/filesystem/operations.hpp>
 
+#include <algorithm>
 #include <iostream>
 #include <csignal>
 #include <map>
 #include <string>
 #include <vector>
 
+using std::endl;
+using std::for_each;
+using std::map;
+using std::make_pair;
+using std::string;
+using std::vector;
+
+#ifndef CXX_GLOBAL_CSTD
+using std::exit;
+using std::signal;
+using std::system;
+#endif
+
+namespace fs = boost::filesystem;
 
 namespace lyx {
 
@@ -87,31 +104,20 @@ using support::package;
 using support::prependEnvPath;
 using support::rtrim;
 using support::Systemcall;
+using frontend::LyXView;
 
 namespace Alert = frontend::Alert;
 namespace os = support::os;
-namespace fs = boost::filesystem;
-
-using std::endl;
-using std::for_each;
-using std::map;
-using std::make_pair;
-using std::string;
-using std::vector;
 
-#ifndef CXX_GLOBAL_CSTD
-using std::exit;
-using std::signal;
-using std::system;
-#endif
 
 
 /// are we using the GUI at all?
-/** 
+/**
 * We default to true and this is changed to false when the export feature is used.
 */
 bool use_gui = true;
 
+bool quitting; // flag, that we are quitting the program
 
 namespace {
 
@@ -147,7 +153,7 @@ void reconfigureUserLyXDir()
 
 
 /// The main application class private implementation.
-struct LyX::Singletons 
+struct LyX::Singletons
 {
        Singletons()
        {
@@ -163,9 +169,9 @@ struct LyX::Singletons
        ///
        boost::scoped_ptr<KeyMap> toplevel_keymap_;
        ///
-       boost::scoped_ptr<LyXServer> lyx_server_;
+       boost::scoped_ptr<Server> lyx_server_;
        ///
-       boost::scoped_ptr<LyXServerSocket> lyx_socket_;
+       boost::scoped_ptr<ServerSocket> lyx_socket_;
        ///
        boost::scoped_ptr<frontend::Application> application_;
        /// lyx session, containing lastfiles, lastfilepos, and lastopened
@@ -182,10 +188,10 @@ struct LyX::Singletons
 
        // The system converters copy after reading lyxrc.defaults.
        Converters system_converters_;
-       
+
        ///
        Movers movers_;
-       
+
        ///
        Movers system_movers_;
 };
@@ -265,28 +271,28 @@ LyXFunc const & LyX::lyxFunc() const
 }
 
 
-LyXServer & LyX::server()
+Server & LyX::server()
 {
        BOOST_ASSERT(pimpl_->lyx_server_.get());
-       return *pimpl_->lyx_server_.get(); 
+       return *pimpl_->lyx_server_.get();
 }
 
 
-LyXServer const & LyX::server() const 
+Server const & LyX::server() const
 {
        BOOST_ASSERT(pimpl_->lyx_server_.get());
-       return *pimpl_->lyx_server_.get(); 
+       return *pimpl_->lyx_server_.get();
 }
 
 
-LyXServerSocket & LyX::socket()
+ServerSocket & LyX::socket()
 {
        BOOST_ASSERT(pimpl_->lyx_socket_.get());
        return *pimpl_->lyx_socket_.get();
 }
 
 
-LyXServerSocket const & LyX::socket() const
+ServerSocket const & LyX::socket() const
 {
        BOOST_ASSERT(pimpl_->lyx_socket_.get());
        return *pimpl_->lyx_socket_.get();
@@ -340,7 +346,7 @@ Messages & LyX::getMessages(std::string const & language)
        if (it != pimpl_->messages_.end())
                return it->second;
 
-       std::pair<map<string, Messages>::iterator, bool> result = 
+       std::pair<map<string, Messages>::iterator, bool> result =
                        pimpl_->messages_.insert(std::make_pair(language, Messages(language)));
 
        BOOST_ASSERT(result.second);
@@ -360,9 +366,9 @@ void LyX::setGuiLanguage(std::string const & language)
 }
 
 
-Buffer const * const LyX::updateInset(Inset const * inset) const
+Buffer const * LyX::updateInset(Inset const * inset) const
 {
-       if (!inset)
+       if (quitting || !inset)
                return 0;
 
        Buffer const * buffer_ptr = 0;
@@ -379,15 +385,30 @@ Buffer const * const LyX::updateInset(Inset const * inset) const
 }
 
 
+void LyX::hideDialogs(std::string const & name, Inset * inset) const
+{
+       if (quitting || !use_gui)
+               return;
+
+       vector<int> const & view_ids = pimpl_->application_->gui().viewIds();
+       vector<int>::const_iterator it = view_ids.begin();
+       vector<int>::const_iterator const end = view_ids.end();
+       for (; it != end; ++it)
+               pimpl_->application_->gui().view(*it).getDialogs().
+                       hide(name, inset);
+}
+
+
 int LyX::exec(int & argc, char * argv[])
 {
        // Here we need to parse the command line. At least
        // we need to parse for "-dbg" and "-help"
        easyParse(argc, argv);
 
-       try { support::init_package(to_utf8(from_local8bit(argv[0])),
-                             cl_system_support, cl_user_support,
-                             support::top_build_dir_is_one_level_up);
+       try {
+               support::init_package(to_utf8(from_local8bit(argv[0])),
+                             cl_system_support, cl_user_support,
+                             support::top_build_dir_is_one_level_up);
        } catch (support::ExceptionMessage const & message) {
                if (message.type_ == support::ErrorException) {
                        Alert::error(message.title_, message.details_);
@@ -397,6 +418,10 @@ int LyX::exec(int & argc, char * argv[])
                }
        }
 
+       // Reinit the messages machinery in case package() knows
+       // something interesting about the locale directory.
+       Messages::init();
+
        if (!use_gui) {
                // FIXME: create a ConsoleApplication
                int exit_status = init(argc, argv);
@@ -413,22 +438,20 @@ int LyX::exec(int & argc, char * argv[])
                }
 
                BufferList::iterator begin = pimpl_->buffer_list_.begin();
-               BufferList::iterator end = pimpl_->buffer_list_.end();
 
                bool final_success = false;
-               for (BufferList::iterator I = begin; I != end; ++I) {
+               for (BufferList::iterator I = begin; I != pimpl_->buffer_list_.end(); ++I) {
                        Buffer * buf = *I;
+                       if (buf != buf->getMasterBuffer())
+                               continue;
                        bool success = false;
                        buf->dispatch(batch_command, &success);
-                       final_success |= success;                       
+                       final_success |= success;
                }
                prepareExit();
                return !final_success;
        }
 
-       // Force adding of font path _before_ Application is initialized
-       support::os::addFontResources();
-
        // Let the frontend parse and remove all arguments that it knows
        pimpl_->application_.reset(createApplication(argc, argv));
 
@@ -454,17 +477,14 @@ int LyX::exec(int & argc, char * argv[])
        */
        // Note: socket callback must be registered after init(argc, argv)
        // such that package().temp_dir() is properly initialized.
-       pimpl_->lyx_server_.reset(new LyXServer(&pimpl_->lyxfunc_, lyxrc.lyxpipes));
-       pimpl_->lyx_socket_.reset(new LyXServerSocket(&pimpl_->lyxfunc_, 
+       pimpl_->lyx_server_.reset(new Server(&pimpl_->lyxfunc_, lyxrc.lyxpipes));
+       pimpl_->lyx_socket_.reset(new ServerSocket(&pimpl_->lyxfunc_,
                        FileName(package().temp_dir().absFilename() + "/lyxsocket")));
 
        // Start the real execution loop.
        exit_status = pimpl_->application_->exec();
-       
-       prepareExit();
 
-       // Restore original font resources after Application is destroyed.
-       support::os::restoreFontResources();
+       prepareExit();
 
        return exit_status;
 }
@@ -472,6 +492,10 @@ int LyX::exec(int & argc, char * argv[])
 
 void LyX::prepareExit()
 {
+       // Clear the clipboard and selection stack:
+       cap::clearCutStack();
+       cap::clearSelection();
+
        // Set a flag that we do quitting from the program,
        // so no refreshes are necessary.
        quitting = true;
@@ -552,6 +576,17 @@ int LyX::init(int & argc, char * argv[])
 }
 
 
+void LyX::addFileToLoad(FileName const & fname)
+{
+       vector<FileName>::const_iterator cit = std::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()
 {
        vector<FileName>::const_iterator it = pimpl_->files_to_load_.begin();
@@ -581,6 +616,32 @@ void LyX::execBatchCommands()
        // aknowledged.
        restoreGuiSession();
 
+       // if reconfiguration is needed.
+       if (textclasslist.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")))
+               {
+               case 0:
+                       // regular reconfigure
+                       pimpl_->lyxfunc_.dispatch(FuncRequest(LFUN_RECONFIGURE, ""));
+                       break;
+               case 1:
+                       // reconfigure --without-latex-config
+                       pimpl_->lyxfunc_.dispatch(FuncRequest(LFUN_RECONFIGURE,
+                               " --without-latex-config"));
+                       break;
+               }
+               pimpl_->lyxfunc_.dispatch(FuncRequest(LFUN_LYX_QUIT));
+               return;
+       }
+       
        // Execute batch commands if available
        if (batch_command.empty())
                return;
@@ -596,6 +657,10 @@ void LyX::restoreGuiSession()
 {
        LyXView * view = newLyXView();
 
+       // if there is no valid class list, do not load any file. 
+       if (textclasslist.empty())
+               return;
+
        // if some files were specified at command-line we assume that the
        // user wants to edit *these* files and not to restore the session.
        if (!pimpl_->files_to_load_.empty()) {
@@ -605,21 +670,33 @@ void LyX::restoreGuiSession()
                // clear this list to save a few bytes of RAM
                pimpl_->files_to_load_.clear();
                pimpl_->session_->lastOpened().clear();
-               return;
-       }
 
-       if (!lyxrc.load_session)
-               return;
+       } else if (lyxrc.load_session) {
+               vector<FileName> const & lastopened = pimpl_->session_->lastOpened().getfiles();
+               // do not add to the lastfile list since these files are restored from
+               // last session, and should be already there (regular files), or should
+               // not be added at all (help files).
+               for_each(lastopened.begin(), lastopened.end(),
+                       bind(&LyXView::loadLyXFile, view, _1, false));
+
+               // clear this list to save a few bytes of RAM
+               pimpl_->session_->lastOpened().clear();
+       }
 
-       vector<FileName> const & lastopened = pimpl_->session_->lastOpened().getfiles();
-       // do not add to the lastfile list since these files are restored from
-       // last session, and should be already there (regular files), or should
-       // not be added at all (help files).
-       for_each(lastopened.begin(), lastopened.end(),
-               bind(&LyXView::loadLyXFile, view, _1, false));
+       BufferList::iterator I = pimpl_->buffer_list_.begin();
+       BufferList::iterator end = pimpl_->buffer_list_.end();
+       for (; I != end; ++I) {
+               Buffer * buf = *I;
+               if (buf != buf->getMasterBuffer())
+                       continue;
+               updateLabels(*buf);
+       }
 
-       // clear this list to save a few bytes of RAM
-       pimpl_->session_->lastOpened().clear();
+       // FIXME: Switch to the last loaded Buffer. This must not be the first one
+       // because the Buffer won't be connected in this case. The correct solution
+       // would be to avoid the manual connection of the current Buffer in LyXView.
+       if (!pimpl_->buffer_list_.empty())
+               view->setBuffer(pimpl_->buffer_list_.last());
 }
 
 
@@ -668,7 +745,7 @@ LyXView * LyX::newLyXView()
                        posy = convert<int>(val);
        }
 
-       if (!geometryArg.empty()) 
+       if (!geometryArg.empty())
        {
                width = 0;
                height = 0;
@@ -796,7 +873,7 @@ void LyX::initGuiFont()
                lyxrc.sans_font_name = pimpl_->application_->sansFontName();
 
        if (lyxrc.typewriter_font_name.empty())
-               lyxrc.typewriter_font_name 
+               lyxrc.typewriter_font_name
                        = pimpl_->application_->typewriterFontName();
 }
 
@@ -879,22 +956,26 @@ bool LyX::init()
        LYXERR(Debug::INIT) << "Reading layouts..." << endl;
        if (!LyXSetStyle())
                return false;
+       //...and the modules
+       moduleList.load();
 
-       if (use_gui) {
-               // Set the language defined by the user.
-               //setGuiLanguage(lyxrc.gui_language);
+       // read keymap and ui files in batch mode as well
+       // because InsetInfo needs to know these to produce
+       // the correct output
 
-               // Set up bindings
-               pimpl_->toplevel_keymap_.reset(new KeyMap);
-               defaultKeyBindings(pimpl_->toplevel_keymap_.get());
-               pimpl_->toplevel_keymap_->read(lyxrc.bind_file);
+       // Set the language defined by the user.
+       //setGuiLanguage(lyxrc.gui_language);
 
-               pimpl_->lyxfunc_.initKeySequences(pimpl_->toplevel_keymap_.get());
+       // Set up bindings
+       pimpl_->toplevel_keymap_.reset(new KeyMap);
+       defaultKeyBindings(pimpl_->toplevel_keymap_.get());
+       pimpl_->toplevel_keymap_->read(lyxrc.bind_file);
 
-               // Read menus
-               if (!readUIFile(lyxrc.ui_file))
-                       return false;
-       }
+       pimpl_->lyxfunc_.initKeySequences(pimpl_->toplevel_keymap_.get());
+
+       // Read menus
+       if (!readUIFile(lyxrc.ui_file))
+               return false;
 
        if (lyxerr.debugging(Debug::LYXRC))
                lyxrc.print();
@@ -924,8 +1005,8 @@ bool LyX::init()
        }
 
        LYXERR(Debug::INIT) << "LyX tmp dir: `"
-                           << package().temp_dir().absFilename()
-                           << '\'' << endl;
+                           << package().temp_dir().absFilename()
+                           << '\'' << endl;
 
        LYXERR(Debug::INIT) << "Reading session information '.lyx/session'..." << endl;
        pimpl_->session_.reset(new Session(lyxrc.num_lastfiles));
@@ -1068,6 +1149,7 @@ bool LyX::queryUserLyXDir(bool explicit_userdir)
                first_start = false;
 
                return needsUpdate("lyxrc.defaults")
+                       || needsUpdate("lyxmodules.lst")
                        || needsUpdate("textclass.lst")
                        || needsUpdate("packages.lst");
        }
@@ -1158,7 +1240,7 @@ bool LyX::readUIFile(string const & name, bool include)
 
        LYXERR(Debug::INIT) << "About to read " << name << "..." << endl;
 
-       
+
        FileName ui_path;
        if (include) {
                ui_path = libFileSearch("ui", name, "inc");
@@ -1168,7 +1250,7 @@ bool LyX::readUIFile(string const & name, bool include)
        }
        else
                ui_path = libFileSearch("ui", name, "ui");
-       
+
        if (ui_path.empty()) {
                LYXERR(Debug::INIT) << "Could not find " << name << endl;
                showFileError(name);
@@ -1238,10 +1320,10 @@ bool LyX::readLanguagesFile(string const & name)
 
 // Read the encodings file `name'
 bool LyX::readEncodingsFile(string const & enc_name,
-                            string const & symbols_name)
+                           string const & symbols_name)
 {
        LYXERR(Debug::INIT) << "About to read " << enc_name << " and "
-                           << symbols_name << "..." << endl;
+                           << symbols_name << "..." << endl;
 
        FileName const symbols_path = libFileSearch(string(), symbols_name);
        if (symbols_path.empty()) {
@@ -1464,7 +1546,7 @@ LyXFunc & theLyXFunc()
 }
 
 
-LyXServer & theLyXServer()
+Server & theServer()
 {
        // FIXME: this should not be use_gui dependent
        BOOST_ASSERT(use_gui);
@@ -1472,7 +1554,7 @@ LyXServer & theLyXServer()
 }
 
 
-LyXServerSocket & theLyXServerSocket()
+ServerSocket & theServerSocket()
 {
        // FIXME: this should not be use_gui dependent
        BOOST_ASSERT(use_gui);
@@ -1482,7 +1564,6 @@ LyXServerSocket & theLyXServerSocket()
 
 KeyMap & theTopLevelKeymap()
 {
-       BOOST_ASSERT(use_gui);
        return LyX::ref().topLevelKeymap();
 }