X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2Finsetgraphics.C;h=cf6917c091473d8c1652009b22a5b9f6378fb57d;hb=b249c0b0bb43b8c724e82412b22e9ac019bebb87;hp=63152f4e7d90ddd62dfc037df4a65a7d9b762195;hpb=46e5fe4a67e6645e0cb6a74c47c6036efc6625de;p=lyx.git diff --git a/src/insets/insetgraphics.C b/src/insets/insetgraphics.C index 63152f4e7d..cf6917c091 100644 --- a/src/insets/insetgraphics.C +++ b/src/insets/insetgraphics.C @@ -54,13 +54,8 @@ TODO #include "insets/insetgraphics.h" #include "insets/insetgraphicsParams.h" +#include "insets/renderers.h" -#include "graphics/GraphicsLoader.h" -#include "graphics/GraphicsImage.h" -#include "graphics/GraphicsParams.h" - -#include "lyxtext.h" -#include "dimension.h" #include "buffer.h" #include "BufferView.h" #include "converter.h" @@ -73,34 +68,25 @@ TODO #include "Lsstream.h" #include "lyxlex.h" #include "lyxrc.h" -#include "Lsstream.h" -#include "frontends/lyx_gui.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/tostr.h" #include "support/systemcall.h" -#include "support/os.h" -#include "support/lstrings.h" -#include #include -#include #include // For the std::max extern string system_tempdir; // set by Exporters +using namespace lyx::support; + using std::ostream; using std::endl; @@ -148,87 +134,42 @@ string findTargetFormat(string const & suffix, LatexRunParams const & runparams) } // 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) -{ - loader.connect(boost::bind(&InsetGraphics::statusChanged, &parent_)); -} - - -void InsetGraphics::Cache::update(string const & file_with_path) -{ - lyx::Assert(!file_with_path.empty()); - - string const path = OnlyPath(file_with_path); - loader.reset(file_with_path, parent_.params().as_grfxParams(path)); -} - - InsetGraphics::InsetGraphics() : graphic_label(uniqueID()), - cache_(new Cache(*this)) -{} + graphic_(new GraphicRenderer) +{ + graphic_->connect(boost::bind(&InsetGraphics::statusChanged, this)); +} -InsetGraphics::InsetGraphics(InsetGraphics const & ig, - string const & filepath) +InsetGraphics::InsetGraphics(InsetGraphics const & ig) : Inset(ig), + boost::signals::trackable(), graphic_label(uniqueID()), - cache_(new Cache(*this)) + graphic_(new GraphicRenderer(*ig.graphic_)) { - setParams(ig.params(), filepath); + graphic_->connect(boost::bind(&InsetGraphics::statusChanged, this)); + setParams(ig.params()); } -// InsetGraphics::InsetGraphics(InsetGraphics const & ig, -// string const & filepath, -// bool same_id) -// : Inset(ig, same_id), -// graphic_label(uniqueID()), -// cache_(new Cache(*this)) -// { -// setParams(ig.params(), filepath); -// } - - -Inset * InsetGraphics::clone(Buffer const & buffer) const +InsetBase * InsetGraphics::clone() const { - return new InsetGraphics(*this, buffer.filePath()); + return new InsetGraphics(*this); } -// Inset * InsetGraphics::clone(Buffer const & buffer, bool same_id) const -// { -// return new InsetGraphics(*this, buffer.filePath(), same_id); -// } +InsetGraphics::~InsetGraphics() +{ + InsetGraphicsMailer(*this).hideDialog(); +} -InsetGraphics::~InsetGraphics() +void InsetGraphics::statusChanged() { - InsetGraphicsMailer mailer(*this); - mailer.hideDialog(); + BufferView * bv = graphic_->view(); + if (bv) + bv->updateInset(this); } @@ -236,11 +177,11 @@ dispatch_result InsetGraphics::localDispatch(FuncRequest const & cmd) { switch (cmd.action) { case LFUN_INSET_MODIFY: { + string const bufpath = cmd.view()->buffer()->filePath(); InsetGraphicsParams p; - InsetGraphicsMailer::string2params(cmd.argument, p); + InsetGraphicsMailer::string2params(cmd.argument, bufpath, p); if (!p.filename.empty()) { - string const filepath = cmd.view()->buffer()->filePath(); - setParams(p, filepath); + setParams(p); cmd.view()->updateInset(this); } return DISPATCHED; @@ -261,161 +202,16 @@ dispatch_result InsetGraphics::localDispatch(FuncRequest const & cmd) } -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(); -} - - -void InsetGraphics::dimension(BufferView *, LyXFont const & font, - Dimension & dim) const -{ - cache_->old_ascent = 50; - if (imageIsDrawable()) - cache_->old_ascent = cache_->loader.image()->getHeight(); - dim.a = cache_->old_ascent; - dim.d = 0; - if (imageIsDrawable()) - dim.w = cache_->loader.image()->getWidth() + 2 * TEXT_TO_INSET_OFFSET; - else { - 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); - font_width = std::max(font_width, font_metrics::width(msg, msgFont)); - } - - dim.w = std::max(50, font_width + 15); - } -} - - -BufferView * InsetGraphics::view() const +void InsetGraphics::metrics(MetricsInfo & mi, Dimension & dim) const { - return cache_->view.lock().get(); + graphic_->metrics(mi, dim); + dim_ = dim; } -void InsetGraphics::draw(BufferView * bv, LyXFont const & font, - int baseline, float & x) const +void InsetGraphics::draw(PainterInfo & pi, int x, int y) 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); - } - } + graphic_->draw(pi, x, y); } @@ -425,10 +221,10 @@ Inset::EDITABLE InsetGraphics::editable() const } -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()); } @@ -437,15 +233,15 @@ 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"; - 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 +268,7 @@ void InsetGraphics::readInsetGraphics(LyXLex & lex) // 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; } @@ -492,8 +288,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 { @@ -507,7 +303,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]; @@ -535,17 +331,17 @@ string const InsetGraphics::prepareFile(Buffer const * buf, { // 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; + string orig_file = params().filename; + string const rel_file = MakeRelPath(orig_file, buf->filePath()); - 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; + } + + bool const zipped = zippedFile(orig_file); // If the file is compressed and we have specified that it // should not be uncompressed, then just return its name and @@ -553,17 +349,11 @@ string const InsetGraphics::prepareFile(Buffer const * buf, 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; @@ -575,23 +365,22 @@ string const InsetGraphics::prepareFile(Buffer const * buf, 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); + if (graphic_->hasFileChanged() || !IsFileReadable(temp_file)) { + bool const success = copy(orig_file, temp_file); lyxerr[Debug::GRAPHICS] << "\tCopying zipped file from " - << orig_file_with_path << " to " << temp_file + << orig_file << " to " << temp_file << (success ? " succeeded\n" : " failed\n"); } else lyxerr[Debug::GRAPHICS] << "\tzipped file " << temp_file << " exists! Maybe no tempdir ...\n"; - orig_file_with_path = unzipFile(temp_file); + orig_file = 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 from = getExtFromContents(orig_file); string const to = findTargetFormat(from, runparams); lyxerr[Debug::GRAPHICS] << "\t we have: from " << from << " to " << to << '\n'; @@ -601,8 +390,8 @@ string const InsetGraphics::prepareFile(Buffer const * buf, // 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; + return RemoveExtension(orig_file); + return orig_file; } // We're going to be running the exported buffer through the LaTeX @@ -617,34 +406,16 @@ string const InsetGraphics::prepareFile(Buffer const * buf, // 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; 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; - - // 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) { - string str = bformat(_("Could not copy the file\n%1$s\n" - "into the temporary directory."), orig_file_with_path); - Alert::error(_("Graphics display failed"), str); - return orig_file; - } + temp_file = copyFileToDir(buf->tmppath, orig_file); + if (temp_file.empty()) { + string str = bformat(_("Could not copy the file\n%1$s\n" + "into the temporary directory."), + orig_file); + Alert::error(_("Graphics display failed"), str); + return orig_file; } if (from == to) { @@ -678,7 +449,7 @@ string const InsetGraphics::prepareFile(Buffer const * buf, one.startscript(Systemcall::Wait, command); if (!IsFileReadable(ChangeExtension(outfile_base, to))) { string str = bformat(_("No information for converting %1$s " - "format files to %1$s.\n" + "format files to %2$s.\n" "Try defining a convertor in the preferences."), from, to); Alert::error(_("Could not convert image"), str); } @@ -697,9 +468,12 @@ int InsetGraphics::latex(Buffer const * buf, ostream & os, << "insetgraphics::latex: Filename = " << params().filename << endl; + string const relative_file = MakeRelPath(params().filename, 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; bool const file_exists = !file_.empty() && (IsFileReadable(file_) || // original @@ -743,7 +517,7 @@ 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 (runparams.nice) { - os << before <<'{' << params().filename << '}' << after; + os << before <<'{' << relative_file << '}' << after; return 1; } @@ -752,9 +526,11 @@ int InsetGraphics::latex(Buffer const * buf, ostream & os, // appropriate (when there are several versions in different formats) string const latex_str = message.empty() ? (before + '{' + os::external_path(prepareFile(buf, runparams)) + '}' + after) : - (before + '{' + params().filename + " not found!}" + 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); } @@ -780,7 +556,7 @@ int InsetGraphics::linuxdoc(Buffer const *, ostream &) const // 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 @@ -808,15 +584,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()) @@ -825,8 +593,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; @@ -839,6 +607,12 @@ InsetGraphicsParams const & InsetGraphics::params() const } +BufferView * InsetGraphics::view() const +{ + return graphic_->view(); +} + + string const InsetGraphicsMailer::name_("graphics"); InsetGraphicsMailer::InsetGraphicsMailer(InsetGraphics & inset) @@ -848,12 +622,16 @@ InsetGraphicsMailer::InsetGraphicsMailer(InsetGraphics & inset) string const InsetGraphicsMailer::inset2string() const { - return params2string(inset_.params()); + BufferView * bv = inset_.view(); + if (bv) + return params2string(inset_.params(), bv->buffer()->filePath()); + return string(); } void InsetGraphicsMailer::string2params(string const & in, - InsetGraphicsParams & params) + string const & buffer_path, + InsetGraphicsParams & params) { params = InsetGraphicsParams(); @@ -873,18 +651,19 @@ void InsetGraphicsMailer::string2params(string const & in, if (lex.isOK()) { InsetGraphics inset; - inset.readInsetGraphics(lex); + inset.readInsetGraphics(lex, buffer_path); params = inset.params(); } } string const -InsetGraphicsMailer::params2string(InsetGraphicsParams const & params) +InsetGraphicsMailer::params2string(InsetGraphicsParams const & params, + string const & buffer_path) { ostringstream data; data << name_ << ' '; - params.Write(data); + params.Write(data, buffer_path); data << "\\end_inset\n"; return STRCONV(data.str()); }