nautilus-preferences-window.c 17.8 KB
Newer Older
1
/* nautilus-preferences-window.c - Functions to create and show the nautilus
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
 *  preference window.
 *
 *  Copyright (C) 2002 Jan Arne Petersen
 *  Copyright (C) 2016 Carlos Soriano <csoriano@gnome.com>
 *
 *  The Gnome Library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Library General Public License as
 *  published by the Free Software Foundation; either version 2 of the
 *  License, or (at your option) any later version.
 *
 *  The Gnome Library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Library General Public License for more details.
 *
 *  You should have received a copy of the GNU Library General Public
 *  License along with the Gnome Library; see the file COPYING.LIB.  If not,
 *  see <http://www.gnu.org/licenses/>.
 *
 *  Authors: Jan Arne Petersen <jpetersen@uni-bonn.de>
 */
23 24 25

#include <config.h>

26
#include "nautilus-preferences-window.h"
27 28 29 30 31 32 33 34 35 36

#include <string.h>
#include <time.h>
#include <gtk/gtk.h>
#include <gio/gio.h>

#include <glib/gi18n.h>

#include <eel/eel-glib-extensions.h>

37 38
#include <nautilus-extension.h>

39 40 41 42
#include "nautilus-column-chooser.h"
#include "nautilus-column-utilities.h"
#include "nautilus-global-preferences.h"
#include "nautilus-module.h"
43 44 45 46

/* string enum preferences */
#define NAUTILUS_PREFERENCES_DIALOG_DEFAULT_VIEW_WIDGET "default_view_combobox"
#define NAUTILUS_PREFERENCES_DIALOG_PREVIEW_FILES_WIDGET                       \
47
    "preview_image_combobox"
48
#define NAUTILUS_PREFERENCES_DIALOG_PREVIEW_FOLDER_WIDGET                      \
49
    "preview_folder_combobox"
50 51 52

/* bool preferences */
#define NAUTILUS_PREFERENCES_DIALOG_FOLDERS_FIRST_WIDGET                       \
53
    "sort_folders_first_checkbutton"
54
#define NAUTILUS_PREFERENCES_DIALOG_DELETE_PERMANENTLY_WIDGET                  \
55
    "show_delete_permanently_checkbutton"
56
#define NAUTILUS_PREFERENCES_DIALOG_CREATE_LINK_WIDGET                         \
57
    "show_create_link_checkbutton"
58
#define NAUTILUS_PREFERENCES_DIALOG_LIST_VIEW_USE_TREE_WIDGET                  \
59
    "use_tree_view_checkbutton"
60
#define NAUTILUS_PREFERENCES_DIALOG_TRASH_CONFIRM_WIDGET                       \
61
    "trash_confirm_checkbutton"
62
#define NAUTILUS_PREFERENCES_DIALOG_USE_NEW_VIEWS_WIDGET                       \
63
    "use_new_views_checkbutton"
64 65 66

/* int enums */
#define NAUTILUS_PREFERENCES_DIALOG_THUMBNAIL_LIMIT_WIDGET                     \
67
    "preview_image_size_spinbutton"
68

69 70 71 72 73
static const char * const speed_tradeoff_values[] =
{
    "local-only", "always", "never",
    NULL
};
74

75 76 77 78
static const char * const click_behavior_components[] =
{
    "single_click_radiobutton", "double_click_radiobutton", NULL
};
79

80
static const char * const click_behavior_values[] = {"single", "double", NULL};
81

82 83 84 85 86 87 88 89 90 91 92 93
static const char * const executable_text_components[] =
{
    "scripts_execute_radiobutton", "scripts_view_radiobutton",
    "scripts_confirm_radiobutton", NULL
};

static const char * const executable_text_values[] =
{
    "launch", "display", "ask",
    NULL
};

94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
static const char * const recursive_search_components[] =
{
    "search_recursive_only_this_computer_radiobutton", "search_recursive_all_locations_radiobutton", "search_recursive_never_radiobutton", NULL
};

static const char * const thumbnails_components[] =
{
    "thumbnails_only_this_computer_radiobutton", "thumbnails_all_files_radiobutton", "thumbnails_never_radiobutton", NULL
};

static const char * const count_components[] =
{
    "count_only_this_computer_radiobutton", "count_all_files_radiobutton", "count_never_radiobutton", NULL
};

static const char * const icon_captions_components[] =
{
    "captions_0_combobox", "captions_1_combobox", "captions_2_combobox", NULL
};
113

114
static GtkWidget *preferences_window = NULL;
115 116

static void columns_changed_callback(NautilusColumnChooser *chooser,
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
                                     gpointer               callback_data)
{
    char **visible_columns;
    char **column_order;

    nautilus_column_chooser_get_settings (NAUTILUS_COLUMN_CHOOSER (chooser),
                                          &visible_columns, &column_order);

    g_settings_set_strv (nautilus_list_view_preferences,
                         NAUTILUS_PREFERENCES_LIST_VIEW_DEFAULT_VISIBLE_COLUMNS,
                         (const char * const *) visible_columns);
    g_settings_set_strv (nautilus_list_view_preferences,
                         NAUTILUS_PREFERENCES_LIST_VIEW_DEFAULT_COLUMN_ORDER,
                         (const char * const *) column_order);

    g_strfreev (visible_columns);
    g_strfreev (column_order);
134 135
}

136 137 138 139
static void free_column_names_array(GPtrArray *column_names)
{
    g_ptr_array_foreach (column_names, (GFunc) g_free, NULL);
    g_ptr_array_free (column_names, TRUE);
140 141 142
}

static void create_icon_caption_combo_box_items(GtkComboBoxText *combo_box,
143 144 145 146
                                                GList           *columns)
{
    GList *l;
    GPtrArray *column_names;
147

148
    column_names = g_ptr_array_new ();
149

150 151 152
    /* Translators: this is referred to captions under icons. */
    gtk_combo_box_text_append_text (combo_box, _("None"));
    g_ptr_array_add (column_names, g_strdup ("none"));
153

154 155 156 157 158
    for (l = columns; l != NULL; l = l->next)
    {
        NautilusColumn *column;
        char *name;
        char *label;
159

160
        column = NAUTILUS_COLUMN (l->data);
161

162
        g_object_get (G_OBJECT (column), "name", &name, "label", &label, NULL);
163

164 165 166 167 168 169 170
        /* Don't show name here, it doesn't make sense */
        if (!strcmp (name, "name"))
        {
            g_free (name);
            g_free (label);
            continue;
        }
171

172 173
        gtk_combo_box_text_append_text (combo_box, label);
        g_ptr_array_add (column_names, name);
174

175 176 177 178
        g_free (label);
    }
    g_object_set_data_full (G_OBJECT (combo_box), "column_names", column_names,
                            (GDestroyNotify) free_column_names_array);
179 180
}

181
static void icon_captions_changed_callback(GtkComboBox *widget,
182 183 184 185 186
                                           gpointer     user_data)
{
    GPtrArray *captions;
    GtkBuilder *builder;
    int i;
187

188
    builder = GTK_BUILDER (user_data);
189

190
    captions = g_ptr_array_new ();
191

192 193 194 195 196 197
    for (i = 0; icon_captions_components[i] != NULL; i++)
    {
        GtkWidget *combo_box;
        int active;
        GPtrArray *column_names;
        char *name;
198

199 200 201
        combo_box = GTK_WIDGET (
            gtk_builder_get_object (builder, icon_captions_components[i]));
        active = gtk_combo_box_get_active (GTK_COMBO_BOX (combo_box));
202

203
        column_names = g_object_get_data (G_OBJECT (combo_box), "column_names");
204

205 206 207 208
        name = g_ptr_array_index (column_names, active);
        g_ptr_array_add (captions, name);
    }
    g_ptr_array_add (captions, NULL);
209

210 211 212 213
    g_settings_set_strv (nautilus_icon_view_preferences,
                         NAUTILUS_PREFERENCES_ICON_VIEW_CAPTIONS,
                         (const char **) captions->pdata);
    g_ptr_array_free (captions, TRUE);
214 215 216 217
}

static void update_caption_combo_box(GtkBuilder *builder,
                                     const char *combo_box_name,
218 219 220 221 222
                                     const char *name)
{
    GtkWidget *combo_box;
    int i;
    GPtrArray *column_names;
223

224
    combo_box = GTK_WIDGET (gtk_builder_get_object (builder, combo_box_name));
225

226 227
    g_signal_handlers_block_by_func (
        combo_box, G_CALLBACK (icon_captions_changed_callback), builder);
228

229
    column_names = g_object_get_data (G_OBJECT (combo_box), "column_names");
230

231 232 233 234 235 236 237
    for (i = 0; i < column_names->len; ++i)
    {
        if (!strcmp (name, g_ptr_array_index (column_names, i)))
        {
            gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), i);
            break;
        }
238 239
    }

240 241
    g_signal_handlers_unblock_by_func (
        combo_box, G_CALLBACK (icon_captions_changed_callback), builder);
242 243
}

244 245 246 247
static void update_icon_captions_from_settings(GtkBuilder *builder)
{
    char **captions;
    int i, j;
248

249 250 251 252 253
    captions = g_settings_get_strv (nautilus_icon_view_preferences,
                                    NAUTILUS_PREFERENCES_ICON_VIEW_CAPTIONS);
    if (captions == NULL)
    {
        return;
254 255
    }

256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271
    for (i = 0, j = 0; icon_captions_components[i] != NULL; i++)
    {
        char *data;

        if (captions[j])
        {
            data = captions[j];
            ++j;
        }
        else
        {
            data = "none";
        }

        update_caption_combo_box (builder, icon_captions_components[i], data);
    }
272

273
    g_strfreev (captions);
274 275 276
}

static void
277 278 279 280 281
nautilus_preferences_window_setup_icon_caption_page (GtkBuilder *builder)
{
    GList *columns;
    int i;
    gboolean writable;
282

283 284
    writable = g_settings_is_writable (nautilus_icon_view_preferences,
                                       NAUTILUS_PREFERENCES_ICON_VIEW_CAPTIONS);
285

286
    columns = nautilus_get_common_columns ();
287

288 289 290
    for (i = 0; icon_captions_components[i] != NULL; i++)
    {
        GtkWidget *combo_box;
291

292 293
        combo_box = GTK_WIDGET (
            gtk_builder_get_object (builder, icon_captions_components[i]));
294

295 296
        create_icon_caption_combo_box_items (GTK_COMBO_BOX_TEXT (combo_box), columns);
        gtk_widget_set_sensitive (combo_box, writable);
297

298 299 300 301
        g_signal_connect_data (
            combo_box, "changed", G_CALLBACK (icon_captions_changed_callback),
            g_object_ref (builder), (GClosureNotify) g_object_unref, 0);
    }
302

303
    nautilus_column_list_free (columns);
304

305
    update_icon_captions_from_settings (builder);
306 307
}

308 309 310 311
static void set_columns_from_settings(NautilusColumnChooser *chooser)
{
    char **visible_columns;
    char **column_order;
312

313 314 315 316 317 318
    visible_columns = g_settings_get_strv (
        nautilus_list_view_preferences,
        NAUTILUS_PREFERENCES_LIST_VIEW_DEFAULT_VISIBLE_COLUMNS);
    column_order =
        g_settings_get_strv (nautilus_list_view_preferences,
                             NAUTILUS_PREFERENCES_LIST_VIEW_DEFAULT_COLUMN_ORDER);
319

320 321
    nautilus_column_chooser_set_settings (NAUTILUS_COLUMN_CHOOSER (chooser),
                                          visible_columns, column_order);
322

323 324
    g_strfreev (visible_columns);
    g_strfreev (column_order);
325 326 327
}

static void use_default_callback(NautilusColumnChooser *chooser,
328 329 330 331 332 333 334
                                 gpointer               user_data)
{
    g_settings_reset (nautilus_list_view_preferences,
                      NAUTILUS_PREFERENCES_LIST_VIEW_DEFAULT_VISIBLE_COLUMNS);
    g_settings_reset (nautilus_list_view_preferences,
                      NAUTILUS_PREFERENCES_LIST_VIEW_DEFAULT_COLUMN_ORDER);
    set_columns_from_settings (chooser);
335 336 337
}

static void
338 339 340 341
nautilus_preferences_window_setup_list_column_page (GtkBuilder *builder)
{
    GtkWidget *chooser;
    GtkWidget *box;
342

343 344 345 346 347
    chooser = nautilus_column_chooser_new (NULL);
    g_signal_connect (chooser, "changed", G_CALLBACK (columns_changed_callback),
                      chooser);
    g_signal_connect (chooser, "use-default", G_CALLBACK (use_default_callback),
                      chooser);
348

349
    set_columns_from_settings (NAUTILUS_COLUMN_CHOOSER (chooser));
350

351 352
    gtk_widget_show (chooser);
    box = GTK_WIDGET (gtk_builder_get_object (builder, "list_columns_vbox"));
353

354
    gtk_box_pack_start (GTK_BOX (box), chooser, TRUE, TRUE, 0);
355 356
}

357 358 359
static gboolean
format_spin_button (GtkSpinButton *spin_button,
                    gpointer       user_data)
360
{
361
    gint value;
362 363
    gchar *text;

364 365
    value = gtk_spin_button_get_value_as_int (spin_button);
    text = g_strdup_printf (_("%d MB"), value);
366 367 368
    gtk_entry_set_text (GTK_ENTRY (spin_button), text);

    return TRUE;
369 370
}

371
static void nautilus_preferences_window_setup_thumbnail_limit_formatting (GtkBuilder *builder)
372
{
373
    GtkSpinButton *spin;
374

375
    spin = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "preview_image_size_spinbutton"));
376

377 378
    g_signal_connect (spin, "output", G_CALLBACK (format_spin_button),
                      spin);
379 380
}

381 382 383 384
static void bind_builder_bool(GtkBuilder *builder,
                              GSettings  *settings,
                              const char *widget_name,
                              const char *prefs)
385
{
386 387
    g_settings_bind (settings, prefs, gtk_builder_get_object (builder, widget_name),
                     "active", G_SETTINGS_BIND_DEFAULT);
388 389
}

390 391 392 393
static void bind_builder_uint_spin(GtkBuilder *builder,
                                   GSettings  *settings,
                                   const char *widget_name,
                                   const char *prefs)
394
{
395 396
    g_settings_bind (settings, prefs, gtk_builder_get_object (builder, widget_name),
                     "value", G_SETTINGS_BIND_DEFAULT);
397 398
}

399
static GVariant *radio_mapping_set(const GValue       *gvalue,
400
                                   const GVariantType *expected_type,
401 402 403 404 405 406 407 408 409
                                   gpointer            user_data)
{
    const gchar *widget_value = user_data;
    GVariant *retval = NULL;

    if (g_value_get_boolean (gvalue))
    {
        retval = g_variant_new_string (widget_value);
    }
410

411
    return retval;
412 413
}

414 415 416 417 418 419
static gboolean radio_mapping_get(GValue   *gvalue,
                                  GVariant *variant,
                                  gpointer  user_data)
{
    const gchar *widget_value = user_data;
    const gchar *value;
420

421
    value = g_variant_get_string (variant, NULL);
422

423 424 425 426 427 428 429 430
    if (g_strcmp0 (value, widget_value) == 0)
    {
        g_value_set_boolean (gvalue, TRUE);
    }
    else
    {
        g_value_set_boolean (gvalue, FALSE);
    }
431

432
    return TRUE;
433 434
}

435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451
static void bind_builder_radio(GtkBuilder  *builder,
                               GSettings   *settings,
                               const char **widget_names,
                               const char  *prefs,
                               const char **values)
{
    GtkWidget *button;
    int i;

    for (i = 0; widget_names[i] != NULL; i++)
    {
        button = GTK_WIDGET (gtk_builder_get_object (builder, widget_names[i]));

        g_settings_bind_with_mapping (settings, prefs, button, "active",
                                      G_SETTINGS_BIND_DEFAULT, radio_mapping_get,
                                      radio_mapping_set, (gpointer) values[i], NULL);
    }
452 453
}

454
static void nautilus_preferences_window_setup(GtkBuilder *builder,
455 456 457 458 459
                                              GtkWindow  *parent_window)
{
    GtkWidget *window;

    /* setup preferences */
460
    bind_builder_bool (builder, gtk_filechooser_preferences,
461 462 463 464 465 466 467 468 469 470 471 472 473 474
                       NAUTILUS_PREFERENCES_DIALOG_FOLDERS_FIRST_WIDGET,
                       NAUTILUS_PREFERENCES_SORT_DIRECTORIES_FIRST);
    bind_builder_bool (builder, nautilus_preferences,
                       NAUTILUS_PREFERENCES_DIALOG_TRASH_CONFIRM_WIDGET,
                       NAUTILUS_PREFERENCES_CONFIRM_TRASH);
    bind_builder_bool (builder, nautilus_list_view_preferences,
                       NAUTILUS_PREFERENCES_DIALOG_LIST_VIEW_USE_TREE_WIDGET,
                       NAUTILUS_PREFERENCES_LIST_VIEW_USE_TREE);
    bind_builder_bool (builder, nautilus_preferences,
                       NAUTILUS_PREFERENCES_DIALOG_CREATE_LINK_WIDGET,
                       NAUTILUS_PREFERENCES_SHOW_CREATE_LINK);
    bind_builder_bool (builder, nautilus_preferences,
                       NAUTILUS_PREFERENCES_DIALOG_DELETE_PERMANENTLY_WIDGET,
                       NAUTILUS_PREFERENCES_SHOW_DELETE_PERMANENTLY);
475 476 477
    bind_builder_bool (builder, nautilus_preferences,
                       NAUTILUS_PREFERENCES_DIALOG_USE_NEW_VIEWS_WIDGET,
                       NAUTILUS_PREFERENCES_USE_EXPERIMENTAL_VIEWS);
478 479 480 481

    bind_builder_radio (
        builder, nautilus_preferences, (const char **) click_behavior_components,
        NAUTILUS_PREFERENCES_CLICK_POLICY, (const char **) click_behavior_values);
482 483 484 485
    bind_builder_radio (builder, nautilus_preferences,
                        (const char **) executable_text_components,
                        NAUTILUS_PREFERENCES_EXECUTABLE_TEXT_ACTIVATION,
                        (const char **) executable_text_values);
486 487 488 489 490 491 492 493 494 495 496 497 498
    bind_builder_radio (builder, nautilus_preferences,
                        (const char **) recursive_search_components,
                        NAUTILUS_PREFERENCES_RECURSIVE_SEARCH,
                        (const char **) speed_tradeoff_values);
    bind_builder_radio (builder, nautilus_preferences,
                        (const char **) thumbnails_components,
                        NAUTILUS_PREFERENCES_SHOW_FILE_THUMBNAILS,
                        (const char **) speed_tradeoff_values);
    bind_builder_radio (builder, nautilus_preferences,
                        (const char **) count_components,
                        NAUTILUS_PREFERENCES_SHOW_DIRECTORY_ITEM_COUNTS,
                        (const char **) speed_tradeoff_values);

499
    bind_builder_uint_spin (builder, nautilus_preferences,
500
                            NAUTILUS_PREFERENCES_DIALOG_THUMBNAIL_LIMIT_WIDGET,
501
                            NAUTILUS_PREFERENCES_FILE_THUMBNAIL_LIMIT);
502

503
    nautilus_preferences_window_setup_thumbnail_limit_formatting (builder);
504 505 506 507 508 509 510
    nautilus_preferences_window_setup_icon_caption_page (builder);
    nautilus_preferences_window_setup_list_column_page (builder);

    /* UI callbacks */
    window = GTK_WIDGET (gtk_builder_get_object (builder, "preferences_window"));
    preferences_window = window;

511
    gtk_window_set_icon_name (GTK_WINDOW (preferences_window), APPLICATION_ID);
512 513 514 515 516 517

    g_object_add_weak_pointer (G_OBJECT (window), (gpointer *) &preferences_window);

    gtk_window_set_transient_for (GTK_WINDOW (preferences_window), parent_window);

    gtk_widget_show (preferences_window);
518 519
}

520 521 522
void nautilus_preferences_window_show(GtkWindow *window)
{
    GtkBuilder *builder;
523

524 525 526 527 528
    if (preferences_window != NULL)
    {
        gtk_window_present (GTK_WINDOW (preferences_window));
        return;
    }
529

530
    builder = gtk_builder_new ();
531

532 533
    gtk_builder_add_from_resource (
        builder, "/org/gnome/nautilus/ui/nautilus-preferences-window.ui", NULL);
534

535
    nautilus_preferences_window_setup (builder, window);
536

537
    g_object_unref (builder);
538
}