1 /* Dia -- a diagram creation/manipulation program
2 * Copyright (C) 1998 Alexander Larsson
3 *
4 * sheets_dialog_callbacks.c : a sheets and objects dialog
5 * Copyright (C) 2002 M.C. Nelson
6 Steffen Macke
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 *
22 */
23
24 #ifdef HAVE_CONFIG_H
25 # include <config.h>
26 #endif
27
28 #include <errno.h>
29 #include <string.h>
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #ifdef HAVE_UNISTD_H
33 #include <unistd.h>
34 #endif
35 #include <time.h>
36 #ifdef HAVE_UTIME_H
37 #include <utime.h>
38 #else
39 /* isn't this placement common ? */
40 #include <sys/utime.h>
41 #ifdef G_OS_WIN32
42 # define utime(n,b) _utime(n,b)
43 # define utim_buf _utimbuf
44 #endif
45 #endif
46
47 #include <glib/gstdio.h>
48 #include <gmodule.h>
49
50 #undef GTK_DISABLE_DEPRECATED /* GtkOptionMenu */
51 #ifdef GNOME
52 #include <gnome.h>
53 #else
54 #include <gtk/gtk.h>
55 #endif
56
57 #include <libxml/tree.h>
58 #include <libxml/parser.h>
59 #include <libxml/xmlmemory.h>
60
61 #include "gtkwrapbox.h"
62
63 #include "dia_dirs.h"
64 #include "dia_xml_libxml.h"
65 #include "plug-ins.h"
66 #include "object.h"
67
68 #include "interface.h"
69 #include "message.h"
70 #include "sheets.h"
71 #include "sheets_dialog_callbacks.h"
72 #include "sheets_dialog.h"
73
74 #include "pixmaps/line_break.xpm"
75 #include "intl.h"
76
77 static GSList *radio_group = NULL;
78
79 static void
sheets_dialog_hide(void)80 sheets_dialog_hide(void)
81 {
82 gtk_widget_hide(sheets_dialog);
83 }
84
85 gboolean
on_sheets_main_dialog_delete_event(GtkWidget * widget,GdkEvent * event,gpointer user_data)86 on_sheets_main_dialog_delete_event (GtkWidget *widget,
87 GdkEvent *event,
88 gpointer user_data)
89 {
90 sheets_dialog_hide();
91 return TRUE;
92 }
93
94
95 static void
sheets_dialog_up_down_set_sensitive(GList * wrapbox_button_list,GtkToggleButton * togglebutton)96 sheets_dialog_up_down_set_sensitive(GList *wrapbox_button_list,
97 GtkToggleButton *togglebutton)
98 {
99 GtkWidget *button;
100
101 button = lookup_widget(sheets_dialog, "button_move_up");
102
103 /* If the active button is the 1st in the wrapbox, OR
104 if the active button is a linebreak AND is 2nd in the wrapbox
105 THEN set the 'Up' button to insensitive */
106
107 if (!wrapbox_button_list
108 || GTK_TOGGLE_BUTTON(g_list_first(wrapbox_button_list)->data) == togglebutton
109 || (!gtk_object_get_data(GTK_OBJECT(togglebutton), "sheet_object_mod")
110 && g_list_nth(wrapbox_button_list, 1)
111 && GTK_TOGGLE_BUTTON(g_list_nth(wrapbox_button_list, 1)->data)
112 == togglebutton))
113 gtk_widget_set_sensitive(button, FALSE);
114 else
115 gtk_widget_set_sensitive(button, TRUE);
116
117 button = lookup_widget(sheets_dialog, "button_move_down");
118 if (!wrapbox_button_list
119 || GTK_TOGGLE_BUTTON(g_list_last(wrapbox_button_list)->data) == togglebutton
120 || (!gtk_object_get_data(GTK_OBJECT(togglebutton), "sheet_object_mod")
121 && g_list_previous(g_list_last(wrapbox_button_list))
122 && GTK_TOGGLE_BUTTON(g_list_previous(g_list_last(wrapbox_button_list))
123 ->data)
124 == togglebutton))
125 gtk_widget_set_sensitive(button, FALSE);
126 else
127 gtk_widget_set_sensitive(button, TRUE);
128 }
129
130 static void
on_sheets_dialog_object_button_toggled(GtkToggleButton * togglebutton,gpointer ud_wrapbox)131 on_sheets_dialog_object_button_toggled(GtkToggleButton *togglebutton,
132 gpointer ud_wrapbox)
133 {
134 GList *wrapbox_button_list;
135 GtkWidget *button;
136 GtkWidget *table_sheets;
137 GtkWidget *optionmenu_left;
138 GtkWidget *optionmenu_right;
139 gchar *sheet_left;
140 gchar *sheet_right;
141
142 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(togglebutton)) == FALSE)
143 return;
144
145 /* We remember the active button so we don't have to search for it later */
146
147 gtk_object_set_data(GTK_OBJECT(ud_wrapbox), "active_button", togglebutton);
148
149 /* Same with the active wrapbox */
150
151 table_sheets = lookup_widget(sheets_dialog, "table_sheets");
152 gtk_object_set_data(GTK_OBJECT(table_sheets), "active_wrapbox", ud_wrapbox);
153
154 optionmenu_left = lookup_widget(sheets_dialog, "optionmenu_left");
155 sheet_left = gtk_object_get_data(GTK_OBJECT(optionmenu_left),
156 "active_sheet_name");
157
158 optionmenu_right = lookup_widget(sheets_dialog, "optionmenu_right");
159 sheet_right = gtk_object_get_data(GTK_OBJECT(optionmenu_right),
160 "active_sheet_name");
161
162 if ((gboolean)gtk_object_get_data(GTK_OBJECT(ud_wrapbox), "is_left") ==TRUE)
163 {
164 gtk_object_set_data(GTK_OBJECT(table_sheets), "active_optionmenu",
165 optionmenu_left);
166 button = lookup_widget(sheets_dialog, "button_copy");
167 gtk_object_set(GTK_OBJECT(button), "label", _("Copy ->"), NULL);
168 button = lookup_widget(sheets_dialog, "button_copy_all");
169 gtk_object_set(GTK_OBJECT(button), "label", _("Copy All ->"), NULL);
170 button = lookup_widget(sheets_dialog, "button_move");
171 gtk_object_set(GTK_OBJECT(button), "label", _("Move ->"), NULL);
172 button = lookup_widget(sheets_dialog, "button_move_all");
173 gtk_object_set(GTK_OBJECT(button), "label", _("Move All ->"), NULL);
174 }
175 else
176 {
177 gtk_object_set_data(GTK_OBJECT(table_sheets), "active_optionmenu",
178 optionmenu_right);
179 button = lookup_widget(sheets_dialog, "button_copy");
180 gtk_object_set(GTK_OBJECT(button), "label", _("<- Copy"), NULL);
181 button = lookup_widget(sheets_dialog, "button_copy_all");
182 gtk_object_set(GTK_OBJECT(button), "label", _("<- Copy All"), NULL);
183 button = lookup_widget(sheets_dialog, "button_move");
184 gtk_object_set(GTK_OBJECT(button), "label", _("<- Move"), NULL);
185 button = lookup_widget(sheets_dialog, "button_move_all");
186 gtk_object_set(GTK_OBJECT(button), "label", _("<- Move All"), NULL);
187 }
188
189 sheet_left = sheet_left ? sheet_left : ""; /* initial value can be NULL */
190
191 if (!strcmp(sheet_left, sheet_right)
192 || gtk_object_get_data(GTK_OBJECT(togglebutton), "is_hidden_button")
193 || !gtk_object_get_data(GTK_OBJECT(togglebutton), "sheet_object_mod"))
194 {
195 button = lookup_widget(sheets_dialog, "button_copy");
196 gtk_widget_set_sensitive(button, FALSE);
197 button = lookup_widget(sheets_dialog, "button_copy_all");
198 gtk_widget_set_sensitive(button, FALSE);
199 button = lookup_widget(sheets_dialog, "button_move");
200 gtk_widget_set_sensitive(button, FALSE);
201 button = lookup_widget(sheets_dialog, "button_move_all");
202 gtk_widget_set_sensitive(button, FALSE);
203 }
204 else
205 {
206 button = lookup_widget(sheets_dialog, "button_copy");
207 gtk_widget_set_sensitive(button, TRUE);
208 button = lookup_widget(sheets_dialog, "button_copy_all");
209 gtk_widget_set_sensitive(button, TRUE);
210 button = lookup_widget(sheets_dialog, "button_move");
211 gtk_widget_set_sensitive(button, TRUE);
212 button = lookup_widget(sheets_dialog, "button_move_all");
213 gtk_widget_set_sensitive(button, TRUE);
214 }
215
216 wrapbox_button_list = gtk_container_children(GTK_CONTAINER(ud_wrapbox));
217
218 if (g_list_length(wrapbox_button_list))
219 {
220 SheetMod *sm;
221
222 sheets_dialog_up_down_set_sensitive(wrapbox_button_list, togglebutton);
223
224 sm = gtk_object_get_data(GTK_OBJECT(togglebutton), "sheet_mod");
225
226 button = lookup_widget(sheets_dialog, "button_edit");
227 if (!gtk_object_get_data(GTK_OBJECT(togglebutton), "sheet_object_mod")
228 && sm->sheet.scope == SHEET_SCOPE_SYSTEM)
229 gtk_widget_set_sensitive(button, FALSE);
230 else
231 gtk_widget_set_sensitive(button, TRUE);
232
233 button = lookup_widget(sheets_dialog, "button_remove");
234 if (gtk_object_get_data(GTK_OBJECT(togglebutton), "is_hidden_button")
235 && sm->sheet.shadowing == NULL
236 && sm->sheet.scope == SHEET_SCOPE_SYSTEM)
237 gtk_widget_set_sensitive(button, FALSE);
238 else
239 gtk_widget_set_sensitive(button, TRUE);
240 }
241 else
242 {
243 button = lookup_widget(sheets_dialog, "button_move_up");
244 gtk_widget_set_sensitive(button, FALSE);
245 button = lookup_widget(sheets_dialog, "button_move_down");
246 gtk_widget_set_sensitive(button, FALSE);
247 button = lookup_widget(sheets_dialog, "button_edit");
248 gtk_widget_set_sensitive(button, FALSE);
249 button = lookup_widget(sheets_dialog, "button_remove");
250 gtk_widget_set_sensitive(button, FALSE);
251 }
252 g_list_free(wrapbox_button_list);
253 }
254
255 static void
sheets_dialog_wrapbox_add_line_break(GtkWidget * wrapbox)256 sheets_dialog_wrapbox_add_line_break(GtkWidget *wrapbox)
257 {
258 SheetMod *sm;
259 GtkWidget *button;
260 GtkStyle *style;
261 GdkPixmap *pixmap, *mask;
262 GtkWidget *gtkpixmap;
263
264 sm = gtk_object_get_data(GTK_OBJECT(wrapbox), "sheet_mod");
265 g_assert(sm);
266
267 button = gtk_radio_button_new(radio_group);
268 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
269
270 gtk_object_set_data(GTK_OBJECT(button), "sheet_mod", sm);
271
272 radio_group = gtk_radio_button_group(GTK_RADIO_BUTTON(button));
273
274 gtk_toggle_button_set_mode(GTK_TOGGLE_BUTTON(button), FALSE);
275 gtk_container_set_border_width(GTK_CONTAINER(button), 0);
276
277 style = gtk_widget_get_style(wrapbox);
278 pixmap =
279 gdk_pixmap_colormap_create_from_xpm_d(NULL,
280 gtk_widget_get_colormap(wrapbox),
281 &mask,
282 &style->bg[GTK_STATE_NORMAL],
283 line_break_xpm);
284
285 gtkpixmap = gtk_pixmap_new(pixmap, mask);
286 gtk_container_add(GTK_CONTAINER(button), gtkpixmap);
287 gtk_widget_show(gtkpixmap);
288
289 gtk_wrap_box_pack(GTK_WRAP_BOX(wrapbox), button, FALSE, TRUE, FALSE, TRUE);
290 gtk_widget_show(button);
291
292 gtk_tooltips_set_tip(sheets_dialog_tooltips, button, _("Line Break"), NULL);
293
294 g_signal_connect(GTK_OBJECT(button), "toggled",
295 G_CALLBACK(on_sheets_dialog_object_button_toggled),
296 wrapbox);
297 }
298
299 static void
sheets_dialog_object_set_tooltip(SheetObjectMod * som,GtkWidget * button)300 sheets_dialog_object_set_tooltip(SheetObjectMod *som, GtkWidget *button)
301 {
302 gchar *tip;
303
304 switch (som->type){
305 case OBJECT_TYPE_SVG:
306 tip = g_strdup_printf(_("%s\nShape"), som->sheet_object.description);
307 break;
308 case OBJECT_TYPE_PROGRAMMED:
309 tip = g_strdup_printf(_("%s\nObject"), som->sheet_object.description);
310 break;
311 default:
312 tip = g_strdup_printf(_("%s\nUnassigned type"), som->sheet_object.description);
313 break;
314 }
315
316 gtk_tooltips_set_tip(sheets_dialog_tooltips, button, tip, NULL);
317 g_free(tip);
318 }
319
320 static GtkWidget *
sheets_dialog_create_object_button(SheetObjectMod * som,SheetMod * sm,GtkWidget * wrapbox)321 sheets_dialog_create_object_button(SheetObjectMod *som, SheetMod *sm,
322 GtkWidget *wrapbox)
323 {
324 GtkWidget *button;
325 GdkPixmap *pixmap, *mask;
326 GtkWidget *gtkpixmap;
327
328 button = gtk_radio_button_new(radio_group);
329 radio_group = gtk_radio_button_group(GTK_RADIO_BUTTON(button));
330
331 gtk_toggle_button_set_mode(GTK_TOGGLE_BUTTON(button), FALSE);
332 gtk_container_set_border_width(GTK_CONTAINER(button), 0);
333
334 create_object_pixmap(&som->sheet_object, wrapbox, &pixmap, &mask);
335 gtkpixmap = gtk_pixmap_new(pixmap, mask);
336 gtk_container_add(GTK_CONTAINER(button), gtkpixmap);
337 gtk_widget_show(gtkpixmap);
338
339 sheets_dialog_object_set_tooltip(som, button);
340
341 gtk_object_set_data(GTK_OBJECT(button), "sheet_mod", sm);
342 gtk_object_set_data(GTK_OBJECT(button), "sheet_object_mod", som);
343
344 g_signal_connect(GTK_OBJECT(button), "toggled",
345 G_CALLBACK(on_sheets_dialog_object_button_toggled),
346 wrapbox);
347 return button;
348 }
349
350 gboolean optionmenu_activate_first_pass = TRUE;
351
352 void
on_sheets_dialog_optionmenu_activate(GtkMenuItem * menuitem,gpointer user_data)353 on_sheets_dialog_optionmenu_activate (GtkMenuItem *menuitem,
354 gpointer user_data)
355 {
356 GtkWidget *wrapbox;
357 Sheet *sheet;
358 GtkWidget *optionmenu;
359 GSList *object_mod_list;
360 GtkWidget *hidden_button;
361 GList *button_list;
362
363 sheet = &(((SheetMod *)(user_data))->sheet);
364
365 wrapbox = gtk_object_get_data(GTK_OBJECT(menuitem), "wrapbox");
366 g_assert(wrapbox);
367
368 /* The hidden button is necessary to keep track of radio_group
369 when there are no objects and to force 'toggled' events */
370
371 if (optionmenu_activate_first_pass)
372 {
373 hidden_button = gtk_radio_button_new(NULL);
374 optionmenu_activate_first_pass = FALSE;
375 }
376 else
377 {
378 hidden_button = gtk_radio_button_new(radio_group);
379 radio_group = gtk_radio_button_group(GTK_RADIO_BUTTON(hidden_button));
380 }
381
382 g_signal_connect(GTK_OBJECT(hidden_button), "toggled",
383 G_CALLBACK(on_sheets_dialog_object_button_toggled),
384 wrapbox);
385 gtk_object_set_data(GTK_OBJECT(hidden_button), "is_hidden_button",
386 (gpointer)TRUE);
387 gtk_object_set_data(GTK_OBJECT(wrapbox), "hidden_button", hidden_button);
388 gtk_object_set_data(GTK_OBJECT(hidden_button), "sheet_mod", user_data);
389
390 if (gtk_object_get_data(GTK_OBJECT(wrapbox), "is_left"))
391 optionmenu = lookup_widget(sheets_dialog, "optionmenu_left");
392 else
393 optionmenu = lookup_widget(sheets_dialog, "optionmenu_right");
394 gtk_object_set_data(GTK_OBJECT(optionmenu), "active_sheet_name", sheet->name);
395
396 gtk_container_foreach(GTK_CONTAINER(wrapbox),
397 (GtkCallback)gtk_widget_destroy, NULL);
398
399 radio_group = gtk_radio_button_group(GTK_RADIO_BUTTON(hidden_button));
400
401 gtk_wrap_box_set_aspect_ratio(GTK_WRAP_BOX(wrapbox), 4 * 1.0 / 9);
402 /* MCNFIXME: calculate this */
403 #ifdef CHANGE_COLOUR_OF_MODIFIED_SHEETS
404 {
405 GtkRcStyle *style;
406
407 style->fg[0].red = style->bg[0].red = 56000;
408 style->fg[1].red = style->bg[1].red = 56000;
409 style->fg[2].red = style->bg[2].red = 56000;
410 style->fg[3].red = style->bg[3].red = 56000;
411 style->fg[4].red = style->bg[4].red = 56000;
412 style->color_flags[0] |= 0x0f;
413 style->color_flags[1] |= 0x0f;
414 style->color_flags[2] |= 0x0f;
415 style->color_flags[3] |= 0x0f;
416 style->color_flags[4] |= 0x0f;
417
418 sw = lookup_widget(sheets_dialog, "scrolledwindow_right");
419 gtk_widget_modify_style(wrapbox, style);
420 }
421 #endif
422
423 gtk_object_set_data(GTK_OBJECT(wrapbox), "sheet_mod", user_data);
424
425 for (object_mod_list = sheet->objects; object_mod_list;
426 object_mod_list = g_slist_next(object_mod_list))
427 {
428 GtkWidget *button;
429 SheetObjectMod *som;
430
431 som = object_mod_list->data;
432 if (som->mod == SHEET_OBJECT_MOD_DELETED)
433 continue;
434
435 if (som->sheet_object.line_break == TRUE)
436 sheets_dialog_wrapbox_add_line_break(wrapbox);
437
438 button = sheets_dialog_create_object_button(som, user_data, wrapbox);
439
440 gtk_wrap_box_pack_wrapped(GTK_WRAP_BOX(wrapbox), button,
441 FALSE, TRUE, FALSE, TRUE, som->sheet_object.line_break);
442
443 gtk_widget_show(button);
444 }
445
446 button_list = gtk_container_children(GTK_CONTAINER(wrapbox));
447
448 if (g_list_length(button_list))
449 {
450 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(hidden_button), TRUE);
451 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button_list->data), TRUE);
452 }
453 else
454 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(hidden_button), TRUE);
455
456 g_list_free(button_list);
457 }
458
459 static void
sheets_dialog_apply_revert_set_sensitive(gboolean is_sensitive)460 sheets_dialog_apply_revert_set_sensitive(gboolean is_sensitive)
461 {
462 GtkWidget *button;
463
464 button = lookup_widget(sheets_dialog, "button_apply");
465 gtk_widget_set_sensitive(button, is_sensitive);
466
467 button = lookup_widget(sheets_dialog, "button_revert");
468 gtk_widget_set_sensitive(button, is_sensitive);
469 }
470
471 typedef enum
472 {
473 SHEETS_DIALOG_MOVE_UP = -1,
474 SHEETS_DIALOG_MOVE_DOWN = +1
475 }
476 SheetsDialogMoveDir;
477 #define \
478 SHEETS_DIALOG_MOVE_NONE SHEETS_DIALOG_MOVE_UP
479
480 static void
_gtk_wrap_box_set_child_forced_break(GtkWrapBox * box,GtkWidget * child,gboolean wrapped)481 _gtk_wrap_box_set_child_forced_break (GtkWrapBox* box, GtkWidget* child,
482 gboolean wrapped)
483 {
484 gboolean hexpand, hfill, vexpand, vfill, dummy;
485
486 gtk_wrap_box_query_child_packing (box, child, &hexpand, &hfill,
487 &vexpand, &vfill, &dummy);
488 gtk_wrap_box_set_child_packing (box, child, hexpand, hfill,
489 vexpand, vfill, wrapped);
490 }
491 static void
sheets_dialog_normalize_line_breaks(GtkWidget * wrapbox,SheetsDialogMoveDir dir)492 sheets_dialog_normalize_line_breaks(GtkWidget *wrapbox, SheetsDialogMoveDir dir)
493 {
494 GList *button_list;
495 GList *iter_list;
496 gboolean is_line_break;
497
498 button_list = gtk_container_children(GTK_CONTAINER(wrapbox));
499
500 is_line_break = FALSE;
501 for (iter_list = button_list; iter_list; iter_list = g_list_next(iter_list))
502 {
503 SheetMod *sm;
504 SheetObjectMod *som;
505
506 sm = gtk_object_get_data(GTK_OBJECT(iter_list->data), "sheet_mod");
507 som = gtk_object_get_data(GTK_OBJECT(iter_list->data), "sheet_object_mod");
508 if (som)
509 {
510 if (is_line_break)
511 {
512 if (som->sheet_object.line_break == FALSE)
513 {
514 if (sm->mod == SHEETMOD_MOD_NONE)
515 sm->mod = SHEETMOD_MOD_CHANGED;
516
517 som->mod = SHEET_OBJECT_MOD_CHANGED;
518 }
519
520 som->sheet_object.line_break = TRUE;
521 _gtk_wrap_box_set_child_forced_break(GTK_WRAP_BOX(wrapbox),
522 GTK_WIDGET(iter_list->data), TRUE);
523 }
524 else
525 {
526 if (som->sheet_object.line_break == TRUE)
527 {
528 if (sm->mod == SHEETMOD_MOD_NONE)
529 sm->mod = SHEETMOD_MOD_CHANGED;
530 som->mod = SHEET_OBJECT_MOD_CHANGED;
531 }
532
533 som->sheet_object.line_break = FALSE;
534 _gtk_wrap_box_set_child_forced_break(GTK_WRAP_BOX(wrapbox),
535 GTK_WIDGET(iter_list->data), FALSE);
536 }
537 is_line_break = FALSE;
538 }
539 else
540 {
541 if (is_line_break)
542 {
543 if (dir == SHEETS_DIALOG_MOVE_UP)
544 {
545 iter_list = g_list_previous(iter_list);
546 gtk_widget_destroy(GTK_WIDGET(iter_list->data));
547 iter_list = g_list_next(iter_list);
548 radio_group = gtk_radio_button_group(GTK_RADIO_BUTTON(iter_list
549 ->data));
550 }
551 else
552 {
553 GList *tmp_list;
554
555 tmp_list = g_list_previous(iter_list);
556 gtk_widget_destroy(GTK_WIDGET(iter_list->data));
557 radio_group = gtk_radio_button_group(GTK_RADIO_BUTTON(tmp_list
558 ->data));
559 }
560 }
561 else
562 is_line_break = TRUE;
563 }
564 }
565
566 /* We delete a trailing linebreak button in the wrapbox */
567
568 iter_list = g_list_last(button_list);
569 if (iter_list && !gtk_object_get_data(GTK_OBJECT(iter_list->data),
570 "sheet_object_mod"))
571 {
572 gtk_widget_destroy(GTK_WIDGET(iter_list->data));
573 if (g_list_previous(iter_list))
574 {
575 gtk_toggle_button_set_active(g_list_previous(iter_list)->data, TRUE);
576 radio_group = gtk_radio_button_group(GTK_RADIO_BUTTON(
577 g_list_previous(iter_list)->data));
578 }
579 }
580
581 g_list_free(button_list);
582 }
583
584 GtkWidget *
sheets_dialog_get_active_button(GtkWidget ** wrapbox,GList ** button_list)585 sheets_dialog_get_active_button(GtkWidget **wrapbox, GList **button_list)
586 {
587 GtkWidget *table_sheets;
588
589 table_sheets = lookup_widget(sheets_dialog, "table_sheets");
590 *wrapbox = gtk_object_get_data(GTK_OBJECT(table_sheets), "active_wrapbox");
591 *button_list = gtk_container_children(GTK_CONTAINER(*wrapbox));
592 return gtk_object_get_data(GTK_OBJECT(*wrapbox), "active_button");
593 }
594
595
596 static void
sheets_dialog_move_up_or_down(SheetsDialogMoveDir dir)597 sheets_dialog_move_up_or_down(SheetsDialogMoveDir dir)
598 {
599 GtkWidget *table_sheets;
600 GtkWidget *wrapbox;
601 GList *button_list;
602 GtkWidget *active_button;
603 gint button_pos;
604 SheetObjectMod *som;
605 SheetObjectMod *som_next;
606 GList *next_button_list;
607
608 table_sheets = lookup_widget(sheets_dialog, "table_sheets");
609 wrapbox = gtk_object_get_data(GTK_OBJECT(table_sheets), "active_wrapbox");
610
611 button_list = gtk_container_children(GTK_CONTAINER(wrapbox));
612 active_button = gtk_object_get_data(GTK_OBJECT(wrapbox), "active_button");
613
614 button_pos = g_list_index(button_list, active_button);
615 gtk_wrap_box_reorder_child(GTK_WRAP_BOX(wrapbox),
616 GTK_WIDGET(active_button), button_pos + dir);
617 g_list_free(button_list);
618
619 sheets_dialog_normalize_line_breaks(wrapbox, dir);
620
621 /* And then reorder the backing store if necessary */
622
623 button_list = gtk_container_children(GTK_CONTAINER(wrapbox));
624 active_button = gtk_object_get_data(GTK_OBJECT(wrapbox), "active_button");
625
626 som = gtk_object_get_data(GTK_OBJECT(active_button), "sheet_object_mod");
627
628 next_button_list = g_list_next(g_list_find(button_list, active_button));
629 if (next_button_list)
630 som_next = gtk_object_get_data(GTK_OBJECT(next_button_list->data),
631 "sheet_object_mod");
632 else
633 som_next = NULL; /* either 1) no button after 'active_button'
634 or 2) button after 'active_button' is line break */
635
636 /* This is all a little hairy, but the idea is that we don't need
637 to reorder the backing store if the button was moved to the other
638 side of a line break button since a line break button doesn't
639 exist in the backing store. Starting to look a little like lisp... */
640
641 if (som && (((dir == SHEETS_DIALOG_MOVE_DOWN)
642 && (som->sheet_object.line_break == FALSE))
643 || (((dir == SHEETS_DIALOG_MOVE_UP)
644 && som_next))))
645 {
646 SheetMod *sm;
647 GSList *object_list;
648 gint object_pos;
649
650 som->mod = SHEET_OBJECT_MOD_CHANGED;
651
652 sm = gtk_object_get_data(GTK_OBJECT(active_button), "sheet_mod");
653 if (sm->mod == SHEETMOD_MOD_NONE)
654 sm->mod = SHEETMOD_MOD_CHANGED;
655
656 object_list = g_slist_find(sm->sheet.objects, som);
657 g_assert(object_list);
658
659 object_pos = g_slist_position(sm->sheet.objects, object_list);
660 sm->sheet.objects = g_slist_remove_link(sm->sheet.objects, object_list);
661 sm->sheet.objects = g_slist_insert(sm->sheet.objects, object_list->data,
662 object_pos + dir);
663 }
664
665 sheets_dialog_apply_revert_set_sensitive(TRUE);
666
667 sheets_dialog_up_down_set_sensitive(button_list,
668 GTK_TOGGLE_BUTTON(active_button));
669 g_list_free(button_list);
670 }
671
672 void
on_sheets_dialog_button_move_up_clicked(GtkButton * button,gpointer user_data)673 on_sheets_dialog_button_move_up_clicked(GtkButton *button, gpointer user_data)
674 {
675 sheets_dialog_move_up_or_down(SHEETS_DIALOG_MOVE_UP);
676 }
677
678 void
on_sheets_dialog_button_move_down_clicked(GtkButton * button,gpointer user_data)679 on_sheets_dialog_button_move_down_clicked(GtkButton *button, gpointer user_data)
680 {
681 sheets_dialog_move_up_or_down(SHEETS_DIALOG_MOVE_DOWN);
682 }
683
684 void
on_sheets_dialog_button_close_clicked(GtkButton * button,gpointer user_data)685 on_sheets_dialog_button_close_clicked (GtkButton *button,
686 gpointer user_data)
687 {
688 sheets_dialog_hide();
689 }
690
691 static GtkWidget *sheets_new_dialog;
692
693 typedef enum
694 {
695 SHEETS_NEW_DIALOG_TYPE_SVG_SHAPE = 1, /* allows g_assert() */
696 SHEETS_NEW_DIALOG_TYPE_LINE_BREAK,
697 SHEETS_NEW_DIALOG_TYPE_SHEET
698 }
699 SheetsNewDialogType;
700
701 GList *sheets_new_dialog_combo_list = NULL;
702
703 void
on_sheets_dialog_button_new_clicked(GtkButton * button,gpointer user_data)704 on_sheets_dialog_button_new_clicked (GtkButton *button,
705 gpointer user_data)
706 {
707 GtkWidget *combo;
708 GtkWidget *wrapbox;
709 GList *button_list;
710 GtkWidget *active_button;
711 gboolean is_line_break_sensitive;
712
713 sheets_new_dialog = create_sheets_new_dialog();
714
715 if (sheets_new_dialog_combo_list)
716 {
717 combo = lookup_widget(sheets_new_dialog, "combo_from_file");
718 gtk_combo_set_popdown_strings(GTK_COMBO(combo),
719 sheets_new_dialog_combo_list);
720 }
721
722 /* Deterine if a line break button can be put after the active button */
723
724 active_button = sheets_dialog_get_active_button(&wrapbox, &button_list);
725 is_line_break_sensitive = TRUE;
726 if (gtk_object_get_data(GTK_OBJECT(active_button), "sheet_mod"))
727 {
728 button_list = g_list_next(g_list_find(button_list, active_button));
729 if (!button_list || !gtk_object_get_data(GTK_OBJECT(button_list->data),
730 "sheet_mod"))
731 is_line_break_sensitive = FALSE;
732 g_list_free(button_list);
733 }
734 else
735 is_line_break_sensitive = FALSE;
736
737 active_button = lookup_widget(sheets_new_dialog, "radiobutton_line_break");
738 gtk_widget_set_sensitive(active_button, is_line_break_sensitive);
739
740 /* Use the 'ok' button to hold the current 'type' selection */
741
742 active_button = lookup_widget(sheets_new_dialog, "button_ok");
743 gtk_object_set_data(GTK_OBJECT(active_button), "active_type",
744 (gpointer)SHEETS_NEW_DIALOG_TYPE_SVG_SHAPE);
745
746 gtk_widget_show(sheets_new_dialog);
747 }
748
749 void
on_sheets_new_dialog_button_cancel_clicked(GtkButton * button,gpointer user_data)750 on_sheets_new_dialog_button_cancel_clicked
751 (GtkButton *button,
752 gpointer user_data)
753 {
754 gtk_widget_destroy(sheets_new_dialog);
755 sheets_new_dialog = NULL;
756 }
757
758 void
on_sheets_new_dialog_button_ok_clicked(GtkButton * button,gpointer user_data)759 on_sheets_new_dialog_button_ok_clicked (GtkButton *button,
760 gpointer user_data)
761 {
762 SheetsNewDialogType active_type;
763 GtkWidget *table_sheets;
764 GtkWidget *wrapbox;
765 GList *button_list;
766 GtkWidget *active_button;
767
768 table_sheets = lookup_widget(sheets_dialog, "table_sheets");
769 wrapbox = gtk_object_get_data(GTK_OBJECT(table_sheets), "active_wrapbox");
770
771 active_type = (SheetsNewDialogType)gtk_object_get_data(GTK_OBJECT(button),
772 "active_type");
773 g_assert(active_type);
774
775 switch (active_type)
776 {
777 GtkWidget *entry;
778 gchar *file_name;
779 gchar *p;
780 struct stat stat_buf;
781 GList *plugin_list;
782 DiaObjectType *ot;
783 typedef gboolean (*CustomObjectLoadFunc) (gchar*, DiaObjectType **);
784 CustomObjectLoadFunc custom_object_load_fn;
785 gint pos;
786 GtkWidget *active_button;
787 GList *button_list;
788 SheetObjectMod *som;
789 SheetMod *sm;
790 SheetObject *sheet_obj;
791 Sheet *sheet;
792 GtkWidget *optionmenu;
793
794 case SHEETS_NEW_DIALOG_TYPE_SVG_SHAPE:
795
796 entry = lookup_widget(sheets_new_dialog, "combo_entry_from_file");
797 /* Since this is a file name, no utf8 translation is needed */
798 file_name = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1);
799
800 p = file_name + strlen(file_name) - 6;
801 if (strcmp(p, ".shape"))
802 {
803 message_error(_("Filename must end with '%s': '%s'"),
804 ".shape", dia_message_filename(file_name));
805 g_free(file_name);
806 return;
807 }
808
809 if (g_stat(file_name, &stat_buf) == -1)
810 {
811 message_error(_("Error examining %s: %s"),
812 dia_message_filename(file_name), strerror(errno));
813 g_free(file_name);
814 return;
815 }
816
817 custom_object_load_fn = NULL;
818 for (plugin_list = dia_list_plugins(); plugin_list != NULL;
819 plugin_list = g_list_next(plugin_list))
820 {
821 PluginInfo *info = plugin_list->data;
822
823 custom_object_load_fn =
824 (CustomObjectLoadFunc)dia_plugin_get_symbol (info, "custom_object_load");
825 if (custom_object_load_fn)
826 break;
827 }
828 g_assert(custom_object_load_fn);
829
830 if (!(*custom_object_load_fn)(file_name, &ot))
831 {
832 xmlDoc *doc = NULL;
833 xmlNode *root_element = NULL;
834
835 /* See if the user tries to open a diagram as a shape */
836 doc = xmlReadFile(file_name, NULL, 0);
837 if(doc != NULL)
838 {
839 root_element = xmlDocGetRootElement(doc);
840 if(0 == g_strncasecmp((gchar *)root_element->name, "dia", 3))
841 message_error(
842 _("Please export the diagram as a shape."));
843 xmlFreeDoc(doc);
844 }
845 message_error(_("Could not interpret shape file: '%s'"),
846 dia_message_filename(file_name));
847 xmlCleanupParser();
848 g_free(file_name);
849 return;
850 }
851 object_register_type(ot);
852
853 entry = lookup_widget(sheets_new_dialog, "entry_svg_description");
854 sheet_obj = g_new0(SheetObject, 1);
855 sheet_obj->object_type = g_strdup(ot->name);
856 {
857 sheet_obj->description =
858 gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1);
859 }
860 sheet_obj->pixmap = ot->pixmap;
861 sheet_obj->user_data = ot->default_user_data;
862 sheet_obj->user_data_type = USER_DATA_IS_OTHER;
863 sheet_obj->line_break = FALSE;
864 sheet_obj->pixmap_file = g_strdup(ot->pixmap_file);
865 sheet_obj->has_icon_on_sheet = FALSE;
866
867 sm = gtk_object_get_data(GTK_OBJECT(wrapbox), "sheet_mod");
868 som = sheets_append_sheet_object_mod(sheet_obj, sm);
869 som->mod = SHEET_OBJECT_MOD_NEW;
870 som->svg_filename = g_strdup(file_name);
871 if (sm->mod == SHEETMOD_MOD_NONE)
872 sm->mod = SHEETMOD_MOD_CHANGED;
873
874 active_button = sheets_dialog_create_object_button(som, sm, wrapbox);
875 gtk_wrap_box_pack(GTK_WRAP_BOX(wrapbox), active_button,
876 FALSE, TRUE, FALSE, TRUE);
877 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(active_button), TRUE);
878 gtk_widget_show(active_button);
879
880 sheets_new_dialog_combo_list = g_list_append(sheets_new_dialog_combo_list,
881 file_name);
882 break;
883
884 case SHEETS_NEW_DIALOG_TYPE_LINE_BREAK:
885
886 sheets_dialog_wrapbox_add_line_break(wrapbox);
887
888 button_list = gtk_container_children(GTK_CONTAINER(wrapbox));
889 active_button = gtk_object_get_data(GTK_OBJECT(wrapbox), "active_button");
890 pos = g_list_index(button_list, active_button);
891 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_list_last(button_list)
892 ->data), TRUE);
893 gtk_wrap_box_reorder_child(GTK_WRAP_BOX(wrapbox),
894 g_list_last(button_list)->data, pos + 1);
895
896 sheets_dialog_normalize_line_breaks(wrapbox, SHEETS_DIALOG_MOVE_NONE);
897
898 sm = gtk_object_get_data(GTK_OBJECT(wrapbox), "sheet_mod");
899 if (sm->mod == SHEETMOD_MOD_NONE)
900 sm->mod = SHEETMOD_MOD_CHANGED;
901
902 g_list_free(button_list);
903 break;
904
905 case SHEETS_NEW_DIALOG_TYPE_SHEET:
906 {
907 gchar *sheet_name;
908 gchar *sheet_descrip;
909
910 entry = lookup_widget(sheets_new_dialog, "entry_sheet_name");
911 sheet_name = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1);
912
913 sheet_name = g_strchug(g_strchomp(sheet_name));
914 if (!*sheet_name)
915 {
916 message_error(_("Sheet must have a Name"));
917 return;
918 }
919
920 entry = lookup_widget(sheets_new_dialog, "entry_sheet_description");
921 sheet_descrip = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1);
922
923 sheet = g_new0(Sheet, 1);
924 sheet->name = sheet_name;
925 sheet->filename = "";
926 sheet->description = sheet_descrip;
927 sheet->scope = SHEET_SCOPE_USER;
928 sheet->shadowing = NULL;
929 sheet->objects = NULL;
930
931 sm = sheets_append_sheet_mods(sheet);
932 sm->mod = SHEETMOD_MOD_NEW;
933
934 table_sheets = lookup_widget(sheets_dialog, "table_sheets");
935 optionmenu = gtk_object_get_data(GTK_OBJECT(table_sheets),
936 "active_optionmenu");
937 g_assert(optionmenu);
938 sheets_optionmenu_create(optionmenu, wrapbox, sheet_name);
939 }
940 break;
941
942 default:
943 g_assert_not_reached();
944 }
945
946 sheets_dialog_apply_revert_set_sensitive(TRUE);
947
948 button_list = gtk_container_children(GTK_CONTAINER(wrapbox));
949 active_button = gtk_object_get_data(GTK_OBJECT(wrapbox), "active_button");
950 sheets_dialog_up_down_set_sensitive(button_list,
951 GTK_TOGGLE_BUTTON(active_button));
952 g_list_free(button_list);
953
954 gtk_widget_destroy(sheets_new_dialog);
955 sheets_new_dialog = NULL;
956 }
957
958 static GtkWidget *sheets_shapeselection_dialog;
959
960 void
on_sheets_new_dialog_button_browse_clicked(GtkButton * button,gpointer user_data)961 on_sheets_new_dialog_button_browse_clicked
962 (GtkButton *button,
963 gpointer user_data)
964 {
965 sheets_shapeselection_dialog = create_sheets_shapeselection_dialog();
966 gtk_widget_show(sheets_shapeselection_dialog);
967 }
968
969 void
on_sheets_shapeselection_dialog_button_cancel_clicked(GtkButton * button,gpointer user_data)970 on_sheets_shapeselection_dialog_button_cancel_clicked
971 (GtkButton *button,
972 gpointer user_data)
973 {
974 gtk_widget_destroy(sheets_shapeselection_dialog);
975 sheets_shapeselection_dialog = NULL;
976 }
977
978 void
on_sheets_shapeselection_dialog_button_ok_clicked(GtkButton * button,gpointer user_data)979 on_sheets_shapeselection_dialog_button_ok_clicked
980 (GtkButton *button,
981 gpointer user_data)
982 {
983 const gchar *filename;
984 GtkWidget *entry;
985
986 filename =
987 gtk_file_selection_get_filename(
988 GTK_FILE_SELECTION(sheets_shapeselection_dialog));
989
990 entry = lookup_widget(sheets_new_dialog, "combo_entry_from_file");
991 /* Since this is a filename entry from the dialog, no utf is needed */
992 gtk_entry_set_text(GTK_ENTRY(entry), filename);
993
994 gtk_widget_destroy(sheets_shapeselection_dialog);
995 sheets_shapeselection_dialog = NULL;
996 }
997
998 static GtkWidget *sheets_edit_dialog;
999
1000 void
on_sheets_dialog_button_edit_clicked(GtkButton * button,gpointer user_data)1001 on_sheets_dialog_button_edit_clicked (GtkButton *button,
1002 gpointer user_data)
1003 {
1004 GtkWidget *wrapbox;
1005 GList *button_list;
1006 GtkWidget *active_button;
1007 SheetObjectMod *som;
1008 gchar *descrip = "";
1009 gchar *type = "";
1010 GtkWidget *entry;
1011 SheetMod *sm;
1012 gchar *name = "";
1013
1014 if (sheets_edit_dialog == NULL)
1015 sheets_edit_dialog = create_sheets_edit_dialog();
1016
1017 active_button = sheets_dialog_get_active_button(&wrapbox, &button_list);
1018 som = gtk_object_get_data(GTK_OBJECT(active_button), "sheet_object_mod");
1019 if (som)
1020 {
1021 descrip = som->sheet_object.description;
1022 type = sheet_object_mod_get_type_string(som);
1023 }
1024
1025 entry = lookup_widget(sheets_edit_dialog, "entry_object_description");
1026 if (som)
1027 gtk_entry_set_text(GTK_ENTRY(entry), descrip);
1028 else
1029 gtk_widget_set_sensitive(entry, FALSE);
1030
1031 entry = lookup_widget(sheets_edit_dialog, "entry_object_type");
1032 if (som)
1033 gtk_entry_set_text(GTK_ENTRY(entry), type);
1034 else
1035 gtk_widget_set_sensitive(entry, FALSE);
1036
1037 sm = gtk_object_get_data(GTK_OBJECT(active_button), "sheet_mod");
1038 if (sm)
1039 {
1040 name = sm->sheet.name;
1041 descrip = sm->sheet.description;
1042 }
1043
1044 entry = lookup_widget(sheets_edit_dialog, "entry_sheet_name");
1045 gtk_entry_set_text(GTK_ENTRY(entry), name);
1046 #if CAN_EDIT_SHEET_NAME
1047 if (sm->sheet.scope == SHEET_SCOPE_SYSTEM)
1048 #endif
1049 gtk_widget_set_sensitive(entry, FALSE);
1050
1051 entry = lookup_widget(sheets_edit_dialog, "entry_sheet_description");
1052 gtk_entry_set_text(GTK_ENTRY(entry), descrip);
1053
1054 gtk_widget_show(sheets_edit_dialog);
1055 }
1056
1057 void
on_sheets_edit_dialog_button_cancel_clicked(GtkButton * button,gpointer user_data)1058 on_sheets_edit_dialog_button_cancel_clicked
1059 (GtkButton *button,
1060 gpointer user_data)
1061 {
1062 gtk_widget_destroy(sheets_edit_dialog);
1063 sheets_edit_dialog = NULL;
1064 }
1065
1066 static GtkWidget *sheets_remove_dialog;
1067
1068 typedef enum
1069 {
1070 SHEETS_REMOVE_DIALOG_TYPE_OBJECT = 1,
1071 SHEETS_REMOVE_DIALOG_TYPE_SHEET
1072 }
1073 SheetsRemoveDialogType;
1074
1075 void
on_sheets_dialog_button_remove_clicked(GtkButton * button,gpointer user_data)1076 on_sheets_dialog_button_remove_clicked (GtkButton *button,
1077 gpointer user_data)
1078 {
1079 GtkWidget *wrapbox;
1080 GList *button_list;
1081 GtkWidget *active_button;
1082 SheetMod *sm;
1083 GtkWidget *entry;
1084 GtkWidget *radio_button;
1085
1086 sheets_remove_dialog = create_sheets_remove_dialog();
1087
1088 active_button = sheets_dialog_get_active_button(&wrapbox, &button_list);
1089 g_assert(active_button);
1090
1091 /* Force a change in state in the radio button for set sensitive */
1092
1093 radio_button = lookup_widget(sheets_remove_dialog, "radiobutton_sheet");
1094 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_button), TRUE);
1095
1096 entry = lookup_widget(sheets_remove_dialog, "entry_object");
1097 if (gtk_object_get_data(GTK_OBJECT(active_button), "is_hidden_button"))
1098 {
1099 radio_button = lookup_widget(sheets_remove_dialog, "radiobutton_object");
1100 gtk_widget_set_sensitive(radio_button, FALSE);
1101 gtk_widget_set_sensitive(entry, FALSE);
1102 }
1103 else
1104 {
1105 SheetObjectMod *som;
1106
1107 som = gtk_object_get_data(GTK_OBJECT(active_button), "sheet_object_mod");
1108 if (!som)
1109 gtk_entry_set_text(GTK_ENTRY(entry), _("Line Break"));
1110 else
1111 gtk_entry_set_text(GTK_ENTRY(entry), som->sheet_object.description);
1112
1113 radio_button = lookup_widget(sheets_remove_dialog, "radiobutton_object");
1114 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_button), TRUE);
1115 }
1116
1117 entry = lookup_widget(sheets_remove_dialog, "entry_sheet");
1118 sm = gtk_object_get_data(GTK_OBJECT(active_button), "sheet_mod");
1119
1120 /* Note: It is currently impossible to remove a user sheet that has
1121 been shadowed by a more recent system sheet--the logic is just
1122 too hairy. Once the user sheet has been updated, or the [copy of
1123 system] sheet has been removed, then they can remove the user
1124 sheet just fine (in the next invocation of dia). This would
1125 be rare, to say the least... */
1126
1127 if (sm->sheet.shadowing == NULL && sm->sheet.scope == SHEET_SCOPE_SYSTEM)
1128 {
1129 GtkWidget *radio_button;
1130
1131 radio_button = lookup_widget(sheets_remove_dialog, "radiobutton_sheet");
1132 gtk_widget_set_sensitive(radio_button, FALSE);
1133 gtk_widget_set_sensitive(entry, FALSE);
1134 }
1135 gtk_entry_set_text(GTK_ENTRY(entry), sm->sheet.name);
1136
1137 gtk_widget_show(sheets_remove_dialog);
1138 }
1139
1140 void
on_sheets_remove_dialog_button_cancel_clicked(GtkButton * button,gpointer user_data)1141 on_sheets_remove_dialog_button_cancel_clicked
1142 (GtkButton *button,
1143 gpointer user_data)
1144 {
1145 gtk_widget_destroy(sheets_remove_dialog);
1146 sheets_remove_dialog = NULL;
1147 }
1148
1149 static void
sheets_dialog_togglebutton_set_sensitive(GtkToggleButton * togglebutton,GtkWidget * dialog,gchar * widget_names[],gint type)1150 sheets_dialog_togglebutton_set_sensitive(GtkToggleButton *togglebutton,
1151 GtkWidget *dialog,
1152 gchar *widget_names[], gint type)
1153 {
1154 gboolean is_sensitive;
1155 guint i;
1156 GtkWidget *tmp;
1157
1158 is_sensitive = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(togglebutton));
1159 if (is_sensitive)
1160 {
1161 tmp = lookup_widget(dialog, "button_ok");
1162 gtk_object_set_data(GTK_OBJECT(tmp), "active_type", (gpointer)type);
1163 }
1164
1165 for (i = 0; widget_names[i]; i++)
1166 {
1167 tmp = lookup_widget(dialog, widget_names[i]);
1168 gtk_widget_set_sensitive(tmp, is_sensitive);
1169 }
1170 }
1171
1172 void
on_sheets_new_dialog_radiobutton_svg_shape_toggled(GtkToggleButton * togglebutton,gpointer user_data)1173 on_sheets_new_dialog_radiobutton_svg_shape_toggled
1174 (GtkToggleButton *togglebutton,
1175 gpointer user_data)
1176 {
1177 static gchar *widget_names[] =
1178 {
1179 "combo_from_file",
1180 "button_browse",
1181 "label_svg_description",
1182 "entry_svg_description",
1183 NULL
1184 };
1185
1186 sheets_dialog_togglebutton_set_sensitive(togglebutton, sheets_new_dialog,
1187 widget_names,
1188 SHEETS_NEW_DIALOG_TYPE_SVG_SHAPE);
1189 }
1190
1191 void
on_sheets_new_dialog_radiobutton_sheet_toggled(GtkToggleButton * togglebutton,gpointer user_data)1192 on_sheets_new_dialog_radiobutton_sheet_toggled
1193 (GtkToggleButton *togglebutton,
1194 gpointer user_data)
1195 {
1196 static gchar *widget_names[] =
1197 {
1198 "entry_sheet_name",
1199 "entry_sheet_description",
1200 "label_description",
1201 NULL
1202 };
1203
1204 sheets_dialog_togglebutton_set_sensitive(togglebutton, sheets_new_dialog,
1205 widget_names,
1206 SHEETS_NEW_DIALOG_TYPE_SHEET);
1207 }
1208
1209 void
on_sheets_new_dialog_radiobutton_line_break_toggled(GtkToggleButton * togglebutton,gpointer user_data)1210 on_sheets_new_dialog_radiobutton_line_break_toggled
1211 (GtkToggleButton *togglebutton,
1212 gpointer user_data)
1213 {
1214 static gchar *widget_names[] =
1215 {
1216 NULL
1217 };
1218
1219 sheets_dialog_togglebutton_set_sensitive(togglebutton, sheets_new_dialog,
1220 widget_names,
1221 SHEETS_NEW_DIALOG_TYPE_LINE_BREAK);
1222 }
1223
1224 void
on_sheets_remove_dialog_radiobutton_object_toggled(GtkToggleButton * togglebutton,gpointer user_data)1225 on_sheets_remove_dialog_radiobutton_object_toggled
1226 (GtkToggleButton *togglebutton,
1227 gpointer user_data)
1228 {
1229 gchar *widget_names[] =
1230 {
1231 "pixmap_object",
1232 "entry_object",
1233 NULL
1234 };
1235
1236 sheets_dialog_togglebutton_set_sensitive(togglebutton, sheets_remove_dialog,
1237 widget_names,
1238 SHEETS_REMOVE_DIALOG_TYPE_OBJECT);
1239 }
1240
1241 void
on_sheets_remove_dialog_radiobutton_sheet_toggled(GtkToggleButton * togglebutton,gpointer user_data)1242 on_sheets_remove_dialog_radiobutton_sheet_toggled
1243 (GtkToggleButton *togglebutton,
1244 gpointer user_data)
1245 {
1246 gchar *widget_names[] =
1247 {
1248 "entry_sheet",
1249 NULL
1250 };
1251
1252 sheets_dialog_togglebutton_set_sensitive(togglebutton, sheets_remove_dialog,
1253 widget_names,
1254 SHEETS_REMOVE_DIALOG_TYPE_SHEET);
1255 }
1256
1257 static GtkWidget *
sheets_dialog_set_new_active_button(void)1258 sheets_dialog_set_new_active_button(void)
1259 {
1260 GtkWidget *active_button;
1261 GtkWidget *wrapbox;
1262 GList *button_list;
1263 GList *active_button_list;
1264 GtkWidget *new_active_button;
1265
1266 active_button = sheets_dialog_get_active_button(&wrapbox, &button_list);
1267
1268 active_button_list = g_list_find(button_list, active_button);
1269 g_assert(active_button_list);
1270 if (g_list_next(active_button_list))
1271 new_active_button = g_list_next(active_button_list)->data;
1272 else
1273 {
1274 if (g_list_previous(active_button_list))
1275 new_active_button = g_list_previous(active_button_list)->data;
1276 else
1277 new_active_button = gtk_object_get_data(GTK_OBJECT(wrapbox),
1278 "hidden_button");
1279 }
1280 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(new_active_button), TRUE);
1281
1282 return new_active_button;
1283 }
1284
1285 void
on_sheets_remove_dialog_button_ok_clicked(GtkButton * button,gpointer user_data)1286 on_sheets_remove_dialog_button_ok_clicked
1287 (GtkButton *button,
1288 gpointer user_data)
1289 {
1290 SheetsRemoveDialogType type;
1291 GtkWidget *wrapbox;
1292 GList *button_list;
1293 GtkWidget *active_button;
1294
1295 type = (SheetsRemoveDialogType)gtk_object_get_data(GTK_OBJECT(button),
1296 "active_type");
1297
1298 active_button = sheets_dialog_get_active_button(&wrapbox, &button_list);
1299
1300 switch (type)
1301 {
1302 SheetObjectMod *som;
1303 GtkWidget *new_active_button;
1304 SheetMod *sm;
1305 GtkWidget *table_sheets;
1306 GtkWidget *optionmenu;
1307
1308 case SHEETS_REMOVE_DIALOG_TYPE_OBJECT:
1309
1310 som = gtk_object_get_data(GTK_OBJECT(active_button), "sheet_object_mod");
1311 if (som)
1312 {
1313 sm = gtk_object_get_data(GTK_OBJECT(active_button), "sheet_mod");
1314 sm->mod = SHEETMOD_MOD_CHANGED;
1315 som->mod = SHEET_OBJECT_MOD_DELETED;
1316 }
1317 new_active_button = sheets_dialog_set_new_active_button();
1318
1319 gtk_widget_destroy(active_button);
1320 radio_group = gtk_radio_button_group(GTK_RADIO_BUTTON(new_active_button));
1321
1322 sheets_dialog_normalize_line_breaks(wrapbox, SHEETS_DIALOG_MOVE_NONE);
1323 break;
1324
1325 case SHEETS_REMOVE_DIALOG_TYPE_SHEET:
1326
1327 sm = gtk_object_get_data(GTK_OBJECT(active_button), "sheet_mod");
1328 sm->mod = SHEETMOD_MOD_DELETED;
1329
1330 if (sm->sheet.shadowing && sm->sheet.scope == SHEET_SCOPE_USER)
1331 sheets_append_sheet_mods(sm->sheet.shadowing);
1332
1333 table_sheets = lookup_widget(sheets_dialog, "table_sheets");
1334 optionmenu = gtk_object_get_data(GTK_OBJECT(table_sheets),
1335 "active_optionmenu");
1336 g_assert(optionmenu);
1337 sheets_optionmenu_create(optionmenu, wrapbox, NULL);
1338
1339 break;
1340
1341 default:
1342 g_assert_not_reached();
1343 }
1344
1345 g_list_free(button_list);
1346
1347 sheets_dialog_apply_revert_set_sensitive(TRUE);
1348 gtk_widget_destroy(sheets_remove_dialog);
1349 sheets_remove_dialog = NULL;
1350 }
1351
1352 void
on_sheets_edit_dialog_button_ok_clicked(GtkButton * button,gpointer user_data)1353 on_sheets_edit_dialog_button_ok_clicked
1354 (GtkButton *button,
1355 gpointer user_data)
1356 {
1357 GtkWidget *active_button;
1358 GtkWidget *wrapbox;
1359 GList *button_list;
1360 GtkWidget *entry;
1361 gboolean something_changed = FALSE;
1362
1363 active_button = sheets_dialog_get_active_button(&wrapbox, &button_list);
1364 g_assert(active_button);
1365
1366 entry = lookup_widget(sheets_edit_dialog, "entry_object_description");
1367 if ((gboolean)gtk_object_get_data(GTK_OBJECT(entry), "changed") == TRUE)
1368 {
1369 SheetMod *sm;
1370 SheetObjectMod *som;
1371
1372 som = gtk_object_get_data(GTK_OBJECT(active_button), "sheet_object_mod");
1373 som->sheet_object.description =
1374 gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1);
1375 sheets_dialog_object_set_tooltip(som, active_button);
1376
1377 som->mod = SHEET_OBJECT_MOD_CHANGED;
1378
1379 sm = gtk_object_get_data(GTK_OBJECT(active_button), "sheet_mod");
1380 if (sm->mod == SHEETMOD_MOD_NONE)
1381 sm->mod = SHEETMOD_MOD_CHANGED;
1382
1383 something_changed = TRUE;
1384 }
1385
1386 entry = lookup_widget(sheets_edit_dialog, "entry_sheet_description");
1387 if ((gboolean)gtk_object_get_data(GTK_OBJECT(entry), "changed") == TRUE)
1388 {
1389 SheetMod *sm;
1390
1391 sm = gtk_object_get_data(GTK_OBJECT(active_button), "sheet_mod");
1392 sm->sheet.description =
1393 gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1);
1394
1395 if (sm->mod == SHEETMOD_MOD_NONE)
1396 sm->mod = SHEETMOD_MOD_CHANGED;
1397 something_changed = TRUE;
1398 }
1399
1400 #ifdef CAN_EDIT_SHEET_NAME
1401 /* This must be last because we reload the sheets if changed */
1402
1403 entry = lookup_widget(sheets_edit_dialog, "entry_sheet_name");
1404 if ((gboolean)gtk_object_get_data(GTK_OBJECT(entry), "changed") == TRUE)
1405 {
1406 SheetMod *sm;
1407 GtkWidget *table_sheets;
1408 GtkWidget *optionmenu;
1409
1410 sm = gtk_object_get_data(GTK_OBJECT(active_button), "sheet_mod");
1411 sm->sheet.name = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1);
1412 if (sm->mod == SHEETMOD_MOD_NONE)
1413 sm->mod = SHEETMOD_MOD_CHANGED;
1414
1415 table_sheets = lookup_widget(sheets_dialog, "table_sheets");
1416 optionmenu = gtk_object_get_data(GTK_OBJECT(table_sheets),
1417 "active_optionmenu");
1418 sheets_optionmenu_create(optionmenu, wrapbox, NULL);
1419
1420 something_changed = TRUE;
1421 }
1422 #endif
1423 if (something_changed == TRUE)
1424 sheets_dialog_apply_revert_set_sensitive(TRUE);
1425
1426 gtk_widget_destroy(sheets_edit_dialog);
1427 sheets_edit_dialog = NULL;
1428 }
1429
1430 void
on_sheets_edit_dialog_entry_object_description_changed(GtkEditable * editable,gpointer user_data)1431 on_sheets_edit_dialog_entry_object_description_changed
1432 (GtkEditable *editable,
1433 gpointer user_data)
1434 {
1435 gtk_object_set_data(GTK_OBJECT(editable), "changed", (gpointer)TRUE);
1436 }
1437
1438
1439 void
on_sheets_edit_dialog_entry_sheet_description_changed(GtkEditable * editable,gpointer user_data)1440 on_sheets_edit_dialog_entry_sheet_description_changed
1441 (GtkEditable *editable,
1442 gpointer user_data)
1443 {
1444 gtk_object_set_data(GTK_OBJECT(editable), "changed", (gpointer)TRUE);
1445 }
1446
1447 void
on_sheets_edit_dialog_entry_sheet_name_changed(GtkEditable * editable,gpointer user_data)1448 on_sheets_edit_dialog_entry_sheet_name_changed
1449 (GtkEditable *editable,
1450 gpointer user_data)
1451 {
1452 gtk_object_set_data(GTK_OBJECT(editable), "changed", (gpointer)TRUE);
1453 }
1454
1455 static GtkWidget *
sheets_dialog_get_target_wrapbox(GtkWidget * wrapbox)1456 sheets_dialog_get_target_wrapbox(GtkWidget *wrapbox)
1457 {
1458 if (gtk_object_get_data(GTK_OBJECT(wrapbox), "is_left"))
1459 return gtk_object_get_data(GTK_OBJECT(sheets_dialog), "wrapbox_right");
1460 else
1461 return gtk_object_get_data(GTK_OBJECT(sheets_dialog), "wrapbox_left");
1462 }
1463
1464 static void
sheets_dialog_copy_object(GtkWidget * active_button,GtkWidget * target_wrapbox)1465 sheets_dialog_copy_object(GtkWidget *active_button, GtkWidget *target_wrapbox)
1466 {
1467 GtkWidget *button;
1468 SheetMod *sm;
1469 SheetObjectMod *som;
1470 SheetObjectMod *som_new;
1471
1472 sm = gtk_object_get_data(GTK_OBJECT(target_wrapbox), "sheet_mod");
1473 som = gtk_object_get_data(GTK_OBJECT(active_button), "sheet_object_mod");
1474
1475 if (!som)
1476 return;
1477
1478
1479 som_new = g_new0(SheetObjectMod, 1);
1480 {
1481 SheetObject *so = &som_new->sheet_object;
1482
1483 so->object_type = g_strdup(som->sheet_object.object_type);
1484 so->description = g_strdup(som->sheet_object.description);
1485 so->pixmap = som->sheet_object.pixmap;
1486 so->user_data = som->sheet_object.user_data;
1487 so->user_data_type = som->sheet_object.user_data_type;
1488 so->line_break = FALSE; /* must be false--we don't copy linebreaks */
1489 so->pixmap_file = g_strdup(som->sheet_object.pixmap_file);
1490 so->has_icon_on_sheet = som->sheet_object.has_icon_on_sheet;
1491 }
1492
1493 som_new->type = som->type;
1494 som_new->mod = SHEET_OBJECT_MOD_NONE;
1495
1496 sm->sheet.objects = g_slist_append(sm->sheet.objects, som_new);
1497 if (sm->mod == SHEETMOD_MOD_NONE)
1498 sm->mod = SHEETMOD_MOD_CHANGED;
1499
1500 button = sheets_dialog_create_object_button(som_new, sm, target_wrapbox);
1501 gtk_wrap_box_pack(GTK_WRAP_BOX(target_wrapbox), button,
1502 FALSE, TRUE, FALSE, TRUE);
1503 gtk_widget_show(button);
1504
1505 sheets_dialog_apply_revert_set_sensitive(TRUE);
1506 }
1507
1508 void
on_sheets_dialog_button_copy_clicked(GtkButton * button,gpointer user_data)1509 on_sheets_dialog_button_copy_clicked (GtkButton *button,
1510 gpointer user_data)
1511 {
1512 GtkWidget *active_button;
1513 GtkWidget *wrapbox;
1514 GList *button_list;
1515 GtkWidget *target_wrapbox;
1516
1517 active_button = sheets_dialog_get_active_button(&wrapbox, &button_list);
1518
1519 target_wrapbox = sheets_dialog_get_target_wrapbox(wrapbox);
1520
1521 sheets_dialog_copy_object(active_button, target_wrapbox);
1522 }
1523
1524 void
on_sheets_dialog_button_copy_all_clicked(GtkButton * button,gpointer user_data)1525 on_sheets_dialog_button_copy_all_clicked
1526 (GtkButton *button,
1527 gpointer user_data)
1528 {
1529 GtkWidget *active_button;
1530 GtkWidget *wrapbox;
1531 GList *button_list, *iter_list;
1532 GtkWidget *target_wrapbox;
1533
1534 active_button = sheets_dialog_get_active_button(&wrapbox, &button_list);
1535
1536 target_wrapbox = sheets_dialog_get_target_wrapbox(wrapbox);
1537
1538 for (iter_list = button_list; iter_list; iter_list = g_list_next(iter_list))
1539 sheets_dialog_copy_object(iter_list->data, target_wrapbox);
1540 }
1541
1542 void
on_sheets_dialog_button_move_clicked(GtkButton * button,gpointer user_data)1543 on_sheets_dialog_button_move_clicked (GtkButton *button,
1544 gpointer user_data)
1545 {
1546 GtkWidget *active_button;
1547 GtkWidget *wrapbox;
1548 GList *button_list;
1549 GtkWidget *target_wrapbox;
1550 SheetObjectMod *som;
1551 GtkWidget *new_active_button;
1552
1553 active_button = sheets_dialog_get_active_button(&wrapbox, &button_list);
1554
1555 target_wrapbox = sheets_dialog_get_target_wrapbox(wrapbox);
1556
1557 sheets_dialog_copy_object(active_button, target_wrapbox);
1558
1559 som = gtk_object_get_data(GTK_OBJECT(active_button), "sheet_object_mod");
1560 if (som) {
1561 SheetMod *sm;
1562
1563 som->mod = SHEET_OBJECT_MOD_DELETED;
1564 /* also mark the source sheet as changed */
1565 sm = gtk_object_get_data(GTK_OBJECT(active_button), "sheet_mod");
1566 sm->mod = SHEETMOD_MOD_CHANGED;
1567 }
1568
1569 new_active_button = sheets_dialog_set_new_active_button();
1570
1571 gtk_widget_destroy(active_button);
1572 radio_group = gtk_radio_button_group(GTK_RADIO_BUTTON(new_active_button));
1573
1574 sheets_dialog_normalize_line_breaks(wrapbox, SHEETS_DIALOG_MOVE_NONE);
1575 }
1576
1577 void
on_sheets_dialog_button_move_all_clicked(GtkButton * button,gpointer user_data)1578 on_sheets_dialog_button_move_all_clicked
1579 (GtkButton *button,
1580 gpointer user_data)
1581 {
1582 GtkWidget *active_button;
1583 GtkWidget *wrapbox;
1584 GList *button_list;
1585 GList *iter_list;
1586 GtkWidget *target_wrapbox;
1587 SheetObjectMod *som;
1588
1589 active_button = sheets_dialog_get_active_button(&wrapbox, &button_list);
1590
1591 target_wrapbox = sheets_dialog_get_target_wrapbox(wrapbox);
1592
1593 for (iter_list = button_list; iter_list; iter_list = g_list_next(iter_list))
1594 {
1595 sheets_dialog_copy_object(iter_list->data, target_wrapbox);
1596
1597 som = gtk_object_get_data(GTK_OBJECT(iter_list->data), "sheet_object_mod");
1598 if (som)
1599 som->mod = SHEET_OBJECT_MOD_DELETED;
1600
1601 gtk_widget_destroy(iter_list->data);
1602
1603 /* MCNFIXME: do we have to resanitize the radio_group? */
1604 }
1605
1606 /* Force the 1st button in the target wrapbox to be active after moving */
1607
1608 button_list = gtk_container_children(GTK_CONTAINER(target_wrapbox));
1609 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button_list->data), TRUE);
1610 }
1611
1612 static gboolean
copy_file(gchar * src,gchar * dst)1613 copy_file(gchar *src, gchar *dst)
1614 {
1615 FILE *fp_src;
1616 FILE *fp_dst;
1617 int c;
1618
1619 if ((fp_src = g_fopen(src, "rb")) == NULL)
1620 {
1621 message_error(_("Couldn't open '%s': %s"),
1622 dia_message_filename(src), strerror(errno));
1623 return FALSE;
1624 }
1625
1626 if ((fp_dst = g_fopen(dst, "wb")) == NULL)
1627 {
1628 message_error(_("Couldn't open '%s': %s"),
1629 dia_message_filename(dst), strerror(errno));
1630 return FALSE;
1631 }
1632
1633 while ((c = fgetc(fp_src)) != EOF)
1634 fputc(c, fp_dst);
1635
1636 fclose(fp_src);
1637 fclose(fp_dst);
1638
1639 return TRUE;
1640 }
1641
1642 /* write a sheet to ~/.dia/sheets */
1643 static gboolean
write_user_sheet(Sheet * sheet)1644 write_user_sheet(Sheet *sheet)
1645 {
1646 FILE *file;
1647 xmlDocPtr doc;
1648 xmlNodePtr root;
1649 xmlNodePtr node;
1650 xmlNodePtr object_node;
1651 xmlNodePtr desc_node;
1652 xmlNodePtr icon_node;
1653 gchar buf[512];
1654 time_t time_now;
1655 const char *username;
1656 gchar *dir_user_sheets;
1657 gchar *filename;
1658 SheetObject *sheetobject;
1659 GSList *sheet_objects;
1660
1661 dir_user_sheets = dia_config_filename("sheets");
1662 if (!*(sheet->filename))
1663 {
1664 gchar *basename;
1665
1666 basename = g_strdup(sheet->name);
1667 basename = g_strdelimit(basename, G_STR_DELIMITERS G_DIR_SEPARATOR_S, '_');
1668 filename = g_strdup_printf("%s%s%s.sheet", dir_user_sheets,
1669 G_DIR_SEPARATOR_S, basename);
1670 g_free(basename);
1671 }
1672 else
1673 filename = g_strdup_printf("%s%s%s", dir_user_sheets,
1674 G_DIR_SEPARATOR_S, g_basename(sheet->filename));
1675
1676 file = g_fopen(filename, "w");
1677
1678 if (file==NULL)
1679 {
1680 message_error(_("Couldn't open: '%s' for writing"),
1681 dia_message_filename(filename));
1682 g_free(filename);
1683 return FALSE;
1684 }
1685 fclose(file);
1686
1687 time_now = time(NULL);
1688 username = g_get_user_name();
1689 if (username==NULL)
1690 username = _("a user");
1691
1692 doc = xmlNewDoc((const xmlChar *)"1.0");
1693 doc->encoding = xmlStrdup((const xmlChar *)"UTF-8");
1694 doc->standalone = FALSE;
1695 root = xmlNewDocNode(doc, NULL, (const xmlChar *)"sheet", NULL);
1696 doc->xmlRootNode = root;
1697 xmlSetProp(root, (const xmlChar *)"xmlns", (const xmlChar *) DIA_XML_NAME_SPACE_BASE "dia-sheet-ns");
1698
1699 /* comments */
1700 xmlAddChild(root, xmlNewText((const xmlChar *)"\n"));
1701 xmlAddChild(root, xmlNewComment((const xmlChar *)"Dia-Version: "VERSION));
1702 xmlAddChild(root, xmlNewText((const xmlChar *)"\n"));
1703 g_snprintf(buf, sizeof(buf), _("File: %s"), filename);
1704 xmlAddChild(root, xmlNewComment((xmlChar *)buf));
1705 xmlAddChild(root, xmlNewText((const xmlChar *)"\n"));
1706 g_snprintf(buf, sizeof(buf), _("Date: %s"), ctime(&time_now));
1707 buf[strlen(buf)-1] = '\0'; /* remove the trailing new line */
1708 xmlAddChild(root, xmlNewComment((xmlChar *)buf));
1709 xmlAddChild(root, xmlNewText((const xmlChar *)"\n"));
1710 g_snprintf(buf, sizeof(buf), _("For: %s"), username);
1711 xmlAddChild(root, xmlNewComment((xmlChar *)buf));
1712 xmlAddChild(root, xmlNewText((const xmlChar *)"\n\n"));
1713
1714 /* sheet name */
1715 node = xmlNewChild(root, NULL, (const xmlChar *)"name", NULL);
1716 xmlAddChild(node, xmlNewText((xmlChar *)sheet->name));
1717 xmlAddChild(root, xmlNewText((const xmlChar *)"\n"));
1718
1719 /* sheet description */
1720 node = xmlNewChild(root, NULL, (const xmlChar *)"description", NULL);
1721 xmlAddChild(node, xmlNewText((xmlChar *)sheet->description));
1722 xmlAddChild(root, xmlNewText((const xmlChar *)"\n"));
1723
1724 /* content */
1725 node = xmlNewChild(root, NULL, (const xmlChar *)"contents", NULL);
1726 xmlAddChild(node, xmlNewText((const xmlChar *)"\n"));
1727 xmlAddChild(node, xmlNewComment((const xmlChar *) _("add shapes here")));
1728 xmlAddChild(node, xmlNewText((const xmlChar *)"\n"));
1729
1730 /* objects */
1731 for (sheet_objects = sheet->objects; sheet_objects;
1732 sheet_objects = g_slist_next(sheet_objects))
1733 {
1734 SheetObjectMod *som;
1735
1736 som = sheet_objects->data;
1737
1738 if (som->mod == SHEET_OBJECT_MOD_DELETED)
1739 continue;
1740
1741 /* If its a new shape, then copy the .shape and .xpm files from
1742 their current location to ~/.dia/shapes/ */
1743
1744 if (som->mod == SHEET_OBJECT_MOD_NEW)
1745 {
1746 gchar *dia_user_shapes;
1747 gchar *dest;
1748
1749 dia_user_shapes = dia_config_filename("shapes");
1750
1751 dest = g_strdup_printf("%s%s%s", dia_user_shapes, G_DIR_SEPARATOR_S,
1752 g_basename(som->svg_filename));
1753 copy_file(som->svg_filename, dest);
1754 g_free(dest);
1755
1756 dest = g_strdup_printf("%s%s%s", dia_user_shapes, G_DIR_SEPARATOR_S,
1757 g_basename(som->sheet_object.pixmap_file));
1758 copy_file(som->sheet_object.pixmap_file, dest);
1759 g_free(dest);
1760 }
1761
1762 sheetobject = &som->sheet_object;
1763 object_node = xmlNewChild(node, NULL, (const xmlChar *)"object", NULL);
1764
1765 xmlSetProp(object_node, (const xmlChar *)"name", (xmlChar *)sheetobject->object_type);
1766
1767 if (sheetobject->user_data_type == USER_DATA_IS_INTDATA)
1768 {
1769 gchar *user_data;
1770
1771 user_data = g_strdup_printf("%u", (guint)(sheetobject->user_data));
1772 xmlSetProp(object_node, (const xmlChar *)"intdata", (xmlChar *) user_data);
1773 g_free(user_data);
1774 }
1775
1776 xmlAddChild(object_node, xmlNewText((const xmlChar *)"\n"));
1777 desc_node = xmlNewChild(object_node, NULL, (const xmlChar *)"description", NULL);
1778 xmlAddChild(desc_node, xmlNewText((xmlChar *) sheetobject->description));
1779 /* xmlAddChild(object_node, xmlNewText((const xmlChar *)"\n")); */
1780
1781 if (sheetobject->has_icon_on_sheet == TRUE)
1782 {
1783 gchar *canonical_icon;
1784 gchar *canonical_user_sheets;
1785 gchar *canonical_sheets;
1786 gchar *icon;
1787
1788 xmlAddChild(object_node, xmlNewText((const xmlChar *)"\n"));
1789 icon_node = xmlNewChild(object_node, NULL, (const xmlChar *)"icon", NULL);
1790 canonical_icon = dia_get_canonical_path(sheetobject->pixmap_file);
1791 icon = canonical_icon;
1792 canonical_user_sheets = dia_get_canonical_path(dir_user_sheets);
1793 canonical_sheets = dia_get_canonical_path(dia_get_data_directory("sheets"));
1794 if(g_str_has_prefix(icon, canonical_user_sheets))
1795 icon += strlen(canonical_user_sheets) + 1;
1796 if(g_str_has_prefix(icon, canonical_sheets))
1797 icon += strlen(canonical_sheets) + 1;
1798 xmlAddChild(icon_node, xmlNewText((xmlChar *) icon));
1799 xmlAddChild(object_node, xmlNewText((const xmlChar *)"\n"));
1800 g_free(canonical_icon);
1801 g_free(canonical_user_sheets);
1802 g_free(canonical_sheets);
1803 }
1804 }
1805 xmlSetDocCompressMode(doc, 0);
1806 xmlDiaSaveFile(filename, doc);
1807 xmlFreeDoc(doc);
1808 return TRUE;
1809 }
1810
1811 static void
touch_file(gchar * filename)1812 touch_file(gchar *filename)
1813 {
1814 struct stat stat_buf;
1815 struct utimbuf utim_buf;
1816
1817 g_stat(filename, &stat_buf);
1818 utim_buf.actime = stat_buf.st_atime;
1819 utim_buf.modtime = time(NULL);
1820 utime(filename, &utim_buf);
1821 }
1822
1823 static gint
sheets_find_sheet(gconstpointer a,gconstpointer b)1824 sheets_find_sheet(gconstpointer a, gconstpointer b)
1825 {
1826 if (!strcmp(((Sheet *)a)->name, ((Sheet *)b)->name))
1827 return 0;
1828 else
1829 return 1;
1830 }
1831
1832 extern GSList *sheets_mods_list;
1833
1834 void
on_sheets_dialog_button_apply_clicked(GtkButton * button,gpointer user_data)1835 on_sheets_dialog_button_apply_clicked (GtkButton *button,
1836 gpointer user_data)
1837 {
1838 GSList *iter_list;
1839
1840 for (iter_list = sheets_mods_list; iter_list;
1841 iter_list = g_slist_next(iter_list))
1842 {
1843 SheetMod *sm;
1844 GSList *sheets_list;
1845 GSList *find_list;
1846
1847 sm = iter_list->data;
1848 switch (sm->mod)
1849 {
1850 GSList *sheet_object_mods_list;
1851 GSList *list;
1852 Sheet *new_sheet = NULL;
1853
1854 case SHEETMOD_MOD_NEW:
1855 write_user_sheet(&sm->sheet);
1856
1857 sheet_object_mods_list = sm->sheet.objects;
1858 sm->sheet.objects = NULL;
1859 /* we have to transfer 'permanent' memory */
1860 new_sheet = g_new0 (Sheet, 1);
1861 *new_sheet = sm->sheet;
1862 register_sheet(new_sheet);
1863
1864 for (list = sheet_object_mods_list; list; list = g_slist_next(list))
1865 {
1866 SheetObjectMod *som;
1867 SheetObject *new_object;
1868
1869 som = list->data;
1870 if (som->mod == SHEET_OBJECT_MOD_DELETED)
1871 continue;
1872
1873 new_object = g_new0(SheetObject, 1);
1874 *new_object = som->sheet_object;
1875 sheet_append_sheet_obj(new_sheet, new_object);
1876 }
1877
1878 dia_sort_sheets();
1879 fill_sheet_menu();
1880 break;
1881
1882 case SHEETMOD_MOD_CHANGED:
1883 write_user_sheet(&sm->sheet);
1884
1885 sheet_object_mods_list = sm->sheet.objects;
1886 sheets_list = get_sheets_list();
1887
1888 sheets_list = g_slist_find_custom(sheets_list, &sm->sheet,
1889 sheets_find_sheet);
1890 g_assert(sheets_list);
1891 ((Sheet *)(sheets_list->data))->objects = NULL;
1892
1893 for (list = sheet_object_mods_list; list; list = g_slist_next(list))
1894 {
1895 SheetObjectMod *som;
1896 SheetObject *new_object;
1897
1898 som = list->data;
1899 if (som->mod == SHEET_OBJECT_MOD_DELETED)
1900 continue;
1901
1902 new_object = g_new0(SheetObject, 1);
1903 *new_object = som->sheet_object;
1904 sheet_append_sheet_obj(sheets_list->data, new_object);
1905 }
1906 fill_sheet_menu();
1907 break;
1908
1909 case SHEETMOD_MOD_DELETED:
1910 if (sm->sheet.scope == SHEET_SCOPE_SYSTEM)
1911 touch_file(sm->sheet.shadowing->filename);
1912 else
1913 g_unlink(sm->sheet.filename);
1914
1915 sheets_list = get_sheets_list();
1916 find_list = g_slist_find_custom(sheets_list, &sm->sheet,
1917 sheets_find_sheet);
1918 g_assert(sheets_list);
1919 if (!g_slist_remove_link(sheets_list, find_list))
1920 g_warning ("No sheets left?");
1921
1922 dia_sort_sheets();
1923 fill_sheet_menu();
1924 break;
1925
1926 case SHEETMOD_MOD_NONE:
1927 break;
1928
1929 default:
1930 g_assert_not_reached();
1931 }
1932 }
1933 {
1934 optionmenu_activate_first_pass = TRUE;
1935
1936 sheets_dialog_apply_revert_set_sensitive(FALSE);
1937 sheets_dialog_create();
1938 }
1939 }
1940
1941 void
on_sheets_dialog_button_revert_clicked(GtkButton * button,gpointer user_data)1942 on_sheets_dialog_button_revert_clicked (GtkButton *button,
1943 gpointer user_data)
1944 {
1945 optionmenu_activate_first_pass = TRUE;
1946
1947 sheets_dialog_apply_revert_set_sensitive(FALSE);
1948 sheets_dialog_create();
1949 }
1950
1951