4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "bcdisplayinfo.h"
29 #include <sys/types.h>
35 int action; // 1 = update from client, 2 = client closes
40 #define _(String) gettext(String)
41 #define gettext_noop(String) String
42 #define N_(String) gettext_noop (String)
44 #include "empty_svg.h"
51 SvgWin::SvgWin(SvgMain *client)
52 : PluginClientWindow(client, 300, 280, 300, 280, 1)
54 this->client = client;
62 void SvgWin::create_objects()
66 // add_tool(new BC_Title(x, y, _("In X:")));
68 // in_x = new SvgCoord(this, client, x, y, &client->config.in_x);
69 // in_x->create_objects();
72 // add_tool(new BC_Title(x, y, _("In Y:")));
74 // in_y = new SvgCoord(this, client, x, y, &client->config.in_y);
75 // in_y->create_objects();
78 // add_tool(new BC_Title(x, y, _("In W:")));
80 // in_w = new SvgCoord(this, client, x, y, &client->config.in_w);
81 // in_w->create_objects();
84 // add_tool(new BC_Title(x, y, _("In H:")));
86 // in_h = new SvgCoord(this, client, x, y, &client->config.in_h);
87 // in_h->create_objects();
93 add_tool(new BC_Title(x, y, _("Out X:")));
95 out_x = new SvgCoord(this, client, x, y, &client->config.out_x);
96 out_x->create_objects();
99 add_tool(new BC_Title(x, y, _("Out Y:")));
101 out_y = new SvgCoord(this, client, x, y, &client->config.out_y);
102 out_y->create_objects();
105 /* add_tool(new BC_Title(x, y, _("Out W:")));
107 out_w = new SvgCoord(this, client, x, y, &client->config.out_w);
108 out_w->create_objects();
111 add_tool(new BC_Title(x, y, _("Out H:")));
113 out_h = new SvgCoord(this, client, x, y, &client->config.out_h);
114 out_h->create_objects();
118 add_tool(new_svg_button = new NewSvgButton(client, this, x, y));
119 add_tool(edit_svg_button = new EditSvgButton(client, this, x+190, y));
120 add_tool(svg_file_title = new BC_Title(x, y+26, client->config.svg_file));
128 int SvgWin::close_event()
134 SvgCoord::SvgCoord(SvgWin *win,
139 : BC_TumbleTextBox(win,
147 //printf("SvgWidth::SvgWidth %f\n", client->config.w);
148 this->client = client;
153 SvgCoord::~SvgCoord()
157 int SvgCoord::handle_event()
159 *value = atof(get_text());
160 client->send_configure_change();
164 NewSvgButton::NewSvgButton(SvgMain *client, SvgWin *window, int x, int y)
165 : BC_GenericButton(x, y, _("New/Open SVG..."))
167 this->client = client;
168 this->window = window;
171 int NewSvgButton::handle_event()
173 window->editing_lock.lock();
174 if (!window->editing)
177 window->editing_lock.unlock();
182 // FIXME - display an error
183 window->editing_lock.unlock();
189 void NewSvgButton::run()
191 // ======================================= get path from user
193 //printf("NewSvgButton::run 1\n");
196 strncpy(filename, client->config.svg_file, sizeof(filename));
197 // Loop until file is chosen
199 char directory[1024];
200 strncpy(directory, client->config.svg_file, sizeof(directory));
201 char *cp = strrchr(directory, '/');
203 if( !directory[0] ) {
204 char *cp = getenv("HOME");
205 if( !cp ) strncpy(directory, cp, sizeof(directory));
207 NewSvgWindow *new_window = new NewSvgWindow(client, window, directory);
208 new_window->create_objects();
209 new_window->update_filter("*.svg");
210 result = new_window->run_window();
211 const char *filepath = new_window->get_path(0);
212 if( result || !filepath || !*filepath ) {
213 window->editing_lock.lock();
215 window->editing_lock.unlock();
216 return; // cancel or no filename given
218 strcpy(filename, filepath);
221 // Extend the filename with .svg
222 if(strlen(filename) < 4 ||
223 strcasecmp(&filename[strlen(filename) - 4], ".svg")) {
224 strcat(filename, ".svg");
227 if( !access(filename, R_OK) )
230 FILE *out = fopen(filename,"w");
232 unsigned long size = sizeof(empty_svg) - 4;
233 fwrite(empty_svg+4, size, 1, out);
238 } while(result); // file doesn't exist so repeat
241 strcpy(client->config.svg_file, filename);
242 client->send_configure_change();
245 if(quit_now) window->set_done(0);
246 window->editing_lock.lock();
248 window->editing_lock.unlock();
253 EditSvgButton::EditSvgButton(SvgMain *client, SvgWin *window, int x, int y)
254 : BC_GenericButton(x, y, _("Edit"))
256 this->client = client;
257 this->window = window;
261 EditSvgButton::~EditSvgButton() {
262 struct fifo_struct fifo_buf;
263 fifo_buf.pid = getpid();
266 write (fh_fifo, &fifo_buf, sizeof(fifo_buf)); // break the thread out of reading from fifo
269 int EditSvgButton::handle_event()
272 window->editing_lock.lock();
273 if (!window->editing && client->config.svg_file[0] != 0)
276 window->editing_lock.unlock();
280 // FIXME - display an error
281 window->editing_lock.unlock();
286 void EditSvgButton::run()
288 // ======================================= get path from user
292 //struct stat st_png;
293 //char filename[1024];
294 char filename_png[1024];
295 char filename_fifo[1024];
296 struct fifo_struct fifo_buf;
297 SvgInkscapeThread *inkscape_thread = new SvgInkscapeThread(client, window);
299 strcpy(filename_png, client->config.svg_file);
300 strcat(filename_png, ".png");
301 remove(filename_png);
302 strcpy(filename_fifo, filename_png);
303 strcat(filename_fifo, ".fifo");
304 if (mkfifo(filename_fifo, S_IRWXU) != 0) {
305 perror("Error while creating fifo file");
307 fh_fifo = open(filename_fifo, O_RDWR);
309 inkscape_thread->fh_fifo = fh_fifo;
310 inkscape_thread->start();
311 while (inkscape_thread->running() && (!quit_now)) {
312 Timer::delay(200); // poll file every 200ms
313 read(fh_fifo, &fifo_buf, sizeof(fifo_buf));
315 if (fifo_buf.action == 1) {
316 client->send_configure_change();
317 } else if (fifo_buf.action == 2) {
318 printf(_("Inkscape has exited\n"));
319 } else if (fifo_buf.action == 3) {
320 printf(_("Plugin window has closed\n"));
321 delete inkscape_thread;
326 remove(filename_fifo); // fifo destroyed on last close
327 inkscape_thread->join();
329 window->editing_lock.lock();
331 window->editing_lock.unlock();
333 client->send_configure_change();
336 SvgInkscapeThread::SvgInkscapeThread(SvgMain *client, SvgWin *window)
339 this->client = client;
340 this->window = window;
343 SvgInkscapeThread::~SvgInkscapeThread()
345 // what do we do? kill inkscape?
349 void SvgInkscapeThread::run()
353 sprintf(command, "inkscape --with-gui %s", client->config.svg_file);
354 printf(_("Running external SVG editor: %s\n"), command);
358 printf(_("External SVG editor finished\n"));
359 struct fifo_struct fifo_buf;
360 fifo_buf.pid = getpid();
362 write (fh_fifo, &fifo_buf, sizeof(fifo_buf));
370 NewSvgWindow::NewSvgWindow(SvgMain *client, SvgWin *window, char *init_directory)
372 BC_WindowBase::get_resources()->filebox_h / 2,
374 _("SVG Plugin: Pick SVG file"),
375 _("Open an existing SVG file or create a new one"))
377 this->window = window;
380 NewSvgWindow::~NewSvgWindow() {}