r1008: pt_BR translation update
[cinelerra_cv/mob.git] / plugins / svg / svgwin.C
blob07b78a5277534da13b4fd37f6aa46d18c75e9b8b
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>
8 #include <sys/types.h>
9 #include <fcntl.h>
10 #include <sys/stat.h>
12 struct fifo_struct {
13         int pid;
14         int action;  // 1 = update from client, 2 = client closes
15       };
18 #include <libintl.h>
19 #define _(String) gettext(String)
20 #define gettext_noop(String) String
21 #define N_(String) gettext_noop (String)
23 #include "empty_svg.h"
27 PLUGIN_THREAD_OBJECT(SvgMain, SvgThread, SvgWin)
34 SvgWin::SvgWin(SvgMain *client, int x, int y)
35  : BC_Window(client->gui_string, 
36         x,
37         y,
38         300, 
39         280, 
40         300, 
41         280, 
42         0, 
43         0,
44         1)
45
46         this->client = client; 
47         this->editing = 0;
50 SvgWin::~SvgWin()
54 int SvgWin::create_objects()
56         int x = 10, y = 10;
58 //      add_tool(new BC_Title(x, y, _("In X:")));
59         y += 20;
60 //      in_x = new SvgCoord(this, client, x, y, &client->config.in_x);
61 //      in_x->create_objects();
62         y += 30;
64 //      add_tool(new BC_Title(x, y, _("In Y:")));
65         y += 20;
66 //      in_y = new SvgCoord(this, client, x, y, &client->config.in_y);
67 //      in_y->create_objects();
68         y += 30;
70 //      add_tool(new BC_Title(x, y, _("In W:")));
71         y += 20;
72 //      in_w = new SvgCoord(this, client, x, y, &client->config.in_w);
73 //      in_w->create_objects();
74         y += 30;
76 //      add_tool(new BC_Title(x, y, _("In H:")));
77         y += 20;
78 //      in_h = new SvgCoord(this, client, x, y, &client->config.in_h);
79 //      in_h->create_objects();
80         y += 30;
83         x += 150;
84         y = 10;
85         add_tool(new BC_Title(x, y, _("Out X:")));
86         y += 20;
87         out_x = new SvgCoord(this, client, x, y, &client->config.out_x);
88         out_x->create_objects();
89         y += 30;
91         add_tool(new BC_Title(x, y, _("Out Y:")));
92         y += 20;
93         out_y = new SvgCoord(this, client, x, y, &client->config.out_y);
94         out_y->create_objects();
95         y += 30;
97 /*      add_tool(new BC_Title(x, y, _("Out W:")));
98         y += 20;
99         out_w = new SvgCoord(this, client, x, y, &client->config.out_w);
100         out_w->create_objects();
101         y += 30;
103         add_tool(new BC_Title(x, y, _("Out H:")));
104         y += 20;
105         out_h = new SvgCoord(this, client, x, y, &client->config.out_h);
106         out_h->create_objects();
107         y += 30;
109         x -= 150;
110         add_tool(new_svg_button = new NewSvgButton(client, this, x, y));
111         add_tool(edit_svg_button = new EditSvgButton(client, this, x+190, y));
112         add_tool(svg_file_title = new BC_Title(x, y+26, client->config.svg_file));
114         x +=150;
116         show_window();
117         flush();
118         return 0;
121 int SvgWin::close_event()
123         set_done(1);
124         return 1;
127 SvgCoord::SvgCoord(SvgWin *win, 
128         SvgMain *client, 
129         int x, 
130         int y,
131         float *value)
132  : BC_TumbleTextBox(win,
133         *value,
134         (float)0,
135         (float)3000,
136         x, 
137         y, 
138         100)
140 //printf("SvgWidth::SvgWidth %f\n", client->config.w);
141         this->client = client;
142         this->win = win;
143         this->value = value;
146 SvgCoord::~SvgCoord()
150 int SvgCoord::handle_event()
152         *value = atof(get_text());
154         client->send_configure_change();
155         return 1;
158 NewSvgButton::NewSvgButton(SvgMain *client, SvgWin *window, int x, int y)
159  : BC_GenericButton(x, y, _("New/Open SVG..."))
161         this->client = client;
162         this->window = window;
163         quit_now = 0;
165 int NewSvgButton::handle_event()
167         window->editing_lock.lock();
168         if (!window->editing) 
169         {
170                 window->editing = 1;
171                 window->editing_lock.unlock();
172                 quit_now = 0;
173                 start();
174         } else
175         {
176                 // FIXME - display an error
177                 window->editing_lock.unlock();
178         }
180         return 1;
183 void NewSvgButton::run()
185 // ======================================= get path from user
186         int result;
187 //printf("NewSvgButton::run 1\n");
188         char directory[1024], filename[1024];
189         sprintf(directory, "~");
190         client->defaults->get("DIRECTORY", directory);
192         result = 1;
193 // Loop until file is chosen
194         do{
195                 NewSvgWindow *new_window;
197                 new_window = new NewSvgWindow(client, window, directory);
198                 new_window->create_objects();
199                 new_window->update_filter("*.svg");
200                 result = new_window->run_window();
201                 client->defaults->update("DIRECTORY", new_window->get_path(0));
202                 strcpy(filename, new_window->get_path(0));
203                 delete new_window;
205 // Extend the filename with .svg
206                 if(strlen(filename) < 4 || 
207                         strcasecmp(&filename[strlen(filename) - 4], ".svg"))
208                 {
209                         strcat(filename, ".svg");
210                 }
212 // ======================================= try to save it
213                 if((filename[0] == 0) || (result == 1)) {
214                         window->editing_lock.lock();
215                         window->editing = 0;
216                         window->editing_lock.unlock();
217                         return;              // no filename given
218                 }
219                 FILE *in;
220                 if(in = fopen(filename, "rb"))
221                 {
222                         fclose(in);
223                         // file exists
224                         result = 0; 
225                 } else
226                 {
227                         // create fresh file
228                         in = fopen(filename, "w+");
229                         unsigned long size;
230                         size = (((unsigned long)empty_svg[0]) << 24) +
231                                 (((unsigned long)empty_svg[1]) << 16) +
232                                 (((unsigned long)empty_svg[2]) << 8) +
233                                 ((unsigned long)empty_svg[3]);
234                         printf("in: %p size: %li\n", in, size);
235                         // FIXME this is not cool on different arhitectures
236                         
237                         fwrite(empty_svg+4, size,  1, in);
238                         fclose(in);
239                         result = 0;
240                 }
241         } while(result);        // file doesn't exist so repeat
242         
244         window->svg_file_title->update(filename);
245         window->flush();
246         strcpy(client->config.svg_file, filename);
247         client->need_reconfigure = 1;
248         client->force_raw_render = 1;
249         client->send_configure_change();
251 // save it
252         if(quit_now) window->set_done(0);
253         window->editing_lock.lock();
254         window->editing = 0;
255         window->editing_lock.unlock();
257         return;
260 EditSvgButton::EditSvgButton(SvgMain *client, SvgWin *window, int x, int y)
261  : BC_GenericButton(x, y, _("Edit"))
263         this->client = client;
264         this->window = window;
265         quit_now = 0;
268 EditSvgButton::~EditSvgButton() {
269         struct fifo_struct fifo_buf;
270         fifo_buf.pid = getpid();
271         fifo_buf.action = 3;
272         quit_now = 1;
273         write (fh_fifo, &fifo_buf, sizeof(fifo_buf)); // break the thread out of reading from fifo
276 int EditSvgButton::handle_event()
278         
279         window->editing_lock.lock();
280         if (!window->editing && client->config.svg_file[0] != 0) 
281         {
282                 window->editing = 1;
283                 window->editing_lock.unlock();
284                 start();
285         } else
286         {
287                 // FIXME - display an error
288                 window->editing_lock.unlock();
289         }
290         return 1;
293 void EditSvgButton::run()
295 // ======================================= get path from user
296         Timer pausetimer;
297         long delay;
298         int result;
299         time_t last_update;
300         struct stat st_raw;
301         char filename_raw[1024];
302         char filename_fifo[1024];
303         struct fifo_struct fifo_buf;
304         SvgInkscapeThread *inkscape_thread = new SvgInkscapeThread(client, window);
305         
306         strcpy(filename_raw, client->config.svg_file);
307         strcat(filename_raw, ".raw");
308         result = stat (filename_raw, &st_raw);
309         last_update = st_raw.st_mtime;
310         if (result) 
311                 last_update = 0;        
313         strcpy(filename_fifo, filename_raw);
314         strcat(filename_fifo, ".fifo"); 
315         if (mkfifo(filename_fifo, S_IRWXU) != 0) {
316                 perror("Error while creating fifo file");
317         } 
318         fh_fifo = open(filename_fifo, O_RDWR);
319         fifo_buf.action = 0;
320         inkscape_thread->fh_fifo = fh_fifo;
321         inkscape_thread->start();
322         while (inkscape_thread->running() && (!quit_now)) { 
323 //              pausetimer.delay(200); // poll file every 200ms
324                 read(fh_fifo, &fifo_buf, sizeof(fifo_buf));
326                 if (fifo_buf.action == 1) {
327                         result = stat (filename_raw, &st_raw);
328                         // Check if PNG is newer then what we have in memory
329 //                      printf("action1\n");
330 //                      if (last_update < st_raw.st_mtime) { // FIXME this seems to work odd sometimes when fast-refreshing
331 //                              printf("newer pict\n");
332                                 // UPDATE IMAGE
333                                 client->config.last_load = 1;
334                                 client->send_configure_change();
335                                 last_update = st_raw.st_mtime;
336 //                      }
337                 } else 
338                 if (fifo_buf.action == 2) {
339                         printf(_("Inkscape has exited\n"));
340                 } else
341                 if (fifo_buf.action == 3) {
342                         printf(_("Plugin window has closed\n"));
343                         delete inkscape_thread;
344                         close(fh_fifo);
345                         return;
346                 }
347         }
348         inkscape_thread->join();
349         close(fh_fifo);
350         window->editing_lock.lock();
351         window->editing = 0;
352         window->editing_lock.unlock();
356 SvgInkscapeThread::SvgInkscapeThread(SvgMain *client, SvgWin *window)
357  : Thread(1)
359         this->client = client;
360         this->window = window;
363 SvgInkscapeThread::~SvgInkscapeThread()
365         // what do we do? kill inkscape?
366         cancel();
369 void SvgInkscapeThread::run()
371 // Runs the inkscape
372         char command[1024];
373         char filename_raw[1024];
374         strcpy(filename_raw, client->config.svg_file);
375         strcat(filename_raw, ".raw");
377         sprintf(command, "inkscape --cinelerra-export-file=%s %s",
378                 filename_raw, client->config.svg_file);
379         printf(_("Running external SVG editor: %s\n"), command);                
380         enable_cancel();
381         system(command);
382         printf(_("External SVG editor finished\n"));
383         {
384                 struct fifo_struct fifo_buf;
385                 fifo_buf.pid = getpid();
386                 fifo_buf.action = 2;
387                 write (fh_fifo, &fifo_buf, sizeof(fifo_buf));
388         }
389         disable_cancel();
390         return;
395 NewSvgWindow::NewSvgWindow(SvgMain *client, SvgWin *window, char *init_directory)
396  : BC_FileBox(0,
397         BC_WindowBase::get_resources()->filebox_h / 2,
398         init_directory, 
399         _("SVG Plugin: Pick SVG file"), 
400         _("Open an existing SVG file or create a new one"))
402         this->window = window; 
405 NewSvgWindow::~NewSvgWindow() {}