1 /* Dia -- a diagram creation/manipulation program -*- c -*-
2 * Copyright (C) 1998 Alexander Larsson
4 * Property system for dia objects/shapes.
5 * Copyright (C) 2000 James Henstridge
6 * Copyright (C) 2001 Cyrille Chepelov
7 * Major restructuration done in August 2001 by C. Chepelov
9 * Property types for "widget" types (static, buttons, notebooks, frames, etc.)
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 #undef GTK_DISABLE_DEPRECATED /* GtkList */
32 #define WIDGET GtkWidget
34 #include "properties.h"
35 #include "propinternals.h"
37 /******************************/
38 /* The STATIC property type. */
39 /******************************/
42 staticprop_get_widget(StaticProperty
*prop
, PropDialog
*dialog
)
44 GtkWidget
*ret
= NULL
;
45 if (!prop
->common
.descr
) return NULL
;
47 ret
= gtk_label_new(prop
->common
.descr
->tooltip
);
48 gtk_label_set_justify(GTK_LABEL(ret
),GTK_JUSTIFY_LEFT
);
52 static const PropertyOps staticprop_ops
= {
53 (PropertyType_New
) noopprop_new
,
54 (PropertyType_Free
) noopprop_free
,
55 (PropertyType_Copy
) noopprop_copy
,
56 (PropertyType_Load
) invalidprop_load
,
57 (PropertyType_Save
) invalidprop_save
,
58 (PropertyType_GetWidget
) staticprop_get_widget
,
59 (PropertyType_ResetWidget
) noopprop_reset_widget
,
60 (PropertyType_SetFromWidget
) noopprop_set_from_widget
,
62 (PropertyType_CanMerge
) noopprop_can_merge
,
63 (PropertyType_GetFromOffset
) noopprop_get_from_offset
,
64 (PropertyType_SetFromOffset
) noopprop_set_from_offset
68 /******************************/
69 /* The BUTTON property type. */
70 /******************************/
73 buttonprop_get_widget(ButtonProperty
*prop
, PropDialog
*dialog
)
75 GtkWidget
*ret
= NULL
;
76 if (!prop
->common
.descr
) return NULL
;
78 ret
= gtk_button_new_with_label(_(prop
->common
.descr
->tooltip
));
79 prophandler_connect(&prop
->common
,GTK_OBJECT(ret
),"clicked");
84 static const PropertyOps buttonprop_ops
= {
85 (PropertyType_New
) noopprop_new
,
86 (PropertyType_Free
) noopprop_free
,
87 (PropertyType_Copy
) noopprop_copy
,
88 (PropertyType_Load
) invalidprop_load
,
89 (PropertyType_Save
) invalidprop_save
,
90 (PropertyType_GetWidget
) buttonprop_get_widget
,
91 (PropertyType_ResetWidget
) noopprop_reset_widget
,
92 (PropertyType_SetFromWidget
) noopprop_set_from_widget
,
94 (PropertyType_CanMerge
) noopprop_can_merge
,
95 (PropertyType_GetFromOffset
) noopprop_get_from_offset
,
96 (PropertyType_SetFromOffset
) noopprop_set_from_offset
99 /**************************************************/
100 /* The FRAME_BEGIN and FRAME_END property types. */
101 /**************************************************/
103 struct FoldButtonInfo
{
104 GtkWidget
*unfoldbutton
;
109 frame_fold_unfold(GtkWidget
*button1
, gpointer userdata
)
111 struct FoldButtonInfo
*info
= (struct FoldButtonInfo
*)userdata
;
113 if (button1
== info
->unfoldbutton
) {
114 gtk_widget_hide(info
->unfoldbutton
);
115 gtk_widget_show(info
->frame
);
117 gtk_widget_hide(info
->frame
);
118 gtk_widget_show(info
->unfoldbutton
);
123 frame_beginprop_get_widget(FrameProperty
*prop
, PropDialog
*dialog
)
125 gchar
*foldstring
= g_strdup_printf("%s <<<", prop
->common
.descr
->description
);
126 gchar
*unfoldstring
= g_strdup_printf("%s >>>", prop
->common
.descr
->description
);
127 GtkWidget
*frame
= gtk_frame_new(NULL
);
128 GtkWidget
*vbox
= gtk_vbox_new(FALSE
,2);
129 GtkWidget
*foldbutton
= gtk_button_new_with_label(foldstring
);
130 GtkWidget
*unfoldbutton
= gtk_button_new_with_label(unfoldstring
);
132 struct FoldButtonInfo
*info
= g_new(struct FoldButtonInfo
, 1);
135 g_free(unfoldstring
);
138 info
->unfoldbutton
= unfoldbutton
;
140 gtk_frame_set_label_widget(GTK_FRAME(frame
), foldbutton
);
142 gtk_container_set_border_width (GTK_CONTAINER(frame
), 2);
143 gtk_container_add(GTK_CONTAINER(frame
),vbox
);
144 gtk_widget_show(foldbutton
);
145 gtk_widget_show(frame
);
146 gtk_widget_show(vbox
);
148 prop_dialog_add_raw(dialog
, frame
);
150 prop_dialog_add_raw_with_flags(dialog
, unfoldbutton
, FALSE
, FALSE
);
152 gtk_signal_connect(GTK_OBJECT(foldbutton
), "clicked",
153 GTK_SIGNAL_FUNC(frame_fold_unfold
), info
);
154 gtk_signal_connect(GTK_OBJECT(unfoldbutton
), "clicked",
155 GTK_SIGNAL_FUNC(frame_fold_unfold
), info
);
157 prop_dialog_container_push(dialog
,vbox
);
159 return NULL
; /* there is no single widget to add with a label next to it. */
163 frame_endprop_get_widget(FrameProperty
*prop
, PropDialog
*dialog
)
165 prop_dialog_container_pop(dialog
);
169 static const PropertyOps frame_beginprop_ops
= {
170 (PropertyType_New
) noopprop_new
,
171 (PropertyType_Free
) noopprop_free
,
172 (PropertyType_Copy
) noopprop_copy
,
173 (PropertyType_Load
) invalidprop_load
,
174 (PropertyType_Save
) invalidprop_save
,
175 (PropertyType_GetWidget
) frame_beginprop_get_widget
,
176 (PropertyType_ResetWidget
) noopprop_reset_widget
,
177 (PropertyType_SetFromWidget
) noopprop_set_from_widget
,
179 (PropertyType_CanMerge
) noopprop_can_merge
,
180 (PropertyType_GetFromOffset
) noopprop_get_from_offset
,
181 (PropertyType_SetFromOffset
) noopprop_set_from_offset
184 static const PropertyOps frame_endprop_ops
= {
185 (PropertyType_New
) noopprop_new
,
186 (PropertyType_Free
) noopprop_free
,
187 (PropertyType_Copy
) noopprop_copy
,
188 (PropertyType_Load
) invalidprop_load
,
189 (PropertyType_Save
) invalidprop_save
,
190 (PropertyType_GetWidget
) frame_endprop_get_widget
,
191 (PropertyType_ResetWidget
) noopprop_reset_widget
,
192 (PropertyType_SetFromWidget
) noopprop_set_from_widget
,
194 (PropertyType_CanMerge
) noopprop_can_merge
,
195 (PropertyType_GetFromOffset
) noopprop_get_from_offset
,
196 (PropertyType_SetFromOffset
) noopprop_set_from_offset
199 /*********************************************************/
200 /* The MULTICOL_BEGIN, _COLUMN and _END property types. */
201 /*********************************************************/
204 multicol_beginprop_get_widget(MulticolProperty
*prop
, PropDialog
*dialog
)
206 GtkWidget
*multicol
= gtk_hbox_new(FALSE
,1);
208 gtk_container_set_border_width (GTK_CONTAINER(multicol
), 2);
209 gtk_widget_show(multicol
);
211 prop_dialog_add_raw(dialog
,multicol
);
213 prop_dialog_container_push(dialog
,multicol
);
214 prop_dialog_container_push(dialog
,NULL
); /* there must be a _COLUMN soon */
216 return NULL
; /* there is no single widget to add with a label next to it. */
220 multicol_columnprop_get_widget(MulticolProperty
*prop
, PropDialog
*dialog
)
222 GtkWidget
*col
= gtk_vbox_new(FALSE
,1);
224 gtk_container_set_border_width (GTK_CONTAINER(col
), 2);
225 gtk_widget_show(col
);
227 prop_dialog_container_pop(dialog
); /* NULL or the previous column */
229 gtk_box_pack_end_defaults(GTK_BOX(dialog
->lastcont
),col
);
231 prop_dialog_add_raw(dialog
,NULL
); /* to reset the internal table system */
232 prop_dialog_container_push(dialog
,col
);
238 multicol_endprop_get_widget(MulticolProperty
*prop
, PropDialog
*dialog
)
240 prop_dialog_container_pop(dialog
); /* the column */
241 prop_dialog_container_pop(dialog
); /* the multicol */
245 static const PropertyOps multicol_beginprop_ops
= {
246 (PropertyType_New
) noopprop_new
,
247 (PropertyType_Free
) noopprop_free
,
248 (PropertyType_Copy
) noopprop_copy
,
249 (PropertyType_Load
) invalidprop_load
,
250 (PropertyType_Save
) invalidprop_save
,
251 (PropertyType_GetWidget
) multicol_beginprop_get_widget
,
252 (PropertyType_ResetWidget
) noopprop_reset_widget
,
253 (PropertyType_SetFromWidget
) noopprop_set_from_widget
,
255 (PropertyType_CanMerge
) noopprop_can_merge
,
256 (PropertyType_GetFromOffset
) noopprop_get_from_offset
,
257 (PropertyType_SetFromOffset
) noopprop_set_from_offset
260 static const PropertyOps multicol_columnprop_ops
= {
261 (PropertyType_New
) noopprop_new
,
262 (PropertyType_Free
) noopprop_free
,
263 (PropertyType_Copy
) noopprop_copy
,
264 (PropertyType_Load
) invalidprop_load
,
265 (PropertyType_Save
) invalidprop_save
,
266 (PropertyType_GetWidget
) multicol_columnprop_get_widget
,
267 (PropertyType_ResetWidget
) noopprop_reset_widget
,
268 (PropertyType_SetFromWidget
) noopprop_set_from_widget
,
270 (PropertyType_CanMerge
) noopprop_can_merge
,
271 (PropertyType_GetFromOffset
) noopprop_get_from_offset
,
272 (PropertyType_SetFromOffset
) noopprop_set_from_offset
275 static const PropertyOps multicol_endprop_ops
= {
276 (PropertyType_New
) noopprop_new
,
277 (PropertyType_Free
) noopprop_free
,
278 (PropertyType_Copy
) noopprop_copy
,
279 (PropertyType_Load
) invalidprop_load
,
280 (PropertyType_Save
) invalidprop_save
,
281 (PropertyType_GetWidget
) multicol_endprop_get_widget
,
282 (PropertyType_ResetWidget
) noopprop_reset_widget
,
283 (PropertyType_SetFromWidget
) noopprop_set_from_widget
,
285 (PropertyType_CanMerge
) noopprop_can_merge
,
286 (PropertyType_GetFromOffset
) noopprop_get_from_offset
,
287 (PropertyType_SetFromOffset
) noopprop_set_from_offset
290 /*********************************************************/
291 /* The NOTEBOOK_BEGIN, _PAGE and _END property types. */
292 /*********************************************************/
295 notebook_beginprop_get_widget(NotebookProperty
*prop
, PropDialog
*dialog
)
297 GtkWidget
*notebook
= gtk_notebook_new();
299 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook
),GTK_POS_TOP
);
300 gtk_container_set_border_width (GTK_CONTAINER(notebook
), 1);
301 gtk_widget_show(notebook
);
303 prop_dialog_add_raw(dialog
,notebook
);
305 prop_dialog_container_push(dialog
,notebook
);
306 prop_dialog_container_push(dialog
,NULL
); /* there must be a _PAGE soon */
308 return NULL
; /* there is no single widget to add with a label next to it. */
312 notebook_pageprop_get_widget(NotebookProperty
*prop
, PropDialog
*dialog
)
314 GtkWidget
*page
= gtk_vbox_new(FALSE
,1);
315 GtkWidget
*label
= gtk_label_new(_(prop
->common
.descr
->description
));
317 gtk_container_set_border_width (GTK_CONTAINER(page
), 2);
318 gtk_widget_show(page
);
319 gtk_widget_show(label
);
321 prop_dialog_container_pop(dialog
); /* NULL or the previous page */
323 gtk_notebook_append_page(GTK_NOTEBOOK(dialog
->lastcont
),page
,label
);
325 prop_dialog_add_raw(dialog
,NULL
); /* to reset the internal table system */
326 prop_dialog_container_push(dialog
,page
);
332 notebook_endprop_get_widget(NotebookProperty
*prop
, PropDialog
*dialog
)
334 prop_dialog_container_pop(dialog
); /* the page */
335 prop_dialog_container_pop(dialog
); /* the notebook */
339 static const PropertyOps notebook_beginprop_ops
= {
340 (PropertyType_New
) noopprop_new
,
341 (PropertyType_Free
) noopprop_free
,
342 (PropertyType_Copy
) noopprop_copy
,
343 (PropertyType_Load
) invalidprop_load
,
344 (PropertyType_Save
) invalidprop_save
,
345 (PropertyType_GetWidget
) notebook_beginprop_get_widget
,
346 (PropertyType_ResetWidget
) noopprop_reset_widget
,
347 (PropertyType_SetFromWidget
) noopprop_set_from_widget
,
349 (PropertyType_CanMerge
) noopprop_can_merge
,
350 (PropertyType_GetFromOffset
) noopprop_get_from_offset
,
351 (PropertyType_SetFromOffset
) noopprop_set_from_offset
354 static const PropertyOps notebook_pageprop_ops
= {
355 (PropertyType_New
) noopprop_new
,
356 (PropertyType_Free
) noopprop_free
,
357 (PropertyType_Copy
) noopprop_copy
,
358 (PropertyType_Load
) invalidprop_load
,
359 (PropertyType_Save
) invalidprop_save
,
360 (PropertyType_GetWidget
) notebook_pageprop_get_widget
,
361 (PropertyType_ResetWidget
) noopprop_reset_widget
,
362 (PropertyType_SetFromWidget
) noopprop_set_from_widget
,
364 (PropertyType_CanMerge
) noopprop_can_merge
,
365 (PropertyType_GetFromOffset
) noopprop_get_from_offset
,
366 (PropertyType_SetFromOffset
) noopprop_set_from_offset
369 static const PropertyOps notebook_endprop_ops
= {
370 (PropertyType_New
) noopprop_new
,
371 (PropertyType_Free
) noopprop_free
,
372 (PropertyType_Copy
) noopprop_copy
,
373 (PropertyType_Load
) invalidprop_load
,
374 (PropertyType_Save
) invalidprop_save
,
375 (PropertyType_GetWidget
) notebook_endprop_get_widget
,
376 (PropertyType_ResetWidget
) noopprop_reset_widget
,
377 (PropertyType_SetFromWidget
) noopprop_set_from_widget
,
379 (PropertyType_CanMerge
) noopprop_can_merge
,
380 (PropertyType_GetFromOffset
) noopprop_get_from_offset
,
381 (PropertyType_SetFromOffset
) noopprop_set_from_offset
384 /****************************/
385 /* The LIST property type. */
386 /****************************/
389 listprop_emptylines_realloc(ListProperty
*prop
,guint new_size
) {
392 for (i
= 0; i
< prop
->lines
->len
; i
++)
393 g_free(g_ptr_array_index(prop
->lines
,i
));
395 g_ptr_array_set_size(prop
->lines
,new_size
);
399 listprop_copylines(ListProperty
*prop
, GPtrArray
*src
) {
402 listprop_emptylines_realloc(prop
,src
->len
);
404 for (i
= 0; i
< src
->len
; i
++)
405 g_ptr_array_index(prop
->lines
,i
) = g_strdup(g_ptr_array_index(src
,i
));
408 static ListProperty
*
409 listprop_new(const PropDescription
*pdesc
, PropDescToPropPredicate reason
)
411 ListProperty
*prop
= g_new0(ListProperty
,1);
412 initialize_property(&prop
->common
,pdesc
,reason
);
414 prop
->w_selected
= -1;
415 prop
->lines
= g_ptr_array_new();
420 listprop_free(ListProperty
*prop
)
422 listprop_emptylines_realloc(prop
,-1);
423 g_ptr_array_free(prop
->lines
,TRUE
);
426 static ListProperty
*
427 listprop_copy(ListProperty
*src
)
430 (ListProperty
*)src
->common
.ops
->new_prop(src
->common
.descr
,
433 copy_init_property(&prop
->common
,&src
->common
);
434 prop
->selected
= src
->selected
;
435 prop
->w_selected
= src
->w_selected
;
436 listprop_copylines(prop
,src
->lines
);
442 listprop_select_child_signal(GtkList
*list
,
446 prop
->w_selected
= gtk_list_child_position(list
,child
);
450 listprop_get_widget(ListProperty
*prop
, PropDialog
*dialog
)
452 GtkWidget
*ret
= gtk_list_new();
454 gtk_list_set_selection_mode(GTK_LIST(ret
),GTK_SELECTION_BROWSE
);
455 gtk_list_unselect_all(GTK_LIST(ret
));
457 gtk_signal_connect(GTK_OBJECT(ret
), "select-child",
458 GTK_SIGNAL_FUNC(listprop_select_child_signal
), prop
);
460 prophandler_connect(&prop
->common
,GTK_OBJECT(ret
),"selection-changed");
465 make_item(const gchar
*line
) {
466 GtkWidget
*item
= gtk_list_item_new_with_label(line
);
467 gtk_widget_show(item
);
472 listprop_reset_widget(ListProperty
*prop
, WIDGET
*widget
)
476 gtk_list_clear_items(GTK_LIST(widget
),0,-1);
478 for (i
= 0; i
< prop
->lines
->len
; i
++) {
479 items
= g_list_append(items
, make_item(g_ptr_array_index(prop
->lines
,i
)));
481 gtk_list_append_items(GTK_LIST(widget
),items
);
482 prop
->w_selected
= prop
->selected
;
483 gtk_list_select_item(GTK_LIST(widget
),prop
->selected
);
487 listprop_set_from_widget(ListProperty
*prop
, WIDGET
*widget
)
489 prop
->selected
= prop
->w_selected
;
493 listprop_get_from_offset(ListProperty
*prop
,
494 void *base
, guint offset
, guint offset2
)
496 listprop_copylines(prop
,struct_member(base
,offset
, GPtrArray
*));
497 prop
->selected
= struct_member(base
,offset2
,gint
);
501 listprop_set_from_offset(ListProperty
*prop
,
502 void *base
, guint offset
, guint offset2
)
504 struct_member(base
,offset2
,gint
) = prop
->selected
;
507 static const PropertyOps listprop_ops
= {
508 (PropertyType_New
) listprop_new
,
509 (PropertyType_Free
) listprop_free
,
510 (PropertyType_Copy
) listprop_copy
,
512 (PropertyType_Load
) invalidprop_load
,
513 (PropertyType_Save
) invalidprop_save
,
515 (PropertyType_GetWidget
) listprop_get_widget
,
516 (PropertyType_ResetWidget
) listprop_reset_widget
,
517 (PropertyType_SetFromWidget
) listprop_set_from_widget
,
519 (PropertyType_CanMerge
) noopprop_can_merge
,
520 (PropertyType_GetFromOffset
) listprop_get_from_offset
,
521 (PropertyType_SetFromOffset
) listprop_set_from_offset
524 /* ************************************************************** */
527 prop_widgets_register(void)
529 prop_type_register(PROP_TYPE_STATIC
,&staticprop_ops
);
530 prop_type_register(PROP_TYPE_BUTTON
,&buttonprop_ops
);
531 prop_type_register(PROP_TYPE_FRAME_BEGIN
,&frame_beginprop_ops
);
532 prop_type_register(PROP_TYPE_FRAME_END
,&frame_endprop_ops
);
533 prop_type_register(PROP_TYPE_MULTICOL_BEGIN
,&multicol_beginprop_ops
);
534 prop_type_register(PROP_TYPE_MULTICOL_END
,&multicol_endprop_ops
);
535 prop_type_register(PROP_TYPE_MULTICOL_COLUMN
,&multicol_columnprop_ops
);
536 prop_type_register(PROP_TYPE_NOTEBOOK_BEGIN
,¬ebook_beginprop_ops
);
537 prop_type_register(PROP_TYPE_NOTEBOOK_END
,¬ebook_endprop_ops
);
538 prop_type_register(PROP_TYPE_NOTEBOOK_PAGE
,¬ebook_pageprop_ops
);
539 prop_type_register(PROP_TYPE_LIST
,&listprop_ops
);