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