]> git.lyx.org Git - lyx.git/blobdiff - src/lyx_main.C
ensure that Application is properly destroyed after at the end of LyX::priv_exec()
[lyx.git] / src / lyx_main.C
index 422ecc0308892b827cf742728befe9b77d1eb008..f1eb44260610411e3c0ffa3378c882c42cc751e5 100644 (file)
 #include "lyxfunc.h"
 #include "lyxlex.h"
 #include "lyxrc.h"
-#include "lyxtextclasslist.h"
 #include "lyxserver.h"
+#include "lyxtextclasslist.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/Application.h"
 #include "frontends/LyXView.h"
 
 #include "support/environment.h"
 #include "support/filetools.h"
+#include "support/fontutils.h"
 #include "support/lyxlib.h"
 #include "support/convert.h"
 #include "support/os.h"
@@ -71,19 +70,20 @@ using lyx::support::getEnv;
 using lyx::support::i18nLibFileSearch;
 using lyx::support::libFileSearch;
 using lyx::support::package;
-using lyx::support::Path;
 using lyx::support::prependEnvPath;
-using lyx::support::quoteName;
 using lyx::support::rtrim;
 using lyx::support::Systemcall;
 
+using lyx::docstring;
+
+namespace Alert = lyx::frontend::Alert;
 namespace os = lyx::support::os;
 namespace fs = boost::filesystem;
 
 using std::endl;
 using std::string;
 using std::vector;
-using std::mem_fun_ref;
+using std::for_each;
 
 #ifndef CXX_GLOBAL_CSTD
 using std::exit;
@@ -92,13 +92,21 @@ using std::system;
 #endif
 
 
-extern LyXServer * lyxserver;
+/// convenient to have it here.
+boost::scoped_ptr<kb_keymap> toplevel_keymap;
+
+///
+lyx::frontend::Application * theApp;
 
-// This is the global bufferlist object
-BufferList bufferlist;
+namespace lyx {
 
-// convenient to have it here.
-boost::scoped_ptr<kb_keymap> toplevel_keymap;
+/// 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;
+
+}
 
 namespace {
 
@@ -113,9 +121,12 @@ void lyx_exit(int status)
        // FIXME: We should not directly call exit(), since it only
        // guarantees a return to the system, no application cleanup.
        // This may cause troubles with not executed destructors.
-       if (lyx_gui::use_gui)
-               // lyx_gui::exit may return and only schedule the exit
-               lyx_gui::exit(status);
+       if (lyx::use_gui) {
+               theApp->exit(status);
+               // Restore original font resources after Application is destroyed.
+               lyx::support::restoreFontResources();
+       }
+
        exit(status);
 }
 
@@ -123,8 +134,8 @@ void lyx_exit(int status)
 void showFileError(string const & error)
 {
        Alert::warning(_("Could not read configuration file"),
-                  bformat(_("Error while reading the configuration file\n%1$s.\n"
-                    "Please check your installation."), error));
+                      bformat(_("Error while reading the configuration file\n%1$s.\n"
+                          "Please check your installation."), lyx::from_utf8(error)));
 }
 
 
@@ -132,11 +143,11 @@ void reconfigureUserLyXDir()
 {
        string const configure_command = package().configure_command();
 
-       lyxerr << _("LyX: reconfiguring user directory") << endl;
-       Path p(package().user_support());
+       lyxerr << lyx::to_utf8(_("LyX: reconfiguring user directory")) << endl;
+       lyx::support::Path p(package().user_support());
        Systemcall one;
        one.startscript(Systemcall::Wait, configure_command);
-       lyxerr << "LyX: " << _("Done!") << endl;
+       lyxerr << "LyX: " << lyx::to_utf8(_("Done!")) << endl;
 }
 
 } // namespace anon
@@ -170,9 +181,29 @@ LyX const & LyX::cref()
 }
 
 
+BufferList & theBufferList()
+{
+       return LyX::ref().bufferList();
+}
+
+
 LyX::LyX()
        : first_start(false), geometryOption_(false)
-{}
+{
+       buffer_list_.reset(new BufferList);
+}
+
+
+BufferList & LyX::bufferList()
+{
+       return *buffer_list_.get();
+}
+
+
+BufferList const & LyX::bufferList() const
+{
+       return *buffer_list_.get();
+}
 
 
 lyx::Session & LyX::session()
@@ -216,16 +247,29 @@ int 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"
-       lyx_gui::use_gui = easyParse(argc, argv);
+       easyParse(argc, argv);
 
        lyx::support::init_package(argv[0], cl_system_support, cl_user_support,
                                   lyx::support::top_build_dir_is_one_level_up);
 
        // Start the real execution loop.
-       if (lyx_gui::use_gui)
-               return lyx_gui::exec(argc, argv);
-       else
-               return exec2(argc, argv);
+       if (lyx::use_gui) {
+               // Force adding of font path _before_ Application is initialized
+               lyx::support::addFontResources();
+               application_.reset(lyx::createApplication(argc, argv));
+               theApp = application_.get();
+       }
+       else {
+               // FIXME: create a ConsoleApplication
+               theApp = 0;
+       }
+
+       int exit_status = exec2(argc, argv);
+
+       if (lyx::use_gui)
+               application_.reset();
+
+       return exit_status;
 }
 
 
@@ -235,8 +279,9 @@ int LyX::exec2(int & argc, char * argv[])
        // other than documents
        for (int argi = 1; argi < argc ; ++argi) {
                if (argv[argi][0] == '-') {
-                       lyxerr << bformat(_("Wrong command line option `%1$s'. Exiting."),
-                               argv[argi]) << endl;
+                       lyxerr << lyx::to_utf8(
+                               bformat(_("Wrong command line option `%1$s'. Exiting."),
+                               lyx::from_utf8(argv[argi]))) << endl;
                        return EXIT_FAILURE;
                }
        }
@@ -248,9 +293,6 @@ int LyX::exec2(int & argc, char * argv[])
        if (!success)
                return EXIT_FAILURE;
 
-       if (lyx_gui::use_gui)
-               lyx_gui::parse_lyxrc();
-
        vector<string> files;
 
        for (int argi = argc - 1; argi >= 1; --argi)
@@ -279,22 +321,16 @@ int LyX::exec2(int & argc, char * argv[])
                                if (b)
                                        last_loaded = b;
                        } else {
-                               Buffer * buf = bufferlist.newBuffer(s, false);
-                               if (loadLyXFile(buf, s))
+                               Buffer * buf = theBufferList().newBuffer(s, false);
+                               if (loadLyXFile(buf, s)) {
                                        last_loaded = buf;
-                               else
-                                       bufferlist.release(buf);
-
-                               ErrorList const & el = buf->getErrorList();
-                               if (!el.empty()) {
-                                       // There should be a way to use the following but I (abdel) don't know
-                                       // how to make it compile on MSVC2005.
-                                       //for_each(el.begin(), el.end(), mem_fun_ref(&LyX::printError));
-                                       for (ErrorList::const_iterator it = el.begin();
-                                               it != el.end(); ++it) {
-                                                       printError(*it);
-                                       }
+                                       ErrorList const & el = buf->errorList("Parse");
+                                       if (!el.empty())
+                                               for_each(el.begin(), el.end(),
+                                                       boost::bind(&LyX::printError, this, _1));
                                }
+                               else
+                                       theBufferList().release(buf);
                        }
                }
 
@@ -309,7 +345,7 @@ int LyX::exec2(int & argc, char * argv[])
                files.clear(); // the files are already loaded
        }
 
-       if (lyx_gui::use_gui) {
+       if (lyx::use_gui) {
                // determine windows size and position, from lyxrc and/or session
                // initial geometry
                unsigned int width = 690;
@@ -348,8 +384,9 @@ int LyX::exec2(int & argc, char * argv[])
                        height = 0;
                }
                // create the main window
-               LyXView * view = lyx_gui::create_view(width, height, posx, posy, maximize);
-               
+               LyXView * view = &application_->createView(width, height, posx, posy, maximize);
+               ref().addLyXView(view);
+
                // load files
                for_each(files.begin(), files.end(),
                        bind(&LyXView::loadLyXFile, view, _1, true));
@@ -366,7 +403,7 @@ int LyX::exec2(int & argc, char * argv[])
                // clear this list to save a few bytes of RAM
                session_->clearLastOpenedFiles();
 
-               return lyx_gui::start(view, batch_command);
+               return application_->start(batch_command);
        } else {
                // Something went wrong above
                quitLyX(false);
@@ -476,9 +513,9 @@ static void error_handler(int err_sig)
 
 void LyX::printError(ErrorItem const & ei)
 {
-       std::cerr << _("LyX: ") << ei.error
-                 << ':' << ei.description << std::endl;
-
+       docstring tmp = _("LyX: ") + ei.error + lyx::char_type(':')
+               + ei.description;
+       std::cerr << lyx::to_utf8(tmp) << std::endl;
 }
 
 
@@ -502,11 +539,16 @@ bool LyX::init()
        }
 
        if (lyxrc.roman_font_name.empty())
-               lyxrc.roman_font_name = lyx_gui::roman_font_name();
+               lyxrc.roman_font_name = 
+                       lyx::use_gui? application_->romanFontName(): "serif";
+
        if (lyxrc.sans_font_name.empty())
-               lyxrc.sans_font_name = lyx_gui::sans_font_name();
+               lyxrc.sans_font_name =
+                       lyx::use_gui? application_->sansFontName(): "sans";
+
        if (lyxrc.typewriter_font_name.empty())
-               lyxrc.typewriter_font_name = lyx_gui::typewriter_font_name();
+               lyxrc.typewriter_font_name =
+                       lyx::use_gui? application_->typewriterFontName(): "monospace";
 
        //
        // Read configuration files
@@ -526,12 +568,12 @@ bool LyX::init()
        if (!lyxrc.path_prefix.empty())
                prependEnvPath("PATH", lyxrc.path_prefix);
 
-       // Check that user LyX directory is ok. 
+       // Check that user LyX directory is ok.
        if (queryUserLyXDir(package().explicit_user_support()))
                reconfigureUserLyXDir();
 
        // no need for a splash when there is no GUI
-       if (!lyx_gui::use_gui) {
+       if (!lyx::use_gui) {
                first_start = false;
        }
 
@@ -562,7 +604,7 @@ bool LyX::init()
        if (!LyXSetStyle())
                return false;
 
-       if (lyx_gui::use_gui) {
+       if (lyx::use_gui) {
                // Set up bindings
                toplevel_keymap.reset(new kb_keymap);
                defaultKeyBindings(toplevel_keymap.get());
@@ -588,9 +630,9 @@ bool LyX::init()
        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."),
-                                    lyxrc.tempdir_path));
+                                                   "%1$s. Make sure that this\n"
+                                                   "path exists and is writable and try again."),
+                                    lyx::from_utf8(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
@@ -668,9 +710,8 @@ void LyX::emergencyCleanup() const
        // contain documents etc. which might be helpful on
        // a crash
 
-       bufferlist.emergencyWriteAll();
-       if (lyxserver)
-               lyxserver->emergencyCleanup();
+       theBufferList().emergencyWriteAll();
+       application_->server().emergencyCleanup();
 }
 
 
@@ -711,7 +752,7 @@ bool needsUpdate(string const & file)
                addName(package().user_support(), file);
 
        return (! fs::exists(absfile))
-               || (fs::last_write_time(configure_script) 
+               || (fs::last_write_time(configure_script)
                    > fs::last_write_time(absfile));
 }
 
@@ -724,9 +765,9 @@ bool LyX::queryUserLyXDir(bool explicit_userdir)
        if (fs::exists(package().user_support()) &&
            fs::is_directory(package().user_support())) {
                first_start = false;
-               
-               return needsUpdate("lyxrc.defaults") 
-                       || needsUpdate("textclass.lst") 
+
+               return needsUpdate("lyxrc.defaults")
+                       || needsUpdate("textclass.lst")
                        || needsUpdate("packages.lst");
        }
 
@@ -738,23 +779,23 @@ bool LyX::queryUserLyXDir(bool explicit_userdir)
            Alert::prompt(
                    _("Missing user LyX directory"),
                    bformat(_("You have specified a non-existent user "
-                             "LyX directory, %1$s.\n"
-                             "It is needed to keep your own configuration."),
-                           package().user_support()),
+                                          "LyX directory, %1$s.\n"
+                                          "It is needed to keep your own configuration."),
+                           lyx::from_utf8(package().user_support())),
                    1, 0,
                    _("&Create directory"),
                    _("&Exit LyX"))) {
-               lyxerr << _("No user LyX directory. Exiting.") << endl;
+               lyxerr << lyx::to_utf8(_("No user LyX directory. Exiting.")) << endl;
                lyx_exit(EXIT_FAILURE);
        }
 
-       lyxerr << bformat(_("LyX: Creating directory %1$s"),
-                         package().user_support())
+       lyxerr << lyx::to_utf8(bformat(_("LyX: Creating directory %1$s"),
+                         lyx::from_utf8(package().user_support())))
               << endl;
 
        if (!createDirectory(package().user_support(), 0755)) {
                // Failed, so let's exit.
-               lyxerr << _("Failed to create directory. Exiting.")
+               lyxerr << lyx::to_utf8(_("Failed to create directory. Exiting."))
                       << endl;
                lyx_exit(EXIT_FAILURE);
        }
@@ -901,7 +942,6 @@ bool LyX::readEncodingsFile(string const & name)
 
 namespace {
 
-bool is_gui = true;
 string batch;
 
 /// return the the number of arguments consumed
@@ -910,11 +950,11 @@ typedef boost::function<int(string const &, string const &)> cmd_helper;
 int parse_dbg(string const & arg, string const &)
 {
        if (arg.empty()) {
-               lyxerr << _("List of supported debug flags:") << endl;
+               lyxerr << lyx::to_utf8(_("List of supported debug flags:")) << endl;
                Debug::showTags(lyxerr);
                exit(0);
        }
-       lyxerr << bformat(_("Setting debug level to %1$s"), arg) << endl;
+       lyxerr << lyx::to_utf8(bformat(_("Setting debug level to %1$s"), lyx::from_utf8(arg))) << endl;
 
        lyxerr.level(Debug::value(arg));
        Debug::showLevel(lyxerr, lyxerr.level());
@@ -925,7 +965,7 @@ int parse_dbg(string const & arg, string const &)
 int parse_help(string const &, string const &)
 {
        lyxerr <<
-               _("Usage: lyx [ command line switches ] [ name.lyx ... ]\n"
+               lyx::to_utf8(_("Usage: lyx [ command line switches ] [ name.lyx ... ]\n"
                  "Command line switches (case sensitive):\n"
                  "\t-help              summarize LyX usage\n"
                  "\t-userdir dir       set user directory to dir\n"
@@ -942,7 +982,7 @@ int parse_help(string const &, string const &)
                  "                  where fmt is the import format of choice\n"
                  "                  and file.xxx is the file to be imported.\n"
                  "\t-version        summarize version and build info\n"
-                 "Check the LyX man page for more details.") << endl;
+                              "Check the LyX man page for more details.")) << endl;
        exit(0);
        return 0;
 }
@@ -950,7 +990,7 @@ int parse_help(string const &, string const &)
 int parse_version(string const &, string const &)
 {
        lyxerr << "LyX " << lyx_version
-              << " of " << lyx_release_date << endl;
+              << " (" << lyx_release_date << ")" << endl;
        lyxerr << "Built on " << __DATE__ << ", " << __TIME__ << endl;
 
        lyxerr << lyx_version_info << endl;
@@ -961,7 +1001,7 @@ int parse_version(string const &, string const &)
 int parse_sysdir(string const & arg, string const &)
 {
        if (arg.empty()) {
-               lyxerr << _("Missing directory for -sysdir switch") << endl;
+               lyxerr << lyx::to_utf8(_("Missing directory for -sysdir switch")) << endl;
                exit(1);
        }
        cl_system_support = arg;
@@ -971,7 +1011,7 @@ int parse_sysdir(string const & arg, string const &)
 int parse_userdir(string const & arg, string const &)
 {
        if (arg.empty()) {
-               lyxerr << _("Missing directory for -userdir switch") << endl;
+               lyxerr << lyx::to_utf8(_("Missing directory for -userdir switch")) << endl;
                exit(1);
        }
        cl_user_support = arg;
@@ -981,7 +1021,7 @@ int parse_userdir(string const & arg, string const &)
 int parse_execute(string const & arg, string const &)
 {
        if (arg.empty()) {
-               lyxerr << _("Missing command string after --execute switch") << endl;
+               lyxerr << lyx::to_utf8(_("Missing command string after --execute switch")) << endl;
                exit(1);
        }
        batch = arg;
@@ -991,24 +1031,24 @@ int parse_execute(string const & arg, string const &)
 int parse_export(string const & type, string const &)
 {
        if (type.empty()) {
-               lyxerr << _("Missing file type [eg latex, ps...] after "
-                       "--export switch") << endl;
+               lyxerr << lyx::to_utf8(_("Missing file type [eg latex, ps...] after "
+                                        "--export switch")) << endl;
                exit(1);
        }
        batch = "buffer-export " + type;
-       is_gui = false;
+       lyx::use_gui = true;
        return 1;
 }
 
 int parse_import(string const & type, string const & file)
 {
        if (type.empty()) {
-               lyxerr << _("Missing file type [eg latex, ps...] after "
-                       "--import switch") << endl;
+               lyxerr << lyx::to_utf8(_("Missing file type [eg latex, ps...] after "
+                                        "--import switch")) << endl;
                exit(1);
        }
        if (file.empty()) {
-               lyxerr << _("Missing filename for --import") << endl;
+               lyxerr << lyx::to_utf8(_("Missing filename for --import")) << endl;
                exit(1);
        }
 
@@ -1019,7 +1059,7 @@ int parse_import(string const & type, string const & file)
 } // namespace anon
 
 
-bool LyX::easyParse(int & argc, char * argv[])
+void LyX::easyParse(int & argc, char * argv[])
 {
        std::map<string, cmd_helper> cmdmap;
 
@@ -1063,6 +1103,4 @@ bool LyX::easyParse(int & argc, char * argv[])
        }
 
        batch_command = batch;
-
-       return is_gui;
 }