r125: This commit was manufactured by cvs2svn to create tag 'r1_1_7-last'.
[cinelerra_cv/mob.git] / hvirtual / plugins / svg / svgwin.C
blob525f3d07e098ea32780d96831e1d89d9e6e18447
1 #include "bcdisplayinfo.h"
2 #include "clip.h"
3 #include "svgwin.h"
4 #include "string.h"
5 #include "filexml.h"
6 #include <unistd.h>
7 #include <fcntl.h>
9 #include <libintl.h>
10 #define _(String) gettext(String)
11 #define gettext_noop(String) String
12 #define N_(String) gettext_noop (String)
14 #include "empty_svg.h"
18 PLUGIN_THREAD_OBJECT(SvgMain, SvgThread, SvgWin)
25 SvgWin::SvgWin(SvgMain *client, int x, int y)
26  : BC_Window(client->gui_string, 
27         x,
28         y,
29         300, 
30         280, 
31         300, 
32         280, 
33         0, 
34         0,
35         1)
36
37         this->client = client; 
40 SvgWin::~SvgWin()
44 int SvgWin::create_objects()
46         int x = 10, y = 10;
48 //      add_tool(new BC_Title(x, y, _("In X:")));
49         y += 20;
50 //      in_x = new SvgCoord(this, client, x, y, &client->config.in_x);
51 //      in_x->create_objects();
52         y += 30;
54 //      add_tool(new BC_Title(x, y, _("In Y:")));
55         y += 20;
56 //      in_y = new SvgCoord(this, client, x, y, &client->config.in_y);
57 //      in_y->create_objects();
58         y += 30;
60 //      add_tool(new BC_Title(x, y, _("In W:")));
61         y += 20;
62 //      in_w = new SvgCoord(this, client, x, y, &client->config.in_w);
63 //      in_w->create_objects();
64         y += 30;
66 //      add_tool(new BC_Title(x, y, _("In H:")));
67         y += 20;
68 //      in_h = new SvgCoord(this, client, x, y, &client->config.in_h);
69 //      in_h->create_objects();
70         y += 30;
73         x += 150;
74         y = 10;
75         add_tool(new BC_Title(x, y, _("Out X:")));
76         y += 20;
77         out_x = new SvgCoord(this, client, x, y, &client->config.out_x);
78         out_x->create_objects();
79         y += 30;
81         add_tool(new BC_Title(x, y, _("Out Y:")));
82         y += 20;
83         out_y = new SvgCoord(this, client, x, y, &client->config.out_y);
84         out_y->create_objects();
85         y += 30;
87         add_tool(new BC_Title(x, y, _("Out W:")));
88         y += 20;
89         out_w = new SvgCoord(this, client, x, y, &client->config.out_w);
90         out_w->create_objects();
91         y += 30;
93         add_tool(new BC_Title(x, y, _("Out H:")));
94         y += 20;
95         out_h = new SvgCoord(this, client, x, y, &client->config.out_h);
96         out_h->create_objects();
97         y += 30;
99         x -= 150;
100         add_tool(new_svg_button = new NewSvgButton(client, this, x, y));
101         add_tool(edit_svg_button = new EditSvgButton(client, this, x+190, y));
102         add_tool(svg_file_title = new BC_Title(x, y+26, client->config.svg_file));
104         x +=150;
106         show_window();
107         flush();
108         return 0;
111 int SvgWin::close_event()
113         set_done(1);
114         return 1;
117 SvgCoord::SvgCoord(SvgWin *win, 
118         SvgMain *client, 
119         int x, 
120         int y,
121         float *value)
122  : BC_TumbleTextBox(win,
123         *value,
124         (float)0,
125         (float)3000,
126         x, 
127         y, 
128         100)
130 //printf("SvgWidth::SvgWidth %f\n", client->config.w);
131         this->client = client;
132         this->win = win;
133         this->value = value;
136 SvgCoord::~SvgCoord()
140 int SvgCoord::handle_event()
142         *value = atof(get_text());
144         client->send_configure_change();
145         return 1;
148 NewSvgButton::NewSvgButton(SvgMain *client, SvgWin *window, int x, int y)
149  : BC_GenericButton(x, y, _("New/Open SVG..."))
151         this->client = client;
152         this->window = window;
153         quit_now = 0;
155 int NewSvgButton::handle_event()
157         quit_now = 0;
158         start();
159         return 1;
162 void NewSvgButton::run()
164 // ======================================= get path from user
165         int result;
166 //printf("NewSvgButton::run 1\n");
167         char directory[1024], filename[1024];
168         sprintf(directory, "~");
169         client->defaults->get("DIRECTORY", directory);
171 // Loop until file is chosen
172         do{
173                 NewSvgWindow *new_window;
175                 new_window = new NewSvgWindow(client, window, directory);
176                 new_window->create_objects();
177                 new_window->update_filter("*.svg");
178                 result = new_window->run_window();
179                 client->defaults->update("DIRECTORY", new_window->get_path());
180                 strcpy(filename, new_window->get_path());
181                 delete new_window;
183 // Extend the filename with .svg
184                 if(strlen(filename) < 4 || 
185                         strcasecmp(&filename[strlen(filename) - 4], ".svg"))
186                 {
187                         strcat(filename, ".svg");
188                 }
190 // ======================================= try to save it
191                 if(filename[0] == 0) return;              // no filename given
192                 if(result == 1) return;          // user cancelled
193                 FILE *in;
194                 if(in = fopen(filename, "rb"))
195                 {
196                         fclose(in);
197                         // file exists
198                         result = 0; 
199                 } else
200                 {
201                         // create fresh file
202                         in = fopen(filename, "w+");
203                         unsigned long size;
204                         size = (((unsigned long)empty_svg[0]) << 24) +
205                                 (((unsigned long)empty_svg[1]) << 16) +
206                                 (((unsigned long)empty_svg[2]) << 8) +
207                                 ((unsigned long)empty_svg[3]);
208                         printf("in: %p size: %li\n", in, size);
209                         // FIXME this is not cool on different arhitectures
210                         
211                         fwrite(empty_svg+4, size,  1, in);
212                         fclose(in);
213                 }
214         } while(result);        // file doesn't exist so repeat
215         
216         // find out starting pixel width and height of the svg
217         // FIXME - currenlty works only for mm units
218         {
219                 FileXML xml_file;
220                 int result;
221                 xml_file.read_from_file(filename);
222                 do {
223                         result = xml_file.read_tag();
224 //                      printf("tag_title: %s\n", xml_file.tag.get_title());
225                         if (xml_file.tag.title_is("svg\n"))
226                         {
227                                 char *wvalue, *hvalue;
228                                 int slen;
229                                 float w, h;
230                                 wvalue = xml_file.tag.get_property("width");
231                                 slen = strlen(wvalue);
232                                 if (slen<3 || strcmp(wvalue+slen-2, "mm"))
233                                 {
234                                         printf(_("SVG Width is currently only supported in millimeters: %s, falling back to 100\n"), wvalue);
235                                         w = 100;
236                                 } else {
237                                         wvalue[slen-2] = 0;
238                                         w = atof(wvalue);                                       
239                                 }
240         
241                                 hvalue = xml_file.tag.get_property("height");
242                                 slen = strlen(hvalue);
243                                 if (slen<3 || strcmp(hvalue+slen-2, "mm"))
244                                 {
245                                         printf(_("SVG Height is currently only supported in millimeters: %s, falling back to 100\n"), hvalue);
246                                         h = 100;
247                                 } else {
248                                         hvalue[slen-2] = 0;
249                                         h = atof(hvalue);                                       
250                                 }
251                                 client->config.in_w = w;
252                                 client->config.in_h = h;
253                                 client->config.out_w = w;
254                                 client->config.out_h = h;
255                                 client->config.in_x = 0;
256                                 client->config.in_y = 0;
257 //                              client->config.out_x = 0;
258 //                              client->config.out_y = 0;
260                                 window->out_w->update(wvalue);
261                                 window->out_h->update(hvalue);
264                         }
265                 } while (!result);              
266         }
268         window->svg_file_title->update(filename);
269         window->flush();
270         strcpy(client->config.svg_file, filename);
271         client->need_reconfigure = 1;
272         client->force_png_render = 1;
273         client->send_configure_change();
275 // save it
276         if(quit_now) window->set_done(0);
277         return;
280 EditSvgButton::EditSvgButton(SvgMain *client, SvgWin *window, int x, int y)
281  : BC_GenericButton(x, y, _("Edit"))
283         this->client = client;
284         this->window = window;
285         this->editing = 0;
287 int EditSvgButton::handle_event()
289         
290         editing_lock.lock();
291         if (!editing && client->config.svg_file[0] != 0) 
292         {
293                 editing = 1;
294                 editing_lock.unlock();
295                 start();
296         } else
297         {
298                 editing_lock.unlock();
299         }
300                 return 1;
303 void EditSvgButton::run()
305 // ======================================= get path from user
306         Timer pausetimer;
307         long delay;
308         int result;
309         time_t last_update;
310         struct stat st_png;
311         char filename_png[1024];
312         SvgSodipodiThread *sodipodi_thread = new SvgSodipodiThread(client, window);
313         
314         strcpy(filename_png, client->config.svg_file);
315         strcat(filename_png, ".png");
316         result = stat (filename_png, &st_png);
317         last_update = st_png.st_mtime;
318         if (result) 
319                 last_update = 0;        
321         sodipodi_thread->start();
322         while (sodipodi_thread->running()) {
323                 pausetimer.delay(200); // poll file every 200ms
324                 struct stat st_png;
325                 result = stat (filename_png, &st_png);
326 //              printf("checking: %s %li\n", filename_png, st_png.st_mtime);
327                 // Check if PNG is newer then what we have in memory
328                 if (last_update < st_png.st_mtime) {
329                         // UPDATE IMAGE
330 //                      printf("updated\n");
331                         client->send_configure_change();
332                         last_update = st_png.st_mtime;
333                 }
334                 
335         }
336         sodipodi_thread->join();
337         editing_lock.lock();
338         editing = 0;
339         editing_lock.unlock();
343 SvgSodipodiThread::SvgSodipodiThread(SvgMain *client, SvgWin *window)
344  : Thread(1)
346         this->client = client;
347         this->window = window;
350 SvgSodipodiThread::~SvgSodipodiThread()
352         // what do we do? kill sodipodi?
353         cancel();
356 void SvgSodipodiThread::run()
358 // Runs the sodipodi
359         char command[1024];
360         char filename_png[1024];
361         strcpy(filename_png, client->config.svg_file);
362         strcat(filename_png, ".png");
364         sprintf(command, "sodipodi --cinelerra-export-file=%s --export-width=%i --export-height=%i %s",
365                 filename_png, (int)client->config.in_w, (int)client->config.in_h, client->config.svg_file);
366         printf(_("Running external SVG editor: %s\n"), command);                
367         enable_cancel();
368         system(command);
369         disable_cancel();
370         int result;
371         return;
376 NewSvgWindow::NewSvgWindow(SvgMain *client, SvgWin *window, char *init_directory)
377  : BC_FileBox(0,
378         BC_WindowBase::get_resources()->filebox_h / 2,
379         init_directory, 
380         _("SVG Plugin: Pick SVG file"), 
381         _("Open an existing SVG file or create a new one"))
383         this->window = window; 
386 NewSvgWindow::~NewSvgWindow() {}