X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FBuffer.cpp;h=0f37edd9dcb1868dbad7bce1159a87a1172b8e60;hb=44e86aa4e9a602c90a5f96b4c716f28cd2582192;hp=ed94503c14631e77844a214f279e12613ad127a6;hpb=f5648006fbd0c816488c6a9167b4787d1e3a839a;p=lyx.git diff --git a/src/Buffer.cpp b/src/Buffer.cpp index ed94503c14..0f37edd9dc 100644 --- a/src/Buffer.cpp +++ b/src/Buffer.cpp @@ -133,14 +133,6 @@ int const LYX_FORMAT = LYX_FORMAT_LYX; typedef map DepClean; typedef map > RefCache; -void showPrintError(string const & name) -{ - docstring str = bformat(_("Could not print the document %1$s.\n" - "Check that your printer is set up correctly."), - makeDisplayPath(name, 50)); - Alert::error(_("Print document failed"), str); -} - } // namespace anon @@ -249,9 +241,16 @@ public: /// map from children inclusion positions to their scope and their buffer PositionScopeBufferMap position_to_children; - /// Keeps track of old buffer filePath() for save-as operations + /// Contains the old buffer filePath() while saving-as, or the + /// directory where the document was last saved while loading. string old_position; + /** Keeps track of the path of local layout files. + * If possible, it is always relative to the buffer path. + * Empty for layouts in system or user directory. + */ + string layout_position; + /// Container for all sort of Buffer dependant errors. map errorLists; @@ -288,10 +287,15 @@ public: /// we ran updateBuffer(), i.e., whether citation labels may need /// to be updated. mutable bool cite_labels_valid_; - /// these hold the file name and format, written to by Buffer::preview - /// and read from by LFUN_BUFFER_VIEW_CACHE. + + /// These two hold the file name and format, written to by + /// Buffer::preview and read from by LFUN_BUFFER_VIEW_CACHE. FileName preview_file_; string preview_format_; + /// If there was an error when previewing, on the next preview we do + /// a fresh compile (e.g. in case the user installed a package that + /// was missing). + bool preview_error_; mutable RefCache ref_cache_; @@ -427,8 +431,10 @@ Buffer::Impl::Impl(Buffer * owner, FileName const & file, bool readonly_, cite_labels_valid_ = cloned_buffer_->d->cite_labels_valid_; unnamed = cloned_buffer_->d->unnamed; internal_buffer = cloned_buffer_->d->internal_buffer; + layout_position = cloned_buffer_->d->layout_position; preview_file_ = cloned_buffer_->d->preview_file_; preview_format_ = cloned_buffer_->d->preview_format_; + preview_error_ = cloned_buffer_->d->preview_error_; } @@ -916,12 +922,11 @@ int Buffer::readHeader(Lexer & lex) LYXERR(Debug::PARSER, "Handling document header token: `" << token << '\''); - string unknown = params().readToken(lex, token, d->filename.onlyPath()); - if (!unknown.empty()) { - if (unknown[0] != '\\' && token == "\\textclass") { - Alert::warning(_("Unknown document class"), - bformat(_("Using the default document class, because the " - "class %1$s is unknown."), from_utf8(unknown))); + string const result = + params().readToken(lex, token, d->filename.onlyPath()); + if (!result.empty()) { + if (token == "\\textclass") { + d->layout_position = result; } else { ++unknown_tokens; docstring const s = bformat(_("Unknown token: " @@ -1018,7 +1023,9 @@ bool Buffer::readDocument(Lexer & lex) params().indiceslist().addDefault(B_("Index")); // read main text + d->old_position = originFilePath(); bool const res = text().read(lex, errorList, d->inset); + d->old_position.clear(); // inform parent buffer about local macros if (parent()) { @@ -1164,6 +1171,12 @@ void Buffer::setFullyLoaded(bool value) } +bool Buffer::lastPreviewError() const +{ + return d->preview_error_; +} + + PreviewLoader * Buffer::loader() const { if (!isExporting() && lyxrc.preview == LyXRC::PREVIEW_OFF) @@ -1315,8 +1328,12 @@ bool Buffer::save() const // if the file does not yet exist, none of the backup activity // that follows is necessary - if (!fileName().exists()) - return writeFile(fileName()); + if (!fileName().exists()) { + if (!writeFile(fileName())) + return false; + markClean(); + return true; + } // we first write the file to a new name, then move it to its // proper location once that has been done successfully. that @@ -1386,12 +1403,12 @@ bool Buffer::save() const // to restore it, but that would basically mean trying to do again // what we just failed to do. better to leave things as they are. Alert::error(_("Write failure"), - bformat(_("The file has successfully been saved as:\n %1$s.\n" - "But LyX could not move it to:\n %2$s.\n" - "Your original file has been backed up to:\n %3$s"), - from_utf8(savefile.absFileName()), - from_utf8(fileName().absFileName()), - from_utf8(backupName.absFileName()))); + bformat(_("The file has successfully been saved as:\n %1$s.\n" + "But LyX could not move it to:\n %2$s.\n" + "Your original file has been backed up to:\n %3$s"), + from_utf8(savefile.absFileName()), + from_utf8(fileName().absFileName()), + from_utf8(backupName.absFileName()))); } else { // either we did not try to make a backup, or else we tried and failed, // or else the original file was a symlink, in which case it was copied, @@ -1530,7 +1547,7 @@ bool Buffer::write(ostream & ofs) const // now write out the buffer parameters. ofs << "\\begin_header\n"; - params().writeFile(ofs); + params().writeFile(ofs, this); ofs << "\\end_header\n"; // write the text @@ -1765,7 +1782,7 @@ void Buffer::writeLaTeXSource(otexstream & os, } os << "\\makeatletter\n" << "\\def\\input@path{{" - << docdir << "/}}\n" + << docdir << "}}\n" << "\\makeatother\n"; } } @@ -2146,9 +2163,9 @@ void Buffer::getLabelList(vector & list) const } list.clear(); - Toc & toc = d->toc_backend.toc("label"); - TocIterator toc_it = toc.begin(); - TocIterator end = toc.end(); + shared_ptr toc = d->toc_backend.toc("label"); + TocIterator toc_it = toc->begin(); + TocIterator end = toc->end(); for (; toc_it != end; ++toc_it) { if (toc_it->depth() == 0) list.push_back(toc_it->str()); @@ -2421,7 +2438,6 @@ bool Buffer::getStatus(FuncRequest const & cmd, FuncStatus & flag) case LFUN_BRANCH_ADD: case LFUN_BRANCHES_RENAME: - case LFUN_BUFFER_PRINT: // if no Buffer is present, then of course we won't be called! break; @@ -2430,6 +2446,7 @@ bool Buffer::getStatus(FuncRequest const & cmd, FuncStatus & flag) break; case LFUN_BUFFER_VIEW_CACHE: + (d->preview_file_).refresh(); enable = (d->preview_file_).exists(); break; @@ -2530,7 +2547,8 @@ void Buffer::dispatch(FuncRequest const & func, DispatchResult & dr) // Execute the command in the background Systemcall call; - call.startscript(Systemcall::DontWait, command, filePath()); + call.startscript(Systemcall::DontWait, command, + filePath(), layoutPos()); break; } @@ -2655,123 +2673,6 @@ void Buffer::dispatch(FuncRequest const & func, DispatchResult & dr) break; } - case LFUN_BUFFER_PRINT: { - // we'll assume there's a problem until we succeed - dr.setError(true); - string target = func.getArg(0); - string target_name = func.getArg(1); - string command = func.getArg(2); - - if (target.empty() - || target_name.empty() - || command.empty()) { - LYXERR0("Unable to parse " << func.argument()); - docstring const msg = - bformat(_("Unable to parse \"%1$s\""), func.argument()); - dr.setMessage(msg); - break; - } - if (target != "printer" && target != "file") { - LYXERR0("Unrecognized target \"" << target << '"'); - docstring const msg = - bformat(_("Unrecognized target \"%1$s\""), from_utf8(target)); - dr.setMessage(msg); - break; - } - - if (doExport("dvi", true) != ExportSuccess) { - showPrintError(absFileName()); - dr.setMessage(_("Error exporting to DVI.")); - break; - } - - // Push directory path. - string const path = temppath(); - // Prevent the compiler from optimizing away p - FileName pp(path); - PathChanger p(pp); - - // there are three cases here: - // 1. we print to a file - // 2. we print directly to a printer - // 3. we print using a spool command (print to file first) - Systemcall one; - int res = 0; - string const dviname = changeExtension(latexName(true), "dvi"); - - if (target == "printer") { - if (!lyxrc.print_spool_command.empty()) { - // case 3: print using a spool - string const psname = changeExtension(dviname,".ps"); - command += ' ' + lyxrc.print_to_file - + quoteName(psname) - + ' ' - + quoteName(dviname); - - string command2 = lyxrc.print_spool_command + ' '; - if (target_name != "default") { - command2 += lyxrc.print_spool_printerprefix - + target_name - + ' '; - } - command2 += quoteName(psname); - // First run dvips. - // If successful, then spool command - res = one.startscript(Systemcall::Wait, command, - filePath()); - - if (res == 0) { - // If there's no GUI, we have to wait on this command. Otherwise, - // LyX deletes the temporary directory, and with it the spooled - // file, before it can be printed!! - Systemcall::Starttype stype = use_gui ? - Systemcall::DontWait : Systemcall::Wait; - res = one.startscript(stype, command2, - filePath()); - } - } else { - // case 2: print directly to a printer - if (target_name != "default") - command += ' ' + lyxrc.print_to_printer + target_name + ' '; - // as above.... - Systemcall::Starttype stype = use_gui ? - Systemcall::DontWait : Systemcall::Wait; - res = one.startscript(stype, command + - quoteName(dviname), filePath()); - } - - } else { - // case 1: print to a file - FileName const filename(makeAbsPath(target_name, filePath())); - FileName const dvifile(makeAbsPath(dviname, path)); - if (filename.exists()) { - docstring text = bformat( - _("The file %1$s already exists.\n\n" - "Do you want to overwrite that file?"), - makeDisplayPath(filename.absFileName())); - if (Alert::prompt(_("Overwrite file?"), - text, 0, 1, _("&Overwrite"), _("&Cancel")) != 0) - break; - } - command += ' ' + lyxrc.print_to_file - + quoteName(filename.toFilesystemEncoding()) - + ' ' - + quoteName(dvifile.toFilesystemEncoding()); - // as above.... - Systemcall::Starttype stype = use_gui ? - Systemcall::DontWait : Systemcall::Wait; - res = one.startscript(stype, command, filePath()); - } - - if (res == 0) - dr.setError(false); - else { - dr.setMessage(_("Error running external commands.")); - showPrintError(absFileName()); - } - break; - } - case LFUN_BUFFER_VIEW_CACHE: if (!formats.view(*this, d->preview_file_, d->preview_format_)) @@ -3006,6 +2907,38 @@ string Buffer::filePath() const } +string Buffer::originFilePath() const +{ + if (FileName::isAbsolute(params().origin)) + return params().origin; + + return filePath(); +} + + +string Buffer::layoutPos() const +{ + return d->layout_position; +} + + +void Buffer::setLayoutPos(string const & path) +{ + if (path.empty()) { + d->layout_position.clear(); + return; + } + + LATTEST(FileName::isAbsolute(path)); + + d->layout_position = + to_utf8(makeRelPath(from_utf8(path), from_utf8(filePath()))); + + if (d->layout_position.empty()) + d->layout_position = "."; +} + + bool Buffer::isReadonly() const { return d->read_only; @@ -3577,11 +3510,12 @@ void Buffer::changeRefsIfUnique(docstring const & from, docstring const & to) } } - -void Buffer::getSourceCode(odocstream & os, string const & format, +// returns NULL if id-to-row conversion is unsupported +auto_ptr Buffer::getSourceCode(odocstream & os, string const & format, pit_type par_begin, pit_type par_end, OutputWhat output, bool master) const { + auto_ptr texrow(NULL); OutputParams runparams(¶ms().encoding()); runparams.nice = true; runparams.flavor = params().getOutputFlavor(format); @@ -3635,12 +3569,12 @@ void Buffer::getSourceCode(odocstream & os, string const & format, LaTeXFeatures features(*this, params(), runparams); params().validate(features); runparams.use_polyglossia = features.usePolyglossia(); - TexRow texrow; - texrow.reset(); - texrow.newline(); - texrow.newline(); + texrow.reset(new TexRow()); + texrow->reset(); + texrow->newline(); + texrow->newline(); // latex or literate - otexstream ots(os, texrow); + otexstream ots(os, *texrow); // the real stuff latexParagraphs(*this, text(), ots, runparams); @@ -3663,7 +3597,7 @@ void Buffer::getSourceCode(odocstream & os, string const & format, if (output == FullSource) write(ods); else if (output == OnlyPreamble) - params().writeFile(ods); + params().writeFile(ods, this); else if (output == OnlyBody) text().write(ods); os << from_utf8(ods.str()); @@ -3678,15 +3612,17 @@ void Buffer::getSourceCode(odocstream & os, string const & format, writeDocBookSource(os, absFileName(), runparams, output); } else { // latex or literate - d->texrow.reset(); - d->texrow.newline(); - d->texrow.newline(); - otexstream ots(os, d->texrow); + texrow.reset(new TexRow()); + texrow->reset(); + texrow->newline(); + texrow->newline(); + otexstream ots(os, *texrow); if (master) runparams.is_child = true; writeLaTeXSource(ots, string(), runparams, output); } } + return texrow; } @@ -4235,6 +4171,7 @@ Buffer::ExportStatus Buffer::preview(string const & format, bool includeall) con LATTEST (isClone()); d->cloned_buffer_->d->preview_file_ = previewFile; d->cloned_buffer_->d->preview_format_ = format; + d->cloned_buffer_->d->preview_error_ = (status != ExportSuccess); if (status != ExportSuccess) return status; @@ -4524,6 +4461,7 @@ void Buffer::updateBuffer(UpdateScope scope, UpdateType utype) const d->bibinfo_cache_valid_ = true; d->cite_labels_valid_ = true; + /// FIXME: Perf cbuf.tocBackend().update(utype == OutputUpdate); if (scope == UpdateMaster) cbuf.structureChanged(); @@ -4795,13 +4733,13 @@ int Buffer::spellCheck(DocIterator & from, DocIterator & to, DocIterator const end = to_end ? doc_iterator_end(this) : to; // OK, we start from here. for (; from != end; from.forwardPos()) { - // We are only interested in text so remove the math CursorSlice. - while (from.inMathed()) { + // This skips all insets with spell check disabled. + while (!from.allowSpellCheck()) { from.pop_back(); from.pos()++; } // If from is at the end of the document (which is possible - // when leaving the mathed) LyX will crash later otherwise. + // when "from" was changed above) LyX will crash later otherwise. if (from.atEnd() || (!to_end && from >= end)) break; to = from; @@ -4811,7 +4749,6 @@ int Buffer::spellCheck(DocIterator & from, DocIterator & to, word_lang = wl; break; } - // Do not increase progress when from == to, otherwise the word // count will be wrong. if (from != to) { @@ -5010,17 +4947,22 @@ void Buffer::checkMasterBuffer() } -string Buffer::includedFilePath(string const & name) const +string Buffer::includedFilePath(string const & name, string const & ext) const { - if (d->old_position.empty() || d->old_position == filePath()) + bool isabsolute = FileName::isAbsolute(name); + // old_position already contains a trailing path separator + string const absname = isabsolute ? name : d->old_position + name; + + if (d->old_position.empty() + || equivalent(FileName(d->old_position), FileName(filePath())) + || !FileName(addExtension(absname, ext)).exists()) return name; - if (FileName::isAbsolute(name)) + if (isabsolute) return to_utf8(makeRelPath(from_utf8(name), from_utf8(filePath()))); - // old_position already contains a trailing path separator - string const cleanpath = FileName(d->old_position + name).realPath(); - return to_utf8(makeRelPath(from_utf8(cleanpath), from_utf8(filePath()))); + return to_utf8(makeRelPath(from_utf8(FileName(absname).realPath()), + from_utf8(filePath()))); } } // namespace lyx