1 /**
2  * \file PreviewImage.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Angus Leeming
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10 
11 #include <config.h>
12 
13 #include "PreviewImage.h"
14 
15 #include "Buffer.h"
16 #include "Dimension.h"
17 #include "GraphicsImage.h"
18 #include "GraphicsLoader.h"
19 #include "PreviewLoader.h"
20 
21 #include "support/FileName.h"
22 
23 
24 using namespace std;
25 using namespace lyx::support;
26 
27 namespace lyx {
28 namespace graphics {
29 
30 class PreviewImage::Impl {
31 public:
32 	///
33 	Impl(PreviewImage & p, PreviewLoader & l,
34 	     string const & s, FileName const & f, double af);
35 	///
36 	~Impl();
37 	///
38 	Image const * image();
39 	///
40 	void statusChanged();
41 
42 	///
43 	PreviewImage const & parent_;
44 	///
45 	PreviewLoader & ploader_;
46 	///
47 	Loader iloader_;
48 	///
49 	string const snippet_;
50 	///
51 	double const ascent_frac_;
52 };
53 
54 
PreviewImage(PreviewLoader & l,string const & s,FileName const & f,double af)55 PreviewImage::PreviewImage(PreviewLoader & l,
56 			   string const & s,
57 			   FileName const & f,
58 			   double af)
59 	: pimpl_(new Impl(*this, l, s, f, af))
60 {}
61 
62 
~PreviewImage()63 PreviewImage::~PreviewImage()
64 {
65 	delete pimpl_;
66 }
67 
68 
snippet() const69 string const & PreviewImage::snippet() const
70 {
71 	return pimpl_->snippet_;
72 }
73 
74 
filename() const75 support::FileName const & PreviewImage::filename() const
76 {
77 	return pimpl_->iloader_.filename();
78 }
79 
80 
dim() const81 Dimension PreviewImage::dim() const
82 {
83 	Dimension dim;
84 	Image const * const image = pimpl_->iloader_.image();
85 	if (!image)
86 		return dim;
87 
88 	dim.asc = int(pimpl_->ascent_frac_ * double(image->height()) + 0.5);
89 	dim.des = image->height() - dim.asc;
90 	dim.wid = image->width();
91 	return dim;
92 }
93 
94 
image() const95 Image const * PreviewImage::image() const
96 {
97 	return pimpl_->image();
98 }
99 
100 
previewLoader() const101 PreviewLoader & PreviewImage::previewLoader() const
102 {
103 	return pimpl_->ploader_;
104 }
105 
106 
Impl(PreviewImage & p,PreviewLoader & l,string const & s,FileName const & bf,double af)107 PreviewImage::Impl::Impl(PreviewImage & p, PreviewLoader & l, string const & s,
108                          FileName const & bf, double af)
109 	: parent_(p), ploader_(l), iloader_(l.buffer().fileName(), bf),
110 	  snippet_(s), ascent_frac_(af)
111 {
112 	iloader_.setDisplayPixelRatio(l.displayPixelRatio());
113 	// This connection is destroyed at the same time as this.
114 	iloader_.connect([this](){ statusChanged(); });
115 }
116 
117 
~Impl()118 PreviewImage::Impl::~Impl()
119 {
120 	// If these images are generated for a clone, then that may be
121 	// because we are previewing. We therefore do not want to delete
122 	// them when this Buffer is destroyed.
123 	if (!ploader_.buffer().isClone())
124 		iloader_.filename().removeFile();
125 }
126 
127 
image()128 Image const * PreviewImage::Impl::image()
129 {
130 	if (iloader_.status() == WaitingToLoad)
131 		iloader_.startLoading();
132 
133 	return iloader_.image();
134 }
135 
136 
statusChanged()137 void PreviewImage::Impl::statusChanged()
138 {
139 	switch (iloader_.status()) {
140 	case WaitingToLoad:
141 	case Loading:
142 	case Converting:
143 	case Loaded:
144 	case ScalingEtc:
145 		break;
146 
147 	case ErrorNoFile:
148 	case ErrorConverting:
149 	case ErrorLoading:
150 	case ErrorGeneratingPixmap:
151 	case ErrorUnknown:
152 		//iloader_.filename().removeFile();
153 		ploader_.remove(snippet_);
154 		// FIXME: We need to return here, because PreviewLoader::remove
155 		// removes the preview image from the cache, which deletes this
156 		// object, so we should not try to do anything here.
157 		return;
158 
159 	case Ready:
160 		iloader_.filename().removeFile();
161 		break;
162 	}
163 	ploader_.emitSignal(parent_);
164 }
165 
166 } // namespace graphics
167 } // namespace lyx
168