]> git.lyx.org Git - lyx.git/blob - src/graphics/GraphicsCacheItem.C
Angus's insetref-patch and a small fix.
[lyx.git] / src / graphics / GraphicsCacheItem.C
1 // -*- C++ -*-
2 /* This file is part of
3  * =================================================
4  * 
5  *          LyX, The Document Processor
6  *          Copyright 1995 Matthias Ettrich.
7  *          Copyright 1995-2000 The LyX Team.
8  *
9  *          This file Copyright 2000 Baruch Even
10  * ================================================= */
11
12 #include <config.h>
13
14 #ifdef __GNUG__
15 #pragma implementation
16 #endif
17
18 #include "GraphicsCacheItem.h"
19
20 #include "graphics/XPM_Renderer.h"
21 #include "support/filetools.h"
22 #include "debug.h"
23 #include "support/LAssert.h"
24 #include <unistd.h> // unlink
25
26 #include <map>
27
28 #include FORMS_H_LOCATION
29
30 using std::endl;
31 using std::map;
32
33 GraphicsCacheItem::GraphicsCacheItem()
34         : height_(-1), width_(-1), imageStatus_(Loading),
35           pixmap_(0), renderer(0)
36 {}
37
38 GraphicsCacheItem::~GraphicsCacheItem()
39 {
40         if (imageStatus_ == Loaded) {
41                 XFreePixmap(fl_display, pixmap_);
42         }
43
44         delete renderer;
45 }
46
47 bool
48 GraphicsCacheItem::setFilename(string const & filename)
49 {
50         imageStatus_ = Loading;
51
52         renderer = new XPM_Renderer();
53         if (renderXPM(filename))
54                 return true;
55         
56         return false;
57 }
58
59 /*** Callback method ***/
60
61 typedef map<string, GraphicsCacheItem*> CallbackMap;
62 static CallbackMap callbackMap;
63
64 void
65 callback(string cmd, int retval)
66 {
67         lyxerr << "callback, cmd="<<cmd<<", retval="<<retval<<endl;
68
69         GraphicsCacheItem * item = callbackMap[cmd];
70         callbackMap.erase(cmd);
71         
72         item->imageConverted(retval);
73 }
74
75 void
76 GraphicsCacheItem::imageConverted(int retval)
77 {
78         lyxerr << "imageConverted, retval="<<retval<<endl;
79
80         if (retval) {
81                 imageStatus_ = ErrorConverting;
82                 return;
83         }
84
85         // Do the actual image loading from XPM to memory.
86         loadXPMImage(); 
87 }
88
89 /**********************/
90
91 bool
92 GraphicsCacheItem::renderXPM(string const & filename)
93 {
94         // Create the command to do the conversion, this depends on ImageMagicks
95         // convert program.
96         string command = "convert ";
97         command += filename;
98         command += " XPM:";
99
100         // Take only the filename part of the file, without path or extension.
101         string temp = OnlyFilename(filename);
102         temp = ChangeExtension(filename , string());
103         
104         // Add some stuff to have it a unique temp file.
105         xpmfile = TmpFileName(string(), temp);
106         xpmfile = ChangeExtension(xpmfile, ".xpm");     
107         
108         command += xpmfile;
109
110         // Set the callback mapping to point to us.
111         callbackMap[command] = this;
112
113         // Run the convertor.
114         // There is a problem with running it asyncronously, it doesn't return
115         // to call the callback, so until the Systemcalls mechanism is fixed
116         // I use the syncronous method.
117         lyxerr << "Launching convert to xpm, command="<<command<<endl;
118 //      syscall.startscript(Systemcalls::DontWait, command, &callback);
119         syscall.startscript(Systemcalls::Wait, command, &callback);
120
121         return true;
122 }
123
124 // This function gets called from the callback after the image has been
125 // converted successfully.
126 void
127 GraphicsCacheItem::loadXPMImage()
128 {
129         if (! renderer->setFilename(xpmfile)) {
130                 return;
131         }
132
133         if (renderer->renderImage()) {
134                 pixmap_ = renderer->getPixmap();
135                 width_ = renderer->getWidth();
136                 height_ = renderer->getHeight();
137                 imageStatus_ = Loaded;
138         } else {
139                 imageStatus_ = ErrorReading;
140         }
141
142         imageDone.emit();
143
144         // remove the xpm file now.
145         ::unlink(xpmfile.c_str());
146         // and remove the reference to the filename.
147         xpmfile = string();
148 }