]> git.sur5r.net Git - glabels/blob - glabels2/src/merge-properties-dialog.c
2009-09-01 Jim Evins <evins@snaught.com>
[glabels] / glabels2 / src / merge-properties-dialog.c
1 /*
2  *  merge-properties-dialog.c
3  *  Copyright (C) 2001-2009  Jim Evins <evins@snaught.com>.
4  *
5  *  This file is part of gLabels.
6  *
7  *  gLabels 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 3 of the License, or
10  *  (at your option) any later version.
11  *
12  *  gLabels 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 gLabels.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <config.h>
22
23 #include "merge-properties-dialog.h"
24
25 #include <glib/gi18n.h>
26 #include <gtk/gtkbuilder.h>
27 #include <gtk/gtkfilechooserbutton.h>
28 #include <gtk/gtkcombobox.h>
29 #include <gtk/gtkstock.h>
30 #include <gtk/gtktreestore.h>
31 #include <gtk/gtktreeselection.h>
32 #include <gtk/gtkcellrenderertoggle.h>
33 #include <gtk/gtkcellrenderertext.h>
34 #include <gtk/gtklabel.h>
35 #include <string.h>
36
37 #include "label.h"
38 #include "merge.h"
39 #include "util.h"
40 #include "hig.h"
41
42 #include "debug.h"
43
44
45 /*===========================================*/
46 /* Private data types                        */
47 /*===========================================*/
48
49 struct _glMergePropertiesDialogPrivate {
50
51         glLabel      *label;
52         glMerge      *merge;
53
54         GtkBuilder   *builder;
55
56         GtkWidget    *type_combo;
57         GtkWidget    *location_vbox;
58         GtkWidget    *src_entry;
59
60         GtkTreeStore *store;
61         GtkWidget    *treeview;
62
63         GtkWidget    *select_all_button;
64         GtkWidget    *unselect_all_button;
65
66         gchar        *saved_src;
67
68 };
69
70 enum {
71         /* Real columns */
72         SELECT_COLUMN,
73         RECORD_FIELD_COLUMN,
74         VALUE_COLUMN,
75
76         /* Invisible columns */
77         IS_RECORD_COLUMN,
78         DATA_COLUMN, /* points to glMergeRecord */
79
80         N_COLUMNS
81 };
82
83
84 /*===========================================*/
85 /* Private globals                           */
86 /*===========================================*/
87
88
89 /*===========================================*/
90 /* Local function prototypes                 */
91 /*===========================================*/
92
93 static void gl_merge_properties_dialog_finalize   (GObject                      *object);
94 static void gl_merge_properties_dialog_construct  (glMergePropertiesDialog      *dialog,
95                                                    glLabel                      *label,
96                                                    GtkWindow                    *window);
97
98 static void type_changed_cb                       (GtkWidget                    *widget,
99                                                    glMergePropertiesDialog      *dialog);
100
101 static void src_changed_cb                        (GtkWidget                    *widget,
102                                                    glMergePropertiesDialog      *dialog);
103
104 static void response_cb                           (glMergePropertiesDialog      *dialog,
105                                                    gint                          response,
106                                                    gpointer                      user_data);
107
108 static void load_tree                             (GtkTreeStore                 *store,
109                                                    glMerge                      *merge);
110
111 static void record_select_toggled_cb              (GtkCellRendererToggle        *cell,
112                                                    gchar                        *path_str,
113                                                    GtkTreeStore                 *store);
114
115 static void select_all_button_clicked_cb          (GtkWidget                    *widget,
116                                                    glMergePropertiesDialog      *dialog);
117
118 static void unselect_all_button_clicked_cb        (GtkWidget                    *widget,
119                                                    glMergePropertiesDialog      *dialog);
120
121
122 /*****************************************************************************/
123 /* Boilerplate object stuff.                                                 */
124 /*****************************************************************************/
125 G_DEFINE_TYPE (glMergePropertiesDialog, gl_merge_properties_dialog, GTK_TYPE_DIALOG);
126
127
128 static void
129 gl_merge_properties_dialog_class_init (glMergePropertiesDialogClass *class)
130 {
131         GObjectClass *object_class = G_OBJECT_CLASS (class);
132
133         gl_debug (DEBUG_MERGE, "");
134         
135         gl_merge_properties_dialog_parent_class = g_type_class_peek_parent (class);
136
137         object_class->finalize = gl_merge_properties_dialog_finalize;   
138 }
139
140
141 static void
142 gl_merge_properties_dialog_init (glMergePropertiesDialog *dialog)
143 {
144         gl_debug (DEBUG_MERGE, "START");
145
146         dialog->priv = g_new0 (glMergePropertiesDialogPrivate, 1);
147
148         gtk_container_set_border_width (GTK_CONTAINER(dialog), GL_HIG_PAD2);
149
150         gtk_dialog_set_has_separator (GTK_DIALOG(dialog), FALSE);
151         gtk_dialog_add_buttons (GTK_DIALOG (dialog),
152                                 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
153                                 GTK_STOCK_OK, GTK_RESPONSE_OK,
154                                 NULL);
155
156         gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
157
158         g_signal_connect(G_OBJECT (dialog), "response",
159                          G_CALLBACK (response_cb), NULL);
160
161
162         gl_debug (DEBUG_MERGE, "END");
163 }
164
165
166 static void 
167 gl_merge_properties_dialog_finalize (GObject *object)
168 {
169         glMergePropertiesDialog* dialog = GL_MERGE_PROPERTIES_DIALOG (object);
170         
171         gl_debug (DEBUG_MERGE, "START");
172
173         g_return_if_fail (object != NULL);
174         g_return_if_fail (GL_IS_MERGE_PROPERTIES_DIALOG (dialog));
175         g_return_if_fail (dialog->priv != NULL);
176
177         if (dialog->priv->merge != NULL) {
178                 g_object_unref (G_OBJECT (dialog->priv->merge));
179         }
180         if (dialog->priv->builder != NULL) {
181                 g_object_unref (G_OBJECT (dialog->priv->builder));
182         }
183         g_free (dialog->priv);
184
185         G_OBJECT_CLASS (gl_merge_properties_dialog_parent_class)->finalize (object);
186         gl_debug (DEBUG_MERGE, "END");
187 }
188
189
190 /*****************************************************************************/
191 /* NEW merge properties dialog.                                              */
192 /*****************************************************************************/
193 GtkWidget*
194 gl_merge_properties_dialog_new (glLabel   *label,
195                                 GtkWindow *window)
196 {
197         GtkWidget *dialog;
198
199         gl_debug (DEBUG_MERGE, "START");
200
201         dialog = GTK_WIDGET (g_object_new (GL_TYPE_MERGE_PROPERTIES_DIALOG, NULL));
202
203         gl_merge_properties_dialog_construct (GL_MERGE_PROPERTIES_DIALOG (dialog),
204                                               label, window);
205
206         gl_debug (DEBUG_MERGE, "END");
207
208         return dialog;
209 }
210
211
212 /*--------------------------------------------------------------------------*/
213 /* PRIVATE.  Create merge widgets.                                          */
214 /*--------------------------------------------------------------------------*/
215 static void
216 gl_merge_properties_dialog_construct (glMergePropertiesDialog *dialog,
217                                       glLabel                 *label,
218                                       GtkWindow               *window)
219 {
220         GtkBuilder        *builder;
221         static gchar      *object_ids[] = { "merge_properties_vbox", NULL };
222         GError            *error = NULL;
223         gchar             *description;
224         glMergeSrcType     src_type;
225         gchar             *src;
226         gchar             *name, *title;
227         GList             *texts;
228         GtkWidget         *vbox;
229         GtkCellRenderer   *renderer;
230         GtkTreeViewColumn *column;
231         GtkTreeSelection  *selection;
232
233         gl_debug (DEBUG_MERGE, "START");
234
235         g_return_if_fail (GL_IS_MERGE_PROPERTIES_DIALOG (dialog));
236         g_return_if_fail (dialog->priv != NULL);
237
238         if (window) {
239                 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(window));
240                 gtk_window_set_destroy_with_parent (GTK_WINDOW(dialog), TRUE);
241         }
242
243         builder = gtk_builder_new ();
244         gtk_builder_add_objects_from_file (builder,
245                                            GLABELS_BUILDER_DIR "merge-properties-dialog.builder",
246                                            object_ids,
247                                            &error);
248         if (error) {
249                 g_critical ("%s\n\ngLabels may not be installed correctly!", error->message);
250                 g_error_free (error);
251                 return;
252         }
253
254         gl_util_get_builder_widgets (builder,
255                                      "merge_properties_vbox", &vbox,
256                                      "type_combo",            &dialog->priv->type_combo,
257                                      "location_vbox",         &dialog->priv->location_vbox,
258                                      "treeview",              &dialog->priv->treeview,
259                                      "select_all_button",     &dialog->priv->select_all_button,
260                                      "unselect_all_button",   &dialog->priv->unselect_all_button,
261                                      NULL);
262
263         gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), vbox);
264         dialog->priv->builder = builder;
265
266         gl_util_combo_box_add_text_model (GTK_COMBO_BOX (dialog->priv->type_combo));
267
268         dialog->priv->label = label;
269
270         dialog->priv->merge = gl_label_get_merge (dialog->priv->label);
271         description         = gl_merge_get_description (dialog->priv->merge);
272         src_type            = gl_merge_get_src_type (dialog->priv->merge);
273         src                 = gl_merge_get_src (dialog->priv->merge);
274
275         /* --- Window title --- */
276         name = gl_label_get_short_name (label);
277         title = g_strdup_printf ("%s %s", name, _("Merge Properties"));
278         gtk_window_set_title (GTK_WINDOW (dialog), title);
279         g_free (name);
280         g_free (title);
281
282         texts = gl_merge_get_descriptions ();
283         gl_debug (DEBUG_MERGE, "DESCRIPTIONS:");
284         {
285                 GList *p;
286
287                 for (p=texts; p!=NULL; p=p->next) {
288                         gl_debug (DEBUG_MERGE, "    \"%s\"", p->data);
289                 }
290         }
291         gl_util_combo_box_set_strings (GTK_COMBO_BOX (dialog->priv->type_combo),
292                                        texts);
293         gl_merge_free_descriptions (&texts);
294         gl_util_combo_box_set_active_text (GTK_COMBO_BOX (dialog->priv->type_combo),
295                                            description);
296         g_signal_connect (G_OBJECT (dialog->priv->type_combo), "changed",
297                           G_CALLBACK (type_changed_cb), dialog);
298
299         gl_debug (DEBUG_MERGE, "Src_type = %d", src_type);
300         switch (src_type) {
301         case GL_MERGE_SRC_IS_FILE:
302                 dialog->priv->src_entry =
303                         gtk_file_chooser_button_new (_("Select merge-database source"),
304                                                      GTK_FILE_CHOOSER_ACTION_OPEN);
305                 gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (dialog->priv->src_entry),
306                                                src);
307                 g_signal_connect (G_OBJECT (dialog->priv->src_entry),
308                                   "selection-changed",
309                                   G_CALLBACK (src_changed_cb), dialog);
310                 break;
311         default:
312                 dialog->priv->src_entry = gtk_label_new (_("N/A"));
313                 gtk_misc_set_alignment (GTK_MISC (dialog->priv->src_entry), 0.0, 0.5);
314                 break;
315         }
316         gtk_box_pack_start (GTK_BOX (dialog->priv->location_vbox),
317                             dialog->priv->src_entry, FALSE, FALSE, 0);
318         gtk_widget_show_all (GTK_WIDGET (dialog->priv->location_vbox));
319
320         dialog->priv->store = gtk_tree_store_new (N_COLUMNS,
321                                           G_TYPE_BOOLEAN, /* Record selector */
322                                           G_TYPE_STRING,  /* Record/Field name */
323                                           G_TYPE_STRING,  /* Field value */
324                                           G_TYPE_BOOLEAN, /* Is Record? */
325                                           G_TYPE_POINTER  /* Pointer to record */);
326         load_tree (dialog->priv->store, dialog->priv->merge);
327
328         gtk_tree_view_set_model (GTK_TREE_VIEW (dialog->priv->treeview),
329                                  GTK_TREE_MODEL (dialog->priv->store));
330
331         gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (dialog->priv->treeview),
332                                       TRUE);
333         selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->priv->treeview));
334         gtk_tree_selection_set_mode (selection, GTK_SELECTION_NONE);
335         renderer = gtk_cell_renderer_toggle_new ();
336         g_signal_connect (G_OBJECT (renderer), "toggled",
337                           G_CALLBACK (record_select_toggled_cb), dialog->priv->store);
338         column = gtk_tree_view_column_new_with_attributes (_("Select"), renderer,
339                                                            "active", SELECT_COLUMN,
340                                                            "visible", IS_RECORD_COLUMN,
341                                                            NULL);
342         gtk_tree_view_column_set_clickable (column, TRUE);
343         gtk_tree_view_append_column (GTK_TREE_VIEW (dialog->priv->treeview), column);
344         renderer = gtk_cell_renderer_text_new ();
345         g_object_set (G_OBJECT (renderer), "yalign", 0.0, NULL);
346         column = gtk_tree_view_column_new_with_attributes (_("Record/Field"), renderer,
347                                                            "text", RECORD_FIELD_COLUMN,
348                                                            NULL);
349         gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
350         gtk_tree_view_append_column (GTK_TREE_VIEW (dialog->priv->treeview), column);
351         gtk_tree_view_set_expander_column (GTK_TREE_VIEW (dialog->priv->treeview), column);
352         renderer = gtk_cell_renderer_text_new ();
353         g_object_set (G_OBJECT (renderer), "yalign", 0.0, NULL);
354         column = gtk_tree_view_column_new_with_attributes (_("Data"), renderer,
355                                                            "text", VALUE_COLUMN,
356                                                            NULL);
357         gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
358         gtk_tree_view_append_column (GTK_TREE_VIEW (dialog->priv->treeview), column);
359
360         g_signal_connect (G_OBJECT (dialog->priv->select_all_button),
361                           "clicked",
362                           G_CALLBACK (select_all_button_clicked_cb), dialog);
363
364         g_signal_connect (G_OBJECT (dialog->priv->unselect_all_button),
365                           "clicked",
366                           G_CALLBACK (unselect_all_button_clicked_cb), dialog);
367
368
369         g_free (src);
370         g_free (description);
371
372         gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
373
374         gl_debug (DEBUG_MERGE, "END");
375 }
376
377
378 /*--------------------------------------------------------------------------*/
379 /* PRIVATE.  type "changed" callback.                                       */
380 /*--------------------------------------------------------------------------*/
381 static void
382 type_changed_cb (GtkWidget               *widget,
383                  glMergePropertiesDialog *dialog)
384 {
385         gchar             *description;
386         gchar             *name;
387         gchar             *src;
388         glMergeSrcType     src_type;
389
390         gl_debug (DEBUG_MERGE, "START");
391
392         description = gtk_combo_box_get_active_text (GTK_COMBO_BOX (dialog->priv->type_combo));
393         name = gl_merge_description_to_name (description);
394
395         src = gl_merge_get_src (dialog->priv->merge); /* keep current src if possible */
396         if ( src != NULL ) {
397                 gl_debug (DEBUG_MERGE, "Saving src = \"%s\"", src);
398                 g_free (dialog->priv->saved_src);
399                 dialog->priv->saved_src = src;
400         }
401
402         if (dialog->priv->merge != NULL) {
403                 g_object_unref (G_OBJECT(dialog->priv->merge));
404         }
405         dialog->priv->merge = gl_merge_new (name);
406
407         gtk_widget_destroy (dialog->priv->src_entry);
408         src_type = gl_merge_get_src_type (dialog->priv->merge);
409         switch (src_type) {
410         case GL_MERGE_SRC_IS_FILE:
411                 dialog->priv->src_entry =
412                         gtk_file_chooser_button_new (_("Select merge-database source"),
413                                                      GTK_FILE_CHOOSER_ACTION_OPEN);
414                 if (dialog->priv->saved_src != NULL) {
415                         gl_debug (DEBUG_MERGE, "Setting src = \"%s\"", dialog->priv->saved_src);
416                         gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (dialog->priv->src_entry),
417                                                        dialog->priv->saved_src);
418                         gl_merge_set_src (dialog->priv->merge, dialog->priv->saved_src);
419                 }
420                 g_signal_connect (G_OBJECT (dialog->priv->src_entry),
421                                   "selection-changed",
422                                   G_CALLBACK (src_changed_cb), dialog);
423                 break;
424         case GL_MERGE_SRC_IS_FIXED:
425                 dialog->priv->src_entry = gtk_label_new (_("Fixed"));
426                 gtk_misc_set_alignment (GTK_MISC (dialog->priv->src_entry), 0.0, 0.5);
427
428                 gl_debug (DEBUG_MERGE, "Setting src = \"%s\"", dialog->priv->saved_src);
429                 gl_merge_set_src (dialog->priv->merge, "Fixed");
430                 break;
431         default:
432                 dialog->priv->src_entry = gtk_label_new (_("N/A"));
433                 gtk_misc_set_alignment (GTK_MISC (dialog->priv->src_entry), 0.0, 0.5);
434                 break;
435         }
436         gtk_box_pack_start( GTK_BOX (dialog->priv->location_vbox),
437                             dialog->priv->src_entry, FALSE, FALSE, 0);
438         gtk_widget_show_all (dialog->priv->location_vbox);
439
440         load_tree (dialog->priv->store, dialog->priv->merge);
441
442         g_free (description);
443         g_free (name);
444
445         gl_debug (DEBUG_MERGE, "END");
446 }
447
448
449 /*--------------------------------------------------------------------------*/
450 /* PRIVATE.  source "changed" callback.                                     */
451 /*--------------------------------------------------------------------------*/
452 static void
453 src_changed_cb (GtkWidget               *widget,
454                 glMergePropertiesDialog *dialog)
455 {
456         gchar     *src, *orig_src;
457
458         gl_debug (DEBUG_MERGE, "START");
459
460         orig_src = gl_merge_get_src (dialog->priv->merge);
461         src = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog->priv->src_entry));
462
463         gl_debug (DEBUG_MERGE, "orig=\"%s\", new=\"%s\"\n", orig_src, src);
464
465         if (((orig_src == NULL) && (src != NULL)) ||
466             ((orig_src != NULL) && (src == NULL)) ||
467             ((orig_src != NULL) && (src != NULL) && strcmp (src, orig_src)))
468         {
469                 gl_merge_set_src (dialog->priv->merge, src);
470                 load_tree (dialog->priv->store, dialog->priv->merge);
471         }
472
473         g_free (orig_src);
474         g_free (src);
475
476
477         gl_debug (DEBUG_MERGE, "END");
478 }
479
480
481 /*--------------------------------------------------------------------------*/
482 /* PRIVATE.  response callback.                                             */
483 /*--------------------------------------------------------------------------*/
484 static void
485 response_cb (glMergePropertiesDialog *dialog,
486              gint                     response,
487              gpointer                 user_data)
488 {
489         gl_debug (DEBUG_MERGE, "START");
490
491         switch (response) {
492
493         case GTK_RESPONSE_OK:
494                 gl_label_set_merge (dialog->priv->label, dialog->priv->merge);
495                 gtk_widget_hide (GTK_WIDGET (dialog));
496                 break;
497         case GTK_RESPONSE_CANCEL:
498                 /* Let the dialog get rebuilt next time to recover state. */
499                 gtk_widget_destroy (GTK_WIDGET (dialog));
500                 break;
501         case GTK_RESPONSE_DELETE_EVENT:
502                 break;
503         default:
504                 g_print ("response = %d", response);
505                 g_assert_not_reached ();
506         }
507
508         gl_debug (DEBUG_MERGE, "END");
509 }
510
511
512 /*--------------------------------------------------------------------------*/
513 /* PRIVATE.  Load tree store from merge data.                               */
514 /*--------------------------------------------------------------------------*/
515 static void
516 load_tree (GtkTreeStore           *store,
517            glMerge                *merge)
518 {
519         const GList   *record_list;
520         GList         *p_rec, *p_field;
521         glMergeRecord *record;
522         glMergeField  *field;
523         GtkTreeIter    iter1, iter2;
524         gchar         *primary_key;
525         gchar         *primary_value;
526
527         gl_debug (DEBUG_MERGE, "START");
528
529         gtk_tree_store_clear (store);
530
531         primary_key = gl_merge_get_primary_key (merge);
532         record_list = gl_merge_get_record_list (merge);
533
534         for ( p_rec=(GList *)record_list; p_rec!=NULL; p_rec=p_rec->next ) {
535                 record = (glMergeRecord *)p_rec->data;
536                 
537                 primary_value = gl_merge_eval_key (record, primary_key);
538
539                 gtk_tree_store_append (store, &iter1, NULL);
540                 gtk_tree_store_set (store, &iter1,
541                                     SELECT_COLUMN,       record->select_flag,
542                                     RECORD_FIELD_COLUMN, primary_value,
543                                     IS_RECORD_COLUMN,    TRUE,
544                                     DATA_COLUMN,         record,
545                                     -1);
546
547                 g_free (primary_value);
548
549                 for ( p_field=record->field_list; p_field!=NULL; p_field=p_field->next ) {
550                         field = (glMergeField *)p_field->data;
551
552                         gtk_tree_store_append (store, &iter2, &iter1);
553                         gtk_tree_store_set (store, &iter2,
554                                             RECORD_FIELD_COLUMN, field->key,
555                                             VALUE_COLUMN,        field->value,
556                                             IS_RECORD_COLUMN,    FALSE,
557                                             -1);
558                 }
559         }
560
561         g_free (primary_key);
562
563         gl_debug (DEBUG_MERGE, "END");
564 }
565
566
567 /*--------------------------------------------------------------------------*/
568 /* PRIVATE.  Record select toggled.                                         */
569 /*--------------------------------------------------------------------------*/
570 static void
571 record_select_toggled_cb (GtkCellRendererToggle *cell,
572                           gchar                 *path_str,
573                           GtkTreeStore          *store)
574 {
575         GtkTreePath   *path;
576         GtkTreeIter    iter;
577         glMergeRecord *record;
578
579         gl_debug (DEBUG_MERGE, "START");
580
581         /* get toggled iter */
582         path = gtk_tree_path_new_from_string (path_str);
583         gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path);
584
585         /* get current data */
586         gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
587                             DATA_COLUMN,   &record,
588                             -1);
589
590         /* toggle the select flag within the record */
591         record->select_flag ^= 1;
592
593         /* set new value in store */
594         gtk_tree_store_set (store, &iter,
595                             SELECT_COLUMN, record->select_flag,
596                             -1);
597
598         /* clean up */
599         gtk_tree_path_free (path);
600
601         gl_debug (DEBUG_MERGE, "END");
602 }
603
604
605 /*--------------------------------------------------------------------------*/
606 /* PRIVATE.  "Select All" button callback.                                  */
607 /*--------------------------------------------------------------------------*/
608 static void
609 select_all_button_clicked_cb (GtkWidget                    *widget,
610                               glMergePropertiesDialog      *dialog)
611 {
612         GtkTreeModel  *store = GTK_TREE_MODEL (dialog->priv->store);
613         GtkTreeIter    iter;
614         glMergeRecord *record;
615         gboolean       good;
616
617         gl_debug (DEBUG_MERGE, "START");
618
619         for ( good = gtk_tree_model_get_iter_first (store, &iter);
620               good;
621               good = gtk_tree_model_iter_next (store, &iter) )
622         {
623                 
624                 /* get current data */
625                 gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
626                                     DATA_COLUMN,   &record,
627                                     -1);
628
629                 
630                 /* Set select flag within the record */
631                 record->select_flag = TRUE;
632
633                 /* set new value in store */
634                 gtk_tree_store_set (GTK_TREE_STORE (store), &iter,
635                                     SELECT_COLUMN, record->select_flag,
636                                     -1);
637
638         }
639
640         gl_debug (DEBUG_MERGE, "END");
641 }
642
643
644 /*--------------------------------------------------------------------------*/
645 /* PRIVATE.  "Unselect All" button callback.                                */
646 /*--------------------------------------------------------------------------*/
647 static void
648 unselect_all_button_clicked_cb (GtkWidget                    *widget,
649                                 glMergePropertiesDialog      *dialog)
650 {
651         GtkTreeModel  *store = GTK_TREE_MODEL (dialog->priv->store);
652         GtkTreeIter    iter;
653         glMergeRecord *record;
654         gboolean       good;
655
656         gl_debug (DEBUG_MERGE, "START");
657
658         for ( good = gtk_tree_model_get_iter_first (store, &iter);
659               good;
660               good = gtk_tree_model_iter_next (store, &iter) )
661         {
662                 
663                 /* get current data */
664                 gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
665                                     DATA_COLUMN,   &record,
666                                     -1);
667
668                 
669                 /* Set select flag within the record */
670                 record->select_flag = FALSE;
671
672                 /* set new value in store */
673                 gtk_tree_store_set (GTK_TREE_STORE (store), &iter,
674                                     SELECT_COLUMN, record->select_flag,
675                                     -1);
676
677         }
678
679         gl_debug (DEBUG_MERGE, "END");
680 }
681
682
683
684 /*
685  * Local Variables:       -- emacs
686  * mode: C                -- emacs
687  * c-basic-offset: 8      -- emacs
688  * tab-width: 8           -- emacs
689  * indent-tabs-mode: nil  -- emacs
690  * End:                   -- emacs
691  */