1 /* -*- Mode: C; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3 -*- */
2
3 /*
4 * GImageView
5 * Copyright (C) 2001 Takuro Ashie
6 *
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.
11 *
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.
16 *
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.
20 *
21 * $Id: gimv_comment_view.c,v 1.6 2004/09/22 15:37:11 makeinu Exp $
22 */
23
24 #include "gimv_comment_view.h"
25
26 #include <string.h>
27
28 #include "gimageview.h"
29
30 #include "charset.h"
31 #include "dnd.h"
32 #include "gimv_comment.h"
33 #include "gimv_icon_stock.h"
34 #include "gimv_image_info.h"
35 #include "gimv_image_view.h"
36 #include "prefs.h"
37
38
39 #ifdef ENABLE_TREEVIEW
40 typedef enum {
41 COLUMN_TERMINATOR = -1,
42 COLUMN_KEY,
43 COLUMN_VALUE,
44 COLUMN_RAW_ENTRY,
45 N_COLUMN
46 } ListStoreColumn;
47 #endif /* ENABLE_TREEVIEW */
48
49
50 static void gimv_comment_view_set_sensitive (GimvCommentView *cv);
51 static void gimv_comment_view_set_combo_list (GimvCommentView *cv);
52 static void gimv_comment_view_data_enter (GimvCommentView *cv);
53 static void gimv_comment_view_reset_data (GimvCommentView *cv);
54
55
56 /******************************************************************************
57 *
58 * callback functions.
59 *
60 ******************************************************************************/
61 static void
cb_switch_page(GtkNotebook * notebook,GtkNotebookPage * page,gint pagenum,GimvCommentView * cv)62 cb_switch_page (GtkNotebook *notebook,
63 GtkNotebookPage *page,
64 gint pagenum,
65 GimvCommentView *cv)
66 {
67 GtkWidget *widget;
68
69 g_return_if_fail (page);
70 g_return_if_fail (cv);
71
72 if (!cv->button_area) return;
73
74 widget = gtk_notebook_get_nth_page (notebook, pagenum);
75
76 if (widget == cv->data_page || widget == cv->note_page)
77 gtk_widget_show (cv->button_area);
78 else
79 gtk_widget_hide (cv->button_area);
80
81 gimv_comment_view_set_sensitive (cv);
82 }
83
84
85 static void
gimv_comment_view_delete_selected_data(GimvCommentView * cv)86 gimv_comment_view_delete_selected_data (GimvCommentView *cv)
87 {
88 GimvCommentDataEntry *entry;
89
90 g_return_if_fail (cv);
91
92 #ifdef ENABLE_TREEVIEW
93 {
94 GtkTreeView *treeview = GTK_TREE_VIEW (cv->comment_clist);
95 GtkTreeSelection *selection = gtk_tree_view_get_selection (treeview);
96 GtkTreeModel *model;
97 GtkTreeIter iter;
98 gboolean found;
99
100 found = gtk_tree_selection_get_selected (selection, &model, &iter);
101 if (!found) return;
102
103 gtk_tree_model_get (model, &iter,
104 COLUMN_RAW_ENTRY, &entry,
105 COLUMN_TERMINATOR);
106 gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
107 }
108 #else /* ENABLE_TREEVIEW */
109 if (cv->selected_row < 0) return;
110 g_return_if_fail (cv->selected_row < GTK_CLIST (cv->comment_clist)->rows);
111
112 entry = gtk_clist_get_row_data (GTK_CLIST (cv->comment_clist),
113 cv->selected_row);
114 gtk_clist_remove (GTK_CLIST (cv->comment_clist), cv->selected_row);
115 #endif /* ENABLE_TREEVIEW */
116
117 if (entry)
118 gimv_comment_data_entry_remove (cv->comment, entry);
119
120 gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (cv->key_combo)->entry), "\0");
121 gtk_entry_set_text (GTK_ENTRY (cv->value_entry), "\0");
122
123 gimv_comment_view_set_sensitive (cv);
124 }
125
126
127 static void
cb_save_button_pressed(GtkButton * button,GimvCommentView * cv)128 cb_save_button_pressed (GtkButton *button, GimvCommentView *cv)
129 {
130 gchar *note;
131
132 g_return_if_fail (cv);
133 g_return_if_fail (cv->comment);
134
135 #if USE_GTK2
136 {
137 GtkTextBuffer *buffer;
138 GtkTextIter start, end;
139
140 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (cv->note_box));
141
142 gtk_text_buffer_get_iter_at_offset (buffer, &start, 0);
143 gtk_text_buffer_get_iter_at_offset (buffer, &end, -1);
144
145 note = gtk_text_buffer_get_text (buffer, &start, &end, TRUE);
146 }
147 #else /* USE_GTK2 */
148 {
149 gint len;
150
151 len = gtk_text_get_length (GTK_TEXT (cv->note_box));
152 note = gtk_editable_get_chars (GTK_EDITABLE (cv->note_box), 0, len);
153 }
154 #endif /* USE_GTK2 */
155
156 if (note && *note)
157 gimv_comment_update_note (cv->comment, note);
158
159 g_free (note);
160
161 gimv_comment_save_file (cv->comment);
162 }
163
164
165 static void
cb_reset_button_pressed(GtkButton * button,GimvCommentView * cv)166 cb_reset_button_pressed (GtkButton *button, GimvCommentView *cv)
167 {
168 g_return_if_fail (cv);
169 g_return_if_fail (cv->comment);
170
171 gimv_comment_view_change_file (cv, cv->comment->info);
172 }
173
174
175 static void
cb_del_button_pressed(GtkButton * button,GimvCommentView * cv)176 cb_del_button_pressed (GtkButton *button, GimvCommentView *cv)
177 {
178 g_return_if_fail (cv->comment);
179
180 gimv_comment_delete_file (cv->comment);
181 gimv_comment_unref (cv->comment);
182 cv->comment = NULL;
183 gimv_comment_view_clear (cv);
184 }
185
186
187 static void
cb_destroyed(GtkWidget * widget,GimvCommentView * cv)188 cb_destroyed (GtkWidget *widget, GimvCommentView *cv)
189 {
190 g_return_if_fail (cv);
191
192 gtk_signal_disconnect_by_func (GTK_OBJECT (cv->notebook),
193 GTK_SIGNAL_FUNC (cb_switch_page), cv);
194
195 if (cv->comment) {
196 gimv_comment_unref (cv->comment);
197 cv->comment = NULL;
198 }
199
200 if (cv->accel_group) {
201 gtk_accel_group_unref (cv->accel_group);
202 cv->accel_group = NULL;
203 }
204
205 g_free (cv);
206 }
207
208
209 #ifdef ENABLE_TREEVIEW
210 static void
cb_tree_view_cursor_changed(GtkTreeView * treeview,GimvCommentView * cv)211 cb_tree_view_cursor_changed (GtkTreeView *treeview, GimvCommentView *cv)
212 {
213 GtkTreeSelection *selection = gtk_tree_view_get_selection (treeview);
214 GtkTreeModel *model;
215 GtkTreeIter iter;
216 gboolean success;
217 gchar *key = NULL, *value = NULL;
218 GtkEntry *entry1, *entry2;
219
220 entry1 = GTK_ENTRY (GTK_COMBO (cv->key_combo)->entry);
221 entry2 = GTK_ENTRY(cv->value_entry);
222
223 success = gtk_tree_selection_get_selected (selection, &model, &iter);
224 if (success) {
225 gtk_tree_model_get (model, &iter,
226 COLUMN_KEY, &key,
227 COLUMN_VALUE, &value,
228 COLUMN_TERMINATOR);
229 }
230
231 if (key)
232 gtk_entry_set_text (entry1, key);
233 else
234 gtk_entry_set_text (entry1, "\0");
235 if (value)
236 gtk_entry_set_text (entry2, value);
237 else
238 gtk_entry_set_text (entry2, "\0");
239
240 g_free (key);
241 g_free (value);
242
243 gimv_comment_view_set_sensitive (cv);
244 }
245
246 #else /* ENABLE_TREEVIEW */
247
248 static void
cb_clist_select_row(GtkCList * clist,gint row,gint col,GdkEventButton * event,GimvCommentView * cv)249 cb_clist_select_row (GtkCList *clist, gint row, gint col,
250 GdkEventButton *event, GimvCommentView *cv)
251 {
252 gchar *text[2] = {NULL, NULL};
253 gboolean success1, success2;
254
255 g_return_if_fail (cv);
256
257 cv->selected_row = row;
258
259 success1 = gtk_clist_get_text (clist, row, 0, &text[0]);
260 success2 = gtk_clist_get_text (clist, row, 1, &text[1]);
261
262 if (success1) {
263 gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (cv->key_combo)->entry), text[0]);
264 } else {
265 gtk_entry_set_text (GTK_ENTRY(cv->value_entry), "\0");
266 }
267
268 if (success2) {
269 gtk_entry_set_text (GTK_ENTRY(cv->value_entry), text[1]);
270 } else {
271 gtk_entry_set_text (GTK_ENTRY(cv->value_entry), "\0");
272 }
273
274 gimv_comment_view_set_sensitive (cv);
275 }
276
277
278 static void
cb_clist_unselect_row(GtkCList * clist,gint row,gint col,GdkEventButton * event,GimvCommentView * cv)279 cb_clist_unselect_row (GtkCList *clist, gint row, gint col,
280 GdkEventButton *event, GimvCommentView *cv)
281 {
282 g_return_if_fail (cv);
283
284 cv->selected_row = -1;
285
286 gimv_comment_view_set_sensitive (cv);
287 }
288
289
290 static void
cb_clist_row_move(GtkCList * clist,gint arg1,gint arg2,GimvCommentView * cv)291 cb_clist_row_move (GtkCList *clist,
292 gint arg1, gint arg2,
293 GimvCommentView *cv)
294 {
295 GimvCommentDataEntry *entry1, *entry2, *tmpentry;
296 GList *node1, *node2;
297 gint pos1, pos2, tmppos;
298
299 g_return_if_fail (clist && GTK_IS_CLIST (clist));
300 g_return_if_fail (cv);
301 g_return_if_fail (cv->comment);
302
303 entry1 = gtk_clist_get_row_data (clist, arg1);
304 entry2 = gtk_clist_get_row_data (clist, arg2);
305
306 g_return_if_fail (entry1 && entry2);
307
308 node1 = g_list_find (cv->comment->data_list, entry1);
309 node2 = g_list_find (cv->comment->data_list, entry2);
310 g_return_if_fail (node1 && node2);
311
312 pos1 = g_list_position (cv->comment->data_list, node1);
313 pos2 = g_list_position (cv->comment->data_list, node2);
314
315 /* swap data position in the list */
316 if (pos1 > pos2) {
317 tmppos = pos1; pos1 = pos2; pos2 = tmppos;
318 tmpentry = entry1; entry1 = entry2; entry2 = tmpentry;
319 }
320 cv->comment->data_list = g_list_remove (cv->comment->data_list, entry1);
321 cv->comment->data_list = g_list_remove (cv->comment->data_list, entry2);
322 cv->comment->data_list = g_list_insert (cv->comment->data_list, entry2, pos1);
323 cv->comment->data_list = g_list_insert (cv->comment->data_list, entry1, pos2);
324 }
325 #endif /* ENABLE_TREEVIEW */
326
327
328 static gboolean
cb_data_list_key_press(GtkWidget * widget,GdkEventKey * event,GimvCommentView * cv)329 cb_data_list_key_press (GtkWidget *widget, GdkEventKey *event, GimvCommentView *cv)
330 {
331 g_return_val_if_fail (cv, FALSE);
332
333 switch (event->keyval) {
334 case GDK_KP_Enter:
335 case GDK_Return:
336 if (cv->selected_item) {
337 gtk_widget_grab_focus (cv->value_entry);
338 gtk_signal_emit_stop_by_name (GTK_OBJECT (widget),
339 "key_press_event");
340 return TRUE;
341 }
342 break;
343
344 case GDK_Delete:
345 gimv_comment_view_delete_selected_data (cv);
346 return TRUE;
347 break;
348
349 default:
350 break;
351 }
352
353 return FALSE;
354 }
355
356
357 static gboolean
cb_entry_key_press(GtkWidget * widget,GdkEventKey * event,GimvCommentView * cv)358 cb_entry_key_press (GtkWidget *widget, GdkEventKey *event, GimvCommentView *cv)
359 {
360 g_return_val_if_fail (cv, FALSE);
361
362 switch (event->keyval) {
363 case GDK_Tab:
364 if (event->state & GDK_SHIFT_MASK) {
365 gtk_widget_grab_focus (cv->key_combo);
366 } else {
367 gtk_widget_grab_focus (cv->save_button);
368 }
369 gtk_signal_emit_stop_by_name (GTK_OBJECT (widget),
370 "key_press_event");
371 return TRUE;
372 break;
373
374 default:
375 break;
376 }
377
378 return FALSE;
379 }
380
381
382 static void
cb_entry_changed(GtkEditable * entry,GimvCommentView * cv)383 cb_entry_changed (GtkEditable *entry, GimvCommentView *cv)
384 {
385 g_return_if_fail (cv);
386
387 gimv_comment_view_set_sensitive (cv);
388 }
389
390
391 static void
cb_entry_enter(GtkEditable * entry,GimvCommentView * cv)392 cb_entry_enter (GtkEditable *entry, GimvCommentView *cv)
393 {
394 g_return_if_fail (cv);
395
396 gimv_comment_view_data_enter (cv);
397 gtk_widget_grab_focus (cv->comment_clist);
398 }
399
400
401 static void
cb_combo_select(GtkWidget * label,GimvCommentView * cv)402 cb_combo_select (GtkWidget *label, GimvCommentView *cv)
403 {
404 GtkWidget *clist;
405 gchar *key = gtk_object_get_data (GTK_OBJECT (label), "key");
406
407 g_return_if_fail (label && GTK_IS_LIST_ITEM (label));
408 g_return_if_fail (cv);
409 g_return_if_fail (key);
410
411 cv->selected_item = label;
412 clist = cv->comment_clist;
413
414 #ifdef ENABLE_TREEVIEW
415 {
416 GtkTreeView *treeview = GTK_TREE_VIEW (clist);
417 GtkTreeModel *model = gtk_tree_view_get_model (treeview);
418 GtkTreeIter iter;
419 gboolean go_next;
420
421 go_next = gtk_tree_model_get_iter_first (model, &iter);
422
423 for (; go_next; go_next = gtk_tree_model_iter_next (model, &iter)) {
424 GimvCommentDataEntry *entry;
425
426 gtk_tree_model_get (model, &iter,
427 COLUMN_RAW_ENTRY, &entry,
428 COLUMN_TERMINATOR);
429 if (!entry) continue;
430
431 if (entry->key && !strcmp (key, entry->key)) {
432 GtkTreePath *treepath = gtk_tree_model_get_path (model, &iter);
433
434 if (!treepath) continue;
435 gtk_tree_view_set_cursor (treeview, treepath, NULL, FALSE);
436 gtk_tree_path_free (treepath);
437 break;
438 }
439 }
440 }
441 #else /* ENABLE_TREEVIEW */
442 {
443 gint row;
444
445 for (row = 0; row < GTK_CLIST (clist)->rows; row++) {
446 GimvCommentDataEntry *entry;
447
448 entry = gtk_clist_get_row_data (GTK_CLIST (clist), row);
449 if (!entry) continue;
450
451 if (entry->key && !strcmp (key, entry->key)) {
452 gtk_clist_select_row (GTK_CLIST (clist), row, 0);
453 /* gtk_clist_moveto (GTK_CLIST (clist), row, 0, 0.0, 0.0); */
454 break;
455 }
456 }
457 }
458 #endif /* ENABLE_TREEVIEW */
459 }
460
461 static void
cb_combo_deselect(GtkWidget * label,GimvCommentView * cv)462 cb_combo_deselect (GtkWidget *label, GimvCommentView *cv)
463 {
464 g_return_if_fail (label && GTK_IS_LIST_ITEM (label));
465 g_return_if_fail (cv);
466
467 cv->selected_item = NULL;
468 }
469
470
471 static void
cb_file_saved(GimvComment * comment,GimvCommentView * cv)472 cb_file_saved (GimvComment *comment, GimvCommentView *cv)
473 {
474 g_return_if_fail (cv);
475 if (!cv->comment) return;
476
477 gimv_comment_view_reset_data (cv);
478 }
479
480
481 /******************************************************************************
482 *
483 * other private functions.
484 *
485 ******************************************************************************/
486 static GimvCommentView *
gimv_comment_view_new()487 gimv_comment_view_new ()
488 {
489 GimvCommentView *cv;
490
491 cv = g_new0 (GimvCommentView, 1);
492 g_return_val_if_fail (cv, NULL);
493
494 cv->comment = NULL;
495
496 cv->window = NULL;
497 cv->main_vbox = NULL;
498 cv->notebook = NULL;
499 cv->button_area = NULL;
500
501 cv->data_page = NULL;
502 cv->note_page = NULL;
503
504 cv->comment_clist = NULL;
505 cv->selected_row = -1;
506 cv->key_combo = NULL;
507 cv->value_entry = NULL;
508 cv->note_box = NULL;
509 cv->selected_item = NULL;
510
511 cv->save_button = NULL;
512 cv->reset_button = NULL;
513 cv->delete_button = NULL;
514
515 cv->accel_group = NULL;
516 cv->iv = NULL;
517 cv->next_button = NULL;
518 cv->prev_button = NULL;
519 cv->changed = FALSE;
520
521 return cv;
522 }
523
524
525 static GtkWidget *
create_data_page(GimvCommentView * cv)526 create_data_page (GimvCommentView *cv)
527 {
528 GtkWidget *vbox, *vbox1, *hbox, *hbox1;
529 GtkWidget *scrolledwin, *clist, *combo, *entry;
530 GtkWidget *label;
531 gchar *titles[] = {_("Key"), _("Value")};
532
533 label = gtk_label_new (_("Data"));
534 gtk_widget_set_name (label, "TabLabel");
535 gtk_widget_show (label);
536 cv->data_page = vbox = gtk_vbox_new (FALSE, 0);
537 gtk_widget_show (vbox);
538
539 gtk_notebook_append_page (GTK_NOTEBOOK(cv->notebook),
540 vbox, label);
541
542 /* scrolled window & clist */
543 scrolledwin = gtk_scrolled_window_new (NULL, NULL);
544 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(scrolledwin),
545 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
546 #ifdef USE_GTK2
547 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwin),
548 GTK_SHADOW_IN);
549 #endif /* USE_GTK2 */
550 gtk_box_pack_start(GTK_BOX(vbox), scrolledwin, TRUE, TRUE, 0);
551
552 #ifdef ENABLE_TREEVIEW
553 {
554 GtkListStore *store;
555 GtkTreeViewColumn *col;
556 GtkCellRenderer *render;
557
558 store = gtk_list_store_new (N_COLUMN,
559 G_TYPE_STRING,
560 G_TYPE_STRING,
561 G_TYPE_POINTER);
562 clist = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
563 cv->comment_clist = clist;
564
565 gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (clist), TRUE);
566
567 /* set column for key */
568 col = gtk_tree_view_column_new ();
569 gtk_tree_view_column_set_resizable (col, TRUE);
570 gtk_tree_view_column_set_title (col, titles[0]);
571 render = gtk_cell_renderer_text_new ();
572 gtk_tree_view_column_pack_start (col, render, TRUE);
573 gtk_tree_view_column_add_attribute (col, render, "text", COLUMN_KEY);
574 gtk_tree_view_append_column (GTK_TREE_VIEW (clist), col);
575
576 /* set column for value */
577 col = gtk_tree_view_column_new ();
578 gtk_tree_view_column_set_resizable (col, TRUE);
579 gtk_tree_view_column_set_title (col, titles[1]);
580 render = gtk_cell_renderer_text_new ();
581 gtk_tree_view_column_pack_start (col, render, TRUE);
582 gtk_tree_view_column_add_attribute (col, render, "text", COLUMN_VALUE);
583 gtk_tree_view_append_column (GTK_TREE_VIEW (clist), col);
584
585 gtk_signal_connect (GTK_OBJECT (clist),"cursor-changed",
586 GTK_SIGNAL_FUNC (cb_tree_view_cursor_changed), cv);
587
588 gtk_container_add (GTK_CONTAINER (scrolledwin), clist);
589 }
590 #else /* ENABLE_TREEVIEW */
591 clist = cv->comment_clist = gtk_clist_new_with_titles (2, titles);
592 gtk_clist_set_selection_mode (GTK_CLIST (clist), GTK_SELECTION_BROWSE);
593 /* gtk_clist_set_column_width (GTK_CLIST(clist), 0, 80); */
594 gtk_clist_set_column_auto_resize (GTK_CLIST(clist), 0, TRUE);
595 gtk_clist_set_column_auto_resize (GTK_CLIST(clist), 1, TRUE);
596 gtk_clist_set_reorderable(GTK_CLIST(clist), TRUE);
597 gtk_clist_set_use_drag_icons (GTK_CLIST(clist), FALSE);
598 gtk_container_add (GTK_CONTAINER (scrolledwin), clist);
599
600 gtk_signal_connect (GTK_OBJECT (clist),"select_row",
601 GTK_SIGNAL_FUNC (cb_clist_select_row), cv);
602 gtk_signal_connect (GTK_OBJECT (clist),"unselect_row",
603 GTK_SIGNAL_FUNC (cb_clist_unselect_row), cv);
604 gtk_signal_connect (GTK_OBJECT (clist),"row-move",
605 GTK_SIGNAL_FUNC (cb_clist_row_move), cv);
606 #endif /* ENABLE_TREEVIEW */
607 gtk_signal_connect (GTK_OBJECT (clist), "key_press_event",
608 GTK_SIGNAL_FUNC (cb_data_list_key_press), cv);
609 /* entry area */
610 hbox = gtk_hbox_new (FALSE, 0);
611 gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
612 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
613
614 vbox1 = gtk_vbox_new (FALSE, 0);
615 gtk_box_pack_start (GTK_BOX (hbox), vbox1, TRUE, TRUE, 0);
616 hbox1 = gtk_hbox_new (FALSE, 0);
617 gtk_box_pack_start (GTK_BOX (vbox1), hbox1, TRUE, TRUE, 0);
618 label = gtk_label_new (_("Key: "));
619 gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
620 gtk_box_pack_start (GTK_BOX (hbox1), label, FALSE, FALSE, 0);
621
622 cv->key_combo = combo = gtk_combo_new ();
623 gtk_box_pack_start (GTK_BOX (vbox1), combo, TRUE, TRUE, 0);
624 gtk_entry_set_editable (GTK_ENTRY (GTK_COMBO (cv->key_combo)->entry), FALSE);
625
626 vbox1 = gtk_vbox_new (FALSE, 0);
627 gtk_box_pack_start (GTK_BOX (hbox), vbox1, TRUE, TRUE, 0);
628 hbox1 = gtk_hbox_new (FALSE, 0);
629 gtk_box_pack_start (GTK_BOX (vbox1), hbox1, TRUE, TRUE, 0);
630 label = gtk_label_new (_("Value: "));
631 gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
632 gtk_box_pack_start (GTK_BOX (hbox1), label, FALSE, FALSE, 0);
633 cv->value_entry = entry = gtk_entry_new ();
634 gtk_box_pack_start (GTK_BOX (vbox1), entry, TRUE, TRUE, 0);
635 gtk_signal_connect (GTK_OBJECT (entry), "changed",
636 GTK_SIGNAL_FUNC (cb_entry_changed), cv);
637 gtk_signal_connect (GTK_OBJECT (entry), "activate",
638 GTK_SIGNAL_FUNC (cb_entry_enter), cv);
639 gtk_signal_connect (GTK_OBJECT (entry), "key_press_event",
640 GTK_SIGNAL_FUNC (cb_entry_key_press), cv);
641
642 gtk_widget_show_all (cv->data_page);
643
644 return vbox;
645 }
646
647
648 #ifdef USE_GTK2
649 static void
cb_text_buffer_changed(GtkTextBuffer * buffer,GimvCommentView * cv)650 cb_text_buffer_changed (GtkTextBuffer *buffer, GimvCommentView *cv)
651 {
652 if (cv->comment) {
653 cv->changed = TRUE;
654 }
655 }
656 #else /* USE_GTK2 */
657 static void
cb_text_changed(GtkEditable * editable,GimvCommentView * cv)658 cb_text_changed (GtkEditable *editable, GimvCommentView *cv)
659 {
660 if (cv->comment) {
661 cv->changed = TRUE;
662 }
663 }
664 #endif /* USE_GTK2 */
665
666
667 static GtkWidget *
create_note_page(GimvCommentView * cv)668 create_note_page (GimvCommentView *cv)
669 {
670 GtkWidget *scrolledwin;
671 GtkWidget *label;
672
673 /* "Note" page */
674 label = gtk_label_new (_("Note"));
675 gtk_widget_set_name (label, "TabLabel");
676 gtk_widget_show (label);
677
678 cv->note_page = scrolledwin = gtk_scrolled_window_new (NULL, NULL);
679 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(scrolledwin),
680 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
681 #ifdef USE_GTK2
682 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwin),
683 GTK_SHADOW_IN);
684 #endif /* USE_GTK2 */
685 gtk_widget_show (scrolledwin);
686
687 #ifdef USE_GTK2
688 {
689 GtkTextBuffer *textbuf;
690
691 cv->note_box = gtk_text_view_new ();
692 textbuf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (cv->note_box));
693 g_signal_connect (G_OBJECT (textbuf), "changed",
694 G_CALLBACK (cb_text_buffer_changed), cv);
695 }
696 #else /* USE_GTK2 */
697 cv->note_box = gtk_text_new (gtk_scrolled_window_get_hadjustment
698 (GTK_SCROLLED_WINDOW (scrolledwin)),
699 gtk_scrolled_window_get_vadjustment
700 (GTK_SCROLLED_WINDOW (scrolledwin)));
701 gtk_text_set_editable (GTK_TEXT (cv->note_box), TRUE);
702 gtk_signal_connect (GTK_OBJECT (cv->note_box), "changed",
703 GTK_SIGNAL_FUNC (cb_text_changed), cv);
704 #endif /* USE_GTK2 */
705 gtk_container_add (GTK_CONTAINER (scrolledwin), cv->note_box);
706 gtk_widget_show (cv->note_box);
707
708 gtk_notebook_append_page (GTK_NOTEBOOK(cv->notebook),
709 scrolledwin, label);
710
711 return cv->note_page;
712 }
713
714
715 static void
gimv_comment_view_set_sensitive_all(GimvCommentView * cv,gboolean sensitive)716 gimv_comment_view_set_sensitive_all (GimvCommentView *cv, gboolean sensitive)
717 {
718 g_return_if_fail (cv);
719
720 gtk_widget_set_sensitive (cv->comment_clist, sensitive);
721 gtk_widget_set_sensitive (cv->note_box, sensitive);
722
723 gtk_widget_set_sensitive (cv->key_combo, sensitive);
724 gtk_widget_set_sensitive (cv->value_entry, sensitive);
725
726 gtk_widget_set_sensitive (cv->save_button, sensitive);
727 gtk_widget_set_sensitive (cv->reset_button, sensitive);
728 gtk_widget_set_sensitive (cv->delete_button, sensitive);
729 }
730
731
732 static void
gimv_comment_view_set_sensitive(GimvCommentView * cv)733 gimv_comment_view_set_sensitive (GimvCommentView *cv)
734 {
735 const gchar *key_str, *value_str;
736 gboolean selected = FALSE;
737
738 g_return_if_fail (cv);
739
740 key_str = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (cv->key_combo)->entry));
741 value_str = gtk_entry_get_text (GTK_ENTRY (cv->value_entry));
742
743 if (!cv->comment || !GTK_WIDGET_VISIBLE (cv->button_area)) {
744 gimv_comment_view_set_sensitive_all (cv, FALSE);
745 return;
746 } else {
747 gimv_comment_view_set_sensitive_all (cv, TRUE);
748 }
749
750 #ifdef ENABLE_TREEVIEW
751 {
752 GtkTreeView *treeview = GTK_TREE_VIEW (cv->comment_clist);
753 GtkTreeSelection *selection = gtk_tree_view_get_selection (treeview);
754 GtkTreeModel *model;
755 GtkTreeIter iter;
756
757 selected = gtk_tree_selection_get_selected (selection, &model, &iter);
758 }
759 #else /* ENABLE_TREEVIEW */
760 if (cv->selected_row >= 0) selected = TRUE;
761 #endif /* ENABLE_TREEVIEW */
762 }
763
764
765 static void
entry_list_remove_item(GtkWidget * widget,GtkContainer * container)766 entry_list_remove_item (GtkWidget *widget, GtkContainer *container)
767 {
768 g_return_if_fail (widget && GTK_IS_WIDGET (widget));
769 g_return_if_fail (container && GTK_IS_CONTAINER (container));
770
771 gtk_container_remove (container, widget);
772 }
773
774
775 static void
gimv_comment_view_set_combo_list(GimvCommentView * cv)776 gimv_comment_view_set_combo_list (GimvCommentView *cv)
777 {
778 GList *list;
779 GtkWidget *first_label = NULL;
780
781 g_return_if_fail (cv);
782 g_return_if_fail (cv->key_combo);
783
784 gtk_container_foreach (GTK_CONTAINER (GTK_COMBO (cv->key_combo)->list),
785 (GtkCallback) (entry_list_remove_item),
786 GTK_COMBO (cv->key_combo)->list);
787
788 list = gimv_comment_get_data_entry_list ();
789 while (list) {
790 GimvCommentDataEntry *data_entry = list->data;
791 GimvImageInfo *info;
792 GtkWidget *label;
793
794 list = g_list_next (list);
795
796 if (!data_entry) continue;
797 if (!data_entry->display) continue;
798 if (!data_entry->key || !*data_entry->key) continue;
799
800 if (cv->comment)
801 info = cv->comment->info;
802 else
803 info = NULL;
804
805 if (!strcmp ("X-IMG-File-Path-In-Arcvhie", data_entry->key)
806 && info && !gimv_image_info_is_in_archive (info))
807 {
808 continue;
809 }
810
811 label = gtk_list_item_new_with_label (_(data_entry->display_name));
812
813 gtk_object_set_data_full (GTK_OBJECT (label), "key",
814 g_strdup (data_entry->key),
815 (GtkDestroyNotify) g_free);
816 gtk_container_add (GTK_CONTAINER (GTK_COMBO (cv->key_combo)->list),
817 label);
818 gtk_widget_show (label);
819
820 gtk_signal_connect (GTK_OBJECT(label), "select",
821 GTK_SIGNAL_FUNC (cb_combo_select), cv);
822 gtk_signal_connect (GTK_OBJECT(label), "deselect",
823 GTK_SIGNAL_FUNC (cb_combo_deselect), cv);
824
825 if (!first_label)
826 first_label = label;
827 }
828
829 gtk_list_item_select (GTK_LIST_ITEM (first_label));
830 }
831
832
833 static void
gimv_comment_view_data_enter(GimvCommentView * cv)834 gimv_comment_view_data_enter (GimvCommentView *cv)
835 {
836 GimvCommentDataEntry *entry;
837 const gchar *key, *dname, *value;
838 gchar *text[16];
839
840 g_return_if_fail (cv);
841 if (!cv->selected_item) return;
842
843 key = gtk_object_get_data (GTK_OBJECT (cv->selected_item), "key");
844 g_return_if_fail (key);
845
846 dname = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (cv->key_combo)->entry));
847 value = gtk_entry_get_text (GTK_ENTRY (cv->value_entry));
848 g_return_if_fail (dname && *dname);
849
850 entry = gimv_comment_append_data (cv->comment, key, value);
851
852 g_return_if_fail (entry);
853
854 #ifdef ENABLE_TREEVIEW
855 {
856 GtkTreeView *treeview = GTK_TREE_VIEW (cv->comment_clist);
857 GtkTreeModel *model = gtk_tree_view_get_model (treeview);
858 GtkTreeIter iter;
859 gboolean go_next;
860 GimvCommentDataEntry *src_entry;
861
862 go_next = gtk_tree_model_get_iter_first (model, &iter);
863 for (; go_next; go_next = gtk_tree_model_iter_next (model, &iter)) {
864 gtk_tree_model_get (model, &iter,
865 COLUMN_RAW_ENTRY, &src_entry,
866 COLUMN_TERMINATOR);
867 if (src_entry == entry) break;
868 }
869
870 text[0] = entry->display_name;
871 text[1] = entry->value;
872 if (!entry->userdef) text[0] = _(text[0]);
873
874 if (!go_next)
875 gtk_list_store_append (GTK_LIST_STORE (model), &iter);
876 gtk_list_store_set (GTK_LIST_STORE (model), &iter,
877 COLUMN_KEY, text[0],
878 COLUMN_VALUE, text[1],
879 COLUMN_RAW_ENTRY, entry,
880 COLUMN_TERMINATOR);
881 }
882 #else /* ENABLE_TREEVIEW */
883 {
884 GtkCList *clist = GTK_CLIST (cv->comment_clist);
885 gint row = gtk_clist_find_row_from_data (clist, entry);
886
887 text[0] = entry->display_name;
888 text[1] = entry->value;
889 if (!entry->userdef) text[0] = _(text[0]);
890
891 if (row < 0) {
892 row = gtk_clist_append (clist, text);
893 gtk_clist_set_row_data (clist, row, entry);
894 } else {
895 gtk_clist_set_text (clist, row, 1, text[1]);
896 }
897 }
898 #endif /* ENABLE_TREEVIEW */
899
900 cv->changed = TRUE;
901
902 gimv_comment_view_set_sensitive (cv);
903 }
904
905
906 static void
gimv_comment_view_reset_data(GimvCommentView * cv)907 gimv_comment_view_reset_data (GimvCommentView *cv)
908 {
909 GimvImageInfo *info;
910 GList *node;
911 gchar *text[2];
912
913 gimv_comment_view_clear (cv);
914 if (cv->comment) {
915 info = cv->comment->info;
916 node = cv->comment->data_list;
917 while (node) {
918 GimvCommentDataEntry *entry = node->data;
919
920 node = g_list_next (node);
921
922 if (!entry) continue;
923 if (!entry->display) continue;
924
925 if (!strcmp ("X-IMG-File-Path-In-Arcvhie", entry->key)
926 && info && !gimv_image_info_is_in_archive (info))
927 {
928 continue;
929 }
930
931 text[0] = _(entry->display_name);
932 text[1] = entry->value;
933
934 #ifdef ENABLE_TREEVIEW
935 {
936 GtkTreeModel *model;
937 GtkTreeIter iter;
938 model = gtk_tree_view_get_model (GTK_TREE_VIEW (cv->comment_clist));
939 gtk_list_store_append (GTK_LIST_STORE (model), &iter);
940 gtk_list_store_set (GTK_LIST_STORE (model), &iter,
941 COLUMN_KEY, text[0],
942 COLUMN_VALUE, text[1],
943 COLUMN_RAW_ENTRY, entry,
944 COLUMN_TERMINATOR);
945 }
946 #else /* ENABLE_TREEVIEW */
947 {
948 gint row;
949 row = gtk_clist_append (GTK_CLIST (cv->comment_clist), text);
950 gtk_clist_set_row_data (GTK_CLIST (cv->comment_clist),
951 row, entry);
952 }
953 #endif /* ENABLE_TREEVIEW */
954 }
955
956 if (cv->comment->note && *cv->comment->note) {
957 #ifdef USE_GTK2
958 GtkTextBuffer *buffer;
959
960 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (cv->note_box));
961 gtk_text_buffer_set_text (buffer, cv->comment->note, -1);
962 #else /* USE_GTK2 */
963 GdkFont *font;
964
965 if (conf.textentry_font && *conf.textentry_font)
966 font = gdk_fontset_load (conf.textentry_font);
967 else
968 font = NULL;
969
970 gtk_text_insert (GTK_TEXT (cv->note_box), font, NULL, NULL,
971 cv->comment->note, -1);
972
973 if (font)
974 gdk_font_unref (font);
975 #endif /* USE_GTK2 */
976 }
977 }
978
979 cv->changed = FALSE;
980
981 gimv_comment_view_set_sensitive (cv);
982 }
983
984
985 /******************************************************************************
986 *
987 * public functions.
988 *
989 ******************************************************************************/
990 void
gimv_comment_view_clear(GimvCommentView * cv)991 gimv_comment_view_clear (GimvCommentView *cv)
992 {
993 g_return_if_fail (cv);
994
995 #ifdef ENABLE_TREEVIEW
996 {
997 GtkTreeModel *model
998 = gtk_tree_view_get_model (GTK_TREE_VIEW (cv->comment_clist));
999 gtk_list_store_clear (GTK_LIST_STORE (model));
1000 }
1001 #else /* ENABLE_TREEVIEW */
1002 {
1003 gint i;
1004 for (i = GTK_CLIST (cv->comment_clist)->rows - 1; i >= 0; i--) {
1005 gtk_clist_remove (GTK_CLIST (cv->comment_clist), i);
1006 }
1007 }
1008 #endif /* ENABLE_TREEVIEW */
1009
1010 gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (cv->key_combo)->entry), "\0");
1011 gtk_entry_set_text (GTK_ENTRY (cv->value_entry), "\0");
1012
1013 #ifdef USE_GTK2
1014 {
1015 GtkTextBuffer *buffer;
1016 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (cv->note_box));
1017 gtk_text_buffer_set_text (buffer, "\0", -1);
1018 }
1019 #else /* USE_GTK2 */
1020 {
1021 GtkText *text;
1022 text = GTK_TEXT (cv->note_box);
1023 gtk_text_set_point (text, 0);
1024 gtk_text_forward_delete (text, gtk_text_get_length(text));
1025 }
1026 #endif /* USE_GTK2 */
1027
1028 cv->changed = FALSE;
1029
1030 gimv_comment_view_set_sensitive (cv);
1031 }
1032
1033
1034 gboolean
gimv_comment_view_change_file(GimvCommentView * cv,GimvImageInfo * info)1035 gimv_comment_view_change_file (GimvCommentView *cv, GimvImageInfo *info)
1036 {
1037 g_return_val_if_fail (cv, FALSE);
1038
1039 gimv_comment_view_clear (cv);
1040
1041 if (cv->comment) {
1042 gimv_comment_unref (cv->comment);
1043 cv->comment = NULL;
1044 }
1045
1046 cv->comment = gimv_comment_get_from_image_info (info);
1047 gtk_signal_connect (GTK_OBJECT (cv->comment), "file_saved",
1048 GTK_SIGNAL_FUNC (cb_file_saved), cv);
1049
1050 gimv_comment_view_reset_data (cv);
1051 gimv_comment_view_set_combo_list (cv);
1052
1053 return TRUE;
1054 }
1055
1056
1057 GimvCommentView *
gimv_comment_view_create(void)1058 gimv_comment_view_create (void)
1059 {
1060 GimvCommentView *cv;
1061 GtkWidget *hbox, *hbox1;
1062 GtkWidget *button;
1063 guint key;
1064
1065 cv = gimv_comment_view_new ();
1066
1067 cv->accel_group = gtk_accel_group_new ();
1068 cv->iv = NULL;
1069 cv->next_button = NULL;
1070 cv->prev_button = NULL;
1071 cv->changed = FALSE;
1072
1073 cv->main_vbox = gtk_vbox_new (FALSE, 0);
1074 gtk_widget_set_name (cv->main_vbox, "GimvCommentView");
1075 gtk_signal_connect (GTK_OBJECT (cv->main_vbox), "destroy",
1076 GTK_SIGNAL_FUNC (cb_destroyed), cv);
1077
1078 cv->notebook = gtk_notebook_new ();
1079 gtk_container_set_border_width (GTK_CONTAINER (cv->notebook), 1);
1080 gtk_notebook_set_scrollable (GTK_NOTEBOOK (cv->notebook), TRUE);
1081 gtk_box_pack_start(GTK_BOX(cv->main_vbox), cv->notebook, TRUE, TRUE, 0);
1082 gtk_widget_show (cv->notebook);
1083
1084 gtk_signal_connect (GTK_OBJECT(cv->notebook), "switch-page",
1085 GTK_SIGNAL_FUNC(cb_switch_page), cv);
1086
1087 create_data_page (cv);
1088 create_note_page (cv);
1089
1090 /* button area */
1091 hbox = cv->button_area = gtk_hbox_new (FALSE, 0);
1092 gtk_box_pack_start(GTK_BOX(cv->main_vbox), cv->button_area, FALSE, FALSE, 2);
1093 gtk_widget_show (cv->main_vbox);
1094
1095 hbox1 = cv->inner_button_area = gtk_hbox_new (TRUE, 0);
1096 gtk_box_pack_end (GTK_BOX (hbox), hbox1, FALSE, TRUE, 0);
1097 #ifdef USE_GTK2
1098 gtk_box_set_homogeneous (GTK_BOX(hbox1), FALSE);
1099 #endif /* USE_GTK2 */
1100
1101 button = gtk_button_new_with_label (_("_Save"));
1102 cv->save_button = button;
1103 key = gtk_label_parse_uline(GTK_LABEL(GTK_BIN(button)->child),
1104 _("_Save"));
1105 gtk_widget_add_accelerator(button, "clicked",
1106 cv->accel_group, key, GDK_MOD1_MASK, 0);
1107 gtk_signal_connect (GTK_OBJECT (button),"clicked",
1108 GTK_SIGNAL_FUNC (cb_save_button_pressed), cv);
1109 gtk_box_pack_start (GTK_BOX (hbox1), button, FALSE, TRUE, 2);
1110 /* GTK_WIDGET_SET_FLAGS(button,GTK_CAN_DEFAULT); */
1111
1112 button = gtk_button_new_with_label (_("_Reset"));
1113 cv->reset_button = button;
1114 key = gtk_label_parse_uline(GTK_LABEL(GTK_BIN(button)->child),
1115 _("_Reset"));
1116 gtk_widget_add_accelerator(button, "clicked",
1117 cv->accel_group, key, GDK_MOD1_MASK, 0);
1118 gtk_signal_connect (GTK_OBJECT (button),"clicked",
1119 GTK_SIGNAL_FUNC (cb_reset_button_pressed), cv);
1120 gtk_box_pack_start (GTK_BOX (hbox1), button, FALSE, TRUE, 2);
1121 /* GTK_WIDGET_SET_FLAGS(button,GTK_CAN_DEFAULT); */
1122
1123 button = gtk_button_new_with_label (_("_Delete"));
1124 cv->delete_button = button;
1125 key = gtk_label_parse_uline(GTK_LABEL(GTK_BIN(button)->child),
1126 _("_Delete"));
1127 gtk_widget_add_accelerator(button, "clicked",
1128 cv->accel_group, key, GDK_MOD1_MASK, 0);
1129 gtk_signal_connect (GTK_OBJECT (button),"clicked",
1130 GTK_SIGNAL_FUNC (cb_del_button_pressed), cv);
1131 gtk_box_pack_start (GTK_BOX (hbox1), button, FALSE, TRUE, 2);
1132 /* GTK_WIDGET_SET_FLAGS(button,GTK_CAN_DEFAULT); */
1133
1134 gtk_widget_show_all (cv->main_vbox);
1135
1136 gimv_comment_view_set_sensitive (cv);
1137
1138 return cv;
1139 }
1140
1141
1142 static void
cb_prev_button_pressed(GtkButton * button,GimvCommentView * cv)1143 cb_prev_button_pressed (GtkButton *button, GimvCommentView *cv)
1144 {
1145 g_return_if_fail (GIMV_IS_IMAGE_VIEW (cv->iv));
1146
1147 gimv_image_view_prev (cv->iv);
1148 }
1149
1150
1151 static void
cb_next_button_pressed(GtkButton * button,GimvCommentView * cv)1152 cb_next_button_pressed (GtkButton *button, GimvCommentView *cv)
1153 {
1154 g_return_if_fail (GIMV_IS_IMAGE_VIEW (cv->iv));
1155
1156 gimv_image_view_next (cv->iv);
1157 }
1158
1159
1160 GimvCommentView *
gimv_comment_view_create_window(GimvImageInfo * info)1161 gimv_comment_view_create_window (GimvImageInfo *info)
1162 {
1163 GimvCommentView *cv;
1164 gchar buf[BUF_SIZE];
1165
1166 g_return_val_if_fail (info, NULL);
1167
1168 cv = gimv_comment_view_create ();
1169 if (!cv) return NULL;
1170
1171 gtk_container_set_border_width (GTK_CONTAINER (cv->main_vbox), 5);
1172
1173 cv->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1174 g_snprintf (buf, BUF_SIZE, _("Edit Comment (%s)"),
1175 gimv_image_info_get_path (info));
1176 gtk_window_set_title (GTK_WINDOW (cv->window), buf);
1177 gtk_window_set_default_size (GTK_WINDOW (cv->window), 400, 350);
1178 gtk_window_set_position (GTK_WINDOW (cv->window), GTK_WIN_POS_MOUSE);
1179 if (cv->accel_group)
1180 gtk_window_add_accel_group (GTK_WINDOW (cv->window), cv->accel_group);
1181 gtk_container_add (GTK_CONTAINER (cv->window), cv->main_vbox);
1182
1183 gtk_widget_show_all (cv->window);
1184
1185 gimv_comment_view_change_file (cv, info);
1186
1187 gimv_icon_stock_set_window_icon (cv->window->window, "gimv_icon");
1188
1189 return cv;
1190 }
1191
1192
1193 /* FIXME */
1194 void
gimv_comment_view_set_image_view(GimvCommentView * cv,GimvImageView * iv)1195 gimv_comment_view_set_image_view (GimvCommentView *cv, GimvImageView *iv)
1196 {
1197 g_return_if_fail (cv);
1198
1199 /* add next and prev button */
1200 if (iv) {
1201 GtkWidget *hbox, *sep, *button;
1202 guint key;
1203
1204 /* cv->iv = iv; */
1205
1206 hbox = gtk_hbox_new (TRUE, 0);
1207 gtk_box_pack_start (GTK_BOX (cv->button_area), hbox, TRUE, TRUE, 0);
1208
1209 sep = gtk_vseparator_new ();
1210 gtk_box_pack_start (GTK_BOX (cv->button_area),
1211 sep, TRUE, TRUE, 2);
1212
1213 button = gtk_button_new_with_label (_("_Prev"));
1214 cv->prev_button = button;
1215 key = gtk_label_parse_uline(GTK_LABEL(GTK_BIN(button)->child),
1216 _("_Prev"));
1217 gtk_widget_add_accelerator(button, "clicked",
1218 cv->accel_group, key, GDK_MOD1_MASK, 0);
1219 gtk_signal_connect (GTK_OBJECT (button),"clicked",
1220 GTK_SIGNAL_FUNC (cb_prev_button_pressed), cv);
1221 gtk_box_pack_start (GTK_BOX (hbox),
1222 button, FALSE, TRUE, 2);
1223
1224 button = gtk_button_new_with_label (_("_Next"));
1225 cv->next_button = button;
1226 key = gtk_label_parse_uline(GTK_LABEL(GTK_BIN(button)->child),
1227 _("_Next"));
1228 gtk_widget_add_accelerator(button, "clicked",
1229 cv->accel_group, key, GDK_MOD1_MASK, 0);
1230 gtk_signal_connect (GTK_OBJECT (button),"clicked",
1231 GTK_SIGNAL_FUNC (cb_next_button_pressed), cv);
1232 gtk_box_pack_start (GTK_BOX (hbox),
1233 button, FALSE, TRUE, 2);
1234 }
1235 }
1236