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"
30 #include <sys/types.h>
36 int action; // 1 = update from client, 2 = client closes
39 #include "empty_svg.h"
41 SvgWin::SvgWin(SvgMain *client)
42 : PluginClientWindow(client, 300, 280, 300, 280, 1)
44 this->client = client;
52 void SvgWin::create_objects()
56 // add_tool(new BC_Title(x, y, _("In X:")));
58 // in_x = new SvgCoord(this, client, x, y, &client->config.in_x);
59 // in_x->create_objects();
62 // add_tool(new BC_Title(x, y, _("In Y:")));
64 // in_y = new SvgCoord(this, client, x, y, &client->config.in_y);
65 // in_y->create_objects();
68 // add_tool(new BC_Title(x, y, _("In W:")));
70 // in_w = new SvgCoord(this, client, x, y, &client->config.in_w);
71 // in_w->create_objects();
74 // add_tool(new BC_Title(x, y, _("In H:")));
76 // in_h = new SvgCoord(this, client, x, y, &client->config.in_h);
77 // in_h->create_objects();
83 add_tool(new BC_Title(x, y, _("Out X:")));
85 out_x = new SvgCoord(this, client, x, y, &client->config.out_x);
86 out_x->create_objects();
89 add_tool(new BC_Title(x, y, _("Out Y:")));
91 out_y = new SvgCoord(this, client, x, y, &client->config.out_y);
92 out_y->create_objects();
95 /* add_tool(new BC_Title(x, y, _("Out W:")));
97 out_w = new SvgCoord(this, client, x, y, &client->config.out_w);
98 out_w->create_objects();
101 add_tool(new BC_Title(x, y, _("Out H:")));
103 out_h = new SvgCoord(this, client, x, y, &client->config.out_h);
104 out_h->create_objects();
108 add_tool(new_svg_button = new NewSvgButton(client, this, x, y));
109 add_tool(edit_svg_button = new EditSvgButton(client, this, x+190, y));
110 add_tool(svg_file_title = new BC_Title(x, y+26, client->config.svg_file));
118 int SvgWin::close_event()
124 SvgCoord::SvgCoord(SvgWin *win,
129 : BC_TumbleTextBox(win,
137 //printf("SvgWidth::SvgWidth %f\n", client->config.w);
138 this->client = client;
143 SvgCoord::~SvgCoord()
147 int SvgCoord::handle_event()
149 *value = atof(get_text());
150 client->send_configure_change();
154 NewSvgButton::NewSvgButton(SvgMain *client, SvgWin *window, int x, int y)
155 : BC_GenericButton(x, y, _("New/Open SVG..."))
157 this->client = client;
158 this->window = window;
161 int NewSvgButton::handle_event()
163 window->editing_lock.lock();
164 if (!window->editing)
167 window->editing_lock.unlock();
172 // FIXME - display an error
173 window->editing_lock.unlock();
179 void NewSvgButton::run()
181 // ======================================= get path from user
183 //printf("NewSvgButton::run 1\n");
186 strncpy(filename, client->config.svg_file, sizeof(filename));
187 // Loop until file is chosen
189 char directory[1024];
190 strncpy(directory, client->config.svg_file, sizeof(directory));
191 char *cp = strrchr(directory, '/');
193 if( !directory[0] ) {
194 char *cp = getenv("HOME");
195 if( !cp ) strncpy(directory, cp, sizeof(directory));
197 NewSvgWindow *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 const char *filepath = new_window->get_path(0);
202 if( result || !filepath || !*filepath ) {
203 window->editing_lock.lock();
205 window->editing_lock.unlock();
206 return; // cancel or no filename given
208 strcpy(filename, filepath);
211 // Extend the filename with .svg
212 if(strlen(filename) < 4 ||
213 strcasecmp(&filename[strlen(filename) - 4], ".svg")) {
214 strcat(filename, ".svg");
217 if( !access(filename, R_OK) )
220 FILE *out = fopen(filename,"w");
222 unsigned long size = sizeof(empty_svg) - 4;
223 fwrite(empty_svg+4, size, 1, out);
228 } while(result); // file doesn't exist so repeat
231 strcpy(client->config.svg_file, filename);
232 client->send_configure_change();
235 if(quit_now) window->set_done(0);
236 window->editing_lock.lock();
238 window->editing_lock.unlock();
243 EditSvgButton::EditSvgButton(SvgMain *client, SvgWin *window, int x, int y)
244 : BC_GenericButton(x, y, _("Edit"))
246 this->client = client;
247 this->window = window;
251 EditSvgButton::~EditSvgButton() {
252 struct fifo_struct fifo_buf;
253 fifo_buf.pid = getpid();
256 write (fh_fifo, &fifo_buf, sizeof(fifo_buf)); // break the thread out of reading from fifo
259 int EditSvgButton::handle_event()
262 window->editing_lock.lock();
263 if (!window->editing && client->config.svg_file[0] != 0)
266 window->editing_lock.unlock();
270 // FIXME - display an error
271 window->editing_lock.unlock();
276 void EditSvgButton::run()
278 // ======================================= get path from user
282 //struct stat st_png;
283 //char filename[1024];
284 char filename_png[1024];
285 char filename_fifo[1024];
286 struct fifo_struct fifo_buf;
287 SvgInkscapeThread *inkscape_thread = new SvgInkscapeThread(client, window);
289 strcpy(filename_png, client->config.svg_file);
290 strcat(filename_png, ".png");
291 remove(filename_png);
292 strcpy(filename_fifo, filename_png);
293 strcat(filename_fifo, ".fifo");
294 if (mkfifo(filename_fifo, S_IRWXU) != 0) {
295 perror(_("Error while creating fifo file"));
297 fh_fifo = open(filename_fifo, O_RDWR);
299 inkscape_thread->fh_fifo = fh_fifo;
300 inkscape_thread->start();
301 while (inkscape_thread->running() && (!quit_now)) {
302 Timer::delay(200); // poll file every 200ms
303 read(fh_fifo, &fifo_buf, sizeof(fifo_buf));
305 if (fifo_buf.action == 1) {
306 client->send_configure_change();
307 } else if (fifo_buf.action == 2) {
308 printf(_("Inkscape has exited\n"));
309 } else if (fifo_buf.action == 3) {
310 printf(_("Plugin window has closed\n"));
311 delete inkscape_thread;
316 remove(filename_fifo); // fifo destroyed on last close
317 inkscape_thread->join();
319 window->editing_lock.lock();
321 window->editing_lock.unlock();
323 client->send_configure_change();
326 SvgInkscapeThread::SvgInkscapeThread(SvgMain *client, SvgWin *window)
329 this->client = client;
330 this->window = window;
333 SvgInkscapeThread::~SvgInkscapeThread()
335 // what do we do? kill inkscape?
339 void SvgInkscapeThread::run()
343 sprintf(command, "inkscape --with-gui %s", client->config.svg_file);
344 printf(_("Running external SVG editor: %s\n"), command);
348 printf(_("External SVG editor finished\n"));
349 struct fifo_struct fifo_buf;
350 fifo_buf.pid = getpid();
352 write (fh_fifo, &fifo_buf, sizeof(fifo_buf));
360 NewSvgWindow::NewSvgWindow(SvgMain *client, SvgWin *window, char *init_directory)
362 BC_WindowBase::get_resources()->filebox_h / 2,
364 _("SVG Plugin: Pick SVG file"),
365 _("Open an existing SVG file or create a new one"))
367 this->window = window;
370 NewSvgWindow::~NewSvgWindow() {}