X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2FInsetGraphics.cpp;h=421dcf1a6b3e31c7b26896275b73008415afb9ba;hb=2c357c1d23b7b83839a9beb8225d4f1ae4f793b4;hp=318bd55708e11437c9bd1dd120b328efa881dfc1;hpb=0fcae6cc10640f2d5a591152d59d252bb6dc0757;p=lyx.git diff --git a/src/insets/InsetGraphics.cpp b/src/insets/InsetGraphics.cpp index 318bd55708..421dcf1a6b 100644 --- a/src/insets/InsetGraphics.cpp +++ b/src/insets/InsetGraphics.cpp @@ -15,7 +15,6 @@ TODO * What advanced features the users want to do? Implement them in a non latex dependent way, but a logical way. LyX should translate it to latex or any other fitting format. - * Add a way to roll the image file into the file format. * When loading, if the image is not found in the expected place, try to find it in the clipart, or in the same directory with the image. * The image choosing dialog could show thumbnails of the image formats @@ -56,14 +55,12 @@ TODO #include "BufferView.h" #include "Converter.h" #include "Cursor.h" -#include "debug.h" #include "DispatchResult.h" #include "ErrorList.h" #include "Exporter.h" #include "Format.h" #include "FuncRequest.h" #include "FuncStatus.h" -#include "gettext.h" #include "LaTeXFeatures.h" #include "Length.h" #include "Lexer.h" @@ -71,12 +68,17 @@ TODO #include "Mover.h" #include "OutputParams.h" #include "sgml.h" +#include "EmbeddedFiles.h" #include "frontends/alert.h" #include "support/convert.h" +#include "support/debug.h" +#include "support/docstream.h" +#include "support/ExceptionMessage.h" #include "support/filetools.h" -#include "support/lyxlib.h" // sum +#include "support/gettext.h" +#include "support/lyxlib.h" #include "support/lstrings.h" #include "support/os.h" #include "support/Systemcall.h" @@ -87,36 +89,12 @@ TODO #include #include +using namespace std; +using namespace lyx::support; namespace lyx { -using support::bformat; -using support::changeExtension; -using support::compare_timestamps; -using support::contains; -using support::DocFileName; -using support::FileName; -using support::float_equal; -using support::getExtension; -using support::isFileReadable; -using support::isValidLaTeXFilename; -using support::latex_path; -using support::onlyFilename; -using support::removeExtension; -using support::rtrim; -using support::subst; -using support::suffixIs; -using support::Systemcall; -using support::unzipFile; -using support::unzippedFileName; - -using std::endl; -using std::string; -using std::auto_ptr; -using std::istringstream; -using std::ostream; -using std::ostringstream; - +namespace Alert = frontend::Alert; namespace { @@ -126,7 +104,7 @@ string findTargetFormat(string const & format, OutputParams const & runparams) { // Are we using latex or pdflatex? if (runparams.flavor == OutputParams::PDFLATEX) { - LYXERR(Debug::GRAPHICS) << "findTargetFormat: PDF mode" << endl; + LYXERR(Debug::GRAPHICS, "findTargetFormat: PDF mode"); Format const * const f = formats.getFormat(format); // Convert vector graphics to pdf if (f && f->vectorFormat()) @@ -138,7 +116,7 @@ string findTargetFormat(string const & format, OutputParams const & runparams) return "png"; } // If it's postscript, we always do eps. - LYXERR(Debug::GRAPHICS) << "findTargetFormat: PostScript mode" << endl; + LYXERR(Debug::GRAPHICS, "findTargetFormat: PostScript mode"); if (format != "ps") // any other than ps is changed to eps return "eps"; @@ -165,9 +143,9 @@ InsetGraphics::InsetGraphics(InsetGraphics const & ig) } -auto_ptr InsetGraphics::doClone() const +Inset * InsetGraphics::clone() const { - return auto_ptr(new InsetGraphics(*this)); + return new InsetGraphics(*this); } @@ -192,9 +170,16 @@ void InsetGraphics::doDispatch(Cursor & cur, FuncRequest & cmd) Buffer const & buffer = cur.buffer(); InsetGraphicsParams p; InsetGraphicsMailer::string2params(to_utf8(cmd.argument()), buffer, p); - if (!p.filename.empty()) + if (!p.filename.empty()) { + try { + p.filename.enable(buffer.embedded(), &buffer); + } catch (ExceptionMessage const & message) { + Alert::error(message.title_, message.details_); + // do not set parameter if an error happens + break; + } setParams(p); - else + } else cur.noUpdate(); break; } @@ -231,24 +216,43 @@ bool InsetGraphics::getStatus(Cursor & cur, FuncRequest const & cmd, } -void InsetGraphics::edit(Cursor & cur, bool) +void InsetGraphics::registerEmbeddedFiles(Buffer const & buffer, + EmbeddedFileList & files) const +{ + files.registerFile(params().filename, this, buffer); +} + + +void InsetGraphics::updateEmbeddedFile(Buffer const & buf, + EmbeddedFile const & file) +{ + // when embedding is enabled, change of embedding status leads to actions + EmbeddedFile temp = file; + temp.enable(buf.embedded(), &buf); + // this will not be set if an exception is thorwn in enable() + params_.filename = temp; + + LYXERR(Debug::FILES, "Update InsetGraphic with File " + << params_.filename.toFilesystemEncoding() + << ", embedding status: " << params_.filename.embedded() + << ", enabled: " << params_.filename.enabled()); +} + + +void InsetGraphics::edit(Cursor & cur, bool, EntryDirection) { InsetGraphicsMailer(*this).showDialog(&cur.bv()); } -bool InsetGraphics::metrics(MetricsInfo & mi, Dimension & dim) const +void InsetGraphics::metrics(MetricsInfo & mi, Dimension & dim) const { graphic_->metrics(mi, dim); - bool const changed = dim_ != dim; - dim_ = dim; - return changed; } void InsetGraphics::draw(PainterInfo & pi, int x, int y) const { - setPosCache(pi, x, y); graphic_->draw(pi, x, y); } @@ -262,7 +266,7 @@ Inset::EDITABLE InsetGraphics::editable() const void InsetGraphics::write(Buffer const & buf, ostream & os) const { os << "Graphics\n"; - params().Write(os, buf.filePath()); + params().Write(os, buf); } @@ -273,8 +277,9 @@ void InsetGraphics::read(Buffer const & buf, Lexer & lex) if (token == "Graphics") readInsetGraphics(lex, buf.filePath()); else - LYXERR(Debug::GRAPHICS) << "Not a Graphics inset!" << endl; + LYXERR(Debug::GRAPHICS, "Not a Graphics inset!"); + params_.filename.enable(buf.embedded(), &buf); graphic_->update(params().as_grfxParams()); } @@ -287,17 +292,17 @@ void InsetGraphics::readInsetGraphics(Lexer & lex, string const & bufpath) lex.next(); string const token = lex.getString(); - LYXERR(Debug::GRAPHICS) << "Token: '" << token << '\'' - << endl; + LYXERR(Debug::GRAPHICS, "Token: '" << token << '\''); - if (token.empty()) { + if (token.empty()) continue; - } else if (token == "\\end_inset") { + + if (token == "\\end_inset") { finished = true; } else { if (!params_.Read(lex, token, bufpath)) lyxerr << "Unknown token, " << token << ", skipping." - << std::endl; + << endl; } } } @@ -424,7 +429,8 @@ docstring const InsetGraphics::createDocBookAttributes() const // Calculate the options part of the command, we must do it to a string // stream since we copied the code from createLatexParams() ;-) - // FIXME: av: need to translate spec -> Docbook XSL spec (http://www.sagehill.net/docbookxsl/ImageSizing.html) + // FIXME: av: need to translate spec -> Docbook XSL spec + // (http://www.sagehill.net/docbookxsl/ImageSizing.html) // Right now it only works with my version of db2latex :-) odocstringstream options; @@ -458,7 +464,7 @@ docstring const InsetGraphics::createDocBookAttributes() const namespace { -enum CopyStatus { +enum GraphicsCopyStatus { SUCCESS, FAILURE, IDENTICAL_PATHS, @@ -466,41 +472,39 @@ enum CopyStatus { }; -std::pair const +pair const copyFileIfNeeded(FileName const & file_in, FileName const & file_out) { - unsigned long const checksum_in = support::sum(file_in); - unsigned long const checksum_out = support::sum(file_out); + LYXERR(Debug::FILES, "Comparing " << file_in << " and " << file_out); + unsigned long const checksum_in = file_in.checksum(); + unsigned long const checksum_out = file_out.checksum(); if (checksum_in == checksum_out) // Nothing to do... - return std::make_pair(IDENTICAL_CONTENTS, file_out); + return make_pair(IDENTICAL_CONTENTS, file_out); Mover const & mover = getMover(formats.getFormatFromFile(file_in)); bool const success = mover.copy(file_in, file_out); if (!success) { // FIXME UNICODE - LYXERR(Debug::GRAPHICS) - << to_utf8(support::bformat(_("Could not copy the file\n%1$s\n" + LYXERR(Debug::GRAPHICS, + to_utf8(bformat(_("Could not copy the file\n%1$s\n" "into the temporary directory."), - from_utf8(file_in.absFilename()))) - << std::endl; + from_utf8(file_in.absFilename())))); } - CopyStatus status = success ? SUCCESS : FAILURE; - return std::make_pair(status, file_out); + GraphicsCopyStatus status = success ? SUCCESS : FAILURE; + return make_pair(status, file_out); } -std::pair const +pair const copyToDirIfNeeded(DocFileName const & file, string const & dir) { - using support::rtrim; - string const file_in = file.absFilename(); - string const only_path = support::onlyPath(file_in); - if (rtrim(support::onlyPath(file_in) , "/") == rtrim(dir, "/")) - return std::make_pair(IDENTICAL_PATHS, file_in); + string const only_path = onlyPath(file_in); + if (rtrim(onlyPath(file_in) , "/") == rtrim(dir, "/")) + return make_pair(IDENTICAL_PATHS, file_in); string mangled = file.mangledFilename(); if (file.isZipped()) { @@ -514,7 +518,7 @@ copyToDirIfNeeded(DocFileName const & file, string const & dir) string::size_type const ext_len = file_in.length() - base.length(); mangled[mangled.length() - ext_len] = '.'; } - FileName const file_out(support::makeAbsPath(mangled, dir)); + FileName const file_out(makeAbsPath(mangled, dir)); return copyFileIfNeeded(file, file_out); } @@ -533,13 +537,10 @@ string const stripExtensionIfPossible(string const & file, bool nice) // dots with a macro whose definition is just a dot ;-) // The automatic format selection does not work if the file // name is escaped. - string const latex_name = latex_path(file, - support::EXCLUDE_EXTENSION); + string const latex_name = latex_path(file, EXCLUDE_EXTENSION); if (!nice || contains(latex_name, '"')) return latex_name; - return latex_path(removeExtension(file), - support::PROTECT_EXTENSION, - support::ESCAPE_DOTS); + return latex_path(removeExtension(file), PROTECT_EXTENSION, ESCAPE_DOTS); } @@ -554,7 +555,7 @@ string const stripExtensionIfPossible(string const & file, string const & to, bo (to_format == "eps" && file_format == "ps") || (to_format == "ps" && file_format == "eps")) return stripExtensionIfPossible(file, nice); - return latex_path(file, support::EXCLUDE_EXTENSION); + return latex_path(file, EXCLUDE_EXTENSION); } } // namespace anon @@ -567,7 +568,8 @@ string const InsetGraphics::prepareFile(Buffer const & buf, if (params().filename.empty()) return string(); - string const orig_file = params().filename.absFilename(); + string const orig_file = params().filename.availableFile().absFilename(); + // this is for dryrun and display purposes, do not use latexFilename string const rel_file = params().filename.relFilename(buf.filePath()); // previewing source code, no file copying or file format conversion @@ -576,38 +578,37 @@ string const InsetGraphics::prepareFile(Buffer const & buf, // temp_file will contain the file for LaTeX to act on if, for example, // we move it to a temp dir or uncompress it. - FileName temp_file = params().filename; + FileName temp_file = params().filename.availableFile(); // The master buffer. This is useful when there are multiple levels // of include files - Buffer const * m_buffer = buf.getMasterBuffer(); + Buffer const * masterBuffer = buf.masterBuffer(); // Return the output name if we are inside a comment or the file does // not exist. // We are not going to change the extension or using the name of the // temporary file, the code is already complicated enough. - if (runparams.inComment || !isFileReadable(params().filename)) - return params().filename.outputFilename(m_buffer->filePath()); + if (runparams.inComment || !params().filename.isReadableFile()) + return params().filename.outputFilename(masterBuffer->filePath()); // We place all temporary files in the master buffer's temp dir. // This is possible because we use mangled file names. // This is necessary for DVI export. - string const temp_path = m_buffer->temppath(); + string const temp_path = masterBuffer->temppath(); - CopyStatus status; + GraphicsCopyStatus status; boost::tie(status, temp_file) = - copyToDirIfNeeded(params().filename, temp_path); + copyToDirIfNeeded(params().filename.availableFile(), temp_path); if (status == FAILURE) return orig_file; - // a relative filename should be relative to the master - // buffer. + // a relative filename should be relative to the master buffer. // "nice" means that the buffer is exported to LaTeX format but not - // run through the LaTeX compiler. - string output_file = support::os::external_path(runparams.nice ? - params().filename.outputFilename(m_buffer->filePath()) : - onlyFilename(temp_file.absFilename())); + // run through the LaTeX compiler. + string output_file = runparams.nice ? + params().filename.outputFilename(masterBuffer->filePath()) : + onlyFilename(temp_file.absFilename()); if (runparams.nice && !isValidLaTeXFilename(output_file)) { frontend::Alert::warning(_("Invalid filename"), @@ -629,8 +630,7 @@ string const InsetGraphics::prepareFile(Buffer const & buf, // this file, but we can't check, because that would // mean to unzip the file and thereby making the // noUnzip parameter meaningless. - LYXERR(Debug::GRAPHICS) - << "\tpass zipped file to LaTeX.\n"; + LYXERR(Debug::GRAPHICS, "\tpass zipped file to LaTeX."); FileName const bb_orig_file = FileName(changeExtension(orig_file, "bb")); if (runparams.nice) { @@ -654,8 +654,7 @@ string const InsetGraphics::prepareFile(Buffer const & buf, source_file, output_file); // We can't strip the extension, because we don't know // the unzipped file format - return latex_path(output_file, - support::EXCLUDE_EXTENSION); + return latex_path(output_file, EXCLUDE_EXTENSION); } FileName const unzipped_temp_file = @@ -666,33 +665,27 @@ string const InsetGraphics::prepareFile(Buffer const & buf, // temp_file has been unzipped already and // orig_file has not changed in the meantime. temp_file = unzipped_temp_file; - LYXERR(Debug::GRAPHICS) - << "\twas already unzipped to " << temp_file - << endl; + LYXERR(Debug::GRAPHICS, "\twas already unzipped to " << temp_file); } else { // unzipped_temp_file does not exist or is too old temp_file = unzipFile(temp_file); - LYXERR(Debug::GRAPHICS) - << "\tunzipped to " << temp_file << endl; + LYXERR(Debug::GRAPHICS, "\tunzipped to " << temp_file); } } string const from = formats.getFormatFromFile(temp_file); - if (from.empty()) { - LYXERR(Debug::GRAPHICS) - << "\tCould not get file format." << endl; - } + if (from.empty()) + LYXERR(Debug::GRAPHICS, "\tCould not get file format."); + string const to = findTargetFormat(from, runparams); string const ext = formats.extension(to); - LYXERR(Debug::GRAPHICS) - << "\t we have: from " << from << " to " << to << '\n'; + LYXERR(Debug::GRAPHICS, "\t we have: from " << from << " to " << to); // We're going to be running the exported buffer through the LaTeX // compiler, so must ensure that LaTeX can cope with the graphics // file format. - LYXERR(Debug::GRAPHICS) - << "\tthe orig file is: " << orig_file << endl; + LYXERR(Debug::GRAPHICS, "\tthe orig file is: " << orig_file); if (from == to) { if (!runparams.nice && getExtension(temp_file.absFilename()) != ext) { @@ -700,15 +693,14 @@ string const InsetGraphics::prepareFile(Buffer const & buf, // the file format from the extension, so we must // change it. FileName const new_file = FileName(changeExtension(temp_file.absFilename(), ext)); - if (support::rename(temp_file, new_file)) { + if (temp_file.moveTo(new_file)) { temp_file = new_file; output_file = changeExtension(output_file, ext); source_file = FileName(changeExtension(source_file.absFilename(), ext)); - } else - LYXERR(Debug::GRAPHICS) - << "Could not rename file `" - << temp_file << "' to `" << new_file - << "'." << endl; + } else { + LYXERR(Debug::GRAPHICS, "Could not rename file `" + << temp_file << "' to `" << new_file << "'."); + } } // The extension of temp_file might be != ext! runparams.exportdata->addExternalFile(tex_format, source_file, @@ -725,10 +717,9 @@ string const InsetGraphics::prepareFile(Buffer const & buf, // Yes if to_file does not exist or if temp_file is newer than to_file if (compare_timestamps(temp_file, to_file) < 0) { // FIXME UNICODE - LYXERR(Debug::GRAPHICS) - << to_utf8(bformat(_("No conversion of %1$s is needed after all"), - from_utf8(rel_file))) - << std::endl; + LYXERR(Debug::GRAPHICS, + to_utf8(bformat(_("No conversion of %1$s is needed after all"), + from_utf8(rel_file)))); runparams.exportdata->addExternalFile(tex_format, to_file, output_to_file); runparams.exportdata->addExternalFile("dvi", to_file, @@ -736,11 +727,10 @@ string const InsetGraphics::prepareFile(Buffer const & buf, return stripExtensionIfPossible(output_to_file, runparams.nice); } - LYXERR(Debug::GRAPHICS) - << "\tThe original file is " << orig_file << "\n" + LYXERR(Debug::GRAPHICS,"\tThe original file is " << orig_file << "\n" << "\tA copy has been made and convert is to be called with:\n" << "\tfile to convert = " << temp_file << '\n' - << "\t from " << from << " to " << to << '\n'; + << "\t from " << from << " to " << to); // FIXME (Abdel 12/08/06): Is there a need to show these errors? ErrorList el; @@ -762,23 +752,18 @@ int InsetGraphics::latex(Buffer const & buf, odocstream & os, { // If there is no file specified or not existing, // just output a message about it in the latex output. - LYXERR(Debug::GRAPHICS) - << "insetgraphics::latex: Filename = " - << params().filename.absFilename() << endl; + LYXERR(Debug::GRAPHICS, "insetgraphics::latex: Filename = " + << params().filename.absFilename()); - string const relative_file = - params().filename.relFilename(buf.filePath()); - - bool const file_exists = !params().filename.empty() && - isFileReadable(params().filename); + bool const file_exists = !params().filename.empty() + && params().filename.isReadableFile(); string const message = file_exists ? string() : string("bb = 0 0 200 100, draft, type=eps"); // if !message.empty() then there was no existing file // "filename" found. In this case LaTeX // draws only a rectangle with the above bb and the // not found filename in it. - LYXERR(Debug::GRAPHICS) - << "\tMessage = \"" << message << '\"' << endl; + LYXERR(Debug::GRAPHICS, "\tMessage = \"" << message << '\"'); // These variables collect all the latex code that should be before and // after the actual includegraphics command. @@ -800,16 +785,14 @@ int InsetGraphics::latex(Buffer const & buf, odocstream & os, // Write the options if there are any. string const opts = createLatexOptions(); - LYXERR(Debug::GRAPHICS) << "\tOpts = " << opts << endl; + LYXERR(Debug::GRAPHICS, "\tOpts = " << opts); if (!opts.empty() && !message.empty()) before += ('[' + opts + ',' + message + ']'); else if (!opts.empty() || !message.empty()) before += ('[' + opts + message + ']'); - LYXERR(Debug::GRAPHICS) - << "\tBefore = " << before - << "\n\tafter = " << after << endl; + LYXERR(Debug::GRAPHICS, "\tBefore = " << before << "\n\tafter = " << after); string latex_str = before + '{'; // Convert the file if necessary. @@ -820,10 +803,9 @@ int InsetGraphics::latex(Buffer const & buf, odocstream & os, // FIXME UNICODE os << from_utf8(latex_str); - LYXERR(Debug::GRAPHICS) << "InsetGraphics::latex outputting:\n" - << latex_str << endl; + LYXERR(Debug::GRAPHICS, "InsetGraphics::latex outputting:\n" << latex_str); // Return how many newlines we issued. - return int(std::count(latex_str.begin(), latex_str.end(),'\n')); + return int(count(latex_str.begin(), latex_str.end(),'\n')); } @@ -846,39 +828,32 @@ int InsetGraphics::plaintext(Buffer const & buf, odocstream & os, } -namespace { +static int writeImageObject(char const * format, odocstream & os, + OutputParams const & runparams, docstring const & graphic_label, + docstring const & attributes) +{ + if (runparams.flavor != OutputParams::XML) + os << "" ; - } - else { - os << " format=\"" << format << "\">" ; - } - os << ""; - if (runparams.flavor != OutputParams::XML) { - os << std::endl << "]]>" ; - } - return runparams.flavor == OutputParams::XML ? 0 : 2; -} -// end anonymous namespace + os <<"" ; + else + os << " format=\"" << format << "\">" ; + + os << ""; + + if (runparams.flavor != OutputParams::XML) + os << endl << "]]>" ; + + return runparams.flavor == OutputParams::XML ? 0 : 2; } @@ -891,13 +866,13 @@ int InsetGraphics::docbook(Buffer const &, odocstream & os, // In DocBook v5.0, the graphic tag will be eliminated from DocBook, will // need to switch to MediaObject. However, for now this is sufficient and // easier to use. - if (runparams.flavor == OutputParams::XML) { + if (runparams.flavor == OutputParams::XML) runparams.exportdata->addExternalFile("docbook-xml", params().filename); - } else { + else runparams.exportdata->addExternalFile("docbook", params().filename); - } + os << ""; int r = 0; @@ -924,8 +899,8 @@ void InsetGraphics::validate(LaTeXFeatures & features) const features.require("graphicx"); if (features.runparams().nice) { - Buffer const * m_buffer = features.buffer().getMasterBuffer(); - string const rel_file = removeExtension(params().filename.relFilename(m_buffer->filePath())); + Buffer const * masterBuffer = features.buffer().masterBuffer(); + string const rel_file = removeExtension(params().filename.relFilename(masterBuffer->filePath())); if (contains(rel_file, ".")) features.require("lyxdot"); } @@ -1008,7 +983,7 @@ InsetGraphicsMailer::params2string(InsetGraphicsParams const & params, { ostringstream data; data << name_ << ' '; - params.Write(data, buffer.filePath()); + params.Write(data, buffer); data << "\\end_inset\n"; return data.str(); }