]> git.lyx.org Git - lyx.git/blob - src/insets/RenderPreview.cpp
'using namespace std' instead of 'using std::xxx'
[lyx.git] / src / insets / RenderPreview.cpp
1 /**
2  * \file RenderPreview.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 "insets/RenderPreview.h"
14 #include "insets/Inset.h"
15
16 #include "BufferView.h"
17 #include "Dimension.h"
18 #include "support/gettext.h"
19 #include "LyX.h"
20 #include "LyXRC.h"
21 #include "MetricsInfo.h"
22
23 #include "frontends/FontMetrics.h"
24 #include "frontends/Painter.h"
25
26 #include "graphics/PreviewImage.h"
27 #include "graphics/PreviewLoader.h"
28 #include "graphics/Previews.h"
29
30 #include "support/FileName.h"
31 #include "support/lstrings.h"
32
33 #include <boost/bind.hpp>
34
35 using namespace std;
36
37 namespace lyx {
38
39 using support::FileName;
40
41
42 LyXRC_PreviewStatus RenderPreview::status()
43 {
44         return graphics::Previews::status();
45 }
46
47
48 RenderPreview::RenderPreview(Inset const * inset)
49         : parent_(inset)
50 {}
51
52
53 RenderPreview::RenderPreview(RenderPreview const & other,
54                              Inset const * inset)
55         : RenderBase(other),
56           boost::signals::trackable(),
57           snippet_(other.snippet_),
58           parent_(inset)
59 {}
60
61
62 RenderPreview::~RenderPreview()
63 {
64        if (ploader_connection_.connected())
65                ploader_connection_.disconnect();
66 }
67
68
69 RenderBase * RenderPreview::clone(Inset const * inset) const
70 {
71         return new RenderPreview(*this, inset);
72 }
73
74
75 namespace {
76
77 graphics::PreviewLoader & getPreviewLoader(Buffer const & buffer)
78 {
79         graphics::Previews const & previews = graphics::Previews::get();
80         return previews.loader(buffer);
81 }
82
83
84 docstring const statusMessage(BufferView const * bv, string const & snippet)
85 {
86         BOOST_ASSERT(bv);
87
88         Buffer const & buffer = bv->buffer();
89         graphics::PreviewLoader const & loader = getPreviewLoader(buffer);
90         graphics::PreviewLoader::Status const status = loader.status(snippet);
91
92         docstring message;
93         switch (status) {
94         case graphics::PreviewLoader::InQueue:
95         case graphics::PreviewLoader::Processing:
96                 message = _("Preview loading");
97                 break;
98         case graphics::PreviewLoader::Ready:
99                 message = _("Preview ready");
100                 break;
101         case graphics::PreviewLoader::NotFound:
102                 message = _("Preview failed");
103                 break;
104         }
105
106         return message;
107 }
108
109 } // namespace anon
110
111
112 graphics::PreviewImage const *
113 RenderPreview::getPreviewImage(Buffer const & buffer) const
114 {
115         graphics::PreviewLoader const & loader = getPreviewLoader(buffer);
116         return loader.preview(snippet_);
117 }
118
119
120 void RenderPreview::metrics(MetricsInfo & mi, Dimension & dim) const
121 {
122         BOOST_ASSERT(mi.base.bv);
123
124         graphics::PreviewImage const * const pimage =
125                 getPreviewImage(mi.base.bv->buffer());
126
127         if (pimage) {
128                 dim = pimage->dim();
129         } else {
130                 dim.asc = 50;
131                 dim.des = 0;
132
133                 FontInfo font(mi.base.font);
134                 font.setFamily(SANS_FAMILY);
135                 font.setSize(FONT_SIZE_FOOTNOTE);
136                 docstring const stat = statusMessage(mi.base.bv, snippet_);
137                 dim.wid = 15 + theFontMetrics(font).width(stat);
138         }
139
140         dim_ = dim;
141 }
142
143
144 void RenderPreview::draw(PainterInfo & pi, int x, int y) const
145 {
146         BOOST_ASSERT(pi.base.bv);
147
148         graphics::PreviewImage const * const pimage =
149                 getPreviewImage(pi.base.bv->buffer());
150         graphics::Image const * const image = pimage ? pimage->image() : 0;
151
152         if (image) {
153                 pi.pain.image(x, y - dim_.asc, dim_.wid, dim_.height(),
154                               *image);
155
156         } else {
157                 int const offset = Inset::TEXT_TO_INSET_OFFSET;
158
159                 pi.pain.rectangle(x + offset,
160                                   y - dim_.asc,
161                                   dim_.wid - 2 * offset,
162                                   dim_.asc + dim_.des,
163                                   Color_foreground);
164
165                 FontInfo font(pi.base.font);
166                 font.setFamily(SANS_FAMILY);
167                 font.setSize(FONT_SIZE_FOOTNOTE);
168
169                 docstring const stat = statusMessage(pi.base.bv, snippet_);
170                 pi.pain.text(x + offset + 6,
171                              y - theFontMetrics(font).maxAscent() - 4,
172                              stat, font);
173         }
174 }
175
176
177 void RenderPreview::startLoading(Buffer const & buffer) const
178 {
179         if (status() == LyXRC::PREVIEW_OFF || snippet_.empty())
180                 return;
181
182         graphics::PreviewLoader const & loader = getPreviewLoader(buffer);
183         loader.startLoading();
184 }
185
186
187 void RenderPreview::addPreview(docstring const & latex_snippet,
188                                Buffer const & buffer)
189 {
190         if (status() == LyXRC::PREVIEW_OFF)
191                 return;
192
193         graphics::PreviewLoader & loader = getPreviewLoader(buffer);
194         addPreview(latex_snippet, loader);
195 }
196
197
198 void RenderPreview::addPreview(docstring const & latex_snippet,
199                                graphics::PreviewLoader & ploader)
200 {
201         if (status() == LyXRC::PREVIEW_OFF)
202                 return;
203
204         // FIXME UNICODE
205         // We have to make sure that we call latex with the right encoding
206         snippet_ = support::trim(to_utf8(latex_snippet));
207         if (snippet_.empty())
208                 return;
209
210         if (ploader.preview(snippet_))
211                 return;
212
213         // If this is the first time of calling, connect to the
214         // PreviewLoader signal that'll inform us when the preview image
215         // is ready for loading.
216         if (!ploader_connection_.connected()) {
217                 ploader_connection_ = ploader.connect(
218                         boost::bind(&RenderPreview::imageReady, this, _1));
219         }
220
221         ploader.add(snippet_);
222 }
223
224
225 void RenderPreview::removePreview(Buffer const & buffer)
226 {
227         if (snippet_.empty())
228                 return;
229
230         graphics::PreviewLoader & loader = getPreviewLoader(buffer);
231         loader.remove(snippet_);
232         snippet_.erase();
233 }
234
235
236 void RenderPreview::imageReady(graphics::PreviewImage const & pimage)
237 {
238         // Check the current snippet is the same as that previewed.
239         if (snippet_ == pimage.snippet())
240                 parent_->updateFrontend();
241 }
242
243
244 RenderMonitoredPreview::RenderMonitoredPreview(Inset const * inset)
245         : RenderPreview(inset), monitor_(FileName(), 2000)
246 {}
247
248
249 void RenderMonitoredPreview::setAbsFile(FileName const & file)
250 {
251         monitor_.reset(file);
252 }
253
254
255 void RenderMonitoredPreview::draw(PainterInfo & pi, int x, int y) const
256 {
257         RenderPreview::draw(pi, x, y);
258         if (!monitoring())
259                 startMonitoring();
260 }
261
262
263 boost::signals::connection
264 RenderMonitoredPreview::fileChanged(slot_type const & slot)
265 {
266         return monitor_.connect(slot);
267 }
268
269 } // namespace lyx