]> git.lyx.org Git - lyx.git/blob - src/graphics/GraphicsCacheItem.C
to much stuff for my liking...
[lyx.git] / src / graphics / GraphicsCacheItem.C
1 /* This file is part of
2  * =================================================
3  * 
4  *          LyX, The Document Processor
5  *          Copyright 1995 Matthias Ettrich.
6  *          Copyright 1995-2001 The LyX Team.
7  *
8  * \author Baruch Even
9  * \author Herbert Voss <voss@lyx.org>
10  * ================================================= */
11
12 #include <config.h>
13
14 #ifdef __GNUG__
15 #pragma implementation
16 #endif
17
18 #include "graphics/GraphicsCacheItem.h"
19 #include "graphics/GraphicsCache.h"
20 #include "graphics/ImageLoaderXPM.h"
21 #include "converter.h"
22 #include "lyx_gui_misc.h"
23 #include "debug.h"
24 #include "support/LAssert.h"
25 #include "gettext.h"
26 #include "lyxfunc.h"
27
28 #include "frontends/support/LyXImage.h"
29
30 #include "support/filetools.h"
31 #include "support/lyxlib.h"
32
33 using std::endl;
34
35
36 /*
37  * The order of conversion:
38  *
39  * The c-tor calls convertImage()
40  * 
41  * convertImage() verifies that we need to do conversion, if not it will just
42  * call the loadImage()
43  * if conversion is needed, it will initiate the conversion.
44  *
45  * When the conversion is completed imageConverted() is called, which in turn
46  * calls loadImage().
47  *
48  * Since we currently do everything synchronously, convertImage() calls
49  * imageConverted() right after it does the call to the conversion process.
50 */
51
52 GraphicsCacheItem::GraphicsCacheItem(string const & filename)
53         : filename_(filename), imageStatus_(GraphicsCacheItem::Loading)
54 {
55         bool success = convertImage(filename);
56         if (!success) // Conversion failed miserably (couldn't even start).
57                 setStatus(ErrorConverting);
58 }
59
60
61 GraphicsCacheItem::~GraphicsCacheItem()
62 {}
63
64
65 GraphicsCacheItem::ImageStatus 
66 GraphicsCacheItem::getImageStatus() const
67 {
68         return imageStatus_;
69 }
70
71
72 void GraphicsCacheItem::setStatus(ImageStatus new_status)
73 {
74         imageStatus_ = new_status;
75 }
76
77
78 LyXImage * 
79 GraphicsCacheItem::getImage() const
80 {
81         return image_.get();
82 }
83
84
85 void GraphicsCacheItem::imageConverted(bool success)
86 {
87         // Debug output
88         string text = "succeeded";
89         if (!success)
90                 text = "failed";
91         lyxerr << "imageConverted, conversion " << text << "." << endl;
92
93         if (! success) {
94                 lyxerr << "(GraphicsCacheItem::imageConverter) "
95                         "Error converting image." << endl;
96                 setStatus(GraphicsCacheItem::ErrorConverting);
97                 return;
98         }
99
100         // Do the actual image loading from file to memory.
101         loadImage();    
102 }
103
104
105 namespace {
106
107 string const findTargetFormat(string const & from)
108 {
109         typedef ImageLoader::FormatList FormatList;
110         FormatList formats = ImageLoaderXPM().loadableFormats();
111         lyx::Assert(formats.size() > 0); // There must be a format to load from.
112
113         FormatList::const_iterator iter = formats.begin();
114         FormatList::const_iterator end  = formats.end();
115
116         for (; iter != end; ++iter) {
117                 if (converters.isReachable(from, *iter))
118                         break;
119         }
120         if (iter == end) {
121                 // We do not know how to convert the image to something loadable.
122                 lyxerr << "ERROR: Do not know how to convert image." << endl;
123                 return string();
124         }
125         return (*iter);
126 }
127
128 } // anon namespace
129
130         
131 bool GraphicsCacheItem::convertImage(string const & filename)
132 {
133         setStatus(GraphicsCacheItem::Converting);
134 #warning shadowing class variable (Lgb)
135         // Is this needed at all?
136         string filename_ = string(filename);
137         lyxerr << "try to convert image file: " << filename_ << endl;
138 // maybe that other zip extensions also be useful, especially the
139 // ones that may be declared in texmf/tex/latex/config/graphics.cfg.
140 // for example:
141 /* -----------snip-------------
142           {\DeclareGraphicsRule{.pz}{eps}{.bb}{}%
143            \DeclareGraphicsRule{.eps.Z}{eps}{.eps.bb}{}%
144            \DeclareGraphicsRule{.ps.Z}{eps}{.ps.bb}{}%
145            \DeclareGraphicsRule{.ps.gz}{eps}{.ps.bb}{}%
146            \DeclareGraphicsRule{.eps.gz}{eps}{.eps.bb}{}}}%
147    -----------snip-------------*/
148
149         lyxerr << "GetExtension: " << GetExtension(filename_) << endl;
150         bool const zipped = zippedFile(filename_);
151         if (zipped)
152             filename_ = unzipFile(filename_);
153         string const from = getExtFromContents(filename_);      // get the type
154         lyxerr << "GetExtFromContents: " << from << endl;
155         string const to = findTargetFormat(from);
156         lyxerr << "from: " << from << " -> " << to << endl;
157         if (to.empty()) 
158                 return false;
159         // manage zipped files. unzip them first into the tempdir
160         if (from == to) {
161                 // No conversion needed!
162                 // Saves more than just time: prevents the deletion of
163                 // the "to" file after loading when it's the same as the "from"!
164                 tempfile = filename_;
165                 loadImage();    
166                 return true;
167         }
168         // Take only the filename part of the file, without path or extension.
169         string temp = OnlyFilename(filename_);
170         temp = ChangeExtension(filename_, string());
171         
172         // Add some stuff to have it a unique temp file.
173         // This tempfile is deleted in loadImage after it is loaded to memory.
174         tempfile = lyx::tempName(string(), temp);
175         // Remove the temp file, we only want the name...
176         lyx::unlink(tempfile);
177         bool result = converters.convert(0, filename_, tempfile, from, to);
178         tempfile.append(".xpm");
179         // For now we are synchronous
180         imageConverted(result);
181         // Cleanup after the conversion.
182         lyx::unlink(tempfile);
183         if (zipped)
184             lyx::unlink(filename_);
185         tempfile.erase();
186         return true;
187 }
188
189
190 // This function gets called from the callback after the image has been
191 // converted successfully.
192 void
193 GraphicsCacheItem::loadImage()
194 {
195         lyxerr << "Loading XPM Image... ";
196
197         ImageLoaderXPM imageLoader;
198         if (imageLoader.loadImage(tempfile) == ImageLoader::OK) {
199                 lyxerr << "Success." << endl;
200                 image_.reset(imageLoader.getImage());
201                 setStatus(GraphicsCacheItem::Loaded);
202         } else {
203                 lyxerr << "Loading " << tempfile << "Failed" << endl;
204                 setStatus(GraphicsCacheItem::ErrorReading);
205         }
206 }