X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fgraphics%2FGraphicsCacheItem.cpp;h=4939874ab3b8512f9d6282a5595e17fe0b0628af;hb=f887efedf11c198d9b6cc19911fa0a32a93496f3;hp=3b7c3e871be2be59730e2d5f16e1669fcf1917fc;hpb=897436efbb9bd641b61467d185a2dfae9839e575;p=lyx.git diff --git a/src/graphics/GraphicsCacheItem.cpp b/src/graphics/GraphicsCacheItem.cpp index 3b7c3e871b..4939874ab3 100644 --- a/src/graphics/GraphicsCacheItem.cpp +++ b/src/graphics/GraphicsCacheItem.cpp @@ -4,7 +4,7 @@ * Licence details can be found in the file COPYING. * * \author Baruch Even - * \author Herbert Voß + * \author Herbert Voß * \author Angus Leeming * * Full author contact details are available in file CREDITS. @@ -13,36 +13,27 @@ #include #include "GraphicsCacheItem.h" + +#include "GraphicsCache.h" #include "GraphicsConverter.h" #include "GraphicsImage.h" #include "ConverterCache.h" -#include "debug.h" #include "Format.h" +#include "support/debug.h" +#include "support/FileName.h" #include "support/filetools.h" #include "support/FileMonitor.h" -#include "support/lyxlib.h" +#include "support/lassert.h" -#include +#include "support/bind.h" +using namespace std; +using namespace lyx::support; namespace lyx { -using support::FileMonitor; -using support::FileName; -using support::isFileReadable; -using support::makeDisplayPath; -using support::onlyFilename; -using support::tempName; -using support::unlink; -using support::unzipFile; -using support::zippedFile; - -using std::endl; -using std::string; - - namespace graphics { class CacheItem::Impl : public boost::signals::trackable { @@ -51,6 +42,13 @@ public: /// Impl(FileName const & file); + /** + * If no file conversion is needed, then tryDisplayFormat() calls + * loadImage() directly. + * \return true if a conversion is necessary and no error occurred. + */ + bool tryDisplayFormat(FileName & filename, string & from); + /** Start the image conversion process, checking first that it is * necessary. If it is necessary, then a conversion task is started. * CacheItem asumes that the conversion is asynchronous and so @@ -58,9 +56,6 @@ public: * is finished, this Signal is emitted, returning the converted * file to this->imageConverted. * - * If no file conversion is needed, then convertToDisplayFormat() calls - * loadImage() directly. - * * convertToDisplayFormat() will set the loading status flag as * approriate through calls to setStatus(). */ @@ -69,7 +64,7 @@ public: /** Load the image into memory. This is called either from * convertToDisplayFormat() direct or from imageConverted(). */ - void loadImage(); + bool loadImage(); /** Get a notification when the image conversion is done. * Connected to a signal on_finish_ which is passed to @@ -77,12 +72,6 @@ public: */ void imageConverted(bool); - /** Get a notification when the image loading is done. - * Connected to a signal on_finish_ which is passed to - * lyx::graphics::Image::loadImage. - */ - void imageLoaded(bool); - /** Sets the status of the loading process. Also notifies * listeners that the status has changed. */ @@ -119,16 +108,13 @@ public: bool remove_loaded_file_; /// The image and its loading status. - boost::shared_ptr image_; + shared_ptr image_; /// ImageStatus status_; /// This signal is emitted when the image loading status changes. boost::signal statusChanged; - /// The connection to the signal Image::finishedLoading - boost::signals::connection cl_; - /// The connection of the signal ConvProcess::finishedConversion, boost::signals::connection cc_; @@ -143,7 +129,9 @@ CacheItem::CacheItem(FileName const & file) CacheItem::~CacheItem() -{} +{ + delete pimpl_; +} FileName const & CacheItem::filename() const @@ -152,6 +140,20 @@ FileName const & CacheItem::filename() const } +bool CacheItem::tryDisplayFormat() const +{ + if (pimpl_->status_ != WaitingToLoad) + pimpl_->reset(); + FileName filename; + string from; + bool const conversion_needed = pimpl_->tryDisplayFormat(filename, from); + bool const success = status() == Loaded && !conversion_needed; + if (!success) + pimpl_->reset(); + return success; +} + + void CacheItem::startLoading() const { pimpl_->startLoading(); @@ -207,7 +209,7 @@ CacheItem::Impl::Impl(FileName const & file) remove_loaded_file_(false), status_(WaitingToLoad) { - monitor_.connect(boost::bind(&Impl::startLoading, this)); + monitor_.connect(bind(&Impl::startLoading, this)); } @@ -224,23 +226,20 @@ void CacheItem::Impl::reset() { zipped_ = false; if (!unzipped_filename_.empty()) - unlink(unzipped_filename_); + unzipped_filename_.removeFile(); unzipped_filename_.erase(); if (remove_loaded_file_ && !file_to_load_.empty()) - unlink(file_to_load_); + file_to_load_.removeFile(); remove_loaded_file_ = false; file_to_load_.erase(); to_.erase(); - if (image_.get()) + if (image_) image_.reset(); status_ = WaitingToLoad; - if (cl_.connected()) - cl_.disconnect(); - if (cc_.connected()) cc_.disconnect(); @@ -262,22 +261,21 @@ void CacheItem::Impl::setStatus(ImageStatus new_status) void CacheItem::Impl::imageConverted(bool success) { string const text = success ? "succeeded" : "failed"; - LYXERR(Debug::GRAPHICS) << "Image conversion " << text << '.' << endl; + LYXERR(Debug::GRAPHICS, "Image conversion " << text << '.'); file_to_load_ = converter_.get() ? FileName(converter_->convertedFile()) : FileName(); converter_.reset(); cc_.disconnect(); - success = !file_to_load_.empty() && isFileReadable(file_to_load_); + success = !file_to_load_.empty() && file_to_load_.isReadableFile(); if (!success) { - LYXERR(Debug::GRAPHICS) << "Unable to find converted file!" - << endl; + LYXERR(Debug::GRAPHICS, "Unable to find converted file!"); setStatus(ErrorConverting); if (zipped_) - unlink(unzipped_filename_); + unzipped_filename_.removeFile(); return; } @@ -285,57 +283,40 @@ void CacheItem::Impl::imageConverted(bool success) // Add the converted file to the file cache ConverterCache::get().add(filename_, to_, file_to_load_); - loadImage(); + setStatus(loadImage() ? Loaded : ErrorLoading); } // This function gets called from the callback after the image has been // converted successfully. -void CacheItem::Impl::loadImage() +bool CacheItem::Impl::loadImage() { - setStatus(Loading); - LYXERR(Debug::GRAPHICS) << "Loading image." << endl; - - image_ = Image::newImage(); - - cl_.disconnect(); - cl_ = image_->finishedLoading.connect( - boost::bind(&Impl::imageLoaded, this, _1)); - image_->load(file_to_load_); -} + LYXERR(Debug::GRAPHICS, "Loading image."); + image_.reset(newImage()); -void CacheItem::Impl::imageLoaded(bool success) -{ + bool success = image_->load(file_to_load_); string const text = success ? "succeeded" : "failed"; - LYXERR(Debug::GRAPHICS) << "Image loading " << text << '.' << endl; + LYXERR(Debug::GRAPHICS, "Image loading " << text << '.'); // Clean up after loading. if (zipped_) - unlink(unzipped_filename_); + unzipped_filename_.removeFile(); if (remove_loaded_file_ && unzipped_filename_ != file_to_load_) - unlink(file_to_load_); + file_to_load_.removeFile(); - cl_.disconnect(); - - if (!success) { - setStatus(ErrorLoading); - return; - } - - // Inform the outside world. - setStatus(Loaded); + return success; } static string const findTargetFormat(string const & from) { - typedef lyx::graphics::Image::FormatList FormatList; - FormatList const formats = lyx::graphics::Image::loadableFormats(); + typedef vector FormatList; + FormatList const & formats = Cache::get().loadableFormats(); // There must be a format to load from. - BOOST_ASSERT(!formats.empty()); + LASSERT(!formats.empty(), return string()); // Use the standard converter if we don't know the format to load // from. @@ -356,9 +337,8 @@ static string const findTargetFormat(string const & from) if (lyx::graphics::Converter::isReachable(from, *it)) return *it; else - LYXERR(Debug::GRAPHICS) - << "Unable to convert from " << from - << " to " << *it << std::endl; + LYXERR(Debug::GRAPHICS, "Unable to convert from " << from + << " to " << *it); } // Failed! so we have to try to convert it to PPM format @@ -367,83 +347,89 @@ static string const findTargetFormat(string const & from) } -void CacheItem::Impl::convertToDisplayFormat() +bool CacheItem::Impl::tryDisplayFormat(FileName & filename, string & from) { - setStatus(Converting); - // First, check that the file exists! - if (!isFileReadable(filename_)) { + filename_.refresh(); + if (!filename_.isReadableFile()) { if (status_ != ErrorNoFile) { - setStatus(ErrorNoFile); - LYXERR(Debug::GRAPHICS) - << "\tThe file is not readable" << endl; + status_ = ErrorNoFile; + LYXERR(Debug::GRAPHICS, "\tThe file is not readable"); } - return; + return false; } - // Make a local copy in case we unzip it - FileName filename; - zipped_ = zippedFile(filename_); + zipped_ = formats.isZippedFile(filename_); if (zipped_) { - unzipped_filename_ = tempName(FileName(), filename_.toFilesystemEncoding()); + unzipped_filename_ = FileName::tempName( + filename_.toFilesystemEncoding()); if (unzipped_filename_.empty()) { - setStatus(ErrorConverting); - LYXERR(Debug::GRAPHICS) - << "\tCould not create temporary file." << endl; - return; + status_ = ErrorConverting; + LYXERR(Debug::GRAPHICS, "\tCould not create temporary file."); + return false; } filename = unzipFile(filename_, unzipped_filename_.toFilesystemEncoding()); - } else + } else { filename = filename_; + } - docstring const displayed_filename = makeDisplayPath(filename_.absFilename()); - LYXERR(Debug::GRAPHICS) << "[graphics::CacheItem::Impl::convertToDisplayFormat]\n" + docstring const displayed_filename = makeDisplayPath(filename_.absFileName()); + LYXERR(Debug::GRAPHICS, "[CacheItem::Impl::convertToDisplayFormat]\n" << "\tAttempting to convert image file: " << filename - << "\n\twith displayed filename: " << lyx::to_utf8(displayed_filename) - << endl; + << "\n\twith displayed filename: " << to_utf8(displayed_filename)); - string const from = formats.getFormatFromFile(filename); + from = formats.getFormatFromFile(filename); if (from.empty()) { - setStatus(ErrorConverting); - LYXERR(Debug::GRAPHICS) - << "\tCould not determine file format." << endl; + status_ = ErrorConverting; + LYXERR(Debug::GRAPHICS, "\tCould not determine file format."); } - LYXERR(Debug::GRAPHICS) - << "\n\tThe file contains " << from << " format data." << endl; + LYXERR(Debug::GRAPHICS, "\n\tThe file contains " << from << " format data."); to_ = findTargetFormat(from); if (from == to_) { // No conversion needed! - LYXERR(Debug::GRAPHICS) << "\tNo conversion needed (from == to)!" << endl; + LYXERR(Debug::GRAPHICS, "\tNo conversion needed (from == to)!"); file_to_load_ = filename; - loadImage(); - return; + status_ = loadImage() ? Loaded : ErrorLoading; + return false; } if (ConverterCache::get().inCache(filename, to_)) { - LYXERR(Debug::GRAPHICS) << "\tNo conversion needed (file in file cache)!" - << endl; + LYXERR(Debug::GRAPHICS, "\tNo conversion needed (file in file cache)!"); file_to_load_ = ConverterCache::get().cacheName(filename, to_); - loadImage(); + status_ = loadImage() ? Loaded : ErrorLoading; + return false; + } + return true; +} + + +void CacheItem::Impl::convertToDisplayFormat() +{ + LYXERR(Debug::GRAPHICS, "\tConverting it to " << to_ << " format."); + + // Make a local copy in case we unzip it + FileName filename; + string from; + if (!tryDisplayFormat(filename, from)) { + // The image status has changed, tell it to the outside world. + statusChanged(); return; } - LYXERR(Debug::GRAPHICS) << "\tConverting it to " << to_ << " format." << endl; + // We will need a conversion, tell it to the outside world. + setStatus(Converting); // Add some stuff to create a uniquely named temporary file. // This file is deleted in loadImage after it is loaded into memory. - FileName const to_file_base(tempName(FileName(), "CacheItem")); + FileName const to_file_base = FileName::tempName("CacheItem"); remove_loaded_file_ = true; - // Remove the temp file, we only want the name... - // FIXME: This is unsafe! - unlink(to_file_base); - // Connect a signal to this->imageConverted and pass this signal to // the graphics converter so that we can load the modified file // on completion of the conversion process. - converter_.reset(new Converter(filename, to_file_base.absFilename(), from, to_)); - converter_->connect(boost::bind(&Impl::imageConverted, this, _1)); + converter_.reset(new Converter(filename, to_file_base.absFileName(), from, to_)); + converter_->connect(bind(&Impl::imageConverted, this, _1)); converter_->startConversion(); }