]> git.lyx.org Git - lyx.git/blobdiff - src/LyX.cpp
* gcc does not like missing characters in keywords
[lyx.git] / src / LyX.cpp
index e93cfe64941f027ef76d0d6934ed9d5c8c28c8ab..829202e54c656e8d3a7d0e12125f0dd529d3026b 100644 (file)
 
 #include "LyX.h"
 
+#include "Color.h"
 #include "ConverterCache.h"
 #include "Buffer.h"
 #include "buffer_funcs.h"
 #include "BufferList.h"
 #include "Converter.h"
+#include "CutAndPaste.h"
 #include "debug.h"
 #include "Encoding.h"
 #include "ErrorList.h"
 #include "Format.h"
 #include "gettext.h"
 #include "KeyMap.h"
+#include "CmdDef.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 "ModuleList.h"
 #include "Server.h"
 #include "ServerSocket.h"
 #include "TextClassList.h"
@@ -61,7 +63,6 @@
 #include "support/Systemcall.h"
 
 #include <boost/bind.hpp>
-#include <boost/filesystem/operations.hpp>
 
 #include <algorithm>
 #include <iostream>
@@ -83,17 +84,13 @@ using std::signal;
 using std::system;
 #endif
 
-namespace fs = boost::filesystem;
-
 namespace lyx {
 
 using support::addName;
 using support::addPath;
 using support::bformat;
 using support::changeExtension;
-using support::createDirectory;
 using support::createLyXTmpDir;
-using support::destroyDir;
 using support::FileName;
 using support::fileSearch;
 using support::getEnv;
@@ -116,6 +113,7 @@ namespace os = support::os;
 */
 bool use_gui = true;
 
+bool quitting; // flag, that we are quitting the program
 
 namespace {
 
@@ -167,6 +165,8 @@ struct LyX::Singletons
        ///
        boost::scoped_ptr<KeyMap> toplevel_keymap_;
        ///
+       boost::scoped_ptr<CmdDef> toplevel_cmddef_;
+       ///
        boost::scoped_ptr<Server> lyx_server_;
        ///
        boost::scoped_ptr<ServerSocket> lyx_socket_;
@@ -318,6 +318,13 @@ KeyMap & LyX::topLevelKeymap()
 }
 
 
+CmdDef & LyX::topLevelCmdDef()
+{
+       BOOST_ASSERT(pimpl_->toplevel_cmddef_.get());
+       return *pimpl_->toplevel_cmddef_.get();
+}
+
+
 Converters & LyX::converters()
 {
        return pimpl_->converters_;
@@ -364,7 +371,7 @@ 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 (quitting || !inset)
                return 0;
@@ -403,7 +410,8 @@ int LyX::exec(int & argc, char * argv[])
        // we need to parse for "-dbg" and "-help"
        easyParse(argc, argv);
 
-       try { support::init_package(to_utf8(from_local8bit(argv[0])),
+       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) {
@@ -435,11 +443,12 @@ 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->masterBuffer())
+                               continue;
                        bool success = false;
                        buf->dispatch(batch_command, &success);
                        final_success |= success;
@@ -448,9 +457,6 @@ int LyX::exec(int & argc, char * argv[])
                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));
 
@@ -485,15 +491,16 @@ int LyX::exec(int & argc, char * argv[])
 
        prepareExit();
 
-       // Restore original font resources after Application is destroyed.
-       support::os::restoreFontResources();
-
        return exit_status;
 }
 
 
 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;
@@ -506,7 +513,7 @@ void LyX::prepareExit()
                LYXERR(Debug::INFO) << "Deleting tmp dir "
                                    << package().temp_dir().absFilename() << endl;
 
-               if (!destroyDir(package().temp_dir())) {
+               if (!package().temp_dir().destroyDirectory()) {
                        docstring const msg =
                                bformat(_("Unable to remove the temporary directory %1$s"),
                                from_utf8(package().temp_dir().absFilename()));
@@ -595,7 +602,7 @@ void LyX::loadFiles()
                        continue;
 
                Buffer * buf = pimpl_->buffer_list_.newBuffer(it->absFilename(), false);
-               if (loadLyXFile(buf, *it)) {
+               if (buf->loadLyXFile(*it)) {
                        ErrorList const & el = buf->errorList("Parse");
                        if (!el.empty())
                                for_each(el.begin(), el.end(),
@@ -614,6 +621,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;
@@ -629,30 +662,46 @@ 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()) {
                for_each(pimpl_->files_to_load_.begin(),
                        pimpl_->files_to_load_.end(),
-                       bind(&LyXView::loadLyXFile, view, _1, true, false, false));
+                       bind(&LyXView::loadLyXFile, view, _1, true));
                // 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));
 
-       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, false, false));
+               // clear this list to save a few bytes of RAM
+               pimpl_->session_->lastOpened().clear();
+       }
+
+       BufferList::iterator I = pimpl_->buffer_list_.begin();
+       BufferList::iterator end = pimpl_->buffer_list_.end();
+       for (; I != end; ++I) {
+               Buffer * buf = *I;
+               if (buf != buf->masterBuffer())
+                       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());
 }
 
 
@@ -912,22 +961,32 @@ 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 command definitions
+       pimpl_->toplevel_cmddef_.reset(new CmdDef);
+       pimpl_->toplevel_cmddef_->read(lyxrc.def_file);
 
-               // Read menus
-               if (!readUIFile(lyxrc.ui_file))
-                       return false;
-       }
+       // Set up bindings
+       pimpl_->toplevel_keymap_.reset(new KeyMap);
+       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_.get());
+
+       // Read menus
+       if (!readUIFile(lyxrc.ui_file))
+               return false;
 
        if (lyxerr.debugging(Debug::LYXRC))
                lyxrc.print();
@@ -937,8 +996,7 @@ bool LyX::init()
                prependEnvPath("PATH", lyxrc.path_prefix);
 
        FileName const document_path(lyxrc.document_path);
-       if (fs::exists(document_path.toFilesystemEncoding()) &&
-           fs::is_directory(document_path.toFilesystemEncoding()))
+       if (document_path.exists() && document_path.isDirectory())
                package().document_dir() = document_path;
 
        package().temp_dir() = createLyXTmpDir(FileName(lyxrc.tempdir_path));
@@ -971,58 +1029,6 @@ bool LyX::init()
 }
 
 
-void LyX::defaultKeyBindings(KeyMap  * kbmap)
-{
-       kbmap->bind("Right", FuncRequest(LFUN_CHAR_FORWARD));
-       kbmap->bind("Left", FuncRequest(LFUN_CHAR_BACKWARD));
-       kbmap->bind("Up", FuncRequest(LFUN_UP));
-       kbmap->bind("Down", FuncRequest(LFUN_DOWN));
-
-       kbmap->bind("Tab", FuncRequest(LFUN_CELL_FORWARD));
-       kbmap->bind("C-Tab", FuncRequest(LFUN_CELL_SPLIT));
-       kbmap->bind("~S-ISO_Left_Tab", FuncRequest(LFUN_CELL_BACKWARD));
-       kbmap->bind("~S-BackTab", FuncRequest(LFUN_CELL_BACKWARD));
-
-       kbmap->bind("Home", FuncRequest(LFUN_LINE_BEGIN));
-       kbmap->bind("End", FuncRequest(LFUN_LINE_END));
-       kbmap->bind("Prior", FuncRequest(LFUN_SCREEN_UP));
-       kbmap->bind("Next", FuncRequest(LFUN_SCREEN_DOWN));
-
-       kbmap->bind("Return", FuncRequest(LFUN_BREAK_PARAGRAPH));
-       //kbmap->bind("~C-~S-~M-nobreakspace", FuncRequest(LFUN_PROTECTEDSPACE));
-
-       kbmap->bind("Delete", FuncRequest(LFUN_CHAR_DELETE_FORWARD));
-       kbmap->bind("BackSpace", FuncRequest(LFUN_CHAR_DELETE_BACKWARD));
-
-       // kbmap->bindings to enable the use of the numeric keypad
-       // e.g. Num Lock set
-       //kbmap->bind("KP_0", FuncRequest(LFUN_SELF_INSERT));
-       //kbmap->bind("KP_Decimal", FuncRequest(LFUN_SELF_INSERT));
-       kbmap->bind("KP_Enter", FuncRequest(LFUN_BREAK_PARAGRAPH));
-       //kbmap->bind("KP_1", FuncRequest(LFUN_SELF_INSERT));
-       //kbmap->bind("KP_2", FuncRequest(LFUN_SELF_INSERT));
-       //kbmap->bind("KP_3", FuncRequest(LFUN_SELF_INSERT));
-       //kbmap->bind("KP_4", FuncRequest(LFUN_SELF_INSERT));
-       //kbmap->bind("KP_5", FuncRequest(LFUN_SELF_INSERT));
-       //kbmap->bind("KP_6", FuncRequest(LFUN_SELF_INSERT));
-       //kbmap->bind("KP_Add", FuncRequest(LFUN_SELF_INSERT));
-       //kbmap->bind("KP_7", FuncRequest(LFUN_SELF_INSERT));
-       //kbmap->bind("KP_8", FuncRequest(LFUN_SELF_INSERT));
-       //kbmap->bind("KP_9", FuncRequest(LFUN_SELF_INSERT));
-       //kbmap->bind("KP_Divide", FuncRequest(LFUN_SELF_INSERT));
-       //kbmap->bind("KP_Multiply", FuncRequest(LFUN_SELF_INSERT));
-       //kbmap->bind("KP_Subtract", FuncRequest(LFUN_SELF_INSERT));
-       kbmap->bind("KP_Right", FuncRequest(LFUN_CHAR_FORWARD));
-       kbmap->bind("KP_Left", FuncRequest(LFUN_CHAR_BACKWARD));
-       kbmap->bind("KP_Up", FuncRequest(LFUN_UP));
-       kbmap->bind("KP_Down", FuncRequest(LFUN_DOWN));
-       kbmap->bind("KP_Home", FuncRequest(LFUN_LINE_BEGIN));
-       kbmap->bind("KP_End", FuncRequest(LFUN_LINE_END));
-       kbmap->bind("KP_Prior", FuncRequest(LFUN_SCREEN_UP));
-       kbmap->bind("KP_Next", FuncRequest(LFUN_SCREEN_DOWN));
-}
-
-
 void LyX::emergencyCleanup() const
 {
        // what to do about tmpfiles is non-obvious. we would
@@ -1066,41 +1072,36 @@ void LyX::deadKeyBindings(KeyMap * kbmap)
 }
 
 
-namespace {
-
 // return true if file does not exist or is older than configure.py.
-bool needsUpdate(string const & file)
+static bool needsUpdate(string const & file)
 {
        // We cannot initialize configure_script directly because the package
        // is not initialized yet when  static objects are constructed.
-       static string configure_script;
+       static FileName configure_script;
        static bool firstrun = true;
        if (firstrun) {
-               configure_script = FileName(addName(
-                               package().system_support().absFilename(),
-                               "configure.py")).toFilesystemEncoding();
+               configure_script =
+                       FileName(addName(package().system_support().absFilename(),
+                               "configure.py"));
                firstrun = false;
        }
 
-       string const absfile = FileName(addName(
-               package().user_support().absFilename(), file)).toFilesystemEncoding();
-       return (! fs::exists(absfile))
-               || (fs::last_write_time(configure_script)
-                   > fs::last_write_time(absfile));
-}
-
+       FileName absfile = 
+               FileName(addName(package().user_support().absFilename(), file));
+       return !absfile.exists()
+               || configure_script.lastModified() > absfile.lastModified();
 }
 
 
 bool LyX::queryUserLyXDir(bool explicit_userdir)
 {
        // Does user directory exist?
-       string const user_support =
-               package().user_support().toFilesystemEncoding();
-       if (fs::exists(user_support) && fs::is_directory(user_support)) {
+       FileName const sup = package().user_support();
+       if (sup.exists() && sup.isDirectory()) {
                first_start = false;
 
                return needsUpdate("lyxrc.defaults")
+                       || needsUpdate("lyxmodules.lst")
                        || needsUpdate("textclass.lst")
                        || needsUpdate("packages.lst");
        }
@@ -1124,10 +1125,9 @@ bool LyX::queryUserLyXDir(bool explicit_userdir)
        }
 
        lyxerr << to_utf8(bformat(_("LyX: Creating directory %1$s"),
-                         from_utf8(package().user_support().absFilename())))
-              << endl;
+                         from_utf8(sup.absFilename()))) << endl;
 
-       if (!createDirectory(package().user_support(), 0755)) {
+       if (!sup.createDirectory(0755)) {
                // Failed, so let's exit.
                lyxerr << to_utf8(_("Failed to create directory. Exiting."))
                       << endl;
@@ -1515,7 +1515,6 @@ ServerSocket & theServerSocket()
 
 KeyMap & theTopLevelKeymap()
 {
-       BOOST_ASSERT(use_gui);
        return LyX::ref().topLevelKeymap();
 }