-/*
+/**
* \file GraphicsCache.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 <baruch.even@writeme.com>
- * \author Angus Leeming <a.leeming@ic.ac.uk>
+ * \author Baruch Even
+ * \author Angus Leeming
+ *
+ * Full author contact details are available in file CREDITS.
*/
#include <config.h>
-#ifdef __GNUG__
-#pragma implementation
-#endif
-
#include "GraphicsCache.h"
#include "GraphicsCacheItem.h"
#include "GraphicsImage.h"
-#include "GraphicsParams.h"
-#include "insets/insetgraphics.h"
+#include "debug.h"
-// I think that graphicsInit should become a new Dialogs::graphicsInit
-// static method.
-// These #includes would then be moved to Dialogs.C.
-// Angus 25 Feb 2002
-#include "GraphicsImageXPM.h"
-//#include "xformsGraphicsImage.h"
+#include "support/filetools.h"
-namespace {
+#include <map>
-void graphicsInit()
-{
- using namespace grfx;
- using SigC::slot;
-
- // connect the image loader based on the XPM library
- GImage::newImage.connect(slot(&GImageXPM::newImage));
- GImage::loadableFormats.connect(slot(&GImageXPM::loadableFormats));
- // connect the image loader based on the xforms library
-// GImage::newImage.connect(slot(&xformsGImage::newImage));
-// GImage::loadableFormats.connect(slot(&xformsGImage::loadableFormats));
-}
-
-} // namespace anon
-
+using std::string;
-namespace grfx {
-GCache & GCache::get()
-{
- static bool start = true;
- if (start) {
- start = false;
- graphicsInit();
- }
+namespace lyx {
- // Now return the cache
- static GCache singleton;
- return singleton;
-}
+using support::FileName;
+namespace graphics {
-GCache::GCache()
-{
- cache = new CacheType;
-}
+/** The cache contains one item per file, so use a map to find the
+ * cache item quickly by filename.
+ */
+typedef std::map<FileName, Cache::ItemPtr> CacheType;
+class Cache::Impl {
+public:
+ ///
+ CacheType cache;
+};
-// all elements are destroyed by the shared_ptr's in the map.
-GCache::~GCache()
+
+Cache & Cache::get()
{
- delete cache;
+ // Now return the cache
+ static Cache singleton;
+ return singleton;
}
-void GCache::update(InsetGraphics const & inset)
-{
- // A subset only of InsetGraphicsParams is needed for display purposes.
- // The GraphicsParams c-tor also interrogates lyxrc to ascertain whether
- // to display or not.
- GParams params(inset.params());
-
- // Each inset can reference only one file, so check the cache for any
- // graphics files referenced by inset. If the name of this file is
- // different from that in params, then remove the reference.
- CacheType::iterator it = find(inset);
-
- if (it != cache->end()) {
- CacheItemType item = it->second;
- if (item->filename() != params.filename) {
- item->remove(inset);
- if (item->empty())
- cache->erase(it);
- }
- }
-
- // Are we adding a new file or modifying the display of an existing one?
- it = cache->find(params.filename);
+Cache::Cache()
+ : pimpl_(new Impl)
+{}
- if (it != cache->end()) {
- it->second->modify(inset, params);
- return;
- }
- CacheItemType item(new GCacheItem(inset, params));
- if (item.get() != 0)
- (*cache)[params.filename] = item;
-}
+Cache::~Cache()
+{}
-void GCache::remove(InsetGraphics const & inset)
+std::vector<string> Cache::loadableFormats() const
{
- CacheType::iterator it = find(inset);
- if (it == cache->end())
- return;
-
- CacheItemType item = it->second;
- item->remove(inset);
- if (item->empty()) {
- cache->erase(it);
- }
+ return Image::loadableFormats();
}
-void GCache::startLoading(InsetGraphics const & inset)
+void Cache::add(FileName const & file) const
{
- CacheType::iterator it = find(inset);
- if (it == cache->end())
+ // Is the file in the cache already?
+ if (inCache(file)) {
+ lyxerr[Debug::GRAPHICS] << "Cache::add(" << file << "):\n"
+ << "The file is already in the cache."
+ << std::endl;
return;
+ }
- it->second->startLoading(inset);
+ pimpl_->cache[file] = ItemPtr(new CacheItem(file));
}
-ImagePtr const GCache::image(InsetGraphics const & inset) const
+void Cache::remove(FileName const & file) const
{
- CacheType::const_iterator it = find(inset);
- if (it == cache->end())
- return ImagePtr();
-
- return it->second->image(inset);
-}
-
+ CacheType::iterator it = pimpl_->cache.find(file);
+ if (it == pimpl_->cache.end())
+ return;
-ImageStatus GCache::status(InsetGraphics const & inset) const
-{
- CacheType::const_iterator it = find(inset);
- if (it == cache->end())
- return ErrorUnknown;
+ ItemPtr & item = it->second;
- return it->second->status(inset);
+ if (item.use_count() == 1) {
+ // The graphics file is in the cache, but nothing else
+ // references it.
+ pimpl_->cache.erase(it);
+ }
}
-void GCache::changeDisplay(bool changed_background)
+bool Cache::inCache(FileName const & file) const
{
- CacheType::iterator it = cache->begin();
- CacheType::iterator end = cache->end();
- for(; it != end; ++it)
- it->second->changeDisplay(changed_background);
+ return pimpl_->cache.find(file) != pimpl_->cache.end();
}
-GCache::CacheType::iterator
-GCache::find(InsetGraphics const & inset)
+Cache::ItemPtr const Cache::item(FileName const & file) const
{
- CacheType::iterator it = cache->begin();
- for (; it != cache->end(); ++it) {
- if (it->second->referencedBy(inset))
- return it;
- }
-
- return cache->end();
-}
-
+ CacheType::const_iterator it = pimpl_->cache.find(file);
+ if (it == pimpl_->cache.end())
+ return ItemPtr();
-GCache::CacheType::const_iterator
-GCache::find(InsetGraphics const & inset) const
-{
- CacheType::const_iterator it = cache->begin();
- for (; it != cache->end(); ++it) {
- if (it->second->referencedBy(inset))
- return it;
- }
-
- return cache->end();
+ return it->second;
}
-} // namespace grfx
+} // namespace graphics
+} // namespace lyx