]> git.lyx.org Git - lyx.git/blob - src/insets/render_graphic.C
hopefully fix tex2lyx linking.
[lyx.git] / src / insets / render_graphic.C
1 /**
2  * \file render_graphic.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_graphic.h"
14
15 #include "insets/inset.h"
16
17 #include "gettext.h"
18 #include "LColor.h"
19 #include "lyx_main.h"
20 #include "lyxrc.h"
21 #include "metricsinfo.h"
22
23 #include "frontends/FontMetrics.h"
24 #include "frontends/Painter.h"
25
26 #include "graphics/GraphicsImage.h"
27
28 #include "support/filetools.h"
29
30 #include <boost/bind.hpp>
31
32
33 namespace lyx {
34
35 using support::absolutePath;
36 using support::onlyFilename;
37
38 using std::string;
39 using std::auto_ptr;
40
41
42 RenderGraphic::RenderGraphic(InsetBase const * inset)
43 {
44         loader_.connect(boost::bind(&LyX::updateInset,
45                                     boost::cref(LyX::cref()), inset));
46 }
47
48
49 RenderGraphic::RenderGraphic(RenderGraphic const & other,
50                              InsetBase const * inset)
51         : RenderBase(other),
52           loader_(other.loader_),
53           params_(other.params_)
54 {
55         loader_.connect(boost::bind(&LyX::updateInset,
56                                     boost::cref(LyX::cref()), inset));
57 }
58
59
60 auto_ptr<RenderBase> RenderGraphic::clone(InsetBase const * inset) const
61 {
62         return auto_ptr<RenderBase>(new RenderGraphic(*this, inset));
63 }
64
65
66 void RenderGraphic::update(graphics::Params const & params)
67 {
68         params_ = params;
69
70         if (!params_.filename.empty()) {
71                 BOOST_ASSERT(absolutePath(params_.filename));
72                 loader_.reset(params_.filename, params_);
73         }
74 }
75
76
77 namespace {
78
79 bool displayGraphic(graphics::Params const & params)
80 {
81         return params.display != graphics::NoDisplay &&
82                 lyxrc.display_graphics != graphics::NoDisplay;
83 }
84
85
86 docstring const statusMessage(graphics::Params const & params,
87                            graphics::ImageStatus status)
88 {
89         docstring ret;
90
91         if (!displayGraphic(params))
92                 ret = _("Not shown.");
93         else {
94                 switch (status) {
95                 case graphics::WaitingToLoad:
96                         ret = _("Not shown.");
97                         break;
98                 case graphics::Loading:
99                         ret = _("Loading...");
100                         break;
101                 case graphics::Converting:
102                         ret = _("Converting to loadable format...");
103                         break;
104                 case graphics::Loaded:
105                         ret = _("Loaded into memory. Generating pixmap...");
106                         break;
107                 case graphics::ScalingEtc:
108                         ret = _("Scaling etc...");
109                         break;
110                 case graphics::Ready:
111                         ret = _("Ready to display");
112                         break;
113                 case graphics::ErrorNoFile:
114                         ret = _("No file found!");
115                         break;
116                 case graphics::ErrorConverting:
117                         ret = _("Error converting to loadable format");
118                         break;
119                 case graphics::ErrorLoading:
120                         ret = _("Error loading file into memory");
121                         break;
122                 case graphics::ErrorGeneratingPixmap:
123                         ret = _("Error generating the pixmap");
124                         break;
125                 case graphics::ErrorUnknown:
126                         ret = _("No image");
127                         break;
128                 }
129         }
130
131         return ret;
132 }
133
134
135 bool readyToDisplay(graphics::Loader const & loader)
136 {
137         if (!loader.image() || loader.status() != graphics::Ready)
138                 return false;
139         return loader.image()->isDrawable();
140 }
141
142 } // namespace anon
143
144
145 void RenderGraphic::metrics(MetricsInfo & mi, Dimension & dim) const
146 {
147         bool image_ready = displayGraphic(params_) && readyToDisplay(loader_);
148
149         dim.asc = image_ready ? loader_.image()->getHeight() : 50;
150         dim.des = 0;
151
152         if (image_ready) {
153                 dim.wid = loader_.image()->getWidth() +
154                         2 * InsetOld::TEXT_TO_INSET_OFFSET;
155         } else {
156                 int font_width = 0;
157
158                 LyXFont msgFont(mi.base.font);
159                 msgFont.setFamily(LyXFont::SANS_FAMILY);
160
161                 // FIXME UNICODE
162                 docstring const justname = 
163                         from_utf8(onlyFilename(params_.filename));
164                 if (!justname.empty()) {
165                         msgFont.setSize(LyXFont::SIZE_FOOTNOTE);
166                         font_width = theFontMetrics(msgFont)
167                                 .width(justname);
168                 }
169
170                 docstring const msg = statusMessage(params_, loader_.status());
171                 if (!msg.empty()) {
172                         msgFont.setSize(LyXFont::SIZE_TINY);
173                         font_width = std::max(font_width,
174                                 theFontMetrics(msgFont).width(msg));
175                 }
176
177                 dim.wid = std::max(50, font_width + 15);
178         }
179
180         dim_ = dim;
181 }
182
183
184 void RenderGraphic::draw(PainterInfo & pi, int x, int y) const
185 {
186         if (displayGraphic(params_)) {
187                 if (loader_.status() == graphics::WaitingToLoad)
188                         loader_.startLoading();
189                 if (!loader_.monitoring())
190                         loader_.startMonitoring();
191         }
192
193         // This will draw the graphics. If the graphics has not been
194         // loaded yet, we draw just a rectangle.
195
196         if (displayGraphic(params_) && readyToDisplay(loader_)) {
197                 pi.pain.image(x + InsetOld::TEXT_TO_INSET_OFFSET,
198                               y - dim_.asc,
199                               dim_.wid - 2 * InsetOld::TEXT_TO_INSET_OFFSET,
200                               dim_.asc + dim_.des,
201                               *loader_.image());
202
203         } else {
204                 pi.pain.rectangle(x + InsetOld::TEXT_TO_INSET_OFFSET,
205                                   y - dim_.asc,
206                                   dim_.wid - 2 * InsetOld::TEXT_TO_INSET_OFFSET,
207                                   dim_.asc + dim_.des,
208                                   LColor::foreground);
209
210                 // Print the file name.
211                 LyXFont msgFont = pi.base.font;
212                 msgFont.setFamily(LyXFont::SANS_FAMILY);
213                 string const justname = onlyFilename(params_.filename);
214
215                 if (!justname.empty()) {
216                         msgFont.setSize(LyXFont::SIZE_FOOTNOTE);
217                         pi.pain.text(x + InsetOld::TEXT_TO_INSET_OFFSET + 6,
218                                    y - theFontMetrics(msgFont).maxAscent() - 4,
219                                    from_utf8(justname), msgFont);
220                 }
221
222                 // Print the message.
223                 docstring const msg = statusMessage(params_, loader_.status());
224                 if (!msg.empty()) {
225                         msgFont.setSize(LyXFont::SIZE_TINY);
226                         pi.pain.text(x + InsetOld::TEXT_TO_INSET_OFFSET + 6,
227                                      y - 4, msg, msgFont);
228                 }
229         }
230 }
231
232
233 } // namespace lyx