]> git.lyx.org Git - lyx.git/blobdiff - src/insets/insetgraphics.C
* Make the graphics files conform strictly to the Pimpl idiom by moving
[lyx.git] / src / insets / insetgraphics.C
index 5c2f2bbc6cb87571cafb6188832521fe41f63024..7cad1907e90471277e6568820d4e62212571b7d7 100644 (file)
@@ -78,9 +78,9 @@ TODO Before initial production release:
 #include "insets/insetgraphics.h"
 #include "insets/insetgraphicsParams.h"
 
-#include "graphics/GraphicsCache.h"
-#include "graphics/GraphicsCacheItem.h"
+#include "graphics/GraphicsLoader.h"
 #include "graphics/GraphicsImage.h"
+#include "graphics/GraphicsParams.h"
 
 #include "frontends/LyXView.h"
 #include "lyxtext.h"
@@ -103,8 +103,10 @@ TODO Before initial production release:
 #include "support/lyxalgo.h" // lyx::count
 #include "support/path.h"
 #include "support/systemcall.h"
+#include "support/os.h"
 
 #include <boost/bind.hpp>
+#include <boost/signals/trackable.hpp>
 
 #include <algorithm> // For the std::max
 
@@ -149,102 +151,28 @@ string const uniqueID()
 } // namespace anon
 
 
-struct InsetGraphics::Cache
+struct InsetGraphics::Cache : boost::signals::trackable
 {
        ///
        Cache(InsetGraphics &);
        ///
-       ~Cache();
-       ///
-       void reset(grfx::GraphicPtr const &);
-       ///
-       bool empty() const { return !graphic_.get(); }
-       ///
-       grfx::ImageStatus status() const;
-       ///
-       void setStatus(grfx::ImageStatus);
-       ///
-       grfx::GImage * image() const;
-       ///
-       string const filename() const;
-       ///
        void update(string const & file_with_path);
-       ///
-       void modify();
 
        ///
        int old_ascent;
        ///
-       grfx::GraphicPtr graphic_;
+       grfx::Loader loader;
 
 private:
-       /// The connection to cache_->statusChanged.
-       boost::signals::connection cc_;
-       ///
-       grfx::ImageStatus status_;
-       ///
-       grfx::GParams params_;
-       ///
-       grfx::ImagePtr modified_image_;
        ///
        InsetGraphics & parent_;
 };
 
 
 InsetGraphics::Cache::Cache(InsetGraphics & p)
-       : old_ascent(0), status_(grfx::ErrorUnknown), parent_(p)
-{}
-
-
-InsetGraphics::Cache::~Cache()
-{
-       string const old_file = filename();
-       graphic_.reset();
-
-       if (!old_file.empty()) {
-               grfx::GCache & gc = grfx::GCache::get();
-               gc.remove(old_file);
-       }
-}
-
-
-void InsetGraphics::Cache::reset(grfx::GraphicPtr const & graphic)
-{
-       string const old_file = filename();
-       string const new_file = graphic.get() ? graphic->filename() : string();
-       if (old_file == new_file)
-               return;
-
-       graphic_ = graphic;
-
-       if (!old_file.empty()) {
-               grfx::GCache & gc = grfx::GCache::get();
-               gc.remove(old_file);
-       }
-}
-
-
-grfx::ImageStatus InsetGraphics::Cache::status() const
-{
-       return status_;
-}
-
-
-void InsetGraphics::Cache::setStatus(grfx::ImageStatus new_status)
-{
-       status_ = new_status;
-}
-
-
-grfx::GImage * InsetGraphics::Cache::image() const
-{
-       return modified_image_.get();
-}
-
-
-string const InsetGraphics::Cache::filename() const
+       : old_ascent(0), parent_(p)
 {
-       return empty() ? string() : graphic_->filename();
+       loader.connect(boost::bind(&InsetGraphics::statusChanged, &parent_));
 }
 
 
@@ -252,64 +180,8 @@ void InsetGraphics::Cache::update(string const & file_with_path)
 {
        lyx::Assert(!file_with_path.empty());
 
-       // Check whether the file has changed.
-       string current_file = filename();
-
-       if (current_file == file_with_path) {
-               modify();
-               return;
-       }
-
-       // It /has/ changed.
-       // Remove the connection to any previous grfx::CacheItems
-       grfx::GCache & gc = grfx::GCache::get();
-       if (!current_file.empty() && gc.inCache(current_file)) {
-               graphic_.reset();
-               gc.remove(current_file);
-               cc_.disconnect();
-       }
-
-       // Update the cache to point to the new file
-       if (!gc.inCache(file_with_path))
-               gc.add(file_with_path);
-
-       graphic_ = gc.graphic(file_with_path);
-       cc_ = graphic_->statusChanged.connect(
-               boost::bind(&InsetGraphics::statusChanged, &parent_));
-
-       setStatus(graphic_->status());
-       if (status() == grfx::Loaded)
-               modify();
-}
-
-
-void InsetGraphics::Cache::modify()
-{
-       // The image has not been loaded from file
-       if (!graphic_->image().get())
-               return;
-
-       string const path = OnlyPath(filename());
-       grfx::GParams params = parent_.params().asGParams(path);
-
-       if (params == params_)
-               return;
-
-       params_ = params;
-       setStatus(grfx::ScalingEtc);
-       modified_image_.reset(graphic_->image()->clone());
-       modified_image_->clip(params);
-       modified_image_->rotate(params);
-       modified_image_->scale(params);
-       
-       bool const success = modified_image_->setPixmap(params);
-
-       if (success) {
-               setStatus(grfx::Loaded);
-       } else {
-               modified_image_.reset();
-               setStatus(grfx::ErrorScalingEtc);
-       }
+       string const path = OnlyPath(file_with_path);
+       loader.reset(file_with_path, parent_.params().as_grfxParams(path));
 }
 
 
@@ -332,7 +204,6 @@ InsetGraphics::InsetGraphics(InsetGraphics const & ig,
 
 InsetGraphics::~InsetGraphics()
 {
-       cache_->reset(grfx::GraphicPtr());
        // Emits the hide signal to the dialog connected (if any)
        hideDialog();
 }
@@ -342,7 +213,7 @@ string const InsetGraphics::statusMessage() const
 {
        string msg;
 
-       switch (cache_->status()) {
+       switch (cache_->loader.status()) {
        case grfx::WaitingToLoad:
                msg = _("Waiting for draw request to start loading...");
                break;
@@ -352,23 +223,26 @@ string const InsetGraphics::statusMessage() const
        case grfx::Converting:
                msg = _("Converting to loadable format...");
                break;
+       case grfx::Loaded:
+               msg = _("Loaded into memory. Must now generate pixmap.");
+               break;
        case grfx::ScalingEtc:
                msg = _("Scaling etc...");
                break;
-       case grfx::Loaded:
-               msg = _("Loaded.");
+       case grfx::Ready:
+               msg = _("Ready to display");
                break;
        case grfx::ErrorNoFile:
                msg = _("No file found!");
                break;
-       case grfx::ErrorLoading:
-               msg = _("Error loading file into memory");
-               break;
        case grfx::ErrorConverting:
                msg = _("Error converting to loadable format");
                break;
-       case grfx::ErrorScalingEtc:
-               msg = _("Error scaling etc");
+       case grfx::ErrorLoading:
+               msg = _("Error loading file into memory");
+               break;
+       case grfx::ErrorGeneratingPixmap:
+               msg = _("Error generating the pixmap");
                break;
        case grfx::ErrorUnknown:
                msg = _("No image");
@@ -381,10 +255,10 @@ string const InsetGraphics::statusMessage() const
 
 bool InsetGraphics::imageIsDrawable() const
 {
-       if (!cache_->image() || cache_->status() != grfx::Loaded)
+       if (!cache_->loader.image() || cache_->loader.status() != grfx::Ready)
                return false;
 
-       return cache_->image()->getPixmap() != 0;
+       return cache_->loader.image()->isDrawable();
 }
 
 
@@ -392,7 +266,7 @@ int InsetGraphics::ascent(BufferView *, LyXFont const &) const
 {
        cache_->old_ascent = 50;
        if (imageIsDrawable())
-               cache_->old_ascent = cache_->image()->getHeight();
+               cache_->old_ascent = cache_->loader.image()->getHeight();
        return cache_->old_ascent;
 }
 
@@ -406,7 +280,7 @@ int InsetGraphics::descent(BufferView *, LyXFont const &) const
 int InsetGraphics::width(BufferView *, LyXFont const & font) const
 {
        if (imageIsDrawable())
-               return cache_->image()->getWidth();
+               return cache_->loader.image()->getWidth();
        else {
                int font_width = 0;
 
@@ -453,8 +327,8 @@ void InsetGraphics::draw(BufferView * bv, LyXFont const & font,
        int old_x = int(x);
        x += lwidth;
 
-       if (cache_->status() == grfx::WaitingToLoad) {
-               cache_->graphic_->startLoading();
+       if (cache_->loader.status() == grfx::WaitingToLoad) {
+               cache_->loader.startLoading(*this, *bv);
        }
 
        // This will draw the graphics. If the graphics has not been loaded yet,
@@ -464,7 +338,7 @@ void InsetGraphics::draw(BufferView * bv, LyXFont const & font,
        if (imageIsDrawable()) {
                paint.image(old_x + 2, baseline - lascent,
                            lwidth - 4, lascent + ldescent,
-                           *cache_->image());
+                           *cache_->loader.image());
 
        } else {
 
@@ -804,10 +678,11 @@ string const InsetGraphics::prepareFile(Buffer const *buf) const
        // "nice" means that the buffer is exported to LaTeX format but not
        //        run through the LaTeX compiler.
        // if (nice)
-       //     No conversion of the graphics file is needed.
-       //     Return the original filename without any extension.
+       //      no conversion needed!
+       //      Return the original filename as is, because we do not know
+       //      what the user decide.
        if (buf->niceFile)
-               return RemoveExtension(orig_file);
+               return orig_file;
 
        // We're going to be running the exported buffer through the LaTeX
        // compiler, so must ensure that LaTeX can cope with the graphics
@@ -858,7 +733,9 @@ string const InsetGraphics::prepareFile(Buffer const *buf) const
                // No conversion is needed. LaTeX can handle the graphic file as is.
                // This is true even if the orig_file is compressed. We have to return
                // the orig_file_with_path, maybe it is a zipped one
-               return lyxrc.use_tempdir ? temp_file : orig_file_with_path;
+               if (lyxrc.use_tempdir)
+                       return RemoveExtension(temp_file);
+               return RemoveExtension(orig_file_with_path);
        }
 
        string const outfile_base = RemoveExtension(temp_file);
@@ -948,7 +825,7 @@ 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 + '{' + prepareFile(buf) + '}' + after) :
+               (before + '{' + os::external_path(prepareFile(buf)) + '}' + after) :
                (before + '{' + params().filename + " not found!}" + after);
        os << latex_str;
 
@@ -1010,10 +887,6 @@ void InsetGraphics::validate(LaTeXFeatures & features) const
 
 void InsetGraphics::statusChanged()
 {
-       cache_->setStatus(cache_->graphic_->status());
-       if (cache_->status() == grfx::Loaded)
-               cache_->modify();
-
        current_view->updateInset(this, false);
 }