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 info
->unfoldbutton
= unfoldbutton
;
137 gtk_frame_set_label_widget(GTK_FRAME(frame
), foldbutton
);
139 gtk_container_set_border_width (GTK_CONTAINER(frame
), 2);
140 gtk_container_add(GTK_CONTAINER(frame
),vbox
);
141 gtk_widget_show(foldbutton
);
142 gtk_widget_show(frame
);
143 gtk_widget_show(vbox
);
145 prop_dialog_add_raw(dialog
, frame
);
147 prop_dialog_add_raw_with_flags(dialog
, unfoldbutton
, FALSE
, FALSE
);
149 gtk_signal_connect(GTK_OBJECT(foldbutton
), "clicked",
150 GTK_SIGNAL_FUNC(frame_fold_unfold
), info
);
151 gtk_signal_connect(GTK_OBJECT(unfoldbutton
), "clicked",
152 GTK_SIGNAL_FUNC(frame_fold_unfold
), info
);
154 prop_dialog_container_push(dialog
,vbox
);
156 return NULL
; /* there is no single widget to add with a label next to it. */
160 frame_endprop_get_widget(FrameProperty
*prop
, PropDialog
*dialog
)
162 prop_dialog_container_pop(dialog
);
166 static const PropertyOps frame_beginprop_ops
= {
167 (PropertyType_New
) noopprop_new
,
168 (PropertyType_Free
) noopprop_free
,
169 (PropertyType_Copy
) noopprop_copy
,
170 (PropertyType_Load
) invalidprop_load
,
171 (PropertyType_Save
) invalidprop_save
,
172 (PropertyType_GetWidget
) frame_beginprop_get_widget
,
173 (PropertyType_ResetWidget
) noopprop_reset_widget
,
174 (PropertyType_SetFromWidget
) noopprop_set_from_widget
,
176 (PropertyType_CanMerge
) noopprop_can_merge
,
177 (PropertyType_GetFromOffset
) noopprop_get_from_offset
,
178 (PropertyType_SetFromOffset
) noopprop_set_from_offset
181 static const PropertyOps frame_endprop_ops
= {
182 (PropertyType_New
) noopprop_new
,
183 (PropertyType_Free
) noopprop_free
,
184 (PropertyType_Copy
) noopprop_copy
,
185 (PropertyType_Load
) invalidprop_load
,
186 (PropertyType_Save
) invalidprop_save
,
187 (PropertyType_GetWidget
) frame_endprop_get_widget
,
188 (PropertyType_ResetWidget
) noopprop_reset_widget
,
189 (PropertyType_SetFromWidget
) noopprop_set_from_widget
,
191 (PropertyType_CanMerge
) noopprop_can_merge
,
192 (PropertyType_GetFromOffset
) noopprop_get_from_offset
,
193 (PropertyType_SetFromOffset
) noopprop_set_from_offset
196 /*********************************************************/
197 /* The MULTICOL_BEGIN, _COLUMN and _END property types. */
198 /*********************************************************/
201 multicol_beginprop_get_widget(MulticolProperty
*prop
, PropDialog
*dialog
)
203 GtkWidget
*multicol
= gtk_hbox_new(FALSE
,1);
205 gtk_container_set_border_width (GTK_CONTAINER(multicol
), 2);
206 gtk_widget_show(multicol
);
208 prop_dialog_add_raw(dialog
,multicol
);
210 prop_dialog_container_push(dialog
,multicol
);
211 prop_dialog_container_push(dialog
,NULL
); /* there must be a _COLUMN soon */
213 return NULL
; /* there is no single widget to add with a label next to it. */
217 multicol_columnprop_get_widget(MulticolProperty
*prop
, PropDialog
*dialog
)
219 GtkWidget
*col
= gtk_vbox_new(FALSE
,1);
221 gtk_container_set_border_width (GTK_CONTAINER(col
), 2);
222 gtk_widget_show(col
);
224 prop_dialog_container_pop(dialog
); /* NULL or the previous column */
226 gtk_box_pack_end_defaults(GTK_BOX(dialog
->lastcont
),col
);
228 prop_dialog_add_raw(dialog
,NULL
); /* to reset the internal table system */
229 prop_dialog_container_push(dialog
,col
);
235 multicol_endprop_get_widget(MulticolProperty
*prop
, PropDialog
*dialog
)
237 prop_dialog_container_pop(dialog
); /* the column */
238 prop_dialog_container_pop(dialog
); /* the multicol */
242 static const PropertyOps multicol_beginprop_ops
= {
243 (PropertyType_New
) noopprop_new
,
244 (PropertyType_Free
) noopprop_free
,
245 (PropertyType_Copy
) noopprop_copy
,
246 (PropertyType_Load
) invalidprop_load
,
247 (PropertyType_Save
) invalidprop_save
,
248 (PropertyType_GetWidget
) multicol_beginprop_get_widget
,
249 (PropertyType_ResetWidget
) noopprop_reset_widget
,
250 (PropertyType_SetFromWidget
) noopprop_set_from_widget
,
252 (PropertyType_CanMerge
) noopprop_can_merge
,
253 (PropertyType_GetFromOffset
) noopprop_get_from_offset
,
254 (PropertyType_SetFromOffset
) noopprop_set_from_offset
257 static const PropertyOps multicol_columnprop_ops
= {
258 (PropertyType_New
) noopprop_new
,
259 (PropertyType_Free
) noopprop_free
,
260 (PropertyType_Copy
) noopprop_copy
,
261 (PropertyType_Load
) invalidprop_load
,
262 (PropertyType_Save
) invalidprop_save
,
263 (PropertyType_GetWidget
) multicol_columnprop_get_widget
,
264 (PropertyType_ResetWidget
) noopprop_reset_widget
,
265 (PropertyType_SetFromWidget
) noopprop_set_from_widget
,
267 (PropertyType_CanMerge
) noopprop_can_merge
,
268 (PropertyType_GetFromOffset
) noopprop_get_from_offset
,
269 (PropertyType_SetFromOffset
) noopprop_set_from_offset
272 static const PropertyOps multicol_endprop_ops
= {
273 (PropertyType_New
) noopprop_new
,
274 (PropertyType_Free
) noopprop_free
,
275 (PropertyType_Copy
) noopprop_copy
,
276 (PropertyType_Load
) invalidprop_load
,
277 (PropertyType_Save
) invalidprop_save
,
278 (PropertyType_GetWidget
) multicol_endprop_get_widget
,
279 (PropertyType_ResetWidget
) noopprop_reset_widget
,
280 (PropertyType_SetFromWidget
) noopprop_set_from_widget
,
282 (PropertyType_CanMerge
) noopprop_can_merge
,
283 (PropertyType_GetFromOffset
) noopprop_get_from_offset
,
284 (PropertyType_SetFromOffset
) noopprop_set_from_offset
287 /*********************************************************/
288 /* The NOTEBOOK_BEGIN, _PAGE and _END property types. */
289 /*********************************************************/
292 notebook_beginprop_get_widget(NotebookProperty
*prop
, PropDialog
*dialog
)
294 GtkWidget
*notebook
= gtk_notebook_new();
296 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook
),GTK_POS_TOP
);
297 gtk_container_set_border_width (GTK_CONTAINER(notebook
), 1);
298 gtk_widget_show(notebook
);
300 prop_dialog_add_raw(dialog
,notebook
);
302 prop_dialog_container_push(dialog
,notebook
);
303 prop_dialog_container_push(dialog
,NULL
); /* there must be a _PAGE soon */
305 return NULL
; /* there is no single widget to add with a label next to it. */
309 notebook_pageprop_get_widget(NotebookProperty
*prop
, PropDialog
*dialog
)
311 GtkWidget
*page
= gtk_vbox_new(FALSE
,1);
312 GtkWidget
*label
= gtk_label_new(_(prop
->common
.descr
->description
));
314 gtk_container_set_border_width (GTK_CONTAINER(page
), 2);
315 gtk_widget_show(page
);
316 gtk_widget_show(label
);
318 prop_dialog_container_pop(dialog
); /* NULL or the previous page */
320 gtk_notebook_append_page(GTK_NOTEBOOK(dialog
->lastcont
),page
,label
);
322 prop_dialog_add_raw(dialog
,NULL
); /* to reset the internal table system */
323 prop_dialog_container_push(dialog
,page
);
329 notebook_endprop_get_widget(NotebookProperty
*prop
, PropDialog
*dialog
)
331 prop_dialog_container_pop(dialog
); /* the page */
332 prop_dialog_container_pop(dialog
); /* the notebook */
336 static const PropertyOps notebook_beginprop_ops
= {
337 (PropertyType_New
) noopprop_new
,
338 (PropertyType_Free
) noopprop_free
,
339 (PropertyType_Copy
) noopprop_copy
,
340 (PropertyType_Load
) invalidprop_load
,
341 (PropertyType_Save
) invalidprop_save
,
342 (PropertyType_GetWidget
) notebook_beginprop_get_widget
,
343 (PropertyType_ResetWidget
) noopprop_reset_widget
,
344 (PropertyType_SetFromWidget
) noopprop_set_from_widget
,
346 (PropertyType_CanMerge
) noopprop_can_merge
,
347 (PropertyType_GetFromOffset
) noopprop_get_from_offset
,
348 (PropertyType_SetFromOffset
) noopprop_set_from_offset
351 static const PropertyOps notebook_pageprop_ops
= {
352 (PropertyType_New
) noopprop_new
,
353 (PropertyType_Free
) noopprop_free
,
354 (PropertyType_Copy
) noopprop_copy
,
355 (PropertyType_Load
) invalidprop_load
,
356 (PropertyType_Save
) invalidprop_save
,
357 (PropertyType_GetWidget
) notebook_pageprop_get_widget
,
358 (PropertyType_ResetWidget
) noopprop_reset_widget
,
359 (PropertyType_SetFromWidget
) noopprop_set_from_widget
,
361 (PropertyType_CanMerge
) noopprop_can_merge
,
362 (PropertyType_GetFromOffset
) noopprop_get_from_offset
,
363 (PropertyType_SetFromOffset
) noopprop_set_from_offset
366 static const PropertyOps notebook_endprop_ops
= {
367 (PropertyType_New
) noopprop_new
,
368 (PropertyType_Free
) noopprop_free
,
369 (PropertyType_Copy
) noopprop_copy
,
370 (PropertyType_Load
) invalidprop_load
,
371 (PropertyType_Save
) invalidprop_save
,
372 (PropertyType_GetWidget
) notebook_endprop_get_widget
,
373 (PropertyType_ResetWidget
) noopprop_reset_widget
,
374 (PropertyType_SetFromWidget
) noopprop_set_from_widget
,
376 (PropertyType_CanMerge
) noopprop_can_merge
,
377 (PropertyType_GetFromOffset
) noopprop_get_from_offset
,
378 (PropertyType_SetFromOffset
) noopprop_set_from_offset
381 /****************************/
382 /* The LIST property type. */
383 /****************************/
386 listprop_emptylines_realloc(ListProperty
*prop
,guint new_size
) {
389 for (i
= 0; i
< prop
->lines
->len
; i
++)
390 g_free(g_ptr_array_index(prop
->lines
,i
));
392 g_ptr_array_set_size(prop
->lines
,new_size
);
396 listprop_copylines(ListProperty
*prop
, GPtrArray
*src
) {
399 listprop_emptylines_realloc(prop
,src
->len
);
401 for (i
= 0; i
< src
->len
; i
++)
402 g_ptr_array_index(prop
->lines
,i
) = g_strdup(g_ptr_array_index(src
,i
));
405 static ListProperty
*
406 listprop_new(const PropDescription
*pdesc
, PropDescToPropPredicate reason
)
408 ListProperty
*prop
= g_new0(ListProperty
,1);
409 initialize_property(&prop
->common
,pdesc
,reason
);
411 prop
->w_selected
= -1;
412 prop
->lines
= g_ptr_array_new();
417 listprop_free(ListProperty
*prop
)
419 listprop_emptylines_realloc(prop
,-1);
420 g_ptr_array_free(prop
->lines
,TRUE
);
423 static ListProperty
*
424 listprop_copy(ListProperty
*src
)
427 (ListProperty
*)src
->common
.ops
->new_prop(src
->common
.descr
,
430 copy_init_property(&prop
->common
,&src
->common
);
431 prop
->selected
= src
->selected
;
432 prop
->w_selected
= src
->w_selected
;
433 listprop_copylines(prop
,src
->lines
);
439 listprop_select_child_signal(GtkList
*list
,
443 prop
->w_selected
= gtk_list_child_position(list
,child
);
447 listprop_get_widget(ListProperty
*prop
, PropDialog
*dialog
)
449 GtkWidget
*ret
= gtk_list_new();
451 gtk_list_set_selection_mode(GTK_LIST(ret
),GTK_SELECTION_BROWSE
);
452 gtk_list_unselect_all(GTK_LIST(ret
));
454 gtk_signal_connect(GTK_OBJECT(ret
), "select-child",
455 GTK_SIGNAL_FUNC(listprop_select_child_signal
), prop
);
457 prophandler_connect(&prop
->common
,GTK_OBJECT(ret
),"selection-changed");
462 make_item(const gchar
*line
) {
463 return gtk_list_item_new_with_label(line
);
467 listprop_reset_widget(ListProperty
*prop
, WIDGET
*widget
)
471 gtk_list_clear_items(GTK_LIST(widget
),0,-1);
473 for (i
= 0; i
< prop
->lines
->len
; i
++) {
474 items
= g_list_append(items
, make_item(g_ptr_array_index(prop
->lines
,i
)));
476 gtk_list_append_items(GTK_LIST(widget
),items
);
477 prop
->w_selected
= prop
->selected
;
478 gtk_list_select_item(GTK_LIST(widget
),prop
->selected
);
482 listprop_set_from_widget(ListProperty
*prop
, WIDGET
*widget
)
484 prop
->selected
= prop
->w_selected
;
488 listprop_get_from_offset(ListProperty
*prop
,
489 void *base
, guint offset
, guint offset2
)
491 listprop_copylines(prop
,struct_member(base
,offset
, GPtrArray
*));
492 prop
->selected
= struct_member(base
,offset2
,gint
);
496 listprop_set_from_offset(ListProperty
*prop
,
497 void *base
, guint offset
, guint offset2
)
499 struct_member(base
,offset2
,gint
) = prop
->selected
;
502 static const PropertyOps listprop_ops
= {
503 (PropertyType_New
) listprop_new
,
504 (PropertyType_Free
) listprop_free
,
505 (PropertyType_Copy
) listprop_copy
,
507 (PropertyType_Load
) invalidprop_load
,
508 (PropertyType_Save
) invalidprop_save
,
510 (PropertyType_GetWidget
) listprop_get_widget
,
511 (PropertyType_ResetWidget
) listprop_reset_widget
,
512 (PropertyType_SetFromWidget
) listprop_set_from_widget
,
514 (PropertyType_CanMerge
) noopprop_can_merge
,
515 (PropertyType_GetFromOffset
) listprop_get_from_offset
,
516 (PropertyType_SetFromOffset
) listprop_set_from_offset
519 /* ************************************************************** */
522 prop_widgets_register(void)
524 prop_type_register(PROP_TYPE_STATIC
,&staticprop_ops
);
525 prop_type_register(PROP_TYPE_BUTTON
,&buttonprop_ops
);
526 prop_type_register(PROP_TYPE_FRAME_BEGIN
,&frame_beginprop_ops
);
527 prop_type_register(PROP_TYPE_FRAME_END
,&frame_endprop_ops
);
528 prop_type_register(PROP_TYPE_MULTICOL_BEGIN
,&multicol_beginprop_ops
);
529 prop_type_register(PROP_TYPE_MULTICOL_END
,&multicol_endprop_ops
);
530 prop_type_register(PROP_TYPE_MULTICOL_COLUMN
,&multicol_columnprop_ops
);
531 prop_type_register(PROP_TYPE_NOTEBOOK_BEGIN
,¬ebook_beginprop_ops
);
532 prop_type_register(PROP_TYPE_NOTEBOOK_END
,¬ebook_endprop_ops
);
533 prop_type_register(PROP_TYPE_NOTEBOOK_PAGE
,¬ebook_pageprop_ops
);
534 prop_type_register(PROP_TYPE_LIST
,&listprop_ops
);