]> git.lyx.org Git - lyx.git/blob - src/graphics/GraphicsCacheItem.h
493550252a31d56705f19be98b5f2883a564f5fc
[lyx.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 <sigc++/signal_system.h>
43
44 #include <list>
45
46 class InsetGraphics;
47
48 namespace grfx {
49
50 class GParams;
51 class ModifiedItem;
52
53 /// A grfx::GCache item holder.
54 class GCacheItem : boost::noncopyable, public SigC::Object {
55 public:
56         /// the GCacheItem contains data of this type.
57         typedef boost::shared_ptr<ModifiedItem> ModifiedItemPtr;
58
59         ///
60         GCacheItem(InsetGraphics const &, GParams const &);
61
62         /// The params have changed (but still refer to this file).
63         void modify(InsetGraphics const &, GParams const &);
64
65         /// Remove the reference to this inset.
66         void remove(InsetGraphics const &);
67
68         /// It's in the cache. Now start the loading process.
69         void startLoading(InsetGraphics const &);
70
71         /// Is the cache item referenced by any insets at all?
72         bool empty() const;
73
74         /// The name of the original image file.
75         string const & filename() const;
76
77         /// Is this image file referenced by this inset?
78         bool referencedBy(InsetGraphics const &) const;
79
80         /** Returns the image referenced by this inset (or an empty container
81          *  if it's not yet loaded.
82          */
83         ImagePtr const image(InsetGraphics const &) const;
84
85         /// The loading status of the image referenced by this inset.
86         ImageStatus status(InsetGraphics const &) const;
87
88         /** If (changed_background == true), then the background color of the
89          *  graphics inset has changed. Update all images.
90          *  Else, the preferred display type has changed.
91          *  Update the view of all insets whose display type is DEFAULT.
92          */
93         void changeDisplay(bool changed_background);
94
95         /// Used to ascertain the Bounding Box of non (e)ps files.
96         unsigned int raw_width() const;
97         ///
98         unsigned int raw_height() const;
99
100 private:
101         /** Start the image conversion process, checking first that it is
102          *  necessary. If it is necessary, then a conversion task is started.
103          *  GCacheItem asumes that the conversion is asynchronous and so
104          *  passes a Signal to the converting routine. When the conversion
105          *  is finished, this Signal is emitted, returning the converted
106          *  file to this->imageConverted.
107          *
108          *  If no file conversion is needed, then convertToDisplayFormat() calls
109          *  loadImage() directly.
110          *
111          *  convertToDisplayFormat() will set the loading status flag as
112          *  approriate through calls to setStatus().
113          */
114         void convertToDisplayFormat();
115
116         /** Load the image into memory. This is called either from
117          *  convertToDisplayFormat() direct or from imageConverted().
118          */
119         void loadImage();
120
121         /** Get a notification when the image conversion is done.
122          *  Connected to a signal on_finish_ which is passed to
123          *  GConverter::convert.
124          */
125         void imageConverted(string const & file_to_load);
126
127         /** Get a notification when the image loading is done.
128          *  Connected to a signal on_finish_ which is passed to
129          *  GImage::loadImage.
130          */
131         void imageLoaded(bool);
132
133         /// How far have we got in loading the original, unmodified image?
134         ImageStatus status() const;
135
136         /** Sets the status of the loading process. Also notifies
137          *  listeners that the status has chacnged.
138          */
139         void setStatus(ImageStatus new_status);
140
141         /// The filename we refer too.
142         string filename_;
143         /// Is the file compressed?
144         bool zipped_;
145         /// If so, store the uncompressed file in this temporary file.
146         string unzipped_filename_;
147         /// What file are we trying to load?
148         string file_to_load_;
149         /** Should we delete the file after loading? True if the file is
150          *  the result of a conversion process.
151          */
152         bool remove_loaded_file_;
153
154         /// The original, unmodified image and its loading status.
155         ImagePtr image_;
156         ///
157         ImageStatus status_;
158
159         /** A SignalLoadTypePtr is connected to this->imageLoaded and
160          *  then passed to ImagePtr::load.
161          *  When the image has been loaded, the signal is emitted.
162          *
163          *  We pass a shared_ptr because it is eminently possible for the
164          *  ModifiedItem to be destructed before the loading is complete and
165          *  the signal must remain in scope. It doesn't matter if the slot
166          *  disappears, SigC takes care of that.
167          */
168         typedef SigC::Signal1<void, bool> SignalLoadType;
169         ///
170         typedef boost::shared_ptr<SignalLoadType> SignalLoadTypePtr;
171
172         /// The connection of the signal passed to ImagePtr::loadImage.
173         SigC::Connection cl_;
174
175         /** A SignalConvertTypePtr is connected to this->imageConverted and
176          *  then passed to GConverter::convert.
177          *  When the image has been converted to a loadable format, the signal
178          *  is emitted, returning the name of the loadable file to
179          *  imageConverted.
180          */
181         typedef SigC::Signal1<void, string const &> SignalConvertType;
182         ///
183         typedef boost::shared_ptr<SignalConvertType> SignalConvertTypePtr;
184
185         /// The connection of the signal passed to GConverter::convert.
186         SigC::Connection cc_;
187
188         /// The list of all modified images.
189         typedef std::list<ModifiedItemPtr> ListType;
190         ///
191         ListType modified_images;
192 };
193
194
195 ///
196 class ModifiedItem {
197 public:
198         ///
199         ModifiedItem(InsetGraphics const &, GParams const &, ImagePtr const &);
200
201         ///
202         GParams const & params() { return *p_.get(); }
203
204         /// Add inset to the list of insets.
205         void add(InsetGraphics const & inset);
206
207         /// Remove inset from the list of insets.
208         void remove(InsetGraphics const & inset);
209
210         ///
211         bool empty() const { return insets.empty(); }
212
213         /// Is this ModifiedItem referenced by inset?
214         bool referencedBy(InsetGraphics const & inset) const;
215
216         ///
217         ImagePtr const image() const;
218
219         /// How far have we got in loading the modified image?
220         ImageStatus status() const { return status_; }
221
222         /** Called from GCacheItem once the raw image is loaded.
223          *  Modifies the image in accord with p_.
224          */
225         void modify(ImagePtr const &);
226
227         /// Updates the pixmap.
228         void setPixmap();
229
230         /** changeDisplay returns a full ModifiedItemPtr if any of the
231          *  insets have display=DEFAULT and if that DEFAULT value has
232          *  changed.
233          *  If this occurs, then this has these insets removed.
234          */
235         boost::shared_ptr<ModifiedItem> changeDisplay();
236
237         ///
238         typedef std::list<InsetGraphics const *> ListType;
239
240         /// Make these accessible for changeDisplay.
241         ListType insets;
242
243 private:
244         /** Sets the status of the loading process. Also notifies
245          *  listeners that the status has changed.
246          */
247         void setStatus(ImageStatus new_status);
248
249         /// The original and modified images and its loading status.
250         ImagePtr original_image_;
251         ///
252         ImagePtr modified_image_;
253         ///
254         ImageStatus status_;
255         ///
256         boost::shared_ptr<GParams> p_;
257 };
258
259 } // namespace grfx
260
261 #endif // GRAPHICSCACHEITEM_H