]> git.lyx.org Git - lyx.git/blob - src/insets/render_graphic.C
ws changes only
[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 "metricsinfo.h"
20
21 #include "frontends/font_metrics.h"
22 #include "frontends/Painter.h"
23
24 #include "graphics/GraphicsImage.h"
25
26 #include "support/filetools.h"
27
28
29 using lyx::support::AbsolutePath;
30 using lyx::support::OnlyFilename;
31
32 using std::string;
33
34
35 RenderGraphic::RenderGraphic()
36         : checksum_(0)
37 {}
38
39
40 RenderGraphic::RenderGraphic(RenderGraphic const & other)
41         : RenderBase(other),
42           loader_(other.loader_),
43           params_(other.params_),
44           checksum_(0)
45 {}
46
47
48 RenderBase * RenderGraphic::clone() const
49 {
50         return new RenderGraphic(*this);
51 }
52
53
54 void RenderGraphic::update(lyx::graphics::Params const & params)
55 {
56         params_ = params;
57
58         if (!params_.filename.empty()) {
59                 BOOST_ASSERT(AbsolutePath(params_.filename));
60                 loader_.reset(params_.filename, params_);
61         }
62 }
63
64
65 bool RenderGraphic::hasFileChanged() const
66 {
67         unsigned long const new_checksum = loader_.checksum();
68         bool const file_has_changed = checksum_ != new_checksum;
69         if (file_has_changed)
70                 checksum_ = new_checksum;
71         return file_has_changed;
72 }
73
74
75 boost::signals::connection RenderGraphic::connect(slot_type const & slot) const
76 {
77         return loader_.connect(slot);
78 }
79
80
81 string const RenderGraphic::statusMessage() const
82 {
83         switch (loader_.status()) {
84                 case lyx::graphics::WaitingToLoad:
85                         return _("Not shown.");
86                 case lyx::graphics::Loading:
87                         return _("Loading...");
88                 case lyx::graphics::Converting:
89                         return _("Converting to loadable format...");
90                 case lyx::graphics::Loaded:
91                         return _("Loaded into memory. Must now generate pixmap.");
92                 case lyx::graphics::ScalingEtc:
93                         return _("Scaling etc...");
94                 case lyx::graphics::Ready:
95                         return _("Ready to display");
96                 case lyx::graphics::ErrorNoFile:
97                         return _("No file found!");
98                 case lyx::graphics::ErrorConverting:
99                         return _("Error converting to loadable format");
100                 case lyx::graphics::ErrorLoading:
101                         return _("Error loading file into memory");
102                 case lyx::graphics::ErrorGeneratingPixmap:
103                         return _("Error generating the pixmap");
104                 case lyx::graphics::ErrorUnknown:
105                         return _("No image");
106         }
107         return string();
108 }
109
110
111 bool RenderGraphic::readyToDisplay() const
112 {
113         if (!loader_.image() || loader_.status() != lyx::graphics::Ready)
114                 return false;
115         return loader_.image()->isDrawable();
116 }
117
118
119 void RenderGraphic::metrics(MetricsInfo & mi, Dimension & dim) const
120 {
121         bool image_ready = readyToDisplay();
122
123         dim.asc = image_ready ? loader_.image()->getHeight() : 50;
124         dim.des = 0;
125
126         if (image_ready) {
127                 dim.wid = loader_.image()->getWidth() +
128                         2 * InsetOld::TEXT_TO_INSET_OFFSET;
129         } else {
130                 int font_width = 0;
131
132                 LyXFont msgFont(mi.base.font);
133                 msgFont.setFamily(LyXFont::SANS_FAMILY);
134
135                 string const justname = OnlyFilename(params_.filename);
136                 if (!justname.empty()) {
137                         msgFont.setSize(LyXFont::SIZE_FOOTNOTE);
138                         font_width = font_metrics::width(justname, msgFont);
139                 }
140
141                 string const msg = statusMessage();
142                 if (!msg.empty()) {
143                         msgFont.setSize(LyXFont::SIZE_TINY);
144                         font_width = std::max(font_width,
145                                               font_metrics::width(msg, msgFont));
146                 }
147
148                 dim.wid = std::max(50, font_width + 15);
149         }
150
151         dim_ = dim;
152 }
153
154
155 void RenderGraphic::draw(PainterInfo & pi, int x, int y) const
156 {
157         if (params_.display != lyx::graphics::NoDisplay &&
158             loader_.status() == lyx::graphics::WaitingToLoad)
159                 loader_.startLoading();
160
161         if (params_.display != lyx::graphics::NoDisplay &&
162             !loader_.monitoring())
163                 loader_.startMonitoring();
164
165         // This will draw the graphics. If the graphics has not been loaded yet,
166         // we draw just a rectangle.
167
168         if (readyToDisplay()) {
169                 pi.pain.image(x + InsetOld::TEXT_TO_INSET_OFFSET,
170                               y - dim_.asc,
171                               dim_.wid - 2 * InsetOld::TEXT_TO_INSET_OFFSET,
172                               dim_.asc + dim_.des,
173                               *loader_.image());
174
175         } else {
176                 pi.pain.rectangle(x + InsetOld::TEXT_TO_INSET_OFFSET,
177                                   y - dim_.asc,
178                                   dim_.wid - 2 * InsetOld::TEXT_TO_INSET_OFFSET,
179                                   dim_.asc + dim_.des,
180                                   LColor::foreground);
181
182                 // Print the file name.
183                 LyXFont msgFont = pi.base.font;
184                 msgFont.setFamily(LyXFont::SANS_FAMILY);
185                 string const justname = OnlyFilename(params_.filename);
186
187                 if (!justname.empty()) {
188                         msgFont.setSize(LyXFont::SIZE_FOOTNOTE);
189                         pi.pain.text(x + InsetOld::TEXT_TO_INSET_OFFSET + 6,
190                                    y - font_metrics::maxAscent(msgFont) - 4,
191                                    justname, msgFont);
192                 }
193
194                 // Print the message.
195                 string const msg = statusMessage();
196                 if (!msg.empty()) {
197                         msgFont.setSize(LyXFont::SIZE_TINY);
198                         pi.pain.text(x + InsetOld::TEXT_TO_INSET_OFFSET + 6,
199                                      y - 4, msg, msgFont);
200                 }
201         }
202 }