1 /* Dia -- a diagram creation/manipulation program
2 * Copyright (C) 1998 Alexander Larsson
4 * sheets.c : a sheets and objects dialog
5 * Copyright (C) 2002 M.C. Nelson
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 #include <gdk-pixbuf/gdk-pixbuf.h>
34 #include "../lib/plug-ins.h"
35 #include "../lib/sheet.h"
36 #include "../lib/message.h"
37 #include "../lib/object.h"
38 #include "../app/pixmaps/missing.xpm"
40 #include "interface.h"
42 #include "sheets_dialog.h"
43 #include "gtkhwrapbox.h"
45 GtkWidget
*sheets_dialog
= NULL
;
46 GSList
*sheets_mods_list
= NULL
;
47 GtkTooltips
*sheets_dialog_tooltips
= NULL
;
48 static gpointer custom_type_symbol
;
50 /* Given a SheetObject and a SheetMod, create a new SheetObjectMod
51 and hook it into the 'objects' list in the SheetMod->sheet
53 NOTE: that the objects structure points to SheetObjectMod's and
54 *not* SheetObject's */
57 sheets_append_sheet_object_mod(SheetObject
*so
, SheetMod
*sm
)
59 SheetObjectMod
*sheet_object_mod
;
62 sheet_object_mod
= g_new(SheetObjectMod
, 1);
63 sheet_object_mod
->sheet_object
= *so
;
64 sheet_object_mod
->mod
= SHEET_OBJECT_MOD_NONE
;
66 ot
= object_get_type(so
->object_type
);
68 if (ot
->ops
== ((DiaObjectType
*)(custom_type_symbol
))->ops
)
69 sheet_object_mod
->type
= OBJECT_TYPE_SVG
;
71 sheet_object_mod
->type
= OBJECT_TYPE_PROGRAMMED
;
73 sm
->sheet
.objects
= g_slist_append(sm
->sheet
.objects
, sheet_object_mod
);
75 return sheet_object_mod
;
78 /* Given a Sheet, create a SheetMod wrapper for a list of SheetObjectMod's */
81 sheets_append_sheet_mods(Sheet
*sheet
)
84 GSList
*sheet_objects_list
;
86 sheet_mod
= g_new(SheetMod
, 1);
87 sheet_mod
->sheet
= *sheet
;
88 sheet_mod
->type
= SHEETMOD_TYPE_NORMAL
;
89 sheet_mod
->mod
= SHEETMOD_MOD_NONE
;
90 sheet_mod
->sheet
.objects
= NULL
;
92 for (sheet_objects_list
= sheet
->objects
; sheet_objects_list
;
93 sheet_objects_list
= g_slist_next(sheet_objects_list
))
94 sheets_append_sheet_object_mod(sheet_objects_list
->data
, sheet_mod
);
96 sheets_mods_list
= g_slist_append(sheets_mods_list
, sheet_mod
);
102 menu_item_compare_labels(gconstpointer a
, gconstpointer b
)
107 a_list
= gtk_container_children(GTK_CONTAINER(GTK_MENU_ITEM(a
)));
108 g_assert(g_list_length(a_list
) == 1);
110 gtk_label_get(GTK_LABEL(a_list
->data
), &label
);
113 if (!strcmp(label
, (gchar
*)b
))
120 sheets_optionmenu_create(GtkWidget
*option_menu
, GtkWidget
*wrapbox
,
123 GtkWidget
*optionmenu_menu
;
125 GList
*menu_item_list
;
127 /* Delete the contents, if any, of this optionemnu first */
129 optionmenu_menu
= gtk_option_menu_get_menu(GTK_OPTION_MENU(option_menu
));
130 gtk_container_foreach(GTK_CONTAINER(optionmenu_menu
),
131 (GtkCallback
)gtk_widget_destroy
, NULL
);
133 if (!sheets_dialog_tooltips
)
134 sheets_dialog_tooltips
= gtk_tooltips_new();
136 for (sheets_list
= sheets_mods_list
; sheets_list
;
137 sheets_list
= g_slist_next(sheets_list
))
140 GtkWidget
*menu_item
;
143 sheet_mod
= sheets_list
->data
;
145 /* We don't display sheets which have been deleted prior to Apply */
147 if (sheet_mod
->mod
== SHEETMOD_MOD_DELETED
)
151 menu_item
= gtk_menu_item_new_with_label(gettext(sheet_mod
->sheet
.name
));
153 gtk_menu_append(GTK_MENU(optionmenu_menu
), menu_item
);
155 if (sheet_mod
->sheet
.scope
== SHEET_SCOPE_SYSTEM
)
156 tip
= g_strdup_printf(_("%s\nSystem sheet"), sheet_mod
->sheet
.description
);
158 tip
= g_strdup_printf(_("%s\nUser sheet"), sheet_mod
->sheet
.description
);
160 gtk_tooltips_set_tip(GTK_TOOLTIPS(sheets_dialog_tooltips
), menu_item
, tip
,
165 gtk_widget_show(menu_item
);
167 gtk_object_set_data(GTK_OBJECT(menu_item
), "wrapbox", wrapbox
);
169 g_signal_connect(GTK_OBJECT(menu_item
), "activate",
170 G_CALLBACK(on_sheets_dialog_optionmenu_activate
),
171 (gpointer
)sheet_mod
);
174 menu_item_list
= gtk_container_children(GTK_CONTAINER(optionmenu_menu
));
176 /* If we were passed a sheet_name, then make the optionmenu point to that
177 name after creation */
184 list
= g_list_find_custom(menu_item_list
, sheet_name
,
185 menu_item_compare_labels
);
187 index
= g_list_position(menu_item_list
, list
);
188 gtk_option_menu_set_history(GTK_OPTION_MENU(option_menu
), index
);
189 gtk_menu_item_activate(GTK_MENU_ITEM(g_list_nth_data(menu_item_list
,
194 gtk_option_menu_set_history(GTK_OPTION_MENU(option_menu
), 0);
195 gtk_menu_item_activate(GTK_MENU_ITEM(menu_item_list
->data
));
198 g_list_free(menu_item_list
);
202 sheets_dialog_create(void)
206 GtkWidget
*option_menu
;
212 if (sheets_mods_list
)
214 /* FIXME: not sure if I understood the data structure
215 but simply leaking isn't acceptable ... --hb
217 g_slist_foreach(sheets_mods_list
, (GFunc
)g_free
, NULL
);
218 g_slist_free(sheets_mods_list
);
220 sheets_mods_list
= NULL
;
222 if (sheets_dialog
== NULL
)
224 sheets_dialog
= create_sheets_main_dialog();
225 /* Make sure to null our pointer when destroyed */
226 g_signal_connect (GTK_OBJECT (sheets_dialog
), "destroy",
227 G_CALLBACK (gtk_widget_destroyed
),
229 g_signal_connect (GTK_OBJECT (sheets_dialog
), "destroy",
230 G_CALLBACK (gtk_widget_destroyed
),
231 &sheets_dialog_tooltips
);
238 option_menu
= lookup_widget(sheets_dialog
, "optionmenu_left");
239 sheet_left
= gtk_object_get_data(GTK_OBJECT(option_menu
),
240 "active_sheet_name");
242 option_menu
= lookup_widget(sheets_dialog
, "optionmenu_right");
243 sheet_right
= gtk_object_get_data(GTK_OBJECT(option_menu
),
244 "active_sheet_name");
246 wrapbox
= lookup_widget(sheets_dialog
, "wrapbox_left");
247 gtk_widget_destroy(wrapbox
);
249 wrapbox
= lookup_widget(sheets_dialog
, "wrapbox_right");
250 gtk_widget_destroy(wrapbox
);
253 if (custom_type_symbol
== NULL
)
255 /* This little bit identifies a custom object symbol so we can tell the
256 difference later between a SVG shape and a Programmed shape */
258 custom_type_symbol
= NULL
;
259 for (plugin_list
= dia_list_plugins(); plugin_list
!= NULL
;
260 plugin_list
= g_list_next(plugin_list
))
262 PluginInfo
*info
= plugin_list
->data
;
264 custom_type_symbol
= (gpointer
)dia_plugin_get_symbol (info
,
266 if (custom_type_symbol
)
271 if (!custom_type_symbol
)
273 message_warning (_("Can't get symbol 'custom_type' from any module.\n"
274 "Editing shapes is disabled."));
278 for (sheets_list
= get_sheets_list(); sheets_list
;
279 sheets_list
= g_slist_next(sheets_list
))
280 sheets_append_sheet_mods(sheets_list
->data
);
282 sw
= lookup_widget(sheets_dialog
, "scrolledwindow_right");
283 wrapbox
= gtk_hwrap_box_new(FALSE
);
284 gtk_widget_ref(wrapbox
);
285 gtk_object_set_data(GTK_OBJECT(sheets_dialog
), "wrapbox_right", wrapbox
);
286 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(sw
), wrapbox
);
287 gtk_wrap_box_set_justify(GTK_WRAP_BOX(wrapbox
), GTK_JUSTIFY_TOP
);
288 gtk_wrap_box_set_line_justify(GTK_WRAP_BOX(wrapbox
), GTK_JUSTIFY_LEFT
);
289 gtk_widget_show(wrapbox
);
290 gtk_object_set_data(GTK_OBJECT(wrapbox
), "is_left", FALSE
);
291 option_menu
= lookup_widget(sheets_dialog
, "optionmenu_right");
292 sheets_optionmenu_create(option_menu
, wrapbox
, sheet_right
);
294 sw
= lookup_widget(sheets_dialog
, "scrolledwindow_left");
295 wrapbox
= gtk_hwrap_box_new(FALSE
);
296 gtk_widget_ref(wrapbox
);
297 gtk_object_set_data(GTK_OBJECT(sheets_dialog
), "wrapbox_left", wrapbox
);
298 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(sw
), wrapbox
);
299 gtk_wrap_box_set_justify(GTK_WRAP_BOX(wrapbox
), GTK_JUSTIFY_TOP
);
300 gtk_wrap_box_set_line_justify(GTK_WRAP_BOX(wrapbox
), GTK_JUSTIFY_LEFT
);
301 gtk_widget_show(wrapbox
);
302 gtk_object_set_data(GTK_OBJECT(wrapbox
), "is_left", (gpointer
)TRUE
);
303 option_menu
= lookup_widget(sheets_dialog
, "optionmenu_left");
304 sheets_optionmenu_create(option_menu
, wrapbox
, sheet_left
);
310 create_object_pixmap(SheetObject
*so
, GtkWidget
*parent
,
311 GdkPixmap
**pixmap
, GdkBitmap
**mask
)
319 style
= gtk_widget_get_style(parent
);
321 if (so
->pixmap
!= NULL
)
324 gdk_pixmap_colormap_create_from_xpm_d(NULL
,
325 gtk_widget_get_colormap(parent
),
327 &style
->bg
[GTK_STATE_NORMAL
],
332 if (so
->pixmap_file
!= NULL
)
335 GError
*error
= NULL
;
337 pixbuf
= gdk_pixbuf_new_from_file(so
->pixmap_file
, &error
);
340 gdk_pixbuf_render_pixmap_and_mask(pixbuf
, pixmap
, mask
, 1.0);
341 gdk_pixbuf_unref(pixbuf
);
343 message_warning ("%s", error
->message
);
344 g_error_free (error
);
345 *pixmap
= gdk_pixmap_colormap_create_from_xpm_d
347 gtk_widget_get_colormap(parent
),
349 &style
->bg
[GTK_STATE_NORMAL
],
362 lookup_widget (GtkWidget
*widget
,
363 const gchar
*widget_name
)
365 GtkWidget
*parent
, *found_widget
;
369 if (GTK_IS_MENU (widget
))
370 parent
= gtk_menu_get_attach_widget (GTK_MENU (widget
));
372 parent
= widget
->parent
;
378 found_widget
= (GtkWidget
*) gtk_object_get_data (GTK_OBJECT (widget
),
381 g_warning (_("Widget not found: %s"), widget_name
);
385 #include "pixmaps/n_a.xpm"
386 #include "pixmaps/line_break.xpm"
388 /* This is only called by the code written by glade and at the moment
389 it is only used to create the static pixmap of the current sheet object. */
392 create_pixmap(GtkWidget
*dialog
, gchar
*filename
, gboolean arg3
)
394 GdkPixmap
*pixmap
, *mask
;
400 button
= sheets_dialog_get_active_button(&wrapbox
, &button_list
);
401 som
= gtk_object_get_data(GTK_OBJECT(button
), "sheet_object_mod");
404 create_object_pixmap(&som
->sheet_object
, wrapbox
, &pixmap
, &mask
);
410 style
= gtk_widget_get_style(wrapbox
);
412 if ((gboolean
)gtk_object_get_data(GTK_OBJECT(button
), "is_hidden_button")
416 icon
= line_break_xpm
;
419 gdk_pixmap_colormap_create_from_xpm_d(NULL
,
420 gtk_widget_get_colormap(wrapbox
),
422 &style
->bg
[GTK_STATE_NORMAL
],
426 return gtk_pixmap_new(pixmap
, mask
);
429 /* The menu calls us here, after we've been instantiated */
432 sheets_dialog_show_callback(gpointer data
, guint action
, GtkWidget
*widget
)
435 GtkWidget
*option_menu
;
438 sheets_dialog_create();
442 wrapbox
= gtk_object_get_data(GTK_OBJECT(sheets_dialog
), "wrapbox_left");
443 option_menu
= lookup_widget(sheets_dialog
, "optionmenu_left");
444 sheets_optionmenu_create(option_menu
, wrapbox
, interface_current_sheet_name
);
446 g_assert(GTK_IS_WIDGET(sheets_dialog
));
447 gtk_widget_show(sheets_dialog
);
451 sheet_object_mod_get_type_string(SheetObjectMod
*som
)
455 case OBJECT_TYPE_SVG
:
456 return _("SVG Shape");
457 case OBJECT_TYPE_PROGRAMMED
:
458 return _("Programmed DiaObject");
460 g_assert_not_reached();