]> git.lyx.org Git - lyx.git/blob - src/insets/render_preview.C
RenderButton, RenderGraphic and RenderPreview now have a common lineage.
[lyx.git] / src / insets / render_preview.C
1 /**
2  * \file render_preview.C
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 "render_preview.h"
14
15 #include "dimension.h"
16 #include "LColor.h"
17 #include "metricsinfo.h"
18
19 #include "frontends/Painter.h"
20
21 #include "graphics/PreviewImage.h"
22 #include "graphics/PreviewLoader.h"
23 #include "graphics/Previews.h"
24
25 #include "support/lstrings.h"
26
27 #include <boost/bind.hpp>
28
29 using std::string;
30
31 namespace graphics = lyx::graphics;
32 namespace support  = lyx::support;
33
34
35 bool RenderPreview::activated()
36 {
37         return graphics::Previews::activated();
38 }
39
40
41 RenderPreview::RenderPreview()
42         : pimage_(0)
43 {}
44
45
46 RenderPreview::RenderPreview(RenderPreview const & other)
47         : RenderBase(other),
48           boost::signals::trackable(),
49           snippet_(other.snippet_),
50           pimage_(0)
51 {}
52
53
54 RenderBase * RenderPreview::clone() const
55 {
56         return new RenderPreview(*this);
57 }
58
59
60 void RenderPreview::metrics(MetricsInfo &, Dimension & dim) const
61 {
62         if (previewReady()) {
63                 dim.asc = pimage()->ascent();
64                 dim.des = pimage()->descent();
65                 dim.wid = pimage()->width();
66         } else {
67                 dim.asc = 20;
68                 dim.des = 20;
69                 dim.wid = 20;
70         }
71
72         dim_ = dim;
73 }
74
75
76 void RenderPreview::draw(PainterInfo & pi, int x, int y) const
77 {
78         BOOST_ASSERT(pi.base.bv);
79         view_ = pi.base.bv->owner()->view();
80
81         if (!previewReady())
82                 pi.pain.rectangle(x, y - dim_.asc, dim_.wid, dim_.height(),
83                                   LColor::foreground);
84         else
85                 pi.pain.image(x, y - dim_.asc, dim_.wid, dim_.height(),
86                               *(pimage()->image()));
87 }
88
89
90 boost::signals::connection RenderPreview::connect(slot_type const & slot)
91 {
92         return preview_ready_signal_.connect(slot);
93 }
94
95
96 void RenderPreview::generatePreview(string const & latex_snippet,
97                                      Buffer const & buffer)
98 {
99         if (!activated())
100                 return;
101
102         graphics::Previews & previews = graphics::Previews::get();
103         graphics::PreviewLoader & loader = previews.loader(buffer);
104         addPreview(latex_snippet, loader);
105         if (!snippet_.empty())
106                 loader.startLoading();
107 }
108
109
110 void RenderPreview::addPreview(string const & latex_snippet,
111                                 graphics::PreviewLoader & ploader)
112 {
113         if (!activated())
114                 return;
115
116         snippet_ = support::trim(latex_snippet);
117         pimage_ = 0;
118         if (snippet_.empty())
119                 return;
120
121         pimage_ = ploader.preview(snippet_);
122         if (pimage_)
123                 return;
124
125         // If this is the first time of calling, connect to the
126         // PreviewLoader signal that'll inform us when the preview image
127         // is ready for loading.
128         if (!ploader_connection_.connected()) {
129                 ploader_connection_ = ploader.connect(
130                         boost::bind(&RenderPreview::imageReady, this, _1));
131         }
132
133         ploader.add(snippet_);
134 }
135
136
137 void RenderPreview::removePreview(Buffer const & buffer)
138 {
139         if (snippet_.empty())
140                 return;
141
142         graphics::Previews & previews = graphics::Previews::get();
143         graphics::PreviewLoader & loader = previews.loader(buffer);
144         loader.remove(snippet_);
145         snippet_.erase();
146         pimage_ = 0;
147 }
148
149
150 bool RenderPreview::previewReady() const
151 {
152         return pimage_ ? pimage_->image() : false;
153 }
154
155
156 void RenderPreview::imageReady(graphics::PreviewImage const & pimage)
157 {
158         // Check the current snippet is the same as that previewed.
159         if (snippet_ != pimage.snippet())
160                 return;
161
162         pimage_ = &pimage;
163         preview_ready_signal_();
164 }
165
166
167 void RenderMonitoredPreview::startMonitoring(string const & file)
168 {
169         monitor_.reset(file);
170         monitor_.start();
171 }
172
173
174 boost::signals::connection
175 RenderMonitoredPreview::fileChanged(slot_type const & slot)
176 {
177         return monitor_.connect(slot);
178 }