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