X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2Finsetgraphics.C;h=bb4a0cdfd0e749ca75136b3f5a35ffd1296e098b;hb=357a3741c0655e174ad48ded68cca90b09a158e6;hp=0f4d367bb08dc69506ded844fd113237a1dca724;hpb=d5268e6490fa561fa92043eee83a6f6ab26ae1a7;p=lyx.git diff --git a/src/insets/insetgraphics.C b/src/insets/insetgraphics.C index 0f4d367bb0..bb4a0cdfd0 100644 --- a/src/insets/insetgraphics.C +++ b/src/insets/insetgraphics.C @@ -4,9 +4,9 @@ * Licence details can be found in the file COPYING. * * \author Baruch Even - * \author Herbert Voss + * \author Herbert Voß * - * Full author contact details are available in file CREDITS + * Full author contact details are available in file CREDITS. */ /* @@ -52,54 +52,63 @@ TODO #include - #include "insets/insetgraphics.h" -#include "insets/insetgraphicsParams.h" - -#include "graphics/GraphicsLoader.h" -#include "graphics/GraphicsImage.h" -#include "graphics/GraphicsParams.h" +#include "insets/render_graphic.h" -#include "lyxtext.h" #include "buffer.h" #include "BufferView.h" #include "converter.h" +#include "cursor.h" #include "debug.h" +#include "dispatchresult.h" #include "format.h" #include "funcrequest.h" #include "gettext.h" #include "LaTeXFeatures.h" +#include "lyx_main.h" #include "lyxlex.h" #include "lyxrc.h" -#include "frontends/lyx_gui.h" +#include "metricsinfo.h" +#include "outputparams.h" #include "frontends/Alert.h" -#include "frontends/Dialogs.h" -#include "frontends/font_metrics.h" #include "frontends/LyXView.h" -#include "frontends/Painter.h" -#include "support/LAssert.h" #include "support/filetools.h" #include "support/lyxalgo.h" // lyx::count #include "support/lyxlib.h" // float_equal -#include "support/path.h" -#include "support/systemcall.h" #include "support/os.h" +#include "support/systemcall.h" +#include "support/tostr.h" +#include "support/std_sstream.h" -#include #include -#include -#include "support/BoostFormat.h" - -#include // For the std::max +#include + +namespace support = lyx::support; +using lyx::support::AbsolutePath; +using lyx::support::bformat; +using lyx::support::ChangeExtension; +using lyx::support::contains; +using lyx::support::FileName; +using lyx::support::float_equal; +using lyx::support::GetExtension; +using lyx::support::getExtFromContents; +using lyx::support::IsFileReadable; +using lyx::support::LibFileSearch; +using lyx::support::rtrim; +using lyx::support::Systemcall; +using lyx::support::unzipFile; +using lyx::support::unzippedFileName; + +namespace os = lyx::support::os; -extern string system_tempdir; -// set by Exporters -extern bool pdf_mode; - -using std::ostream; using std::endl; +using std::string; +using std::auto_ptr; +using std::istringstream; +using std::ostream; +using std::ostringstream; namespace { @@ -120,22 +129,15 @@ string const RemoveExtension(string const & filename) string const uniqueID() { static unsigned int seed = 1000; - - ostringstream ost; - ost << "graph" << ++seed; - - // Needed if we use lyxstring. - return STRCONV(ost.str()); + return "graph" + tostr(++seed); } -string findTargetFormat(string const & suffix) +string findTargetFormat(string const & suffix, OutputParams const & runparams) { - // pdf_mode means: - // Are we creating a PDF or a PS file? - // (Should actually mean, are we using latex or pdflatex). - if (pdf_mode) { - lyxerr[Debug::GRAPHICS] << "findTargetFormat: PDF mode\n"; + // Are we using latex or pdflatex). + if (runparams.flavor == OutputParams::PDFLATEX) { + lyxerr[Debug::GRAPHICS] << "findTargetFormat: PDF mode" << endl; if (contains(suffix, "ps") || suffix == "pdf") return "pdf"; if (suffix == "jpg") // pdflatex can use jpeg @@ -143,7 +145,7 @@ string findTargetFormat(string const & suffix) return "png"; // and also png } // If it's postscript, we always do eps. - lyxerr[Debug::GRAPHICS] << "findTargetFormat: PostScript mode\n"; + lyxerr[Debug::GRAPHICS] << "findTargetFormat: PostScript mode" << endl; if (suffix != "ps") // any other than ps return "eps"; // is changed to eps return suffix; // let ps untouched @@ -152,318 +154,119 @@ string findTargetFormat(string const & suffix) } // namespace anon -struct InsetGraphics::Cache : boost::signals::trackable -{ - /// - Cache(InsetGraphics &); - /// - void update(string const & file_with_path); - - /// - int old_ascent; - /// - grfx::Loader loader; - /// - unsigned long checksum; - /// - boost::weak_ptr view; - -private: - /// - InsetGraphics & parent_; -}; - - -InsetGraphics::Cache::Cache(InsetGraphics & p) - : old_ascent(0), checksum(0), parent_(p) +InsetGraphics::InsetGraphics() + : graphic_label(uniqueID()), + graphic_(new RenderGraphic) { - loader.connect(boost::bind(&InsetGraphics::statusChanged, &parent_)); + graphic_->connect(boost::bind(&InsetGraphics::statusChanged, this)); } -void InsetGraphics::Cache::update(string const & file_with_path) +InsetGraphics::InsetGraphics(InsetGraphics const & ig) + : InsetOld(ig), + boost::signals::trackable(), + graphic_label(uniqueID()), + graphic_(new RenderGraphic(*ig.graphic_)) { - lyx::Assert(!file_with_path.empty()); - - string const path = OnlyPath(file_with_path); - loader.reset(file_with_path, parent_.params().as_grfxParams(path)); + graphic_->connect(boost::bind(&InsetGraphics::statusChanged, this)); + setParams(ig.params()); } -InsetGraphics::InsetGraphics() - : graphic_label(uniqueID()), - cache_(new Cache(*this)) -{} - - -InsetGraphics::InsetGraphics(InsetGraphics const & ig, - string const & filepath, - bool same_id) - : Inset(ig, same_id), - graphic_label(uniqueID()), - cache_(new Cache(*this)) +auto_ptr InsetGraphics::clone() const { - setParams(ig.params(), filepath); + return auto_ptr(new InsetGraphics(*this)); } -Inset * InsetGraphics::clone(Buffer const & buffer, bool same_id) const +InsetGraphics::~InsetGraphics() { - return new InsetGraphics(*this, buffer.filePath(), same_id); + InsetGraphicsMailer(*this).hideDialog(); } -InsetGraphics::~InsetGraphics() +void InsetGraphics::statusChanged() const { - InsetGraphicsMailer mailer(*this); - mailer.hideDialog(); + LyX::cref().updateInset(this); } -dispatch_result InsetGraphics::localDispatch(FuncRequest const & cmd) +void InsetGraphics::priv_dispatch(LCursor & cur, FuncRequest const & cmd) { - dispatch_result result = UNDISPATCHED; - switch (cmd.action) { case LFUN_INSET_MODIFY: { + Buffer const & buffer = *cur.bv().buffer(); InsetGraphicsParams p; - InsetGraphicsMailer::string2params(cmd.argument, p); - if (p.filename.empty()) - break; - - string const filepath = cmd.view()->buffer()->filePath(); - setParams(p, filepath); - cmd.view()->updateInset(this); - result = DISPATCHED; + InsetGraphicsMailer::string2params(cmd.argument, buffer, p); + if (!p.filename.empty()) { + setParams(p); + cur.bv().update(); + } + break; } - break; - case LFUN_INSET_DIALOG_UPDATE: { - InsetGraphicsMailer mailer(*this); - mailer.updateDialog(cmd.view()); - } - break; + case LFUN_INSET_DIALOG_UPDATE: + InsetGraphicsMailer(*this).updateDialog(&cur.bv()); + break; case LFUN_MOUSE_RELEASE: - edit(cmd.view(), cmd.x, cmd.y, cmd.button()); + InsetGraphicsMailer(*this).showDialog(&cur.bv()); break; default: - result = DISPATCHED; + InsetOld::priv_dispatch(cur, cmd); break; } - - return result; -} - - -string const InsetGraphics::statusMessage() const -{ - using namespace grfx; - - switch (cache_->loader.status()) { - case WaitingToLoad: - return _("Not shown."); - case Loading: - return _("Loading..."); - case Converting: - return _("Converting to loadable format..."); - case Loaded: - return _("Loaded into memory. Must now generate pixmap."); - case ScalingEtc: - return _("Scaling etc..."); - case Ready: - return _("Ready to display"); - case ErrorNoFile: - return _("No file found!"); - case ErrorConverting: - return _("Error converting to loadable format"); - case ErrorLoading: - return _("Error loading file into memory"); - case ErrorGeneratingPixmap: - return _("Error generating the pixmap"); - case ErrorUnknown: - return _("No image"); - } - return string(); -} - - -bool InsetGraphics::imageIsDrawable() const -{ - if (!cache_->loader.image() || cache_->loader.status() != grfx::Ready) - return false; - - return cache_->loader.image()->isDrawable(); -} - - -int InsetGraphics::ascent(BufferView *, LyXFont const &) const -{ - cache_->old_ascent = 50; - if (imageIsDrawable()) - cache_->old_ascent = cache_->loader.image()->getHeight(); - return cache_->old_ascent; } -int InsetGraphics::descent(BufferView *, LyXFont const &) const +void InsetGraphics::edit(LCursor & cur, bool) { - return 0; -} - - -int InsetGraphics::width(BufferView *, LyXFont const & font) const -{ - if (imageIsDrawable()) - return cache_->loader.image()->getWidth() + 2 * TEXT_TO_INSET_OFFSET; - - int font_width = 0; - - LyXFont msgFont(font); - msgFont.setFamily(LyXFont::SANS_FAMILY); - - string const justname = OnlyFilename (params().filename); - if (!justname.empty()) { - msgFont.setSize(LyXFont::SIZE_FOOTNOTE); - font_width = font_metrics::width(justname, msgFont); - } - - string const msg = statusMessage(); - if (!msg.empty()) { - msgFont.setSize(LyXFont::SIZE_TINY); - int const msg_width = font_metrics::width(msg, msgFont); - font_width = std::max(font_width, msg_width); - } - - return std::max(50, font_width + 15); -} - - -BufferView * InsetGraphics::view() const -{ - return cache_->view.lock().get(); -} - - -void InsetGraphics::draw(BufferView * bv, LyXFont const & font, - int baseline, float & x) const -{ - // MakeAbsPath returns params().filename unchanged if it absolute - // already. - string const file_with_path = - MakeAbsPath(params().filename, bv->buffer()->filePath()); - - // A 'paste' operation creates a new inset with the correct filepath, - // but then the 'old' inset stored in the 'copy' operation is actually - // added to the buffer. - // Thus, we should ensure that the filepath is correct. - if (file_with_path != cache_->loader.filename()) - cache_->update(file_with_path); - - cache_->view = bv->owner()->view(); - int oasc = cache_->old_ascent; - - int ldescent = descent(bv, font); - int lascent = ascent(bv, font); - int lwidth = width(bv, font); - - // we may have changed while someone other was drawing us so better - // to not draw anything as we surely call to redraw ourself soon. - // This is not a nice thing to do and should be fixed properly somehow. - // But I still don't know the best way to go. So let's do this like this - // for now (Jug 20020311) - if (lascent != oasc) - return; - - // Make sure now that x is updated upon exit from this routine - int old_x = int(x); - x += lwidth; - - grfx::Params const & gparams = params().as_grfxParams(); - - if (gparams.display != grfx::NoDisplay && - cache_->loader.status() == grfx::WaitingToLoad) - cache_->loader.startLoading(); - - if (!cache_->loader.monitoring()) - cache_->loader.startMonitoring(); - - // This will draw the graphics. If the graphics has not been loaded yet, - // we draw just a rectangle. - Painter & paint = bv->painter(); - - if (imageIsDrawable()) { - paint.image(old_x + TEXT_TO_INSET_OFFSET, baseline - lascent, - lwidth - 2 * TEXT_TO_INSET_OFFSET, lascent + ldescent, - *cache_->loader.image()); - - } else { - - paint.rectangle(old_x + TEXT_TO_INSET_OFFSET, baseline - lascent, - lwidth - 2 * TEXT_TO_INSET_OFFSET, lascent + ldescent); - - // Print the file name. - LyXFont msgFont(font); - msgFont.setFamily(LyXFont::SANS_FAMILY); - string const justname = OnlyFilename (params().filename); - if (!justname.empty()) { - msgFont.setSize(LyXFont::SIZE_FOOTNOTE); - paint.text(old_x + TEXT_TO_INSET_OFFSET + 6, - baseline - font_metrics::maxAscent(msgFont) - 4, - justname, msgFont); - } - - // Print the message. - string const msg = statusMessage(); - if (!msg.empty()) { - msgFont.setSize(LyXFont::SIZE_TINY); - paint.text(old_x + TEXT_TO_INSET_OFFSET + 6, baseline - 4, msg, msgFont); - } - } + InsetGraphicsMailer(*this).showDialog(&cur.bv()); } -void InsetGraphics::edit(BufferView * bv, int, int, mouse_button::state) +void InsetGraphics::metrics(MetricsInfo & mi, Dimension & dim) const { - InsetGraphicsMailer mailer(*this); - mailer.showDialog(bv); + graphic_->metrics(mi, dim); + dim_ = dim; } -void InsetGraphics::edit(BufferView * bv, bool) +void InsetGraphics::draw(PainterInfo & pi, int x, int y) const { - edit(bv, 0, 0, mouse_button::none); + setPosCache(pi, x, y); + graphic_->draw(pi, x, y); } -Inset::EDITABLE InsetGraphics::editable() const +InsetOld::EDITABLE InsetGraphics::editable() const { return IS_EDITABLE; } -void InsetGraphics::write(Buffer const *, ostream & os) const +void InsetGraphics::write(Buffer const & buf, ostream & os) const { os << "Graphics\n"; - params().Write(os); + params().Write(os, buf.filePath()); } -void InsetGraphics::read(Buffer const * buf, LyXLex & lex) +void InsetGraphics::read(Buffer const & buf, LyXLex & lex) { string const token = lex.getString(); if (token == "Graphics") - readInsetGraphics(lex); + readInsetGraphics(lex, buf.filePath()); else - lyxerr[Debug::GRAPHICS] << "Not a Graphics inset!\n"; + lyxerr[Debug::GRAPHICS] << "Not a Graphics inset!" << endl; - cache_->update(MakeAbsPath(params().filename, buf->filePath())); + graphic_->update(params().as_grfxParams()); } -void InsetGraphics::readInsetGraphics(LyXLex & lex) +void InsetGraphics::readInsetGraphics(LyXLex & lex, string const & bufpath) { bool finished = false; @@ -472,7 +275,7 @@ void InsetGraphics::readInsetGraphics(LyXLex & lex) string const token = lex.getString(); lyxerr[Debug::GRAPHICS] << "Token: '" << token << '\'' - << std::endl; + << endl; if (token.empty()) { continue; @@ -486,11 +289,11 @@ void InsetGraphics::readInsetGraphics(LyXLex & lex) << "This document was created with a newer Graphics widget" ", You should use a newer version of LyX to read this" " file." - << std::endl; + << endl; // TODO: Possibly open up a dialog? } else { - if (! params_.Read(lex, token)) + if (!params_.Read(lex, token, bufpath)) lyxerr << "Unknown token, " << token << ", skipping." << std::endl; } @@ -510,8 +313,8 @@ string const InsetGraphics::createLatexOptions() const options << " draft,\n"; if (params().clip) options << " clip,\n"; - if (!lyx::float_equal(params().scale, 0.0, 0.05)) { - if (!lyx::float_equal(params().scale, 100.0, 0.05)) + if (!float_equal(params().scale, 0.0, 0.05)) { + if (!float_equal(params().scale, 100.0, 0.05)) options << " scale=" << params().scale / 100.0 << ",\n"; } else { @@ -525,7 +328,7 @@ string const InsetGraphics::createLatexOptions() const // Make sure rotation angle is not very close to zero; // a float can be effectively zero but not exactly zero. - if (!lyx::float_equal(params().rotateAngle, 0, 0.001)) { + if (!float_equal(params().rotateAngle, 0, 0.001)) { options << " angle=" << params().rotateAngle << ",\n"; if (!params().rotateOrigin.empty()) { options << " origin=" << params().rotateOrigin[0]; @@ -542,195 +345,216 @@ string const InsetGraphics::createLatexOptions() const if (!params().special.empty()) options << params().special << ",\n"; - string opts = STRCONV(options.str()); + string opts = options.str(); // delete last ",\n" return opts.substr(0, opts.size() - 2); } -string const InsetGraphics::prepareFile(Buffer const * buf) const +namespace { + +enum CopyStatus { + SUCCESS, + FAILURE, + IDENTICAL_PATHS, + IDENTICAL_CONTENTS +}; + + +std::pair const +copyToDirIfNeeded(string const & file_in, string const & dir) +{ + using support::rtrim; + + BOOST_ASSERT(AbsolutePath(file_in)); + + 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 mangled; + if (support::zippedFile(file_in)) { + string const ext = GetExtension(file_in); + string const unzipped = support::unzippedFileName(file_in); + mangled = FileName(unzipped).mangledFilename(); + mangled += "." + ext; + } else + mangled = FileName(file_in).mangledFilename(); + + string const file_out = support::MakeAbsPath(mangled, dir); + + unsigned long const checksum_in = support::sum(file_in); + unsigned long const checksum_out = support::sum(file_out); + + if (checksum_in == checksum_out) + // Nothing to do... + return std::make_pair(IDENTICAL_CONTENTS, file_out); + + bool const success = support::copy(file_in, file_out); + if (!success) { + lyxerr[Debug::GRAPHICS] + << support::bformat(_("Could not copy the file\n%1$s\n" + "into the temporary directory."), + file_in) + << std::endl; + } + + CopyStatus status = success ? SUCCESS : FAILURE; + return std::make_pair(status, file_out); +} + + +string const stripExtensionIfPossible(string const & file, string const & to) +{ + // No conversion is needed. LaTeX can handle the graphic file as is. + // This is true even if the orig_file is compressed. + if (formats.getFormat(to)->extension() == GetExtension(file)) + return RemoveExtension(file); + return file; +} + +} // namespace anon + + +string const InsetGraphics::prepareFile(Buffer const & buf, + OutputParams const & runparams) const { + string orig_file = params().filename.absFilename(); + string const rel_file = params().filename.relFilename(buf.filePath()); + // LaTeX can cope if the graphics file doesn't exist, so just return the // filename. - string const orig_file = params().filename; - string orig_file_with_path = - MakeAbsPath(orig_file, buf->filePath()); - lyxerr[Debug::GRAPHICS] << "[InsetGraphics::prepareFile] orig_file = " - << orig_file << "\n\twith path: " - << orig_file_with_path << endl; - - if (!IsFileReadable(orig_file_with_path)) - return orig_file; - - bool const zipped = zippedFile(orig_file_with_path); + if (!IsFileReadable(orig_file)) { + lyxerr[Debug::GRAPHICS] + << "InsetGraphics::prepareFile\n" + << "No file '" << orig_file << "' can be found!" << endl; + return rel_file; + } // If the file is compressed and we have specified that it // should not be uncompressed, then just return its name and // let LaTeX do the rest! + bool const zipped = params().filename.isZipped(); + if (zipped && params().noUnzip) { lyxerr[Debug::GRAPHICS] << "\tpass zipped file to LaTeX but with full path.\n"; - // LaTeX needs an absolue path, otherwise the + // LaTeX needs an absolute path, otherwise the // coresponding *.eps.bb file isn't found - return orig_file_with_path; + return orig_file; } - // Ascertain whether the file has changed. - unsigned long const new_checksum = cache_->loader.checksum(); - bool const file_has_changed = cache_->checksum != new_checksum; - if (file_has_changed) - cache_->checksum = new_checksum; - // temp_file will contain the file for LaTeX to act on if, for example, // we move it to a temp dir or uncompress it. string temp_file = orig_file; if (zipped) { - // Uncompress the file if necessary. - // If it has been uncompressed in a previous call to - // prepareFile, do nothing. - temp_file = MakeAbsPath(OnlyFilename(temp_file), buf->tmppath); - lyxerr[Debug::GRAPHICS] - << "\ttemp_file: " << temp_file << endl; - if (file_has_changed || !IsFileReadable(temp_file)) { - bool const success = lyx::copy(orig_file_with_path, - temp_file); - lyxerr[Debug::GRAPHICS] - << "\tCopying zipped file from " - << orig_file_with_path << " to " << temp_file - << (success ? " succeeded\n" : " failed\n"); - } else + CopyStatus status; + boost::tie(status, temp_file) = + copyToDirIfNeeded(orig_file, buf.temppath()); + + if (status == FAILURE) + return orig_file; + + orig_file = unzippedFileName(temp_file); + if (!IsFileReadable(orig_file)) { + unzipFile(temp_file); lyxerr[Debug::GRAPHICS] - << "\tzipped file " << temp_file - << " exists! Maybe no tempdir ...\n"; - orig_file_with_path = unzipFile(temp_file); - lyxerr[Debug::GRAPHICS] - << "\tunzipped to " << orig_file_with_path << endl; + << "\tunzipped to " << orig_file << endl; + } } - string const from = getExtFromContents(orig_file_with_path); - string const to = findTargetFormat(from); + string const from = getExtFromContents(orig_file); + string const to = findTargetFormat(from, runparams); lyxerr[Debug::GRAPHICS] << "\t we have: from " << from << " to " << to << '\n'; - if (from == to && !lyxrc.use_tempdir) { - // No conversion is needed. LaTeX can handle the - // graphic file as is. - // This is true even if the orig_file is compressed. - if (formats.getFormat(to)->extension() == GetExtension(orig_file)) - return RemoveExtension(orig_file_with_path); - return orig_file_with_path; - } + if (from == to && !lyxrc.use_tempdir) + return stripExtensionIfPossible(orig_file, 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. - // Perform all these manipulations on a temporary file if possible. - // If we are not using a temp dir, then temp_file contains the - // original file. - // to allow files with the same name in different dirs - // we manipulate the original file "any.dir/file.ext" - // to "any_dir_file.ext"! changing the dots in the - // dirname is important for the use of ChangeExtension lyxerr[Debug::GRAPHICS] - << "\tthe orig file is: " << orig_file_with_path << endl; + << "\tthe orig file is: " << orig_file << endl; + bool conversion_needed = true; if (lyxrc.use_tempdir) { - string const ext_tmp = GetExtension(orig_file_with_path); - // without ext and / - temp_file = subst( - ChangeExtension(orig_file_with_path, string()), "/", "_"); - // without dots and again with ext - temp_file = ChangeExtension( - subst(temp_file, ".", "_"), ext_tmp); - // now we have any_dir_file.ext - temp_file = MakeAbsPath(temp_file, buf->tmppath); - lyxerr[Debug::GRAPHICS] - << "\tchanged to: " << temp_file << endl; + CopyStatus status; + boost::tie(status, temp_file) = + copyToDirIfNeeded(orig_file, buf.temppath()); + + if (status == FAILURE) + return orig_file; + else if (status == IDENTICAL_CONTENTS) + conversion_needed = false; + } - // if the file doen't exists, copy it into the tempdir - if (file_has_changed || !IsFileReadable(temp_file)) { - bool const success = lyx::copy(orig_file_with_path, temp_file); - lyxerr[Debug::GRAPHICS] - << "\tcopying from " << orig_file_with_path << " to " - << temp_file - << (success ? " succeeded\n" : " failed\n"); - if (!success) { -#if USE_BOOST_FORMAT - boost::format fmt(_("Could not copy the file\n%1$s\ninto the temporary directory.")); - fmt % orig_file_with_path; - string str = fmt.str(); -#else - string str = _("Could not copy the file\n"); - str += orig_file_with_path; - str += _("\ninto the temporary directory."); -#endif - Alert::error(_("Graphics display failed"), str); - return orig_file; - } - } + if (from == to) + return stripExtensionIfPossible(temp_file, to); - if (from == to) { - // No conversion is needed. LaTeX can handle the - // graphic file as is. - if (formats.getFormat(to)->extension() == GetExtension(orig_file)) - return RemoveExtension(temp_file); - return temp_file; - } + string const to_file_base = RemoveExtension(temp_file); + string const to_file = ChangeExtension(to_file_base, to); + + // Do we need to perform the conversion? + // Yes if to_file does not exist or if temp_file is newer than to_file + if (!conversion_needed || + support::compare_timestamps(temp_file, to_file) < 0) { + lyxerr[Debug::GRAPHICS] + << bformat(_("No conversion of %1$s is needed after all"), + rel_file) + << std::endl; + return to_file_base; } - string const outfile_base = RemoveExtension(temp_file); 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' - << "\toutfile_base = " << outfile_base << '\n' + << "\tto_file_base = " << to_file_base << '\n' << "\t from " << from << " to " << to << '\n'; // if no special converter defined, than we take the default one // from ImageMagic: convert from:inname.from to:outname.to - if (!converters.convert(buf, temp_file, outfile_base, from, to)) { + if (!converters.convert(&buf, temp_file, to_file_base, from, to)) { string const command = - LibFileSearch("scripts", "convertDefault.sh") + + "sh " + LibFileSearch("scripts", "convertDefault.sh") + ' ' + from + ':' + temp_file + ' ' + - to + ':' + outfile_base + '.' + to; + to + ':' + to_file_base + '.' + to; lyxerr[Debug::GRAPHICS] << "No converter defined! I use convertDefault.sh:\n\t" << command << endl; Systemcall one; one.startscript(Systemcall::Wait, command); - if (!IsFileReadable(ChangeExtension(outfile_base, to))) { -#if USE_BOOST_FORMAT - boost::format fmt(_("No information for converting %1$s format files to %1$s.\n" - "Try defining a convertor in the preferences.")); - fmt % from % to; - string str = fmt.str(); -#else - string str = _("No information for converting "); - str += from + _(" format files to ") + to; - str += _(".\nTry defining a convertor in the preferences."); -#endif + if (!IsFileReadable(ChangeExtension(to_file_base, to))) { + string str = bformat(_("No information for converting %1$s " + "format files to %2$s.\n" + "Try defining a convertor in the preferences."), from, to); Alert::error(_("Could not convert image"), str); } } - return RemoveExtension(temp_file); + return to_file_base; } -int InsetGraphics::latex(Buffer const * buf, ostream & os, - bool /*fragile*/, bool/*fs*/) const +int InsetGraphics::latex(Buffer const & buf, ostream & os, + OutputParams const & runparams) const { // 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 << endl; + << params().filename.absFilename() << endl; + + string const relative_file = + params().filename.relFilename(buf.filePath()); // A missing (e)ps-extension is no problem for LaTeX, so // we have to test three different cases - string const file_ = MakeAbsPath(params().filename, buf->filePath()); +#warning uh, but can our cache handle it ? no. + string const file_ = params().filename.absFilename(); bool const file_exists = !file_.empty() && (IsFileReadable(file_) || // original @@ -773,8 +597,8 @@ int InsetGraphics::latex(Buffer const * buf, ostream & os, // "nice" means that the buffer is exported to LaTeX format but not // run through the LaTeX compiler. - if (buf->niceFile) { - os << before <<'{' << params().filename << '}' << after; + if (runparams.nice) { + os << before <<'{' << relative_file << '}' << after; return 1; } @@ -782,47 +606,49 @@ int InsetGraphics::latex(Buffer const * buf, ostream & os, // and remove the extension so the LaTeX will use whatever is // appropriate (when there are several versions in different formats) string const latex_str = message.empty() ? - (before + '{' + os::external_path(prepareFile(buf)) + '}' + after) : - (before + '{' + params().filename + " not found!}" + after); + (before + '{' + os::external_path(prepareFile(buf, runparams)) + '}' + after) : + (before + '{' + relative_file + " not found!}" + after); os << latex_str; + lyxerr[Debug::GRAPHICS] << "InsetGraphics::latex outputting:\n" + << latex_str << endl; // Return how many newlines we issued. return int(lyx::count(latex_str.begin(), latex_str.end(),'\n') + 1); } -int InsetGraphics::ascii(Buffer const *, ostream & os, int) const +int InsetGraphics::plaintext(Buffer const &, ostream & os, + OutputParams const &) const { // No graphics in ascii output. Possible to use gifscii to convert // images to ascii approximation. // 1. Convert file to ascii using gifscii // 2. Read ascii output file and add it to the output stream. // at least we send the filename -#if USE_BOOST_FORMAT - os << '<' - << boost::format(_("Graphics file: %1$s")) % params().filename - << ">\n"; -#else - os << '<' - << _("Graphics file: ") << params().filename - << ">\n"; -#endif + os << '<' << bformat(_("Graphics file: %1$s"), + params().filename.absFilename()) << ">\n"; return 0; } -int InsetGraphics::linuxdoc(Buffer const *, ostream &) const +int InsetGraphics::linuxdoc(Buffer const & buf, ostream & os, + OutputParams const & runparams) const { - // No graphics in LinuxDoc output. Should check how/what to add. + string const file_name = runparams.nice ? + params().filename.relFilename(buf.filePath()): + params().filename.absFilename(); + + os << "\n"; + os << ""; return 0; } // For explanation on inserting graphics into DocBook checkout: -// http://linuxdoc.org/LDP/LDP-Author-Guide/inserting-pictures.html +// http://en.tldp.org/LDP/LDP-Author-Guide/inserting-pictures.html // See also the docbook guide at http://www.docbook.org/ -int InsetGraphics::docbook(Buffer const *, ostream & os, - bool /*mixcont*/) const +int InsetGraphics::docbook(Buffer const &, ostream & os, + OutputParams const &) const { // 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 @@ -838,7 +664,8 @@ void InsetGraphics::validate(LaTeXFeatures & features) const if (params().filename.empty()) return; - features.includeFile(graphic_label, RemoveExtension(params().filename)); + features.includeFile(graphic_label, + RemoveExtension(params().filename.absFilename())); features.require("graphicx"); @@ -847,15 +674,7 @@ void InsetGraphics::validate(LaTeXFeatures & features) const } -void InsetGraphics::statusChanged() -{ - if (!cache_->view.expired()) - cache_->view.lock()->updateInset(this); -} - - -bool InsetGraphics::setParams(InsetGraphicsParams const & p, - string const & filepath) +bool InsetGraphics::setParams(InsetGraphicsParams const & p) { // If nothing is changed, just return and say so. if (params() == p && !p.filename.empty()) @@ -864,8 +683,8 @@ bool InsetGraphics::setParams(InsetGraphicsParams const & p, // Copy the new parameters. params_ = p; - // Update the inset with the new parameters. - cache_->update(MakeAbsPath(params().filename, filepath)); + // Update the display using the new parameters. + graphic_->update(params().as_grfxParams()); // We have changed data, report it. return true; @@ -885,43 +704,42 @@ InsetGraphicsMailer::InsetGraphicsMailer(InsetGraphics & inset) {} -string const InsetGraphicsMailer::inset2string() const +string const InsetGraphicsMailer::inset2string(Buffer const & buffer) const { - return params2string(inset_.params()); + return params2string(inset_.params(), buffer); } void InsetGraphicsMailer::string2params(string const & in, + Buffer const & buffer, InsetGraphicsParams & params) { params = InsetGraphicsParams(); + if (in.empty()) + return; istringstream data(in); LyXLex lex(0,0); lex.setStream(data); - if (lex.isOK()) { - lex.next(); - string const token = lex.getString(); - if (token != name_) - return; - } + string name; + lex >> name; + if (!lex || name != name_) + return print_mailer_error("InsetGraphicsMailer", in, 1, name_); - if (lex.isOK()) { - InsetGraphics inset; - inset.readInsetGraphics(lex); - params = inset.params(); - } + InsetGraphics inset; + inset.readInsetGraphics(lex, buffer.filePath()); + params = inset.params(); } string const -InsetGraphicsMailer::params2string(InsetGraphicsParams const & params) +InsetGraphicsMailer::params2string(InsetGraphicsParams const & params, + Buffer const & buffer) { ostringstream data; data << name_ << ' '; - params.Write(data); + params.Write(data, buffer.filePath()); data << "\\end_inset\n"; - return data.str(); }