X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fgraphics%2FGraphicsCacheItem.C;h=59973327d441815b6bbf1ff202eb94fc5f7c8e6c;hb=33243f70037b067f90d1574b74b34f90a2ef2aa1;hp=4bc078a838b933b07ec4acd58affe49edb7592cd;hpb=1e394731004491d04abe436112b5a89521bbd19a;p=lyx.git diff --git a/src/graphics/GraphicsCacheItem.C b/src/graphics/GraphicsCacheItem.C index 4bc078a838..59973327d4 100644 --- a/src/graphics/GraphicsCacheItem.C +++ b/src/graphics/GraphicsCacheItem.C @@ -1,382 +1,315 @@ -/* +/** * \file GraphicsCacheItem.C - * Copyright 2002 the LyX Team - * Read the file COPYING + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. * - * \author Baruch Even - * \author Herbert Voss - * \author Angus Leeming + * \author Baruch Even + * \author Herbert Voß + * \author Angus Leeming + * + * Full author contact details are available in file CREDITS. */ #include -#ifdef __GNUG__ -#pragma implementation -#endif - -#include "graphics/GraphicsCache.h" -#include "graphics/GraphicsCacheItem.h" -#include "graphics/GraphicsImage.h" -#include "graphics/GraphicsParams.h" -#include "graphics/GraphicsConverter.h" - -#include "insets/insetgraphics.h" +#include "GraphicsCacheItem.h" +#include "GraphicsConverter.h" +#include "GraphicsImage.h" -#include "BufferView.h" #include "debug.h" -#include "gettext.h" -#include "lyx_main.h" // for global dispatch method -#include "support/LAssert.h" #include "support/filetools.h" +#include "support/FileMonitor.h" +#include "support/lyxlib.h" #include -// Very, Very UGLY! -extern BufferView * current_view; - -using std::endl; - -namespace grfx { +namespace support = lyx::support; -GCacheItem::GCacheItem(InsetGraphics const & inset, GParams const & params) - : filename_(params.filename), zipped_(false), - remove_loaded_file_(false), status_(WaitingToLoad) -{ - ModifiedItemPtr item(new ModifiedItem(inset, params, image_)); - modified_images.push_back(item); -} - - -namespace { +using support::ChangeExtension; +using support::FileMonitor; +using support::IsFileReadable; +using support::MakeDisplayPath; +using support::OnlyFilename; +using support::getExtFromContents; +using support::tempName; +using support::unlink; +using support::unzipFile; +using support::unzippedFileName; +using support::zippedFile; -typedef GCacheItem::ModifiedItemPtr ModifiedItemPtr; - -class Compare_Params { -public: - Compare_Params(GParams const & p) : p_(p) {} - - bool operator()(ModifiedItemPtr const & ptr) - { - if (!ptr.get()) - return false; - return ptr->params() == p_; - } - -private: - GParams const & p_; +using std::endl; +using std::string; + + +namespace lyx { +namespace graphics { + +struct CacheItem::Impl : public boost::signals::trackable { + + /// + Impl(string const & file); + + /** 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 + * passes a Signal to the converting routine. When the conversion + * 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(). + */ + void convertToDisplayFormat(); + + /** Load the image into memory. This is called either from + * convertToDisplayFormat() direct or from imageConverted(). + */ + void loadImage(); + + /** Get a notification when the image conversion is done. + * Connected to a signal on_finish_ which is passed to + * Converter::convert. + */ + 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. + */ + void setStatus(ImageStatus new_status); + + /** Can be invoked directly by the user, but is also connected to the + * FileMonitor and so is invoked when the file is changed + * (if monitoring is taking place). + */ + void startLoading(); + + /** If we are asked to load the file for a second or further time, + * (because the file has changed), then we'll have to first reset + * many of the variables below. + */ + void reset(); + + /// The filename we refer too. + string const filename_; + /// + FileMonitor const monitor_; + + /// Is the file compressed? + bool zipped_; + /// If so, store the uncompressed file in this temporary file. + string unzipped_filename_; + /// What file are we trying to load? + string file_to_load_; + /** Should we delete the file after loading? True if the file is + * the result of a conversion process. + */ + bool remove_loaded_file_; + + /// The image and its loading status. + boost::shared_ptr image_; + /// + ImageStatus status_; + + /// This signal is emitted when the image loading status changes. + boost::signal0 statusChanged; + + /// The connection to the signal Image::finishedLoading + boost::signals::connection cl_; + + /// The connection of the signal ConvProcess::finishedConversion, + boost::signals::connection cc_; + + /// + boost::scoped_ptr converter_; }; -class Find_Inset { -public: - Find_Inset(InsetGraphics const & i) : i_(i) {} - bool operator()(ModifiedItemPtr const & ptr) - { - if (!ptr.get()) - return false; - return ptr->referencedBy(i_); - } +CacheItem::CacheItem(string const & file) + : pimpl_(new Impl(file)) +{} -private: - InsetGraphics const & i_; -}; -} // namespace anon +CacheItem::~CacheItem() +{} -void GCacheItem::modify(InsetGraphics const & inset, GParams const & params) +string const & CacheItem::filename() const { - // Does this inset currently reference an existing ModifiedItem with - // different params? - // If so, remove the inset from the ModifiedItem's internal list - // of insets - ListType::iterator begin = modified_images.begin(); - ListType::iterator end = modified_images.end(); - ListType::iterator it = begin; - while (it != end) { - it = std::find_if(it, end, Find_Inset(inset)); - if (it == end) - break; - if ((*it)->params() != params) { - (*it)->remove(inset); - if ((*it)->empty()) - it = modified_images.erase(it); - } - ++it; - } - - // Is there an existing ModifiedItem with these params? - // If so, add inset to the list of insets referencing this ModifiedItem - begin = modified_images.begin(); - end = modified_images.end(); - it = std::find_if(begin, end, Compare_Params(params)); - if (it != end) { - (*it)->add(inset); - return; - } - - // If no ModifiedItem exists with these params, then create one. - ModifiedItemPtr item(new ModifiedItem(inset, params, image_)); - modified_images.push_back(item); - - return; + return pimpl_->filename_; } -void GCacheItem::remove(InsetGraphics const & inset) +void CacheItem::startLoading() const { - // search the list of ModifiedItems for one referenced by this inset. - // If it is found, remove the reference. - // If the ModifiedItem is now referenced by no insets, remove it. - ListType::iterator begin = modified_images.begin(); - ListType::iterator end = modified_images.end(); - ListType::iterator it = std::find_if(begin, end, Find_Inset(inset)); - - if (it == end) - return; - - (*it)->remove(inset); - if ((*it)->empty()) { - modified_images.clear(); - } + pimpl_->startLoading(); } -void GCacheItem::startLoading(InsetGraphics const & inset) +void CacheItem::startMonitoring() const { - if (status() != WaitingToLoad) - return; - - // Check that the image is referenced by this inset - ListType::const_iterator begin = modified_images.begin(); - ListType::const_iterator end = modified_images.end(); - ListType::const_iterator it = - std::find_if(begin, end, Find_Inset(inset)); - - if (it == end) - return; - - if ((*it)->params().display == GParams::NONE) - return; - - convertToDisplayFormat(); + if (!pimpl_->monitor_.monitoring()) + pimpl_->monitor_.start(); } -bool GCacheItem::empty() const +bool CacheItem::monitoring() const { - return modified_images.empty(); + return pimpl_->monitor_.monitoring(); } -bool GCacheItem::referencedBy(InsetGraphics const & inset) const +unsigned long CacheItem::checksum() const { - // Is one of the list of ModifiedItems referenced by this inset? - ListType::const_iterator begin = modified_images.begin(); - ListType::const_iterator end = modified_images.end(); - return std::find_if(begin, end, Find_Inset(inset)) != end; + return pimpl_->monitor_.checksum(); } -string const & GCacheItem::filename() const +Image const * CacheItem::image() const { - return filename_; + return pimpl_->image_.get(); } -ImagePtr const GCacheItem::image(InsetGraphics const & inset) const +ImageStatus CacheItem::status() const { - // find a ModifiedItem that is referenced by this inset. - ListType::const_iterator begin = modified_images.begin(); - ListType::const_iterator end = modified_images.end(); - ListType::const_iterator it = - std::find_if(begin, end, Find_Inset(inset)); - - // Someone's being daft. - if (it == end) - return ImagePtr(); - - // We are expressly requested to not render the image - if ((*it)->params().display == GParams::NONE) - return ImagePtr(); - - // If the original image has been loaded, return what's going on - // in the ModifiedItem - if (status() == Loaded) - return (*it)->image(); - - return ImagePtr(); + return pimpl_->status_; } -ImageStatus GCacheItem::status(InsetGraphics const & inset) const +boost::signals::connection CacheItem::connect(slot_type const & slot) const { - // find a ModifiedItem that is referenced by this inset. - ListType::const_iterator begin = modified_images.begin(); - ListType::const_iterator end = modified_images.end(); - ListType::const_iterator it = - std::find_if(begin, end, Find_Inset(inset)); - - // Someone's being daft. - if (it == end) - return ErrorUnknown; + return pimpl_->statusChanged.connect(slot); +} - if (status() == Loaded) - return (*it)->status(); - return status(); -} +//------------------------------ +// Implementation details follow +//------------------------------ -// Called internally only. Use to ascertain the status of the loading of the -// original image. No scaling etc. -ImageStatus GCacheItem::status() const +CacheItem::Impl::Impl(string const & file) + : filename_(file), + monitor_(file, 2000), + zipped_(false), + remove_loaded_file_(false), + status_(WaitingToLoad) { - return status_; + monitor_.connect(boost::bind(&Impl::startLoading, this)); } -void GCacheItem::setStatus(ImageStatus new_status) +void CacheItem::Impl::startLoading() { - status_ = new_status; + if (status_ != WaitingToLoad) + reset(); - // Loop over all insets and tell the BufferView that it has changed. - typedef ModifiedItem::ListType::const_iterator inset_iterator; - - ListType::const_iterator it = modified_images.begin(); - ListType::const_iterator end = modified_images.end(); - for (; it != end; ++it) { - inset_iterator it2 = (*it)->insets.begin(); - inset_iterator end2 = (*it)->insets.end(); - - for (; it2 != end2; ++it2) { - InsetGraphics * inset = - const_cast(*it2); - - // Use of current_view is very, very Evil!! - current_view->updateInset(inset, false); - } - } + convertToDisplayFormat(); } -void GCacheItem::changeDisplay(bool changed_background) +void CacheItem::Impl::reset() { - ListType::iterator begin = modified_images.begin(); - ListType::iterator end = modified_images.end(); + zipped_ = false; + if (!unzipped_filename_.empty()) + unlink(unzipped_filename_); + unzipped_filename_.erase(); - // The background has changed. Change all modified images. - if (changed_background) { - for (ListType::iterator it = begin; it != end; ++it) { - (*it)->setPixmap(); - } - return; - } + if (remove_loaded_file_ && !file_to_load_.empty()) + unlink(file_to_load_); + remove_loaded_file_ = false; + file_to_load_.erase(); - ListType temp_list; + if (image_.get()) + image_.reset(); - for (ListType::iterator it = begin; it != end; ++it) { - // ModifiedItem::changeDisplay returns a full - // ModifiedItemPtr if any of the insets have display=DEFAULT - // and if that DEFAULT value has changed - ModifiedItemPtr new_item = (*it)->changeDisplay(); - if (!new_item.get()) - continue; + status_ = WaitingToLoad; - temp_list.push_back(new_item); + if (cl_.connected()) + cl_.disconnect(); - // The original store may now be empty - if ((*it)->insets.empty()) { - it = modified_images.erase(it); - } - } + if (cc_.connected()) + cc_.disconnect(); - if (temp_list.empty()) - return; - - // Recombine new_list and modified_images. - begin = modified_images.begin(); - end = modified_images.end(); - - ListType::const_iterator tbegin = temp_list.begin(); - ListType::const_iterator tend = temp_list.end(); - - ListType append_list; + if (converter_.get()) + converter_.reset(); +} - for (ListType::const_iterator tit = tbegin; tit != tend; ++tit) { - GParams const & params = (*tit)->params(); - ListType::iterator it = - std::find_if(begin, end, Compare_Params(params)); - if (it == end) - append_list.push_back(*tit); - else - (*it)->insets.merge((*tit)->insets); - } - if (append_list.empty()) +void CacheItem::Impl::setStatus(ImageStatus new_status) +{ + if (status_ == new_status) return; - modified_images.splice(modified_images.end(), append_list); + status_ = new_status; + statusChanged(); } -void GCacheItem::imageConverted(string const & file_to_load) +void CacheItem::Impl::imageConverted(bool success) { - bool const success = - (!file_to_load.empty() && IsFileReadable(file_to_load)); - string const text = success ? "succeeded" : "failed"; - lyxerr[Debug::GRAPHICS] << "Image conversion " << text << "." << endl; + lyxerr[Debug::GRAPHICS] << "Image conversion " << text << '.' << endl; + + file_to_load_ = converter_.get() ? + converter_->convertedFile() : string(); + converter_.reset(); + cc_.disconnect(); + + success = !file_to_load_.empty() && IsFileReadable(file_to_load_); if (!success) { + lyxerr[Debug::GRAPHICS] << "Unable to find converted file!" + << endl; setStatus(ErrorConverting); if (zipped_) - lyx::unlink(unzipped_filename_); + unlink(unzipped_filename_); return; } - cc_.disconnect(); - - // Do the actual image loading from file to memory. - file_to_load_ = file_to_load; - loadImage(); } // This function gets called from the callback after the image has been // converted successfully. -void GCacheItem::loadImage() +void CacheItem::Impl::loadImage() { setStatus(Loading); lyxerr[Debug::GRAPHICS] << "Loading image." << endl; - // Connect a signal to this->imageLoaded and pass this signal to - // GImage::loadImage. - SignalLoadTypePtr on_finish; - on_finish.reset(new SignalLoadType); - cl_ = on_finish->connect(boost::bind(&GCacheItem::imageLoaded, this, _1)); + image_ = Image::newImage(); - image_ = GImage::newImage(); - image_->load(file_to_load_, on_finish); + cl_.disconnect(); + cl_ = image_->finishedLoading.connect( + boost::bind(&Impl::imageLoaded, this, _1)); + image_->load(file_to_load_); } -void GCacheItem::imageLoaded(bool success) +void CacheItem::Impl::imageLoaded(bool success) { string const text = success ? "succeeded" : "failed"; - lyxerr[Debug::GRAPHICS] << "Image loading " << text << "." << endl; + lyxerr[Debug::GRAPHICS] << "Image loading " << text << '.' << endl; // Clean up after loading. if (zipped_) - lyx::unlink(unzipped_filename_); + unlink(unzipped_filename_); if (remove_loaded_file_ && unzipped_filename_ != file_to_load_) - lyx::unlink(file_to_load_); + unlink(file_to_load_); cl_.disconnect(); @@ -385,299 +318,122 @@ void GCacheItem::imageLoaded(bool success) return; } + // Inform the outside world. setStatus(Loaded); - - // Loop over the list of modified images and create them. - ListType::iterator it = modified_images.begin(); - ListType::iterator end = modified_images.end(); - for (; it != end; ++it) { - (*it)->modify(image_); - } -} - - -unsigned int GCacheItem::raw_width() const -{ - if (!image_.get()) - return 0; - - return image_->getWidth(); } -unsigned int GCacheItem::raw_height() const -{ - if (!image_.get()) - return 0; - - return image_->getHeight(); -} +} // namespace graphics +} // namespace lyx namespace { string const findTargetFormat(string const & from) { - typedef GImage::FormatList FormatList; - FormatList const formats = GImage::loadableFormats(); + typedef lyx::graphics::Image::FormatList FormatList; + FormatList const formats = lyx::graphics::Image::loadableFormats(); // There must be a format to load from. - lyx::Assert(!formats.empty()); + BOOST_ASSERT(!formats.empty()); // First ascertain if we can load directly with no conversion - FormatList::const_iterator it1 = formats.begin(); + FormatList::const_iterator it = formats.begin(); FormatList::const_iterator end = formats.end(); - for (; it1 != end; ++it1) { - if (from == *it1) - return *it1; + for (; it != end; ++it) { + if (from == *it) + return *it; } // So, we have to convert to a loadable format. Can we? - grfx::GConverter const & graphics_converter = grfx::GConverter::get(); - - FormatList::const_iterator it2 = formats.begin(); - for (; it2 != end; ++it2) { - if (graphics_converter.isReachable(from, *it2)) - return *it2; + it = formats.begin(); + for (; it != end; ++it) { + if (lyx::graphics::Converter::isReachable(from, *it)) + return *it; + else + lyxerr[Debug::GRAPHICS] + << "Unable to convert from " << from + << " to " << *it << std::endl; } - // Failed! - return string(); + // Failed! so we have to try to convert it to PPM format + // with the standard converter + return string("ppm"); } } // anon namespace -void GCacheItem::convertToDisplayFormat() +namespace lyx { +namespace graphics { + +void CacheItem::Impl::convertToDisplayFormat() { setStatus(Converting); - string filename = filename_; // Make a local copy in case we unzip it - string const displayed_filename = MakeDisplayPath(filename_); // First, check that the file exists! - if (!IsFileReadable(filename)) { - setStatus(ErrorNoFile); + if (!IsFileReadable(filename_)) { + if (status_ != ErrorNoFile) { + setStatus(ErrorNoFile); + lyxerr[Debug::GRAPHICS] + << "\tThe file is not readable" << endl; + } return; } -// maybe that other zip extensions also be useful, especially the -// ones that may be declared in texmf/tex/latex/config/graphics.cfg. -// for example: -/* -----------snip------------- - {\DeclareGraphicsRule{.pz}{eps}{.bb}{}% - \DeclareGraphicsRule{.eps.Z}{eps}{.eps.bb}{}% - \DeclareGraphicsRule{.ps.Z}{eps}{.ps.bb}{}% - \DeclareGraphicsRule{.ps.gz}{eps}{.ps.bb}{}% - \DeclareGraphicsRule{.eps.gz}{eps}{.eps.bb}{}}}% - -----------snip-------------*/ - - lyxerr[Debug::GRAPHICS] - << "Attempting to convert image file: " << displayed_filename - << "\nwith recognised extension: " << GetExtension(filename) - << "." << endl; - - zipped_ = zippedFile(filename); - if (zipped_) { - filename = unzipFile(filename); - unzipped_filename_ = filename; - } + // Make a local copy in case we unzip it + string filename; + if ((zipped_ = zippedFile(filename_))) { + unzipped_filename_ = tempName(string(), filename_); + if (unzipped_filename_.empty()) { + setStatus(ErrorConverting); + lyxerr[Debug::GRAPHICS] + << "\tCould not create temporary file." << endl; + return; + } + filename = unzipFile(filename_, unzipped_filename_); + } else + filename = filename_; - string const from = getExtFromContents(filename); - string const to = grfx::findTargetFormat(from); + string const displayed_filename = MakeDisplayPath(filename_); + lyxerr[Debug::GRAPHICS] << "[GrahicsCacheItem::convertToDisplayFormat]\n" + << "\tAttempting to convert image file: " << filename + << "\n\twith displayed filename: " << displayed_filename + << endl; + string from = getExtFromContents(filename); lyxerr[Debug::GRAPHICS] - << "The file contains " << from << " format data." << endl; - - if (to.empty()) { - setStatus(ErrorConverting); - return; - } + << "\n\tThe file contains " << from << " format data." << endl; + string const to = findTargetFormat(from); if (from == to) { // No conversion needed! - lyxerr[Debug::GRAPHICS] << "No conversion needed!" << endl; + lyxerr[Debug::GRAPHICS] << "\tNo conversion needed (from == to)!" << endl; file_to_load_ = filename; loadImage(); return; } - lyxerr[Debug::GRAPHICS] << "Converting it to " << to << " format." << endl; - + lyxerr[Debug::GRAPHICS] << "\tConverting it to " << to << " format." << endl; // Take only the filename part of the file, without path or extension. string const temp = ChangeExtension(OnlyFilename(filename), string()); // Add some stuff to create a uniquely named temporary file. // This file is deleted in loadImage after it is loaded into memory. - string const to_file_base = lyx::tempName(string(), temp); + string const to_file_base = tempName(string(), temp); remove_loaded_file_ = true; // Remove the temp file, we only want the name... - lyx::unlink(to_file_base); + // 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. - SignalConvertTypePtr on_finish; - on_finish.reset(new SignalConvertType); - cc_ = on_finish->connect(boost::bind(&GCacheItem::imageConverted, this, _1)); - - GConverter & graphics_converter = GConverter::get(); - graphics_converter.convert(filename, to_file_base, from, to, on_finish); -} - - -ModifiedItem::ModifiedItem(InsetGraphics const & new_inset, - GParams const & new_params, - ImagePtr const & new_image) - : status_(ScalingEtc) -{ - p_.reset(new GParams(new_params)); - insets.push_back(&new_inset); - modify(new_image); -} - - -void ModifiedItem::add(InsetGraphics const & inset) -{ - insets.push_back(&inset); - insets.sort(); -} - - -void ModifiedItem::remove(InsetGraphics const & inset) -{ - ListType::iterator begin = insets.begin(); - ListType::iterator end = insets.end(); - ListType::iterator it = std::remove(begin, end, &inset); - insets.erase(it, end); -} - - -bool ModifiedItem::referencedBy(InsetGraphics const & inset) const -{ - ListType::const_iterator begin = insets.begin(); - ListType::const_iterator end = insets.end(); - return std::find(begin, end, &inset) != end; -} - - -ImagePtr const ModifiedItem::image() const -{ - if (modified_image_.get()) - return modified_image_; - - return original_image_; -} - - -void ModifiedItem::modify(ImagePtr const & new_image) -{ - if (!new_image.get()) - return; - - original_image_ = new_image; - modified_image_.reset(original_image_->clone()); - - if (params().display == GParams::NONE) { - setStatus(Loaded); - return; - } - - setStatus(ScalingEtc); - modified_image_->clip(params()); - modified_image_->rotate(params()); - modified_image_->scale(params()); - setPixmap(); -} - - -void ModifiedItem::setPixmap() -{ - if (!modified_image_.get()) - return; - - if (params().display == GParams::NONE) { - setStatus(Loaded); - return; - } - - bool const success = modified_image_->setPixmap(params()); - - if (success) { - setStatus(Loaded); - } else { - modified_image_.reset(); - setStatus(ErrorScalingEtc); - } -} - - -void ModifiedItem::setStatus(ImageStatus new_status) -{ - status_ = new_status; - - // Tell the BufferView that the inset has changed. - // Very, Very Ugly!! - ListType::const_iterator it = insets.begin(); - ListType::const_iterator end = insets.end(); - for (; it != end; ++it) { - InsetGraphics * inset = const_cast(*it); - current_view->updateInset(inset, false); - } -} - - -namespace { - -struct Params_Changed { - - Params_Changed(GParams const & p) : p_(p) {} - - bool operator()(InsetGraphics const * inset) - { - string const path = OnlyPath(p_.filename); - return inset->params().asGParams(path) != p_; - } - -private: - GParams p_; -}; - -} // namespace anon - -// changeDisplay returns an initialised ModifiedItem if any of the insets -// have display == DEFAULT and if that DEFAULT value has changed. -// If this occurs, then (this) has these insets removed. -ModifiedItemPtr ModifiedItem::changeDisplay() -{ - // Loop over the list of insets. Compare the updated params for each - // with params(). If different, move into a new list. - ListType::iterator begin = insets.begin(); - ListType::iterator end = insets.end(); - ListType::iterator it = - std::remove_if(begin, end, Params_Changed(params())); - - if (it == end) { - // No insets have changed params - return ModifiedItemPtr(); - } - - // it -> end have params that are changed. Move to the new list. - ListType new_insets; - new_insets.insert(new_insets.begin(), it, end); - insets.erase(it, end); - - // Create a new ModifiedItem with these new params. Note that - // the only params that have changed are the display ones, - // so we don't need to crop, rotate, scale. - string const path = OnlyPath(p_->filename); - - ModifiedItemPtr new_item(new ModifiedItem(*this)); - new_item->insets = new_insets; - *(new_item->p_) = (*new_insets.begin())->params().asGParams(path); - - new_item->setPixmap(); - return new_item; + converter_.reset(new Converter(filename, to_file_base, from, to)); + converter_->connect(boost::bind(&Impl::imageConverted, this, _1)); + converter_->startConversion(); } -} // namespace grfx +} // namespace graphics +} // namespace lyx