X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Flyx_main.C;h=caa2a2b6897730040b8fa97abcefda1667b6cf0a;hb=c4320d24cd2d29c2e77958b4a8fd44f2bd587ca7;hp=02263f2d804bb88d66e7ed121b120cf990fd9a5e;hpb=d32701179ebfe26e290109aff6d7e5b58d943275;p=lyx.git diff --git a/src/lyx_main.C b/src/lyx_main.C index 02263f2d80..caa2a2b689 100644 --- a/src/lyx_main.C +++ b/src/lyx_main.C @@ -74,6 +74,7 @@ using support::bformat; using support::createDirectory; using support::createLyXTmpDir; using support::destroyDir; +using support::FileName; using support::fileSearch; using support::getEnv; using support::i18nLibFileSearch; @@ -98,8 +99,6 @@ using std::signal; using std::system; #endif -/// -frontend::Application * theApp = 0; /// are we using the GUI at all? /** @@ -115,6 +114,8 @@ namespace { string cl_system_support; string cl_user_support; +std::string geometryArg; + LyX * singleton_ = 0; void showFileError(string const & error) @@ -164,16 +165,18 @@ struct LyX::Singletons IconvProcessor iconv; }; +/// +frontend::Application * theApp() +{ + if (singleton_) + return &singleton_->application(); + else + return 0; +} + LyX::~LyX() { - // Static data are not treated in the same way at all on the Mac (and - // the LyX singleton has static methods). This is the reason why the - // exit command on the Mac bypasses our dispatch machinery altogether. - // On Linux and Windows we won't pass a second time through quit() - // because quitting will already be set to true. - if (!quitting) - quit(); } @@ -192,10 +195,11 @@ LyX const & LyX::cref() LyX::LyX() - : first_start(false), geometryOption_(false) + : first_start(false) { singleton_ = this; pimpl_.reset(new Singletons); + geometryArg.clear(); } @@ -327,50 +331,75 @@ int LyX::exec(int & argc, char * argv[]) support::init_package(argv[0], cl_system_support, cl_user_support, support::top_build_dir_is_one_level_up); - vector files; - int exit_status = execBatchCommands(argc, argv, files); - - if (exit_status) - return exit_status; + vector files; - if (use_gui) { - // Force adding of font path _before_ Application is initialized - support::addFontResources(); - pimpl_->application_.reset(createApplication(argc, argv)); - initGuiFont(); - // FIXME: this global pointer should probably go. - theApp = pimpl_->application_.get(); - restoreGuiSession(files); - // Start the real execution loop. - - // FIXME - /* Create a CoreApplication class that will provide the main event loop - * and the socket callback registering. With Qt4, only QtCore - * library would be needed. - * When this is done, a server_mode could be created and the following two - * line would be moved out from here. - */ - pimpl_->lyx_server_.reset(new LyXServer(&pimpl_->lyxfunc_, lyxrc.lyxpipes)); - pimpl_->lyx_socket_.reset(new LyXServerSocket(&pimpl_->lyxfunc_, - support::os::internal_path(package().temp_dir() + "/lyxsocket"))); - - // handle the batch commands the user asked for - if (!batch_command.empty()) { - pimpl_->lyxfunc_.dispatch(lyxaction.lookupFunc(batch_command)); + if (!use_gui) { + // FIXME: create a ConsoleApplication + int exit_status = loadFiles(argc, argv, files); + if (exit_status) { + prepareExit(); + return exit_status; } - exit_status = pimpl_->application_->start(batch_command); - // Kill the application object before exiting. This avoid crash - // on exit on Linux. - pimpl_->application_.reset(); - // Restore original font resources after Application is destroyed. - support::restoreFontResources(); + if (batch_command.empty() || pimpl_->buffer_list_.empty()) { + prepareExit(); + return EXIT_SUCCESS; + } + + 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) { + Buffer * buf = *I; + bool success = false; + buf->dispatch(batch_command, &success); + final_success |= success; + } + prepareExit(); + return !final_success; } - else { - // FIXME: create a ConsoleApplication - theApp = 0; + + // Force adding of font path _before_ Application is initialized + support::addFontResources(); + + // Let the frontend parse and remove all arguments that it knows + pimpl_->application_.reset(createApplication(argc, argv)); + + initGuiFont(); + + // Parse and remove all known arguments in the LyX singleton + // Give an error for all remaining ones. + int exit_status = loadFiles(argc, argv, files); + if (exit_status) { + // Kill the application object before exiting. + pimpl_->application_.reset(); + use_gui = false; + prepareExit(); + return exit_status; } + restoreGuiSession(files); + // Start the real execution loop. + + // FIXME + /* Create a CoreApplication class that will provide the main event loop + * and the socket callback registering. With Qt4, only QtCore + * library would be needed. + * When this is done, a server_mode could be created and the following two + * line would be moved out from here. + */ + pimpl_->lyx_server_.reset(new LyXServer(&pimpl_->lyxfunc_, lyxrc.lyxpipes)); + pimpl_->lyx_socket_.reset(new LyXServerSocket(&pimpl_->lyxfunc_, + support::os::internal_path(package().temp_dir() + "/lyxsocket"))); + + exit_status = pimpl_->application_->exec(); + + prepareExit(); + + // Restore original font resources after Application is destroyed. + support::restoreFontResources(); + return exit_status; } @@ -387,12 +416,33 @@ void LyX::prepareExit() // do any other cleanup procedures now lyxerr[Debug::INFO] << "Deleting tmp dir " << package().temp_dir() << endl; + // Prevent the deletion of /tmp if LyX was called with invalid + // arguments. Does not work on windows. + // FIXME: Fix the real bug instead. + if (package().temp_dir() == "/tmp") { + lyxerr << "Not deleting /tmp." << endl; + return; + } + if (!destroyDir(package().temp_dir())) { docstring const msg = bformat(_("Unable to remove the temporary directory %1$s"), from_utf8(package().temp_dir())); Alert::warning(_("Unable to remove temporary directory"), msg); } + + if (use_gui) { + if (pimpl_->session_) + pimpl_->session_->writeFile(); + pimpl_->session_.reset(); + pimpl_->lyx_server_.reset(); + pimpl_->lyx_socket_.reset(); + } + + // Kill the application object before exiting. This avoids crashes + // when exiting on Linux. + if (pimpl_->application_) + pimpl_->application_.reset(); } @@ -406,24 +456,8 @@ void LyX::earlyExit(int status) } -void LyX::quit() -{ - lyxerr[Debug::INFO] << "Running QuitLyX." << endl; - - prepareExit(); - - if (use_gui) { - pimpl_->session_->writeFile(); - pimpl_->lyx_server_.reset(); - pimpl_->lyx_socket_.reset(); - pimpl_->application_->exit(0); - theApp = 0; - } -} - - -int LyX::execBatchCommands(int & argc, char * argv[], - vector & files) +int LyX::loadFiles(int & argc, char * argv[], + vector & files) { // check for any spurious extra arguments // other than documents @@ -443,61 +477,64 @@ int LyX::execBatchCommands(int & argc, char * argv[], if (!success) return EXIT_FAILURE; - for (int argi = argc - 1; argi >= 1; --argi) - files.push_back(os::internal_path(argv[argi])); + for (int argi = argc - 1; argi >= 1; --argi) { + // check for any remaining extra arguments other than + // document file names. These will be passed out to the + // frontend. + if (argv[argi][0] == '-') + continue; + // get absolute path of file and add ".lyx" to + // the filename if necessary + files.push_back(fileSearch(string(), os::internal_path(argv[argi]), "lyx")); + } if (first_start) files.push_back(i18nLibFileSearch("examples", "splash.lyx")); - // Execute batch commands if available - if (!batch_command.empty()) { - - lyxerr[Debug::INIT] << "About to handle -x '" - << batch_command << '\'' << endl; - - Buffer * last_loaded = 0; - - vector::const_iterator it = files.begin(); - vector::const_iterator end = files.end(); - - for (; it != end; ++it) { - // get absolute path of file and add ".lyx" to - // the filename if necessary - string s = fileSearch(string(), *it, "lyx"); - if (s.empty()) { - Buffer * const b = newFile(*it, string(), true); - if (b) - last_loaded = b; - } else { - Buffer * buf = pimpl_->buffer_list_.newBuffer(s, false); - if (loadLyXFile(buf, s)) { - last_loaded = buf; - ErrorList const & el = buf->errorList("Parse"); - if (!el.empty()) - for_each(el.begin(), el.end(), - boost::bind(&LyX::printError, this, _1)); - } - else - pimpl_->buffer_list_.release(buf); - } - } + Buffer * last_loaded = 0; + + vector::const_iterator it = files.begin(); + vector::const_iterator end = files.end(); - // try to dispatch to last loaded buffer first - if (last_loaded) { - success = false; - if (last_loaded->dispatch(batch_command, &success)) { - prepareExit(); - return !success; + for (; it != end; ++it) { + if (it->empty()) { + Buffer * const b = newFile(it->absFilename(), string(), true); + if (b) + last_loaded = b; + } else { + Buffer * buf = pimpl_->buffer_list_.newBuffer(it->absFilename(), false); + if (loadLyXFile(buf, *it)) { + last_loaded = buf; + ErrorList const & el = buf->errorList("Parse"); + if (!el.empty()) + for_each(el.begin(), el.end(), + boost::bind(&LyX::printError, this, _1)); } + else + pimpl_->buffer_list_.release(buf); } - files.clear(); // the files are already loaded } + files.clear(); // the files are already loaded + return EXIT_SUCCESS; } -void LyX::restoreGuiSession(vector const & files) +void LyX::execBatchCommands() +{ + // Execute batch commands if available + if (batch_command.empty()) + return; + + lyxerr[Debug::INIT] << "About to handle -x '" + << batch_command << '\'' << endl; + + pimpl_->lyxfunc_.dispatch(lyxaction.lookupFunc(batch_command)); +} + + +void LyX::restoreGuiSession(vector const & files) { LyXView * view = newLyXView(); @@ -507,7 +544,7 @@ void LyX::restoreGuiSession(vector const & files) // if a file is specified, I assume that user wants to edit *that* file if (files.empty() && lyxrc.load_session) { - vector const & lastopened = pimpl_->session_->lastOpened().getfiles(); + vector const & lastopened = pimpl_->session_->lastOpened().getfiles(); // do not add to the lastfile list since these files are restored from // last seesion, and should be already there (regular files), or should // not be added at all (help files). @@ -528,6 +565,8 @@ LyXView * LyX::newLyXView() // initial geometry unsigned int width = 690; unsigned int height = 510; + // default icon size, will be overwritten by stored session value + unsigned int iconSizeXY = 0; bool maximize = false; // first try lyxrc if (lyxrc.geometry_width != 0 && lyxrc.geometry_height != 0 ) { @@ -544,6 +583,9 @@ LyXView * LyX::newLyXView() height = convert(val); if (session().sessionInfo().load("WindowIsMaximized") == "yes") maximize = true; + val = session().sessionInfo().load("IconSizeXY"); + if (!val.empty()) + iconSizeXY = convert(val); } // if user wants to restore window position @@ -558,12 +600,14 @@ LyXView * LyX::newLyXView() posy = convert(val); } - if (geometryOption_) { + if (!geometryArg.empty()) + { width = 0; height = 0; } + // create the main window - LyXView * view = &pimpl_->application_->createView(width, height, posx, posy, maximize); + LyXView * view = &pimpl_->application_->createView(width, height, posx, posy, maximize, iconSizeXY, geometryArg); return view; } @@ -789,7 +833,7 @@ bool LyX::init() fs::is_directory(lyxrc.document_path)) package().document_dir() = lyxrc.document_path; - package().temp_dir() = createLyXTmpDir(lyxrc.tempdir_path); + package().temp_dir() = createLyXTmpDir(FileName(lyxrc.tempdir_path)).absFilename(); if (package().temp_dir().empty()) { Alert::error(_("Could not create temporary directory"), bformat(_("Could not create a temporary directory in\n" @@ -880,7 +924,8 @@ void LyX::emergencyCleanup() const pimpl_->buffer_list_.emergencyWriteAll(); if (use_gui) { - pimpl_->lyx_server_->emergencyCleanup(); + if (pimpl_->lyx_server_) + pimpl_->lyx_server_->emergencyCleanup(); pimpl_->lyx_server_.reset(); pimpl_->lyx_socket_.reset(); } @@ -980,7 +1025,7 @@ bool LyX::readRcFile(string const & name) { lyxerr[Debug::INIT] << "About to read " << name << "... "; - string const lyxrc_path = libFileSearch(string(), name); + FileName const lyxrc_path = libFileSearch(string(), name); if (!lyxrc_path.empty()) { lyxerr[Debug::INIT] << "Found in " << lyxrc_path << endl; @@ -1029,7 +1074,7 @@ bool LyX::readUIFile(string const & name) lyxerr[Debug::INIT] << "About to read " << name << "..." << endl; - string const ui_path = libFileSearch("ui", name, "ui"); + FileName const ui_path = libFileSearch("ui", name, "ui"); if (ui_path.empty()) { lyxerr[Debug::INIT] << "Could not find " << name << endl; @@ -1087,7 +1132,7 @@ bool LyX::readLanguagesFile(string const & name) { lyxerr[Debug::INIT] << "About to read " << name << "..." << endl; - string const lang_path = libFileSearch(string(), name); + FileName const lang_path = libFileSearch(string(), name); if (lang_path.empty()) { showFileError(name); return false; @@ -1102,7 +1147,7 @@ bool LyX::readEncodingsFile(string const & name) { lyxerr[Debug::INIT] << "About to read " << name << "..." << endl; - string const enc_path = libFileSearch(string(), name); + FileName const enc_path = libFileSearch(string(), name); if (enc_path.empty()) { showFileError(name); return false; @@ -1228,6 +1273,19 @@ int parse_import(string const & type, string const & file) return 2; } +int parse_geometry(string const & arg1, string const &) +{ + geometryArg = arg1; +#if defined(_WIN32) || (defined(__CYGWIN__) && defined(X_DISPLAY_MISSING)) + // remove also the arg + return 1; +#else + // don't remove "-geometry" + return -1; +#endif +} + + } // namespace anon @@ -1248,15 +1306,12 @@ void LyX::easyParse(int & argc, char * argv[]) cmdmap["--export"] = parse_export; cmdmap["-i"] = parse_import; cmdmap["--import"] = parse_import; + cmdmap["-geometry"] = parse_geometry; for (int i = 1; i < argc; ++i) { std::map::const_iterator it = cmdmap.find(argv[i]); - // check for X11 -geometry option - if (support::compare(argv[i], "-geometry") == 0) - geometryOption_ = true; - // don't complain if not found - may be parsed later if (it == cmdmap.end()) continue; @@ -1268,10 +1323,12 @@ void LyX::easyParse(int & argc, char * argv[]) // Now, remove used arguments by shifting // the following ones remove places down. - argc -= remove; - for (int j = i; j < argc; ++j) - argv[j] = argv[j + remove]; - --i; + if (remove > 0) { + argc -= remove; + for (int j = i; j < argc; ++j) + argv[j] = argv[j + remove]; + --i; + } } batch_command = batch;