1 /*
2  * (SLIK) SimpLIstic sKin functions
3  * (C) 2005 John Ellis
4  *
5  * Author: John Ellis
6  *
7  * This software is released under the GNU General Public License (GNU GPL).
8  * Please read the included file COPYING for more information.
9  * This software comes with no warranty of any kind, use at your own risk!
10  */
11 
12 #include "ui2_includes.h"
13 #include "ui2_typedefs.h"
14 
15 #include "ui2_number.h"
16 #include "ui2_number_edit.h"
17 
18 #include "ui2_display.h"
19 #include "ui2_editor.h"
20 #include "ui2_main.h"
21 #include "ui2_skin.h"
22 #include "ui2_widget.h"
23 #include "ui_fileops.h"
24 #include "ui_pixbuf_ops.h"
25 #include "ui_tabcomp.h"
26 #include "ui_utildlg.h"
27 
28 
29 static void number_edit_page_add(GtkWidget *widget, gpointer data);
30 
31 /*
32  *-------
33  * digits
34  *-------
35  */
36 
37 
38 typedef struct _DigitListData DigitListData;
39 struct _DigitListData
40 {
41 	gchar *key;
42 	gchar *text_id;
43 	gchar *data;
44 
45 	gchar *image;
46 };
47 
digit_get_pixbuf(gpointer widget)48 static GdkPixbuf *digit_get_pixbuf(gpointer widget)
49 {
50 	DigitData *digit = widget;
51 
52 	return digit->overlay;
53 }
54 
digit_edit_write(FILE * f,WidgetData * wd,SkinData * skin,const gchar * dir)55 static void digit_edit_write(FILE *f, WidgetData *wd, SkinData *skin, const gchar *dir)
56 {
57 	DigitData *digit = wd->widget;
58 	gchar *image;
59 
60 	image = ui_edit_copy_unique_file(ui_widget_get_data(wd, "image"),
61 					 dir, digit->overlay, "digit_", wd->key);
62 
63 	if (image) ui_edit_widget_set_path_key(wd, "image", dir, image);
64 
65 	ui_edit_write_section(f, "digit", wd->key);
66 
67 	ui_edit_write_key_char(f, "image", image);
68 
69 	g_free(image);
70 }
71 
digit_edit_list_find(GList * list,const gchar * image)72 static DigitListData *digit_edit_list_find(GList *list, const gchar *image)
73 {
74 	GList *work;
75 	work = list;
76 	while(work)
77 		{
78 		DigitListData *dd = work->data;
79 		if (strcmp(image, dd->image) == 0) return dd;
80 		work = work->next;
81 		}
82 	return NULL;
83 }
84 
digit_edit_read(UIData * ui,WidgetData * wd,GList * list)85 static gpointer digit_edit_read(UIData *ui, WidgetData *wd, GList *list)
86 {
87 	DigitListData *dd;
88 	const gchar *image;
89 
90 	image = ui_widget_get_data(wd, "image");
91 
92 	if (!image || digit_edit_list_find(list, image)) return NULL;
93 
94 	dd = g_new0(DigitListData, 1);
95 	dd->image = g_strdup(image);
96 
97 	dd->key = g_strdup(wd->key);
98 	dd->data = g_strdup(ui_widget_get_data(wd, "data"));
99 	dd->text_id = g_strdup(wd->text_id);
100 
101 	return dd;
102 }
103 
digit_edit_free(gpointer data)104 static void digit_edit_free(gpointer data)
105 {
106 	DigitListData *dd = data;
107 
108 	g_free(dd->key);
109 	g_free(dd->text_id);
110 	g_free(dd->data);
111 	g_free(dd->image);
112 	g_free(dd);
113 }
114 
digit_edit_props(UIData * ui,WidgetData * wd,GtkWidget * vbox,gpointer detail_data)115 static gpointer digit_edit_props(UIData *ui, WidgetData *wd, GtkWidget *vbox, gpointer detail_data)
116 {
117 	return detail_data;
118 }
119 
digit_edit_removable(gpointer widget)120 static gint digit_edit_removable(gpointer widget)
121 {
122 	DigitData *digit = widget;
123 
124 	return (digit->ref < 2);
125 }
126 
digit_type_init_edit(WidgetObjectData * od)127 void digit_type_init_edit(WidgetObjectData *od)
128 {
129 	od->func_get_pixbuf = digit_get_pixbuf;
130 
131 	od->func_edit_write = digit_edit_write;
132 
133 	od->func_edit_read = digit_edit_read;
134 	od->func_edit_free = digit_edit_free;
135 
136 	od->func_edit_props = digit_edit_props;
137 
138 	od->func_edit_page_add = number_edit_page_add;
139 
140 	od->func_edit_removable = digit_edit_removable;
141 }
142 
143 
144 /*
145  *-------
146  * numbers
147  *-------
148  */
149 
150 
151 enum {
152 	NUMBER_COLUMN_POINTER = 0,
153 	NUMBER_COLUMN_IMAGE,
154 	NUMBER_COLUMN_KEY,
155 	NUMBER_COLUMN_COUNT
156 };
157 
158 
159 typedef struct _NumberDetail NumberDetail;
160 struct _NumberDetail
161 {
162 	NumberData *number;
163 	GtkWidget *zero_button;
164 	GtkWidget *center_button;
165 	GtkWidget *spin_length;
166 	GtkWidget *spin_rotation;
167 	GtkWidget *digit_key_entry;
168 
169 	WidgetData *wd;
170 	UIData *ui;
171 };
172 
173 typedef struct _NumberPage NumberPage;
174 struct _NumberPage
175 {
176 	GtkWidget *key_entry;
177 	GtkWidget *text_id_entry;
178 	GtkWidget *data_entry;
179 
180 	GtkWidget *image_entry;
181 	GtkWidget *digit_id_entry;
182 
183 	GtkWidget *zeros_button;
184 	GtkWidget *center_button;
185 	GtkWidget *length_spin;
186 	GtkWidget *rotation_spin;
187 
188 	GtkWidget *list;
189 	GtkWidget *image;
190 
191 	GtkWidget *digit_key_entry;
192 
193 	EditData *ed;
194 };
195 
196 
number_get_pixbuf(gpointer widget)197 static GdkPixbuf *number_get_pixbuf(gpointer widget)
198 {
199 	NumberData *number = widget;
200 
201 	return number->digits->overlay;
202 }
203 
number_edit_write(FILE * f,WidgetData * wd,SkinData * skin,const gchar * dir)204 static void number_edit_write(FILE *f, WidgetData *wd, SkinData *skin, const gchar *dir)
205 {
206 	NumberData *number = wd->widget;
207 	gchar *image = NULL;
208 	const gchar *file;
209 	const gchar *digit_id;
210 
211 	file = ui_widget_get_data(wd, "image");
212 	digit_id = ui_widget_get_data(wd, "digit_id");
213 	if (file || (!file && !digit_id))
214 		{
215 		image = ui_edit_copy_unique_file(file, dir, number->digits->overlay, "digit_", wd->key);
216 		}
217 
218 	if (image) ui_edit_widget_set_path_key(wd, "image", dir, image);
219 
220 	ui_edit_write_section(f, "number", wd->key);
221 
222 	if (image)
223 		{
224 		ui_edit_write_key_char(f, "image", image);
225 		}
226 	else
227 		{
228 		ui_edit_write_key_char(f, "digit", digit_id);
229 		}
230 	ui_edit_write_key_int(f, "x", number->x);
231 	ui_edit_write_key_int(f, "y", number->y);
232 	ui_edit_write_key_int(f, "length", number->length);
233 
234 	ui_edit_write_key_bool(f, "zeros", number->zeros);
235 	ui_edit_write_key_bool(f, "center", number->centered);
236 	ui_edit_write_key_int(f, "rotation", number->rotation);
237 
238 	g_free(image);
239 }
240 
number_edit_read(UIData * ui,WidgetData * wd,GList * list)241 static gpointer number_edit_read(UIData *ui, WidgetData *wd, GList *list)
242 {
243 	NumberData *number;
244 	DigitListData *dd;
245 	const gchar *image;
246 
247 	number = wd->widget;
248 
249 	image = ui_widget_get_data(wd, "image");
250 
251 	if (!image || digit_edit_list_find(list, image)) return NULL;
252 
253 	dd = g_new0(DigitListData, 1);
254 	dd->image = g_strdup(image);
255 
256 	dd->key = g_strdup(wd->key);
257 	dd->data = g_strdup(ui_widget_get_data(wd, "data"));
258 	dd->text_id = g_strdup(wd->text_id);
259 
260 	return dd;
261 }
262 
number_edit_props_alter_cb(GtkWidget * button,gpointer data)263 static void number_edit_props_alter_cb(GtkWidget *button, gpointer data)
264 {
265 	NumberDetail *nd = data;
266 
267 	nd->number->zeros = ui_edit_toggle_get(nd->zero_button);
268 	nd->number->centered = ui_edit_toggle_get(nd->center_button);
269 	gtk_widget_set_sensitive(nd->zero_button, !nd->number->centered);
270 
271 	ui_widget_draw(nd->ui, nd->wd, TRUE, TRUE);
272 }
273 
number_edit_props_length_cb(GtkAdjustment * adjustment,gpointer data)274 static void number_edit_props_length_cb(GtkAdjustment *adjustment, gpointer data)
275 {
276 	NumberDetail *nd = data;
277 	gint new_length;
278 	gint old_w, new_w;
279 	gint w, h;
280 	gint max_w;
281 	gint cw, ch;
282 
283 	new_length = ui_edit_spin_get(nd->spin_length);
284 
285 	if (digit_rotation_vertical(nd->number->rotation))
286 		{
287 		max_w = nd->ui->skin->height;
288 		}
289 	else
290 		{
291 		max_w = nd->ui->skin->width;
292 		}
293 
294 	if (new_length * nd->number->digits->width > max_w)
295 		{
296 		new_length = max_w / nd->number->digits->width;
297 		ui_edit_spin_set_blocking(nd->spin_length, new_length, nd);
298 		}
299 
300 	if (new_length == nd->number->length) return;
301 
302 	old_w = nd->number->digits->width * nd->number->length;
303 	new_w = nd->number->digits->width * new_length;
304 	if (digit_rotation_vertical(nd->number->rotation))
305 		{
306 		w = nd->number->digits->height;
307 		h = new_w;
308 		cw = 0;
309 		ch = MAX(0, (old_w - new_w));
310 		}
311 	else
312 		{
313 		w = new_w;
314 		h = nd->number->digits->height;
315 		cw = MAX(0, (old_w - new_w));
316 		ch = 0;
317 		}
318 
319 	if (new_length > nd->number->length)
320 		{
321 		if (nd->number->x + w > nd->ui->skin->width)
322 			{
323 			ui_widget_set_coord(nd->ui, nd->wd, nd->ui->skin->width - w, nd->number->y, TRUE);
324 			}
325 		if (nd->number->y + h > nd->ui->skin->height)
326 			{
327 			ui_widget_set_coord(nd->ui, nd->wd, nd->number->x, nd->ui->skin->height - h, TRUE);
328 			}
329 		}
330 
331 	if (old_w > w) ui_edit_widget_draw_highlight(nd->ui, nd->wd, FALSE);
332 
333 	nd->number->length = new_length;
334 	gdk_pixbuf_unref(nd->number->pixbuf);
335 	nd->number->pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, w, h);
336 
337 	ui_edit_widget_resync(nd->ui, nd->wd, TRUE, cw, ch);
338 }
339 
number_edit_props_rotation_cb(GtkAdjustment * adjustment,gpointer data)340 static void number_edit_props_rotation_cb(GtkAdjustment *adjustment, gpointer data)
341 {
342 	NumberDetail *nd = data;
343 	NumberData *number;
344 	gint new_r;
345 	gint cw, ch;
346 
347 	new_r = ui_edit_spin_get(nd->spin_rotation);
348 	number = nd->number;
349 
350 	if (digit_rotation_vertical(new_r) != digit_rotation_vertical(number->rotation))
351 		{
352 		gint new_w, new_h;
353 		gint old_w, old_h;
354 
355 		ui_edit_widget_draw_highlight(nd->ui, nd->wd, FALSE);
356 
357 		if (digit_rotation_vertical(new_r))
358 			{
359 			old_w = number->length * number->digits->width;
360 			old_h = number->digits->height;
361 			if (number->y + number->length * number->digits->width > nd->ui->skin->height)
362 				{
363 				number->length = MAX(1, ((nd->ui->skin->height - number->y) / number->digits->width));
364 				ui_edit_spin_set_blocking(nd->spin_length, number->length, nd);
365 				}
366 			new_w = old_h;
367 			new_h = number->length * number->digits->width;
368 			}
369 		else
370 			{
371 			old_w = number->digits->height;
372 			old_h = number->length * number->digits->width;
373 			if (number->x + number->length * number->digits->width > nd->ui->skin->width)
374 				{
375 				number->length = MAX(1, ((nd->ui->skin->width - number->x) / number->digits->width));
376 				ui_edit_spin_set_blocking(nd->spin_length, number->length, nd);
377 				}
378 			new_w = number->length * number->digits->width;
379 			new_h = old_w;
380 			}
381 
382 		gdk_pixbuf_unref(number->pixbuf);
383 		number->pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, new_w, new_h);
384 
385 		cw = MAX(0, old_w - new_w);
386 		ch = MAX(0, old_h - new_h);
387 		}
388 	else
389 		{
390 		cw = ch = 0;
391 		}
392 
393 	number->rotation = new_r;
394 	ui_edit_widget_resync(nd->ui, nd->wd, TRUE, cw, ch);
395 }
396 
number_edit_props(UIData * ui,WidgetData * wd,GtkWidget * vbox,gpointer detail)397 static gpointer number_edit_props(UIData *ui, WidgetData *wd, GtkWidget *vbox, gpointer detail)
398 {
399 	NumberData *number = wd->widget;
400 	NumberDetail *nd = detail;
401 
402 	GtkObject *adj;
403 
404 	if (!nd)
405 		{
406 		GtkWidget *hbox;
407 
408 		nd = g_new0(NumberDetail, 1);
409 
410 		hbox = ui_edit_frame_new(vbox, FALSE, NULL);
411 
412 		nd->spin_length = ui_edit_spin_new(hbox, _("Length:"), 1, 8,  &adj);
413 		g_signal_connect(adj, "value_changed",
414 				   G_CALLBACK(number_edit_props_length_cb), nd);
415 
416 		nd->spin_rotation = ui_edit_spin_new(hbox, _("Rotation:"), 0, 270, &adj);
417 		GTK_ADJUSTMENT(adj)->step_increment = 90.0;
418 		gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(nd->spin_rotation), TRUE);
419 		g_signal_connect(adj, "value_changed",
420 				   G_CALLBACK(number_edit_props_rotation_cb), nd);
421 
422 		nd->zero_button = ui_edit_toggle_new(vbox, _("Pad with zeros"));
423 		g_signal_connect(G_OBJECT(nd->zero_button), "clicked",
424 				 G_CALLBACK(number_edit_props_alter_cb), nd);
425 
426 		nd->center_button = ui_edit_toggle_new(vbox, _("Center"));
427 		g_signal_connect(G_OBJECT(nd->center_button), "clicked",
428 				 G_CALLBACK(number_edit_props_alter_cb), nd);
429 
430 		hbox = ui_edit_frame_new(vbox, FALSE, NULL);
431 
432 		nd->digit_key_entry = ui_edit_entry_new(hbox, _("Digit key:"));
433 		ui_edit_frame_sensitive(nd->digit_key_entry, FALSE, TRUE);
434 		}
435 
436 	nd->number = number;
437 	nd->wd = wd;
438 	nd->ui = ui;
439 
440 	ui_edit_toggle_set_blocking(nd->zero_button, number->zeros, nd);
441 	gtk_widget_set_sensitive(nd->zero_button, !nd->number->centered);
442 
443 	ui_edit_toggle_set_blocking(nd->center_button, number->centered, nd);
444 	ui_edit_spin_set_blocking(nd->spin_length, number->length, nd);
445 	ui_edit_spin_set_blocking(nd->spin_rotation, number->rotation, nd);
446 	ui_edit_entry_set(nd->digit_key_entry, ui_widget_get_data(wd, "digit_id"));
447 
448 	return nd;
449 }
450 
number_edit_page_digit_add_cb(GtkWidget * widget,gpointer data)451 static void number_edit_page_digit_add_cb(GtkWidget *widget, gpointer data)
452 {
453 	NumberPage *pd = data;
454 	DigitData *digit;
455 	const gchar *key;
456 	const gchar *text_id;
457 	const gchar *image;
458 
459 	key = ui_edit_entry_get(pd->digit_key_entry);
460 	text_id = ui_edit_entry_get(pd->text_id_entry);
461 	image = ui_edit_entry_get(pd->image_entry);
462 
463 	if (!key || !image || !isfile(image))
464 		{
465 		warning_dialog(_("Digit error"), _("Digit must contain a key and valid image."),
466 			       GTK_STOCK_DIALOG_ERROR, widget);
467 		return;
468 		}
469 
470 	digit = digit_new_from_file(image);
471 
472 	if (digit)
473 		{
474 		WidgetData *wd;
475 		wd = digit_register(pd->ed->ui->skin, digit, key, text_id);
476 		ui_edit_widget_add_finish(pd->ed, wd, image, ui_edit_entry_get(pd->data_entry));
477 		}
478 
479 	tab_completion_append_to_history(pd->image_entry, image);
480 }
481 
number_edit_page_add_cb(GtkWidget * widget,gpointer data)482 static void number_edit_page_add_cb(GtkWidget *widget, gpointer data)
483 {
484 	NumberPage *pd = data;
485 	NumberData *number;
486 	DigitData *digit;
487 	const gchar *key;
488 	const gchar *text_id;
489 	const gchar *digit_id;
490 	const gchar *image;
491 	gint length;
492 	gint zeros;
493 	gint center;
494 	gint rotation;
495 
496 	key = ui_edit_entry_get(pd->key_entry);
497 	text_id = ui_edit_entry_get(pd->text_id_entry);
498 	digit_id = ui_edit_entry_get(pd->digit_id_entry);
499 	image = ui_edit_entry_get(pd->image_entry);
500 
501 	if (!key ||
502 	    ( (!digit_id || !ui_widget_exists(pd->ed->ui, digit_id, digit_type_id())) && (digit_id || !image || !isfile(image)) ) )
503 		{
504 		warning_dialog(_("Number error"), _("Number must contain a key, and valid image or digit key."),
505 			       GTK_STOCK_DIALOG_ERROR, widget);
506 		return;
507 		}
508 
509 	length = ui_edit_spin_get(pd->length_spin);
510 	zeros = ui_edit_toggle_get(pd->zeros_button);
511 	center = ui_edit_toggle_get(pd->center_button);
512 	rotation = ui_edit_spin_get(pd->rotation_spin);
513 
514 	if (digit_id)
515 		{
516 		WidgetData *wd;
517 
518 		wd = skin_widget_get_by_key(pd->ed->ui->skin, digit_id, digit_type_id());
519 		digit = wd->widget;
520 		image = NULL;
521 		}
522 	else
523 		{
524 		digit = digit_new_from_file(image);
525 		}
526 
527 	if (!digit) return;
528 	number = number_new(digit, 0, 0, length, zeros, center, rotation);
529 
530 	if (number)
531 		{
532 		WidgetData *wd;
533 		wd = number_register(pd->ed->ui->skin, number, key, text_id);
534 		ui_widget_set_data(wd, "digit_id", digit_id);
535 		ui_edit_widget_add_finish(pd->ed, wd, image, ui_edit_entry_get(pd->data_entry));
536 		}
537 
538 	if (!digit_id) tab_completion_append_to_history(pd->image_entry, image);
539 }
540 
number_edit_page_sync(NumberPage * pd,DigitListData * dd)541 static void number_edit_page_sync(NumberPage *pd, DigitListData *dd)
542 {
543 	if (!dd) return;
544 
545 	ui_edit_entry_set(pd->image_entry, dd->image);
546 }
547 
number_edit_page_list_cb(GtkTreeSelection * selection,gpointer data)548 static void number_edit_page_list_cb(GtkTreeSelection *selection, gpointer data)
549 {
550 	NumberPage *pd = data;
551 	DigitListData *dd;
552 	GtkTreeModel *store;
553 	GtkTreeIter iter;
554 
555 	if (!gtk_tree_selection_get_selected(selection, &store, &iter)) return;
556 
557 	gtk_tree_model_get(store, &iter, NUMBER_COLUMN_POINTER, &dd, -1);
558 	number_edit_page_sync(pd, dd);
559 }
560 
number_edit_page_digit_cb(GtkWidget * entry,gpointer data)561 static void number_edit_page_digit_cb(GtkWidget *entry, gpointer data)
562 {
563 	NumberPage *pd = data;
564 	gint state;
565 
566 	state = (strlen(gtk_entry_get_text(GTK_ENTRY(pd->digit_id_entry))) == 0);
567 
568 	ui_edit_frame_sensitive(pd->image_entry, state, TRUE);
569 }
570 
number_edit_page_center_cb(GtkWidget * button,gpointer data)571 static void number_edit_page_center_cb(GtkWidget *button, gpointer data)
572 {
573 	NumberPage *pd = data;
574 
575 	gtk_widget_set_sensitive(pd->zeros_button, !ui_edit_toggle_get(pd->center_button));
576 }
577 
number_edit_page_destroy_cb(GtkWidget * widget,gpointer data)578 static void number_edit_page_destroy_cb(GtkWidget *widget, gpointer data)
579 {
580 	NumberPage *pd = data;
581 
582 	g_free(pd);
583 }
584 
number_edit_page_new(EditData * ed)585 static GtkWidget *number_edit_page_new(EditData *ed)
586 {
587 	GtkWidget *hbox;
588 	GtkWidget *hbox2;
589 	GtkWidget *vbox;
590 	GtkWidget *frame;
591 	GtkWidget *button;
592 	GtkWidget *sep;
593 	GtkObject *adj;
594 	NumberPage *pd;
595 	GtkListStore *store;
596 
597 	pd = g_new0(NumberPage, 1);
598 	pd->ed = ed;
599 
600 	hbox = gtk_hbox_new(FALSE, 5);
601 	gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
602 	g_object_set_data(G_OBJECT(hbox), "page", pd);
603 	g_signal_connect(G_OBJECT(hbox), "destroy",
604 			 G_CALLBACK(number_edit_page_destroy_cb), pd);
605 
606 	vbox = gtk_vbox_new(FALSE, 0);
607 	gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);
608 	gtk_widget_show(vbox);
609 
610 	pd->key_entry = ui_edit_key_entry_new(vbox, ed->ui, number_type_id());
611 	pd->data_entry = ui_edit_entry_new(vbox, _("Data:"));
612 	pd->text_id_entry = ui_edit_entry_new(vbox, _("Text id:"));
613 
614 	hbox2 = ui_edit_frame_new(vbox, FALSE, NULL);
615 	pd->length_spin = ui_edit_spin_new(hbox2, _("Length:"), 1, 8, NULL);
616 	pd->rotation_spin = ui_edit_spin_new(hbox2, _("Rotation:"), 0, 270, &adj);
617 	GTK_ADJUSTMENT(adj)->step_increment = 90.0;
618 	gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(pd->rotation_spin), TRUE);
619 
620 	pd->zeros_button = ui_edit_toggle_new(vbox, _("Pad with zeros"));
621 	pd->center_button = ui_edit_toggle_new(vbox, _("Center"));
622 	g_signal_connect(G_OBJECT(pd->center_button), "clicked",
623 			 G_CALLBACK(number_edit_page_center_cb), pd);
624 
625 	pd->digit_id_entry = ui_edit_entry_new(vbox, _("Digit key:"));
626 	g_signal_connect(G_OBJECT(pd->digit_id_entry), "changed",
627 			 G_CALLBACK(number_edit_page_digit_cb), pd);
628 	pd->image_entry = ui_edit_path_entry_new(vbox, _("Image:"), "SLIK_number_image");
629 	pd->image = ui_edit_image_new(vbox);
630 	ui_edit_path_entry_connect_image(pd->image_entry, pd->image);
631 
632 	button = gtk_button_new_with_label(_("Add"));
633 	gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
634 	g_signal_connect(G_OBJECT(button), "clicked",
635 			 G_CALLBACK(number_edit_page_add_cb), pd);
636 	gtk_widget_show(button);
637 
638 	sep = gtk_hseparator_new();
639 	gtk_box_pack_start(GTK_BOX(vbox), sep, FALSE, FALSE, 5);
640 	gtk_widget_show(sep);
641 
642 	frame = ui_edit_frame_new(vbox, TRUE, _("Add digit only"));
643 	pd->digit_key_entry = ui_edit_entry_new(frame, _("Key:"));
644 
645 	button = gtk_button_new_with_label(_("Add"));
646 	gtk_box_pack_end(GTK_BOX(frame), button, FALSE, FALSE, 0);
647 	g_signal_connect(G_OBJECT(button), "clicked",
648 			 G_CALLBACK(number_edit_page_digit_add_cb), pd);
649 	gtk_widget_show(button);
650 
651 	store = gtk_list_store_new(3, G_TYPE_POINTER, GDK_TYPE_PIXBUF, G_TYPE_STRING);
652 	pd->list = ui_edit_list_new(hbox, store,
653 				    G_CALLBACK(number_edit_page_list_cb), pd);
654 	g_object_unref(store);
655 
656 	ui_edit_list_add_column(pd->list, _("Image"), NUMBER_COLUMN_IMAGE, TRUE, FALSE);
657 	ui_edit_list_add_column(pd->list, _("Key"), NUMBER_COLUMN_KEY, FALSE, FALSE);
658 
659 	/* hacky, but it works */
660 	ui_edit_widget_id_list_set_page(ed->widget_id_list, digit_type_id(), hbox);
661 
662 	gtk_widget_show(hbox);
663 
664 	return hbox;
665 }
666 
number_edit_page_add(GtkWidget * widget,gpointer data)667 static void number_edit_page_add(GtkWidget *widget, gpointer data)
668 {
669 	DigitListData *dd = data;
670 	NumberPage *pd;
671 	GtkListStore *store;
672 	GtkTreeIter iter;
673 	GdkPixbuf *pixbuf;
674 
675 	pd = g_object_get_data(G_OBJECT(widget), "page");
676 	store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(pd->list)));
677 
678 	pixbuf = ui_edit_list_pixbuf_from_file(dd->image);
679 
680 	gtk_list_store_append(store, &iter);
681 	gtk_list_store_set(store, &iter,
682 			   NUMBER_COLUMN_POINTER, dd,
683 			   NUMBER_COLUMN_IMAGE, pixbuf,
684 			   NUMBER_COLUMN_KEY, dd->key, -1);
685 
686 	if (pixbuf) gdk_pixbuf_unref(pixbuf);
687 }
688 
number_type_init_edit(WidgetObjectData * od)689 void number_type_init_edit(WidgetObjectData *od)
690 {
691 	od->func_get_pixbuf = number_get_pixbuf;
692 
693 	od->func_edit_write = number_edit_write;
694 
695 	od->func_edit_read = number_edit_read;
696 	od->func_edit_free = digit_edit_free;
697 
698 	od->func_edit_props = number_edit_props;
699 
700 	od->func_edit_page_new = number_edit_page_new;
701 	od->func_edit_page_add = number_edit_page_add;
702 }
703 
704 
705 
706 
707