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