]> git.lyx.org Git - lyx.git/blob - src/insets/render_graphic.C
More unicode conversion
[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 namespace graphics = lyx::graphics;
33
34 using lyx::docstring;
35 using lyx::support::absolutePath;
36 using lyx::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 string 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         // FIXME UNICODE
132         return lyx::to_utf8(ret);
133 }
134
135
136 bool readyToDisplay(graphics::Loader const & loader)
137 {
138         if (!loader.image() || loader.status() != graphics::Ready)
139                 return false;
140         return loader.image()->isDrawable();
141 }
142
143 } // namespace anon
144
145
146 void RenderGraphic::metrics(MetricsInfo & mi, Dimension & dim) const
147 {
148         bool image_ready = displayGraphic(params_) && readyToDisplay(loader_);
149
150         dim.asc = image_ready ? loader_.image()->getHeight() : 50;
151         dim.des = 0;
152
153         if (image_ready) {
154                 dim.wid = loader_.image()->getWidth() +
155                         2 * InsetOld::TEXT_TO_INSET_OFFSET;
156         } else {
157                 int font_width = 0;
158
159                 LyXFont msgFont(mi.base.font);
160                 msgFont.setFamily(LyXFont::SANS_FAMILY);
161
162                 // FIXME UNICODE
163                 docstring const justname = 
164                         lyx::from_utf8(onlyFilename(params_.filename));
165                 if (!justname.empty()) {
166                         msgFont.setSize(LyXFont::SIZE_FOOTNOTE);
167                         font_width = theFontMetrics(msgFont)
168                                 .width(justname);
169                 }
170
171                 // FIXME UNICODE
172                 docstring const msg = 
173                         lyx::from_utf8(statusMessage(params_, loader_.status()));
174                 if (!msg.empty()) {
175                         msgFont.setSize(LyXFont::SIZE_TINY);
176                         font_width = std::max(font_width,
177                                 theFontMetrics(msgFont).width(msg));
178                 }
179
180                 dim.wid = std::max(50, font_width + 15);
181         }
182
183         dim_ = dim;
184 }
185
186
187 void RenderGraphic::draw(PainterInfo & pi, int x, int y) const
188 {
189         if (displayGraphic(params_)) {
190                 if (loader_.status() == graphics::WaitingToLoad)
191                         loader_.startLoading();
192                 if (!loader_.monitoring())
193                         loader_.startMonitoring();
194         }
195
196         // This will draw the graphics. If the graphics has not been
197         // loaded yet, we draw just a rectangle.
198
199         if (displayGraphic(params_) && readyToDisplay(loader_)) {
200                 pi.pain.image(x + InsetOld::TEXT_TO_INSET_OFFSET,
201                               y - dim_.asc,
202                               dim_.wid - 2 * InsetOld::TEXT_TO_INSET_OFFSET,
203                               dim_.asc + dim_.des,
204                               *loader_.image());
205
206         } else {
207                 pi.pain.rectangle(x + InsetOld::TEXT_TO_INSET_OFFSET,
208                                   y - dim_.asc,
209                                   dim_.wid - 2 * InsetOld::TEXT_TO_INSET_OFFSET,
210                                   dim_.asc + dim_.des,
211                                   LColor::foreground);
212
213                 // Print the file name.
214                 LyXFont msgFont = pi.base.font;
215                 msgFont.setFamily(LyXFont::SANS_FAMILY);
216                 string const justname = onlyFilename(params_.filename);
217
218                 if (!justname.empty()) {
219                         docstring djust(justname.begin(), justname.end());
220                         msgFont.setSize(LyXFont::SIZE_FOOTNOTE);
221                         pi.pain.text(x + InsetOld::TEXT_TO_INSET_OFFSET + 6,
222                                    y - theFontMetrics(msgFont).maxAscent() - 4,
223                                    djust, msgFont);
224                 }
225
226                 // Print the message.
227                 string const msg = statusMessage(params_, loader_.status());
228                 if (!msg.empty()) {
229                         docstring dmsg(msg.begin(), msg.end());
230                         msgFont.setSize(LyXFont::SIZE_TINY);
231                         pi.pain.text(x + InsetOld::TEXT_TO_INSET_OFFSET + 6,
232                                      y - 4, dmsg, msgFont);
233                 }
234         }
235 }