src/cmd/fsexam/src/fsexam-preference-dialog.c
changeset 147 8c4ef02c14b8
equal deleted inserted replaced
146:841e634f8d60 147:8c4ef02c14b8
       
     1 /*
       
     2  * CDDL HEADER START
       
     3  *
       
     4  * The contents of this file are subject to the terms of the
       
     5  * Common Development and Distribution License (the "License").
       
     6  * You may not use this file except in compliance with the License.
       
     7  *
       
     8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
       
     9  * or http://www.opensolaris.org/os/licensing.
       
    10  * See the License for the specific language governing permissions
       
    11  * and limitations under the License.
       
    12  *
       
    13  * When distributing Covered Code, include this CDDL HEADER in each
       
    14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
       
    15  * If applicable, add the following below this CDDL HEADER, with the
       
    16  * fields enclosed by brackets "[]" replaced with your own identifying
       
    17  * information: Portions Copyright [yyyy] [name of copyright owner]
       
    18  *
       
    19  * CDDL HEADER END
       
    20  */
       
    21 
       
    22 /*
       
    23  * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
       
    24  * Use is subject to license terms.
       
    25  */
       
    26 #ifdef HAVE_CONFIG_H
       
    27 #include <config.h>
       
    28 #endif
       
    29 
       
    30 #include <stdlib.h>
       
    31 #include <libgen.h>
       
    32 #include <strings.h>
       
    33 #include <string.h>
       
    34 
       
    35 #include <glade/glade.h>
       
    36 #include <gtk/gtk.h>
       
    37 #include <glib.h>
       
    38 #include <libgnome/libgnome.h>
       
    39 #include <libgnomeui/libgnomeui.h>
       
    40 #include <glib/gi18n.h>
       
    41 #include <gconf/gconf-client.h>
       
    42 
       
    43 #include "fsexam-header.h"
       
    44 #include "fsexam-debug.h"
       
    45 #include "fsexam-preference-dialog.h"
       
    46 #include "fsexam-ui.h"
       
    47 #include "callbacks.h"
       
    48 
       
    49 enum {
       
    50     COLUMN_ENCODING_NAME = 0,
       
    51     ENCODING_NUM_COLS
       
    52 };
       
    53 
       
    54 typedef enum {
       
    55     ActionInvalid,
       
    56     ActionAutoDetect,
       
    57     ActionAutoConversion,
       
    58     ActionRecursive,
       
    59     ActionHidden,
       
    60     ActionFollow,
       
    61     ActionRemote,
       
    62     ActionNoCheckSymlink,
       
    63     ActionSpecial,
       
    64     ActionCompress,
       
    65     ActionUseLog,
       
    66     ActionLogFile,
       
    67     ActionHistLen,
       
    68     ENCODING_UP,
       
    69     ENCODING_DOWN,
       
    70     ENCODING_ADD,
       
    71     ENCODING_DELETE,
       
    72     ENCODING_SAVE,
       
    73     ENCODING_RESET
       
    74 } EncodingActionType;
       
    75 
       
    76 static gboolean get_encoding_name_of_row (GtkTreeModel *,
       
    77                                           GtkTreePath *,
       
    78                                           GtkTreeIter *,
       
    79                                           gpointer);
       
    80 static void selection_changed_callback (GtkTreeSelection *, gpointer);
       
    81 static void handle_encoding_action (EncodingActionType, GtkWidget *);
       
    82 static void cb_set_sensitive (GtkWidget *, gpointer);
       
    83 static void cb_pref_reset (GtkDialog *, FSEXAM_pref *);
       
    84 static void cb_encoding_manipulate (GtkWidget *, gpointer);
       
    85 static void selection_changed_callback (GtkTreeSelection *, gpointer);
       
    86 static void pref_dialog_response_callback (GtkWidget *, int, gpointer);
       
    87 static void create_encodings_treeview (GtkTreeView *, GtkWidget *);
       
    88 static void show_pref_help(void);
       
    89 
       
    90 /*
       
    91  * Get the current rows encoding name, and append it to the user
       
    92  * provided list
       
    93  */
       
    94 static gboolean
       
    95 get_encoding_name_of_row (GtkTreeModel *model,
       
    96                           GtkTreePath  *path,
       
    97                           GtkTreeIter  *iter,
       
    98                           gpointer     user_data)
       
    99 {
       
   100     GSList  **list = user_data;
       
   101     gchar   *name = NULL;
       
   102 
       
   103     gtk_tree_model_get (model, iter, COLUMN_ENCODING_NAME, &name, -1);
       
   104     *list = g_slist_prepend (*list, name);  /* free name when free list */
       
   105 
       
   106     return FALSE;
       
   107 }
       
   108 
       
   109 /*
       
   110  *  Event handler for Up/Down/Add/Remove/Save button of encoding treeview
       
   111  */
       
   112 static void
       
   113 handle_encoding_action (EncodingActionType type, GtkWidget *dialog)
       
   114 {
       
   115     GtkTreeSelection *selection = NULL;
       
   116     GtkTreeModel     *model = NULL;
       
   117     GtkWidget        *view = NULL;
       
   118     GtkTreeIter      iter_cur, iter_other;
       
   119 
       
   120     if (type == ActionInvalid)
       
   121         return;
       
   122 
       
   123     view = g_object_get_data (G_OBJECT (dialog), "treeview_encoding_list");
       
   124     selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
       
   125 
       
   126     if (gtk_tree_selection_get_selected (selection, &model, &iter_cur)) {
       
   127         GtkTreePath *treepath = gtk_tree_model_get_path (model, &iter_cur);
       
   128         iter_other = iter_cur;
       
   129 
       
   130         switch (type) {
       
   131             case ENCODING_UP:
       
   132                 if ((gtk_tree_path_prev (treepath)) 
       
   133                     && (gtk_tree_model_get_iter (model, &iter_other, treepath)))
       
   134                 {
       
   135                         gtk_list_store_swap (GTK_LIST_STORE (model), 
       
   136                                              &iter_cur, 
       
   137                                              &iter_other);
       
   138                 }
       
   139 
       
   140                 gtk_widget_set_sensitive (
       
   141                         g_object_get_data (G_OBJECT (dialog), "button_down"),
       
   142                         TRUE);
       
   143                 if (! gtk_tree_path_prev (treepath)) {
       
   144                     gtk_widget_set_sensitive (
       
   145                             g_object_get_data (G_OBJECT (dialog), "button_up"),
       
   146                             FALSE);
       
   147                 }
       
   148                 
       
   149                 break;
       
   150             case ENCODING_DOWN:
       
   151                 if (gtk_tree_model_iter_next (model, &iter_other)) {
       
   152                     gtk_list_store_swap (GTK_LIST_STORE (model), 
       
   153                                          &iter_cur, 
       
   154                                          &iter_other);
       
   155                 }
       
   156 
       
   157                 gtk_widget_set_sensitive (
       
   158                         g_object_get_data (G_OBJECT (dialog), "button_up"),
       
   159                         TRUE);
       
   160                 if (! gtk_tree_model_iter_next (model, &iter_cur)) {
       
   161                     gtk_widget_set_sensitive (
       
   162                         g_object_get_data (G_OBJECT (dialog), "button_down"),
       
   163                         FALSE);
       
   164                 }
       
   165             
       
   166                 break;
       
   167             case ENCODING_DELETE:
       
   168                 gtk_list_store_remove (GTK_LIST_STORE (model), &iter_cur);
       
   169 
       
   170                 break;
       
   171 
       
   172             default:
       
   173                 break;
       
   174         }
       
   175 
       
   176         if (treepath != NULL)
       
   177             gtk_tree_path_free (treepath);
       
   178     }
       
   179 
       
   180     return;
       
   181 }
       
   182 
       
   183 /*
       
   184  * Make related button sensitive or not,
       
   185  * according to 'Button Specail' and 'Button Use Log"
       
   186  */
       
   187 static void
       
   188 cb_set_sensitive (GtkWidget *widget, gpointer data)
       
   189 {
       
   190     GtkWidget   *dialog = data;
       
   191     gboolean    active; 
       
   192 
       
   193     active = gtk_toggle_button_get_active (
       
   194                 g_object_get_data (G_OBJECT (dialog), "special"));
       
   195     gtk_widget_set_sensitive(
       
   196                 g_object_get_data (G_OBJECT (dialog), "compress"), 
       
   197                 active);
       
   198 
       
   199     active = gtk_toggle_button_get_active (
       
   200                 g_object_get_data (G_OBJECT (dialog), "use_log"));
       
   201     gtk_widget_set_sensitive (
       
   202                 g_object_get_data (G_OBJECT (dialog), "log_file"), 
       
   203                 active);
       
   204     gtk_widget_set_sensitive (
       
   205                 g_object_get_data (G_OBJECT (dialog), "label_log_file"), 
       
   206                 active);
       
   207 
       
   208     return;
       
   209 }
       
   210 
       
   211 /*
       
   212  * Refresh FSEXAM_pref data structure after clicked preference dialog's
       
   213  * 'OK' Button
       
   214  *
       
   215  * TODO: Use flags to indicate what we have changed.
       
   216  */
       
   217 static void
       
   218 cb_pref_reset (GtkDialog *dialog, FSEXAM_pref *pref)
       
   219 {
       
   220     gboolean    active;
       
   221     GtkWidget   *w = NULL;
       
   222 
       
   223     w = g_object_get_data (G_OBJECT (dialog), "auto_detect");
       
   224     pref->auto_detect = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
       
   225 
       
   226     w = g_object_get_data (G_OBJECT (dialog), "auto_convert");
       
   227     pref->auto_conversion = gtk_toggle_button_get_active (
       
   228                                     GTK_TOGGLE_BUTTON (w));
       
   229 
       
   230     w = g_object_get_data (G_OBJECT (dialog), "recursive");
       
   231     pref->recursive = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
       
   232 
       
   233     w = g_object_get_data (G_OBJECT (dialog), "hidden");
       
   234     pref->hidden = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
       
   235 
       
   236     w = g_object_get_data (G_OBJECT (dialog), "follow");
       
   237     pref->follow = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
       
   238 
       
   239     w = g_object_get_data (G_OBJECT (dialog), "remote");
       
   240     pref->remote = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
       
   241 
       
   242     w = g_object_get_data (G_OBJECT (dialog), "nocheck_symlink");
       
   243     pref->no_check_symlink_content = gtk_toggle_button_get_active (
       
   244                                     GTK_TOGGLE_BUTTON (w));
       
   245 
       
   246     /* Special type handling setting */
       
   247     w = g_object_get_data (G_OBJECT (dialog), "special");
       
   248     active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
       
   249 
       
   250     if (active) {		/* enable special handling */
       
   251         w = g_object_get_data (G_OBJECT (dialog), "compress");
       
   252         active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
       
   253         if (active) {
       
   254             pref->special |= SPECIAL_COMPRESS;
       
   255         }else{
       
   256             pref->special &= ~SPECIAL_COMPRESS;
       
   257         }
       
   258     }else{
       
   259         pref->special = SPECIAL_NO;
       
   260     }
       
   261 
       
   262     /* Log setting */
       
   263     w = g_object_get_data (G_OBJECT (dialog), "use_log");
       
   264     active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
       
   265     
       
   266     if (active) {
       
   267         gchar *new_log_name = NULL;
       
   268 
       
   269         pref->use_log = TRUE;
       
   270 
       
   271         w = g_object_get_data (G_OBJECT (dialog), "log_file");
       
   272         new_log_name = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (w));
       
   273 
       
   274         if ((pref->log_file == NULL) || ((new_log_name != NULL) 
       
   275 			&& (strcmp (new_log_name, pref->log_file) != 0))) {
       
   276             Log_info  *new_log_info = fsexam_log_open (new_log_name);
       
   277 
       
   278             if (new_log_info != NULL) { /* change to new log struct */
       
   279                 fsexam_log_close (view->setting->log_info);
       
   280                 g_free (pref->log_file);
       
   281 
       
   282                 pref->log_file = g_strdup (new_log_name);
       
   283                 view->setting->log_info = new_log_info;
       
   284             }
       
   285         }
       
   286 
       
   287         g_free (new_log_name);
       
   288     }else{
       
   289         pref->use_log = FALSE;
       
   290 
       
   291         if (view->setting->log_info != NULL) {
       
   292             /*
       
   293              * We won't gfree(pref->log_file), result in it will remember the
       
   294              * last setting: will be written to gconf before exit.
       
   295              */
       
   296             fsexam_log_close (view->setting->log_info);
       
   297             view->setting->log_info = NULL;
       
   298         }
       
   299     }
       
   300 
       
   301     /* history length */
       
   302     w = g_object_get_data (G_OBJECT (dialog), "spinbutton_hist_len");
       
   303     pref->hist_len = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (w));
       
   304 
       
   305     /* update encoding */
       
   306     fsexam_pref_update_encoding (
       
   307                     view->setting->pref,
       
   308                     fsexam_prefdialog_get_encoding_list (GTK_WIDGET (dialog)),
       
   309                     NULL);
       
   310 
       
   311     return;
       
   312 }
       
   313 
       
   314 /* wrapper for cb_create_encoding_dialog func in other source file */
       
   315 static void
       
   316 create_encoding_dialog (GtkWidget *widget, gpointer data)
       
   317 {
       
   318     GtkWidget   *parent = data;
       
   319 
       
   320     cb_create_encoding_dialog (parent);
       
   321 
       
   322     return;
       
   323 }
       
   324 
       
   325 /*
       
   326  *  Wrapper for handle_encoding_action: handle actions on encoding
       
   327  */
       
   328 static void
       
   329 cb_encoding_manipulate (GtkWidget *widget, gpointer user_data)
       
   330 {
       
   331     GtkWidget   *dialog = user_data;
       
   332 
       
   333     EncodingActionType type = ActionInvalid;
       
   334 
       
   335     if (g_object_get_data (G_OBJECT (dialog), "button_up") == widget)
       
   336         type = ENCODING_UP;
       
   337     else if (g_object_get_data (G_OBJECT (dialog), "button_down") == widget)
       
   338         type = ENCODING_DOWN;
       
   339     else if (g_object_get_data (G_OBJECT (dialog), "button_delete") == widget)
       
   340         type = ENCODING_DELETE;
       
   341     else if (g_object_get_data (G_OBJECT (dialog), "button_reset") == widget)
       
   342         type = ENCODING_RESET;
       
   343     
       
   344     handle_encoding_action (type, dialog);
       
   345 
       
   346     if (GTK_WIDGET_CAN_FOCUS (widget))
       
   347         gtk_widget_grab_focus (widget);
       
   348 
       
   349     return;
       
   350 }
       
   351 
       
   352 /* 
       
   353  * callback for 'Save' button:
       
   354  * save encoding into gconf and sync with Encoding list
       
   355  */
       
   356 static void
       
   357 save_encoding_list (GtkWidget *widget, gpointer data)
       
   358 {
       
   359     GtkWidget *dialog = data;
       
   360     GtkWidget *confirm_dlg = NULL;
       
   361     gint      response;
       
   362 
       
   363     confirm_dlg = gtk_message_dialog_new (
       
   364                     GTK_WINDOW (view->mainwin),
       
   365                     GTK_DIALOG_DESTROY_WITH_PARENT,
       
   366                     GTK_MESSAGE_WARNING,
       
   367                     GTK_BUTTONS_YES_NO,
       
   368                     _("Do you want to save this encoding list permanently?"));
       
   369 
       
   370     response = gtk_dialog_run (GTK_DIALOG (confirm_dlg));
       
   371 
       
   372     if (response == GTK_RESPONSE_YES) {
       
   373         GSList *list;
       
   374 
       
   375         list = fsexam_prefdialog_get_encoding_list (dialog);
       
   376         fsexam_pref_update_encoding (view->setting->pref, 
       
   377                                      list, 
       
   378                                      view->setting->pref->gconf_client);
       
   379     }
       
   380 
       
   381     gtk_widget_destroy (confirm_dlg);
       
   382 
       
   383     return;
       
   384 }
       
   385 
       
   386 /*
       
   387  *  Fill in Model data according to Encoding List
       
   388  */
       
   389 static void
       
   390 set_encodings_treeview_model (GtkTreeView *view, GSList *encoding_list)
       
   391 {
       
   392     GtkListStore  *store = NULL;
       
   393     GtkTreeIter   iter;
       
   394     GSList        *list = encoding_list;
       
   395 
       
   396     store = (GTK_LIST_STORE (gtk_tree_view_get_model (view)));
       
   397 	gtk_list_store_clear (store);
       
   398 
       
   399     while (list) {
       
   400         short encoding_id = encoding2id ((gchar *)list->data);
       
   401         list = g_slist_next (list);
       
   402 
       
   403         if (encoding_id == -1)
       
   404             continue;
       
   405 
       
   406         gtk_list_store_append (store, &iter);
       
   407         gtk_list_store_set (store, &iter,
       
   408                             COLUMN_ENCODING_NAME, id2encoding (encoding_id),
       
   409                             -1);
       
   410     }
       
   411 
       
   412 	return;
       
   413 }
       
   414 
       
   415 /*
       
   416  * Create GtkTreeView and empty TreeModel
       
   417  */
       
   418 static void
       
   419 create_encodings_treeview (GtkTreeView *encode_view, 
       
   420                            GtkWidget *dialog)
       
   421 {
       
   422     GtkCellRenderer     *renderer = NULL;
       
   423     GtkTreeViewColumn   *column = NULL;
       
   424     GtkTreeSelection    *selection = NULL;
       
   425 	GtkListStore		*store = NULL;
       
   426     
       
   427     renderer = gtk_cell_renderer_text_new ();
       
   428     column = gtk_tree_view_column_new_with_attributes (NULL,
       
   429                                     renderer,
       
   430                                     "text", COLUMN_ENCODING_NAME,
       
   431                                     NULL);
       
   432     gtk_tree_view_append_column (GTK_TREE_VIEW (encode_view), column);
       
   433     gtk_tree_view_set_search_column (GTK_TREE_VIEW (encode_view),
       
   434                                     COLUMN_ENCODING_NAME);
       
   435 
       
   436     selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (encode_view)),
       
   437     gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
       
   438 
       
   439     /* selection event handler */
       
   440     selection_changed_callback (selection, dialog);
       
   441     g_signal_connect (G_OBJECT (selection), 
       
   442                       "changed",
       
   443                       G_CALLBACK (selection_changed_callback), 
       
   444                       dialog);
       
   445 
       
   446 	/* create empty model */
       
   447 	store = gtk_list_store_new (ENCODING_NUM_COLS, G_TYPE_STRING);
       
   448     gtk_tree_view_set_model (GTK_TREE_VIEW (encode_view), 
       
   449 							 GTK_TREE_MODEL (store));
       
   450     g_object_unref (store);
       
   451 
       
   452     return;
       
   453 
       
   454 }
       
   455 
       
   456 /*
       
   457  * callback to handle sensitive/insensitive of buttons
       
   458  */
       
   459 static void
       
   460 selection_changed_callback (GtkTreeSelection *selection, gpointer data)
       
   461 {
       
   462     GtkWidget       *dialog = data;
       
   463     GtkWidget       *up_button = NULL;
       
   464     GtkWidget       *down_button = NULL;
       
   465     GtkWidget       *delete_button = NULL;
       
   466     GtkTreeModel    *model = NULL;
       
   467     GtkTreeIter     iter;
       
   468     gboolean        has_selection;
       
   469 
       
   470     up_button = g_object_get_data (G_OBJECT (dialog), "button_up");
       
   471     down_button = g_object_get_data (G_OBJECT (dialog), "button_down");
       
   472     delete_button = g_object_get_data (G_OBJECT (dialog), "button_delete");
       
   473 
       
   474     has_selection = gtk_tree_selection_get_selected (
       
   475                                         selection,
       
   476                                         &model,
       
   477                                         &iter);
       
   478 
       
   479     if (has_selection) {
       
   480         GtkTreePath *treepath = NULL;
       
   481     
       
   482         treepath = gtk_tree_model_get_path (model, &iter);
       
   483 
       
   484         gtk_widget_set_sensitive (delete_button, TRUE);
       
   485 
       
   486         if (! gtk_tree_path_prev (treepath))
       
   487             gtk_widget_set_sensitive (up_button, FALSE);
       
   488         else
       
   489             gtk_widget_set_sensitive (up_button, TRUE);
       
   490         
       
   491         if (! gtk_tree_model_iter_next (model, &iter))
       
   492             gtk_widget_set_sensitive (down_button, FALSE);
       
   493         else
       
   494             gtk_widget_set_sensitive (down_button, TRUE);
       
   495 
       
   496         gtk_tree_path_free (treepath);
       
   497     }else{
       
   498         gtk_widget_set_sensitive (up_button, FALSE);
       
   499         gtk_widget_set_sensitive (down_button, FALSE);
       
   500         gtk_widget_set_sensitive (delete_button, FALSE);
       
   501     }
       
   502 
       
   503     return;
       
   504 }
       
   505 
       
   506 static void 
       
   507 show_pref_help(void)
       
   508 {
       
   509     GError *err = NULL;
       
   510 
       
   511     gnome_help_display ("fsexam.xml", "fsexam-prefs", &err);
       
   512 
       
   513     if (err) {
       
   514         GtkWidget *dialog;
       
   515         dialog = gtk_message_dialog_new (
       
   516                         GTK_WINDOW (view->mainwin),
       
   517                         GTK_DIALOG_DESTROY_WITH_PARENT,
       
   518                         GTK_MESSAGE_ERROR,
       
   519                         GTK_BUTTONS_CLOSE,
       
   520                         _("There was an error when displaying help: %s"),
       
   521                         err->message);
       
   522 
       
   523         g_signal_connect (G_OBJECT (dialog),
       
   524                           "response",
       
   525                           G_CALLBACK (gtk_widget_destroy),
       
   526                           NULL);
       
   527 
       
   528         gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
       
   529         gtk_widget_show (dialog);
       
   530         g_error_free (err);
       
   531     }
       
   532 
       
   533     return;
       
   534 }
       
   535 
       
   536 /*
       
   537  * Dialog response event hander 
       
   538  */
       
   539 static void
       
   540 pref_dialog_response_callback (GtkWidget *window, gint id, gpointer data)
       
   541 {
       
   542     FSEXAM_pref     *pref = data;
       
   543 
       
   544     if (id == GTK_RESPONSE_OK) {
       
   545         cb_pref_reset (GTK_DIALOG (window), pref);
       
   546 
       
   547         if (fsexam_debug() & FSEXAM_DBG_OPTION) {
       
   548             fsexam_setting_print (view->setting);
       
   549         }
       
   550     } else if (id == GTK_RESPONSE_HELP) {
       
   551         show_pref_help ();
       
   552         return;
       
   553     }
       
   554 
       
   555     gtk_widget_destroy (window);
       
   556 
       
   557     return;
       
   558 }
       
   559 
       
   560 /*
       
   561  *  callback for 'Preferences' menu: create preference dialog 
       
   562  */
       
   563 void
       
   564 cb_create_pref_dialog ()
       
   565 {
       
   566     FSEXAM_pref  *pref = view->setting->pref;
       
   567     GtkWidget    *dialog = NULL;
       
   568     GtkWidget    *w = NULL;
       
   569     GladeXML     *xml = NULL;
       
   570 		
       
   571     xml = fsexam_gui_load_glade_file (FSEXAM_GLADE_FILE, 
       
   572                                       "pref_dialog",
       
   573                                       GTK_WINDOW (view->mainwin));
       
   574     if (xml == NULL)
       
   575         return;
       
   576 
       
   577     /* main dialog */
       
   578     dialog = glade_xml_get_widget (xml, "pref_dialog");
       
   579     gtk_dialog_set_default_response (GTK_DIALOG (dialog), 
       
   580     		GTK_RESPONSE_CANCEL);
       
   581     g_signal_connect (G_OBJECT (dialog), "response",
       
   582     		G_CALLBACK (pref_dialog_response_callback),
       
   583     		pref);
       
   584 
       
   585     /* buttons */
       
   586     w = glade_xml_get_widget (xml, "chkbtn_auto_detect");
       
   587     g_object_set_data (G_OBJECT (dialog), "auto_detect", w);
       
   588 
       
   589     w = glade_xml_get_widget (xml, "chkbtn_auto_convert");
       
   590     g_object_set_data (G_OBJECT (dialog), "auto_convert", w);
       
   591     
       
   592     w = glade_xml_get_widget (xml, "chkbtn_recursive");
       
   593     g_object_set_data (G_OBJECT (dialog), "recursive", w);
       
   594 
       
   595     w = glade_xml_get_widget (xml, "chkbtn_hidden");
       
   596     g_object_set_data (G_OBJECT (dialog), "hidden", w);
       
   597 
       
   598     w = glade_xml_get_widget (xml, "chkbtn_follow");
       
   599     g_object_set_data (G_OBJECT (dialog), "follow", w);
       
   600 
       
   601     w = glade_xml_get_widget (xml, "chkbtn_remote");
       
   602     g_object_set_data (G_OBJECT (dialog), "remote", w);
       
   603 
       
   604     w = glade_xml_get_widget (xml, "chkbtn_nocheck_symlink");
       
   605     g_object_set_data (G_OBJECT (dialog), "nocheck_symlink", w);
       
   606 
       
   607     /* Special file type */
       
   608     w = glade_xml_get_widget (xml, "chkbtn_special");
       
   609     g_object_set_data (G_OBJECT (dialog), "special", w);
       
   610     g_signal_connect (G_OBJECT (w), "toggled",
       
   611                       G_CALLBACK (cb_set_sensitive), dialog);
       
   612 
       
   613     w = glade_xml_get_widget (xml, "chkbtn_compress");
       
   614     g_object_set_data (G_OBJECT (dialog), "compress", w);
       
   615 
       
   616     /* Use log or not */
       
   617     w = glade_xml_get_widget (xml, "chkbtn_use_log");
       
   618     g_object_set_data (G_OBJECT (dialog), "use_log", w);
       
   619     g_signal_connect (G_OBJECT (w), "toggled", 
       
   620                       G_CALLBACK (cb_set_sensitive), dialog);
       
   621 
       
   622     w = glade_xml_get_widget (xml, "label_log_file");
       
   623     g_object_set_data (G_OBJECT (dialog), "label_log_file", w);
       
   624 
       
   625     w = glade_xml_get_widget (xml, "filebtn_log_file");
       
   626     g_object_set_data (G_OBJECT (dialog), "log_file", w);
       
   627 
       
   628     w = glade_xml_get_widget (xml, "spinbutton_hist_len");
       
   629     g_object_set_data (G_OBJECT (dialog), "spinbutton_hist_len", w);
       
   630 
       
   631     /* Up/Down/Add/Delete buttons */
       
   632     w = glade_xml_get_widget (xml, "chkbtn_up");
       
   633     g_object_set_data (G_OBJECT (dialog), "button_up", w);
       
   634     g_signal_connect (G_OBJECT (w), 
       
   635                       "clicked",
       
   636                       G_CALLBACK (cb_encoding_manipulate),
       
   637                       dialog);
       
   638 
       
   639     w = glade_xml_get_widget (xml, "chkbtn_down");
       
   640     g_object_set_data (G_OBJECT (dialog), "button_down", w);
       
   641     g_signal_connect (G_OBJECT (w), 
       
   642                       "clicked",
       
   643                       G_CALLBACK (cb_encoding_manipulate),
       
   644                       dialog);
       
   645 
       
   646     w = glade_xml_get_widget (xml, "chkbtn_delete");
       
   647     g_object_set_data (G_OBJECT (dialog), "button_delete", w);
       
   648     g_signal_connect (G_OBJECT (w), 
       
   649                       "clicked",
       
   650                       G_CALLBACK (cb_encoding_manipulate),
       
   651                       dialog);
       
   652 
       
   653     w = glade_xml_get_widget (xml, "chkbtn_save");
       
   654     g_object_set_data (G_OBJECT (dialog), "button_save", w);
       
   655     g_signal_connect (G_OBJECT (w), 
       
   656                       "clicked",
       
   657                       G_CALLBACK (save_encoding_list),
       
   658                       dialog);
       
   659 
       
   660     w = glade_xml_get_widget (xml, "chkbtn_add");
       
   661     g_signal_connect (G_OBJECT (w), 
       
   662                       "clicked",
       
   663                       G_CALLBACK (create_encoding_dialog),
       
   664                       dialog);
       
   665 
       
   666     /* Init encoding list from FSEXAM_setting->pref->encoding_list */
       
   667     w  = glade_xml_get_widget (xml, "treeview_encoding_list");
       
   668     g_object_set_data (G_OBJECT (dialog), "treeview_encoding_list", w);
       
   669 
       
   670     /* create tree view and empty tree model */
       
   671     create_encodings_treeview (GTK_TREE_VIEW (w), dialog); 
       
   672    
       
   673     g_object_unref (xml);       /* destroy xml */
       
   674 
       
   675     /* buttons */
       
   676     w = g_object_get_data (G_OBJECT (dialog), "auto_detect");
       
   677     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), pref->auto_detect);
       
   678 
       
   679     w = g_object_get_data (G_OBJECT (dialog), "auto_convert");
       
   680     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), pref->auto_conversion);
       
   681     
       
   682     w = g_object_get_data (G_OBJECT (dialog), "recursive");
       
   683     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), pref->recursive);
       
   684 
       
   685     w = g_object_get_data (G_OBJECT (dialog), "hidden");
       
   686     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), pref->hidden);
       
   687 
       
   688     w = g_object_get_data (G_OBJECT (dialog), "follow");
       
   689     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), pref->follow);
       
   690 
       
   691     w = g_object_get_data (G_OBJECT (dialog), "remote");
       
   692     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w),  pref->remote);
       
   693 
       
   694     w = g_object_get_data (G_OBJECT (dialog), "nocheck_symlink");
       
   695     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), 
       
   696                                   pref->no_check_symlink_content);
       
   697 
       
   698     /* Special file type */
       
   699     w = g_object_get_data (G_OBJECT (dialog), "special");
       
   700     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), 
       
   701                                   pref->special == 0 ? FALSE : TRUE);
       
   702 
       
   703     w = g_object_get_data (G_OBJECT (dialog), "compress");
       
   704 
       
   705     gtk_widget_set_sensitive (w, pref->special == 0 ? FALSE : TRUE);
       
   706     if ((pref->special & SPECIAL_COMPRESS) != 0) {
       
   707         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), TRUE);
       
   708     }else{
       
   709         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), FALSE);
       
   710     }
       
   711 
       
   712     /* Use log or not */
       
   713     w = g_object_get_data (G_OBJECT (dialog), "use_log");
       
   714     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), pref->use_log);
       
   715 
       
   716     w = g_object_get_data (G_OBJECT (dialog), "log_file");
       
   717 
       
   718     if (pref->log_file != NULL) {
       
   719         gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (w), pref->log_file);
       
   720     }
       
   721 
       
   722     /* Use log or not */
       
   723     if (pref->use_log) {
       
   724         gtk_widget_set_sensitive (w, TRUE);
       
   725         gtk_widget_set_sensitive (
       
   726                 g_object_get_data (G_OBJECT (dialog), "label_log_file"),
       
   727                 TRUE);
       
   728     }else{
       
   729         gtk_widget_set_sensitive (w, FALSE);
       
   730         gtk_widget_set_sensitive (
       
   731                 g_object_get_data (G_OBJECT (dialog), "label_log_file"),
       
   732                 FALSE);
       
   733     }
       
   734 
       
   735     w = g_object_get_data (G_OBJECT (dialog), "spinbutton_hist_len");
       
   736     gtk_spin_button_set_value (GTK_SPIN_BUTTON (w), (gdouble)pref->hist_len);
       
   737 
       
   738     /* Init encoding list from FSEXAM_setting->pref->encoding_list */
       
   739     w  = g_object_get_data (G_OBJECT (dialog), "treeview_encoding_list");
       
   740     set_encodings_treeview_model (GTK_TREE_VIEW (w), pref->encode_name_list);
       
   741    
       
   742     gtk_dialog_run (GTK_DIALOG (dialog));
       
   743 
       
   744     return;
       
   745 }
       
   746 
       
   747 /*
       
   748  *  Return a new list containing encoding names.
       
   749  *  Need free it when no one use it any more.
       
   750  */
       
   751 GSList *
       
   752 fsexam_prefdialog_get_encoding_list (GtkWidget *window)
       
   753 {
       
   754     GtkWidget       *treeview = NULL;
       
   755     GtkTreeModel    *treemodel = NULL;
       
   756     GSList          *result = NULL;
       
   757 
       
   758     treeview  = g_object_get_data (G_OBJECT (window), "treeview_encoding_list");
       
   759     treemodel = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
       
   760 
       
   761     gtk_tree_model_foreach (treemodel, 
       
   762                             get_encoding_name_of_row, 
       
   763                             (gpointer) &result);
       
   764 
       
   765     result = g_slist_reverse (result);
       
   766     
       
   767     return result;
       
   768 }
       
   769 
       
   770 /*
       
   771  *  Update encoding treeview according to new encoding list
       
   772  */
       
   773 void
       
   774 fsexam_prefdialog_update_encoding_model (GtkWidget *window, 
       
   775                                          GSList *new_encoding_list)
       
   776 {
       
   777     GtkWidget       *treeview = NULL;
       
   778     GtkListStore    *store = NULL;
       
   779     GtkTreeIter     iter;
       
   780     GSList          *tmp = new_encoding_list;
       
   781 
       
   782     treeview = g_object_get_data (G_OBJECT (window), "treeview_encoding_list");
       
   783     store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (treeview)));
       
   784 
       
   785     gtk_list_store_clear (store);
       
   786 
       
   787     while (tmp != NULL) {
       
   788         gchar *name = tmp->data;
       
   789         short encoding_id = encoding2id (name);
       
   790 
       
   791         tmp = tmp->next;
       
   792 
       
   793         if (encoding_id == -1)
       
   794             continue;
       
   795 
       
   796         gtk_list_store_append (store, &iter);
       
   797         gtk_list_store_set (store, &iter,
       
   798                             COLUMN_ENCODING_NAME, name,
       
   799                             -1);
       
   800     }
       
   801 
       
   802     return;
       
   803 }