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