]> git.lyx.org Git - features.git/blob - src/graphics/GraphicsCacheItem.h
Switch from SigC signals to boost::signals
[features.git] / src / graphics / GraphicsCacheItem.h
1 // -*- C++ -*-
2 /*
3  * \file GraphicsCacheItem.h
4  * Copyright 2002 the LyX Team
5  * Read the file COPYING
6  *
7  * \author Baruch Even <baruch.even@writeme.com>
8  * \author Angus Leeming <a.leeming@ic.ac.uk>
9  *
10  * The graphics cache is a container of GCacheItems. Each GCacheItem, defined
11  * here represents a separate image file. However, each file can be viewed in
12  * different ways (different sizes, rotations etc), so each GCacheItem itself
13  * contains a list of ModifiedItems, also defined here. Each ModifiedItem
14  * has a GParams variable that defines the way it will be viewed. It also
15  * contains a list of the graphics insets that refer to it, so calls through
16  * the GCache to GCacheItem ultimately return the loading status and image
17  * for that particular graphics inset.
18  *
19  * The graphics cache supports fully asynchronous:
20  * file conversion to a loadable format;
21  * file loading.
22  *
23  * Whether you get that, of course, depends on grfx::GConverter and on the
24  * grfx::GImage-derived image class.
25  *
26  * Image modification (scaling, rotation etc) is blocking.
27  */
28
29 #ifndef GRAPHICSCACHEITEM_H
30 #define GRAPHICSCACHEITEM_H
31
32 #ifdef __GNUG__
33 #pragma interface
34 #endif
35
36 #include "GraphicsTypes.h"
37 #include "LString.h"
38
39 #include <boost/utility.hpp>
40 #include <boost/shared_ptr.hpp>
41
42 #include <boost/signals/signal1.hpp>
43 #include <boost/signals/connection.hpp>
44 #include <boost/signals/trackable.hpp>
45
46 #include <list>
47
48 class InsetGraphics;
49
50 namespace grfx {
51
52 class GParams;
53 class ModifiedItem;
54
55 /// A grfx::GCache item holder.
56 class GCacheItem : boost::noncopyable, public boost::signals::trackable {
57 public:
58         /// the GCacheItem contains data of this type.
59         typedef boost::shared_ptr<ModifiedItem> ModifiedItemPtr;
60
61         ///
62         GCacheItem(InsetGraphics const &, GParams const &);
63
64         /// The params have changed (but still refer to this file).
65         void modify(InsetGraphics const &, GParams const &);
66
67         /// Remove the reference to this inset.
68         void remove(InsetGraphics const &);
69
70         /// It's in the cache. Now start the loading process.
71         void startLoading(InsetGraphics const &);
72
73         /// Is the cache item referenced by any insets at all?
74         bool empty() const;
75
76         /// The name of the original image file.
77         string const & filename() const;
78
79         /// Is this image file referenced by this inset?
80         bool referencedBy(InsetGraphics const &) const;
81
82         /** Returns the image referenced by this inset (or an empty container
83          *  if it's not yet loaded.
84          */
85         ImagePtr const image(InsetGraphics const &) const;
86
87         /// The loading status of the image referenced by this inset.
88         ImageStatus status(InsetGraphics const &) const;
89
90         /** If (changed_background == true), then the background color of the
91          *  graphics inset has changed. Update all images.
92          *  Else, the preferred display type has changed.
93          *  Update the view of all insets whose display type is DEFAULT.
94          */
95         void changeDisplay(bool changed_background);
96
97         /// Used to ascertain the Bounding Box of non (e)ps files.
98         unsigned int raw_width() const;
99         ///
100         unsigned int raw_height() const;
101
102 private:
103         /** Start the image conversion process, checking first that it is
104          *  necessary. If it is necessary, then a conversion task is started.
105          *  GCacheItem asumes that the conversion is asynchronous and so
106          *  passes a Signal to the converting routine. When the conversion
107          *  is finished, this Signal is emitted, returning the converted
108          *  file to this->imageConverted.
109          *
110          *  If no file conversion is needed, then convertToDisplayFormat() calls
111          *  loadImage() directly.
112          *
113          *  convertToDisplayFormat() will set the loading status flag as
114          *  approriate through calls to setStatus().
115          */
116         void convertToDisplayFormat();
117
118         /** Load the image into memory. This is called either from
119          *  convertToDisplayFormat() direct or from imageConverted().
120          */
121         void loadImage();
122
123         /** Get a notification when the image conversion is done.
124          *  Connected to a signal on_finish_ which is passed to
125          *  GConverter::convert.
126          */
127         void imageConverted(string const & file_to_load);
128
129         /** Get a notification when the image loading is done.
130          *  Connected to a signal on_finish_ which is passed to
131          *  GImage::loadImage.
132          */
133         void imageLoaded(bool);
134
135         /// How far have we got in loading the original, unmodified image?
136         ImageStatus status() const;
137
138         /** Sets the status of the loading process. Also notifies
139          *  listeners that the status has chacnged.
140          */
141         void setStatus(ImageStatus new_status);
142
143         /// The filename we refer too.
144         string filename_;
145         /// Is the file compressed?
146         bool zipped_;
147         /// If so, store the uncompressed file in this temporary file.
148         string unzipped_filename_;
149         /// What file are we trying to load?
150         string file_to_load_;
151         /** Should we delete the file after loading? True if the file is
152          *  the result of a conversion process.
153          */
154         bool remove_loaded_file_;
155
156         /// The original, unmodified image and its loading status.
157         ImagePtr image_;
158         ///
159         ImageStatus status_;
160
161         /** A SignalLoadTypePtr is connected to this->imageLoaded and
162          *  then passed to ImagePtr::load.
163          *  When the image has been loaded, the signal is emitted.
164          *
165          *  We pass a shared_ptr because it is eminently possible for the
166          *  ModifiedItem to be destructed before the loading is complete and
167          *  the signal must remain in scope. It doesn't matter if the slot
168          *  disappears, SigC takes care of that.
169          */
170         typedef boost::signal1<void, bool> SignalLoadType;
171         ///
172         typedef boost::shared_ptr<SignalLoadType> SignalLoadTypePtr;
173
174         /// The connection of the signal passed to ImagePtr::loadImage.
175         boost::signals::connection cl_;
176
177         /** A SignalConvertTypePtr is connected to this->imageConverted and
178          *  then passed to GConverter::convert.
179          *  When the image has been converted to a loadable format, the signal
180          *  is emitted, returning the name of the loadable file to
181          *  imageConverted.
182          */
183         typedef boost::signal1<void, string const &> SignalConvertType;
184         ///
185         typedef boost::shared_ptr<SignalConvertType> SignalConvertTypePtr;
186
187         /// The connection of the signal passed to GConverter::convert.
188         boost::signals::connection cc_;
189
190         /// The list of all modified images.
191         typedef std::list<ModifiedItemPtr> ListType;
192         ///
193         ListType modified_images;
194 };
195
196
197 ///
198 class ModifiedItem {
199 public:
200         ///
201         ModifiedItem(InsetGraphics const &, GParams const &, ImagePtr const &);
202
203         ///
204         GParams const & params() { return *p_.get(); }
205
206         /// Add inset to the list of insets.
207         void add(InsetGraphics const & inset);
208
209         /// Remove inset from the list of insets.
210         void remove(InsetGraphics const & inset);
211
212         ///
213         bool empty() const { return insets.empty(); }
214
215         /// Is this ModifiedItem referenced by inset?
216         bool referencedBy(InsetGraphics const & inset) const;
217
218         ///
219         ImagePtr const image() const;
220
221         /// How far have we got in loading the modified image?
222         ImageStatus status() const { return status_; }
223
224         /** Called from GCacheItem once the raw image is loaded.
225          *  Modifies the image in accord with p_.
226          */
227         void modify(ImagePtr const &);
228
229         /// Updates the pixmap.
230         void setPixmap();
231
232         /** changeDisplay returns a full ModifiedItemPtr if any of the
233          *  insets have display=DEFAULT and if that DEFAULT value has
234          *  changed.
235          *  If this occurs, then this has these insets removed.
236          */
237         boost::shared_ptr<ModifiedItem> changeDisplay();
238
239         ///
240         typedef std::list<InsetGraphics const *> ListType;
241
242         /// Make these accessible for changeDisplay.
243         ListType insets;
244
245 private:
246         /** Sets the status of the loading process. Also notifies
247          *  listeners that the status has changed.
248          */
249         void setStatus(ImageStatus new_status);
250
251         /// The original and modified images and its loading status.
252         ImagePtr original_image_;
253         ///
254         ImagePtr modified_image_;
255         ///
256         ImageStatus status_;
257         ///
258         boost::shared_ptr<GParams> p_;
259 };
260
261 } // namespace grfx
262
263 #endif // GRAPHICSCACHEITEM_H