main.c 33.5 KB
Newer Older
1
/* $Id$ */
2 3
/*
 *  Copyright (c) 2008 Stephan Arts <stephan@xfce.org>
4
 *  Copyright (c) 2008 Jannis Pohlmann <jannis@xfce.org>
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

21
#ifdef HAVE_CONFIG_H
22
#include <config.h>
23
#endif
24

25 26 27 28 29
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
30 31
#endif

32
#include <glib.h>
33 34
#include <gtk/gtk.h>

35
#include <libxfce4ui/libxfce4ui.h>
36
#include <libxfce4util/libxfce4util.h>
37
#include <xfconf/xfconf.h>
38

Stephan Arts's avatar
Stephan Arts committed
39
#include "appearance-dialog_ui.h"
40
#include "images.h"
41

42 43 44 45 46 47
#define INCH_MM      25.4

/* Use a fallback DPI of 96 which should be ok-ish on most systems
 * and is only applied on rare occasions */
#define FALLBACK_DPI 96

48
/* Increase this number if new gtk settings have been added */
49 50
#define INITIALIZE_UINT (1)

51 52
enum
{
53 54 55 56 57 58 59 60 61 62 63
    COLUMN_THEME_NAME,
    COLUMN_THEME_DISPLAY_NAME,
    COLUMN_THEME_COMMENT,
    N_THEME_COLUMNS
};

enum
{
    COLUMN_RGBA_PIXBUF,
    COLUMN_RGBA_NAME,
    N_RGBA_COLUMNS
64 65
};

66
/* String arrays with the settings in combo boxes */
67 68 69 70
static const gchar* toolbar_styles_array[] =
{
    "icons", "text", "both", "both-horiz"
};
71

72 73 74 75
static const gchar* xft_hint_styles_array[] =
{
    "hintnone", "hintslight", "hintmedium", "hintfull"
};
76

77
static const gchar* xft_rgba_array[] =
78
{
79 80 81
    "none", "rgb", "bgr", "vrgb", "vbgr"
};

82
/* Option entries */
83
static GdkNativeWindow opt_socket_id = 0;
84 85 86
static gboolean opt_version = FALSE;
static GOptionEntry option_entries[] =
{
87
    { "socket-id", 's', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_INT, &opt_socket_id, N_("Settings manager socket"), N_("SOCKET ID") },
88
    { "version", 'v', 0, G_OPTION_ARG_NONE, &opt_version, N_("Version information"), NULL },
89 90 91
    { NULL }
};

92
/* Global xfconf channel */
93 94
static XfconfChannel *xsettings_channel;

95 96 97
static int
compute_xsettings_dpi (GtkWidget *widget)
{
98
    GdkScreen *screen;
99 100 101
    int width_mm, height_mm;
    int width, height;
    int dpi;
102 103 104 105

    screen = gtk_widget_get_screen (widget);
    width_mm = gdk_screen_get_width_mm (screen);
    height_mm = gdk_screen_get_height_mm (screen);
106
    dpi = FALLBACK_DPI;
107

108 109
    if (width_mm > 0 && height_mm > 0)
    {
110 111
        width = gdk_screen_get_width (screen);
        height = gdk_screen_get_height (screen);
112 113 114 115 116 117 118
        dpi = MIN (INCH_MM * width  / width_mm,
                   INCH_MM * height / height_mm);
    }

    return dpi;
}

119
static void
120
cb_theme_tree_selection_changed (GtkTreeSelection *selection,
Nick Schermer's avatar
Nick Schermer committed
121
                                 const gchar      *property)
122
{
123 124 125 126
    GtkTreeModel *model;
    gboolean      has_selection;
    gchar        *name;
    GtkTreeIter   iter;
127

128 129 130 131 132
    /* Get the selected list iter */
    has_selection = gtk_tree_selection_get_selected (selection, &model, &iter);
    if (G_LIKELY (has_selection))
    {
        /* Get the theme name */
133
        gtk_tree_model_get (model, &iter, COLUMN_THEME_NAME, &name, -1);
134

135
        /* Store the new theme */
Nick Schermer's avatar
Nick Schermer committed
136
        xfconf_channel_set_string (xsettings_channel, property, name);
137

138 139 140
        /* Cleanup */
        g_free (name);
    }
141 142
}

143
static void
144
cb_icon_theme_tree_selection_changed (GtkTreeSelection *selection)
145
{
146 147 148
    /* Set the new icon theme */
    cb_theme_tree_selection_changed (selection, "/Net/IconThemeName");
}
149

150 151 152 153 154
static void
cb_ui_theme_tree_selection_changed (GtkTreeSelection *selection)
{
    /* Set the new UI theme */
    cb_theme_tree_selection_changed (selection, "/Net/ThemeName");
155 156
}

157 158
static void
cb_toolbar_style_combo_changed (GtkComboBox *combo)
159
{
160 161
    gint active;

162
    /* Get active item, prevent number outside the array */
163 164
    active = CLAMP (gtk_combo_box_get_active (combo), 0, (gint) G_N_ELEMENTS (toolbar_styles_array));

165
    /* Save setting */
166
    xfconf_channel_set_string (xsettings_channel, "/Gtk/ToolbarStyle", toolbar_styles_array[active]);
167 168
}

169 170
static void
cb_antialias_check_button_toggled (GtkToggleButton *toggle)
171
{
172 173
    gint active;

174 175 176
    /* Don't allow an inconsistent button anymore */
    gtk_toggle_button_set_inconsistent (toggle, FALSE);

177
    /* Get active */
178 179
    active = gtk_toggle_button_get_active (toggle) ? 1 : 0;

180
    /* Save setting */
181
    xfconf_channel_set_int (xsettings_channel, "/Xft/Antialias", active);
182 183
}

184 185
static void
cb_hinting_style_combo_changed (GtkComboBox *combo)
186
{
187 188
    gint active;

189
    /* Get active item, prevent number outside the array */
190 191
    active = CLAMP (gtk_combo_box_get_active (combo), 0, (gint) G_N_ELEMENTS (xft_hint_styles_array));

192
    /* Save setting */
193
    xfconf_channel_set_string (xsettings_channel, "/Xft/HintStyle", xft_hint_styles_array[active]);
194 195
}

196 197
static void
cb_rgba_style_combo_changed (GtkComboBox *combo)
198
{
199 200
    gint active;

201
    /* Get active item, prevent number outside the array */
202 203
    active = CLAMP (gtk_combo_box_get_active (combo), 0, (gint) G_N_ELEMENTS (xft_rgba_array));

204
    /* Save setting */
205
    xfconf_channel_set_string (xsettings_channel, "/Xft/RGBA", xft_rgba_array[active]);
206 207
}

208
static void
209 210
cb_custom_dpi_check_button_toggled (GtkToggleButton *custom_dpi_toggle,
                                    GtkSpinButton   *custom_dpi_spin)
211
{
212 213 214
    gint dpi;

    if (gtk_toggle_button_get_active (custom_dpi_toggle))
215
    {
216 217 218 219 220 221 222 223
        /* Custom DPI is activated, so restore the last custom DPI we know about */
        dpi = xfconf_channel_get_int (xsettings_channel, "/Xfce/LastCustomDPI", -1);

        /* Unfortunately, we don't have a valid custom DPI value to use, so compute it */
        if (dpi <= 0)
            dpi = compute_xsettings_dpi (GTK_WIDGET (custom_dpi_toggle));

        /* Apply the computed custom DPI value */
224
        xfconf_channel_set_int (xsettings_channel, "/Xft/DPI", dpi);
225

226 227 228 229
        gtk_widget_set_sensitive (GTK_WIDGET (custom_dpi_spin), TRUE);
    }
    else
    {
230 231 232 233 234
        /* Custom DPI is deactivated, so remember the current value as the last custom DPI */
        dpi = gtk_spin_button_get_value_as_int (custom_dpi_spin);
        xfconf_channel_set_int (xsettings_channel, "/Xfce/LastCustomDPI", dpi);

        /* Tell xfsettingsd to compute the value itself */
235
        xfconf_channel_set_int (xsettings_channel, "/Xft/DPI", -1);
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251

        /* Make the spin button insensitive */
        gtk_widget_set_sensitive (GTK_WIDGET (custom_dpi_spin), FALSE);
    }
}

static void
cb_custom_dpi_spin_button_changed (GtkSpinButton   *custom_dpi_spin,
                                   GtkToggleButton *custom_dpi_toggle)
{
    gint dpi = gtk_spin_button_get_value_as_int (custom_dpi_spin);

    if (GTK_WIDGET_IS_SENSITIVE (custom_dpi_spin) && gtk_toggle_button_get_active (custom_dpi_toggle))
    {
        /* Custom DPI is turned on and the spin button has changed, so remember the value */
        xfconf_channel_set_int (xsettings_channel, "/Xfce/LastCustomDPI", dpi);
252
    }
253 254 255

    /* Tell xfsettingsd to apply the custom DPI value */
    xfconf_channel_set_int (xsettings_channel, "/Xft/DPI", dpi);
256 257
}

258
#ifdef ENABLE_SOUND_SETTINGS
259 260 261 262 263 264 265 266 267
static void
cb_enable_event_sounds_check_button_toggled (GtkToggleButton *toggle, GtkWidget *button)
{
    gboolean active;

    active = gtk_toggle_button_get_active (toggle);
    gtk_widget_set_sensitive (button, active);
    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), active);
}
268
#endif
269

270
static void
271 272
appearance_settings_load_icon_themes (GtkListStore *list_store,
                                      GtkTreeView  *tree_view)
273
{
274 275 276 277 278 279 280 281 282
    GDir         *dir;
    GtkTreePath  *tree_path;
    GtkTreeIter   iter;
    XfceRc       *index_file;
    const gchar  *file;
    gchar       **icon_theme_dirs;
    gchar        *index_filename;
    const gchar  *theme_name;
    const gchar  *theme_comment;
283
    gchar        *comment_escaped;
284 285
    gchar        *active_theme_name;
    gint          i;
286
    GSList       *check_list = NULL;
287 288

    /* Determine current theme */
289
    active_theme_name = xfconf_channel_get_string (xsettings_channel, "/Net/IconThemeName", "Rodent");
290 291

    /* Determine directories to look in for icon themes */
292
    xfce_resource_push_path (XFCE_RESOURCE_ICONS, DATADIR G_DIR_SEPARATOR_S "icons");
293 294 295 296 297
    icon_theme_dirs = xfce_resource_dirs (XFCE_RESOURCE_ICONS);
    xfce_resource_pop_path (XFCE_RESOURCE_ICONS);

    /* Iterate over all base directories */
    for (i = 0; icon_theme_dirs[i] != NULL; ++i)
298
    {
299 300
        /* Open directory handle */
        dir = g_dir_open (icon_theme_dirs[i], 0, NULL);
301

302 303 304
        /* Try next base directory if this one cannot be read */
        if (G_UNLIKELY (dir == NULL))
            continue;
305

306 307
        /* Iterate over filenames in the directory */
        while ((file = g_dir_read_name (dir)) != NULL)
308
        {
309 310
            /* Build filename for the index.theme of the current icon theme directory */
            index_filename = g_build_filename (icon_theme_dirs[i], file, "index.theme", NULL);
311

312 313
            /* Try to open the theme index file */
            index_file = xfce_rc_simple_open (index_filename, TRUE);
314

315
            if (index_file != NULL
316
                && g_slist_find_custom (check_list, file, (GCompareFunc) g_utf8_collate) == NULL)
317
            {
318
                /* Set the icon theme group */
319
                xfce_rc_set_group (index_file, "Icon Theme");
320

321 322 323
                /* Check if the icon theme is valid and visible to the user */
                if (G_LIKELY (xfce_rc_has_entry (index_file, "Directories")
                              && !xfce_rc_read_bool_entry (index_file, "Hidden", FALSE)))
324
                {
325 326 327
                    /* Insert the theme in the check list */
                    check_list = g_slist_prepend (check_list, g_strdup (file));

328 329 330
                    /* Get translated icon theme name and comment */
                    theme_name = xfce_rc_read_entry (index_file, "Name", file);
                    theme_comment = xfce_rc_read_entry (index_file, "Comment", NULL);
331

332 333 334
                    /* Escape the comment, since tooltips are markup, not text */
                    comment_escaped = theme_comment ? g_markup_escape_text (theme_comment, -1) : NULL;

335 336
                    /* Append icon theme to the list store */
                    gtk_list_store_append (list_store, &iter);
337
                    gtk_list_store_set (list_store, &iter,
338 339
                                        COLUMN_THEME_NAME, file,
                                        COLUMN_THEME_DISPLAY_NAME, theme_name,
340 341 342 343
                                        COLUMN_THEME_COMMENT, comment_escaped, -1);

                    /* Cleanup */
                    g_free (comment_escaped);
344 345

                    /* Check if this is the active theme, if so, select it */
346
                    if (G_UNLIKELY (g_utf8_collate (file, active_theme_name) == 0))
347
                    {
348 349
                        tree_path = gtk_tree_model_get_path (GTK_TREE_MODEL (list_store), &iter);
                        gtk_tree_selection_select_path (gtk_tree_view_get_selection (tree_view), tree_path);
350
                        gtk_tree_view_scroll_to_cell (tree_view, tree_path, NULL, TRUE, 0.5, 0);
351
                        gtk_tree_path_free (tree_path);
352 353 354
                    }
                }
            }
355

356 357 358
            /* Close theme index file */
            if (G_LIKELY (index_file))
                xfce_rc_close (index_file);
359

360 361
            /* Free theme index filename */
            g_free (index_filename);
362 363
        }

364 365
        /* Close directory handle */
        g_dir_close (dir);
366 367
    }

368 369
    /* Free active theme name */
    g_free (active_theme_name);
370

371 372
    /* Free list of base directories */
    g_strfreev (icon_theme_dirs);
373

374 375 376 377 378 379
    /* Free the check list */
    if (G_LIKELY (check_list))
    {
        g_slist_foreach (check_list, (GFunc) g_free, NULL);
        g_slist_free (check_list);
    }
380 381
}

382
static void
383 384
appearance_settings_load_ui_themes (GtkListStore *list_store,
                                    GtkTreeView  *tree_view)
385
{
386 387 388 389 390 391 392 393 394 395 396
    GDir         *dir;
    GtkTreePath  *tree_path;
    GtkTreeIter   iter;
    XfceRc       *index_file;
    const gchar  *file;
    gchar       **ui_theme_dirs;
    gchar        *index_filename;
    const gchar  *theme_name;
    const gchar  *theme_comment;
    gchar        *active_theme_name;
    gchar        *gtkrc_filename;
397
    gchar        *comment_escaped;
398 399
    gint          i;
    GSList       *check_list = NULL;
400

401 402
    /* Determine current theme */
    active_theme_name = xfconf_channel_get_string (xsettings_channel, "/Net/ThemeName", "Default");
403

404 405 406 407
    /* Determine directories to look in for ui themes */
    xfce_resource_push_path (XFCE_RESOURCE_THEMES, DATADIR G_DIR_SEPARATOR_S "themes");
    ui_theme_dirs = xfce_resource_dirs (XFCE_RESOURCE_THEMES);
    xfce_resource_pop_path (XFCE_RESOURCE_THEMES);
408

409 410
    /* Iterate over all base directories */
    for (i = 0; ui_theme_dirs[i] != NULL; ++i)
411
    {
412 413
        /* Open directory handle */
        dir = g_dir_open (ui_theme_dirs[i], 0, NULL);
414

415 416 417 418 419 420
        /* Try next base directory if this one cannot be read */
        if (G_UNLIKELY (dir == NULL))
            continue;

        /* Iterate over filenames in the directory */
        while ((file = g_dir_read_name (dir)) != NULL)
421
        {
422 423
            /* Build the theme style filename */
            gtkrc_filename = g_build_filename (ui_theme_dirs[i], file, "gtk-2.0", "gtkrc", NULL);
424

425 426
            /* Check if the gtkrc file exists and the theme is not already in the list */
            if (g_file_test (gtkrc_filename, G_FILE_TEST_EXISTS)
427
                && g_slist_find_custom (check_list, file, (GCompareFunc) g_utf8_collate) == NULL)
428 429 430
            {
                /* Insert the theme in the check list */
                check_list = g_slist_prepend (check_list, g_strdup (file));
431

432 433
                /* Build filename for the index.theme of the current ui theme directory */
                index_filename = g_build_filename (ui_theme_dirs[i], file, "index.theme", NULL);
434

435 436
                /* Try to open the theme index file */
                index_file = xfce_rc_simple_open (index_filename, TRUE);
437

438 439 440 441 442
                if (G_LIKELY (index_file != NULL))
                {
                    /* Get translated ui theme name and comment */
                    theme_name = xfce_rc_read_entry (index_file, "Name", file);
                    theme_comment = xfce_rc_read_entry (index_file, "Comment", NULL);
443

444 445
                    /* Escape the comment because tooltips are markup, not text */
                    comment_escaped = theme_comment ? g_markup_escape_text (theme_comment, -1) : NULL;
446

447 448 449 450 451 452 453
                    /* Close theme index file */
                    xfce_rc_close (index_file);
                }
                else
                {
                    /* Set defaults */
                    theme_name = file;
454
                    comment_escaped = NULL;
455
                }
456

457 458
                /* Append ui theme to the list store */
                gtk_list_store_append (list_store, &iter);
459
                gtk_list_store_set (list_store, &iter,
460 461
                                    COLUMN_THEME_NAME, file,
                                    COLUMN_THEME_DISPLAY_NAME, theme_name,
462
                                    COLUMN_THEME_COMMENT, comment_escaped, -1);
463

464 465
                /* Cleanup */
                g_free (comment_escaped);
466 467

                /* Check if this is the active theme, if so, select it */
468
                if (G_UNLIKELY (g_utf8_collate (file, active_theme_name) == 0))
469 470 471
                {
                    tree_path = gtk_tree_model_get_path (GTK_TREE_MODEL (list_store), &iter);
                    gtk_tree_selection_select_path (gtk_tree_view_get_selection (tree_view), tree_path);
472
                    gtk_tree_view_scroll_to_cell (tree_view, tree_path, NULL, TRUE, 0.5, 0);
473 474 475 476 477 478
                    gtk_tree_path_free (tree_path);
                }

                /* Free theme index filename */
                g_free (index_filename);
            }
479

480 481
            /* Free gtkrc filename */
            g_free (gtkrc_filename);
482 483
        }

484 485
        /* Close directory handle */
        g_dir_close (dir);
486 487
    }

488 489
    /* Free active theme name */
    g_free (active_theme_name);
490

491 492
    /* Free list of base directories */
    g_strfreev (ui_theme_dirs);
493

494 495 496 497 498 499
    /* Free the check list */
    if (G_LIKELY (check_list))
    {
        g_slist_foreach (check_list, (GFunc) g_free, NULL);
        g_slist_free (check_list);
    }
500 501
}

502 503 504 505
static void
appearance_settings_dialog_channel_property_changed (XfconfChannel *channel,
                                                     const gchar   *property_name,
                                                     const GValue  *value,
506
                                                     GtkBuilder    *builder)
507
{
508
    GObject      *object;
509 510
    gchar        *str;
    guint         i;
511
    gint          antialias, dpi, custom_dpi;
512 513 514
    GtkTreeModel *model;

    g_return_if_fail (property_name != NULL);
515
    g_return_if_fail (GTK_IS_BUILDER (builder));
516 517 518 519 520 521 522 523

    if (strcmp (property_name, "/Xft/RGBA") == 0)
    {
        str = xfconf_channel_get_string (xsettings_channel, property_name, xft_rgba_array[0]);
        for (i = 0; i < G_N_ELEMENTS (xft_rgba_array); i++)
        {
            if (strcmp (str, xft_rgba_array[i]) == 0)
            {
524 525
                object = gtk_builder_get_object (builder, "xft_rgba_combo_box");
                gtk_combo_box_set_active (GTK_COMBO_BOX (object), i);
526 527 528 529 530 531 532 533 534 535 536 537
                break;
            }
        }
        g_free (str);
    }
    else if (strcmp (property_name, "/Gtk/ToolbarStyle") == 0)
    {
        str = xfconf_channel_get_string (xsettings_channel, property_name, toolbar_styles_array[2]);
        for (i = 0; i < G_N_ELEMENTS (toolbar_styles_array); i++)
        {
            if (strcmp (str, toolbar_styles_array[i]) == 0)
            {
538 539
                object = gtk_builder_get_object (builder, "gtk_toolbar_style_combo_box");
                gtk_combo_box_set_active (GTK_COMBO_BOX (object), i);
540 541 542 543 544 545 546 547 548 549 550 551
                break;
            }
        }
        g_free (str);
    }
    else if (strcmp (property_name, "/Xft/HintStyle") == 0)
    {
        str = xfconf_channel_get_string (xsettings_channel, property_name, xft_hint_styles_array[0]);
        for (i = 0; i < G_N_ELEMENTS (xft_hint_styles_array); i++)
        {
            if (strcmp (str, xft_hint_styles_array[i]) == 0)
            {
552 553
                object = gtk_builder_get_object (builder, "xft_hinting_style_combo_box");
                gtk_combo_box_set_active (GTK_COMBO_BOX (object), i);
554 555 556 557 558 559 560
                break;
            }
        }
        g_free (str);
    }
    else if (strcmp (property_name, "/Xft/Antialias") == 0)
    {
561
        object = gtk_builder_get_object (builder, "xft_antialias_check_button");
562 563 564 565
        antialias = xfconf_channel_get_int (xsettings_channel, property_name, -1);
        switch (antialias)
        {
            case 1:
566
                gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (object), TRUE);
567 568 569
                break;

            case 0:
570
                gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (object), FALSE);
571 572 573
                break;

            default: /* -1 */
574
                gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (object), TRUE);
575 576 577 578 579
                break;
        }
    }
    else if (strcmp (property_name, "/Xft/DPI") == 0)
    {
580
        /* The DPI has changed, so get its value and the last known custom value */
581 582 583
        dpi = xfconf_channel_get_int (xsettings_channel, property_name, FALLBACK_DPI);
        custom_dpi = xfconf_channel_get_int (xsettings_channel, "/Xfce/LastCustomDPI", -1);

584
        /* Activate the check button if we're using a custom DPI */
585 586
        object = gtk_builder_get_object (builder, "xft_custom_dpi_check_button");
        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (object), dpi >= 0);
587 588 589

        /* If we're not using a custom DPI, compute the future custom DPI automatically */
        if (custom_dpi == -1)
590
            custom_dpi = compute_xsettings_dpi (GTK_WIDGET (object));
591

592
        object = gtk_builder_get_object (builder, "xft_custom_dpi_spin_button");
593 594

        if (dpi > 0)
595
        {
596
            /* We're using a custom DPI, so use the current DPI setting for the spin value */
597
            gtk_spin_button_set_value (GTK_SPIN_BUTTON (object), dpi);
598 599 600
        }
        else
        {
601
            /* Set the spin button value to the last custom DPI */
602
            gtk_spin_button_set_value (GTK_SPIN_BUTTON (object), custom_dpi);
603 604 605 606
        }
    }
    else if (strcmp (property_name, "/Net/ThemeName") == 0)
    {
607 608 609
        GtkTreeIter iter;
        gboolean    reload;

610 611
        object = gtk_builder_get_object (builder, "gtk_theme_treeview");
        model = gtk_tree_view_get_model (GTK_TREE_VIEW (object));
612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635
        reload = TRUE;

        if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (object)),
                                             &model,
                                             &iter))
        {
            gchar *selected_name;
            gchar *new_name;

            gtk_tree_model_get (model, &iter, COLUMN_THEME_NAME, &selected_name, -1);

            new_name = xfconf_channel_get_string (channel, property_name, NULL);

            reload = (strcmp (new_name, selected_name) != 0);

            g_free (selected_name);
            g_free (new_name);
        }

        if (reload)
        {
            gtk_list_store_clear (GTK_LIST_STORE (model));
            appearance_settings_load_ui_themes (GTK_LIST_STORE (model), GTK_TREE_VIEW (object));
        }
636 637 638
    }
    else if (strcmp (property_name, "/Net/IconThemeName") == 0)
    {
639 640 641 642 643
        GtkTreeIter iter;
        gboolean    reload;

        reload = TRUE;

644 645
        object = gtk_builder_get_object (builder, "icon_theme_treeview");
        model = gtk_tree_view_get_model (GTK_TREE_VIEW (object));
646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669

        if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (object)),
                                             &model,
                                             &iter))
        {
            gchar *selected_name;
            gchar *new_name;

            gtk_tree_model_get (model, &iter, COLUMN_THEME_NAME, &selected_name, -1);

            new_name = xfconf_channel_get_string (channel, property_name, NULL);

            reload = (strcmp (new_name, selected_name) != 0);

            g_free (selected_name);
            g_free (new_name);
        }


        if (reload)
        {
            gtk_list_store_clear (GTK_LIST_STORE (model));
            appearance_settings_load_icon_themes (GTK_LIST_STORE (model), GTK_TREE_VIEW (object));
        }
670 671 672
    }
}

673
static void
674
appearance_settings_dialog_configure_widgets (GtkBuilder *builder)
675
{
676
    GObject          *object, *object2;
677 678
    GtkListStore     *list_store;
    GtkCellRenderer  *renderer;
679
    GdkPixbuf        *pixbuf;
680
    GtkTreeSelection *selection;
681

682
    /* Icon themes list */
683
    object = gtk_builder_get_object (builder, "icon_theme_treeview");
684

685 686
    list_store = gtk_list_store_new (N_THEME_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
    gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (list_store), COLUMN_THEME_DISPLAY_NAME, GTK_SORT_ASCENDING);
687 688
    gtk_tree_view_set_model (GTK_TREE_VIEW (object), GTK_TREE_MODEL (list_store));
    gtk_tree_view_set_tooltip_column (GTK_TREE_VIEW (object), COLUMN_THEME_COMMENT);
689 690

    renderer = gtk_cell_renderer_text_new ();
691
    gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (object), 0, "", renderer, "text", COLUMN_THEME_DISPLAY_NAME, NULL);
692

693
    appearance_settings_load_icon_themes (list_store, GTK_TREE_VIEW (object));
694 695 696

    g_object_unref (G_OBJECT (list_store));

697 698 699
    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (object));
    gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
    g_signal_connect (G_OBJECT (selection), "changed", G_CALLBACK (cb_icon_theme_tree_selection_changed), NULL);
700

701
    /* Gtk (UI) themes */
702
    object = gtk_builder_get_object (builder, "gtk_theme_treeview");
703

704 705
    list_store = gtk_list_store_new (N_THEME_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
    gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (list_store), COLUMN_THEME_DISPLAY_NAME, GTK_SORT_ASCENDING);
706 707
    gtk_tree_view_set_model (GTK_TREE_VIEW (object), GTK_TREE_MODEL (list_store));
    gtk_tree_view_set_tooltip_column (GTK_TREE_VIEW (object), COLUMN_THEME_COMMENT);
708 709

    renderer = gtk_cell_renderer_text_new();
710
    gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (object), 0, "", renderer, "text", COLUMN_THEME_DISPLAY_NAME, NULL);
711

712
    appearance_settings_load_ui_themes (list_store, GTK_TREE_VIEW (object));
713 714 715

    g_object_unref (G_OBJECT (list_store));

716 717 718
    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (object));
    gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
    g_signal_connect (G_OBJECT (selection), "changed", G_CALLBACK (cb_ui_theme_tree_selection_changed), NULL);
719 720

    /* Subpixel (rgba) hinting Combo */
721
    object = gtk_builder_get_object (builder, "xft_rgba_store");
722

723
    pixbuf = gdk_pixbuf_new_from_xpm_data (rgba_image_none_xpm);
724
    gtk_list_store_insert_with_values (GTK_LIST_STORE (object), NULL, 0, 0, pixbuf, 1, _("None"), -1);
725 726 727
    g_object_unref (G_OBJECT (pixbuf));

    pixbuf = gdk_pixbuf_new_from_xpm_data (rgba_image_rgb_xpm);
728
    gtk_list_store_insert_with_values (GTK_LIST_STORE (object), NULL, 1, 0, pixbuf, 1, _("RGB"), -1);
729 730 731
    g_object_unref (G_OBJECT (pixbuf));

    pixbuf = gdk_pixbuf_new_from_xpm_data (rgba_image_bgr_xpm);
732
    gtk_list_store_insert_with_values (GTK_LIST_STORE (object), NULL, 2, 0, pixbuf, 1, _("BGR"), -1);
733 734 735
    g_object_unref (G_OBJECT (pixbuf));

    pixbuf = gdk_pixbuf_new_from_xpm_data (rgba_image_vrgb_xpm);
736
    gtk_list_store_insert_with_values (GTK_LIST_STORE (object), NULL, 3, 0, pixbuf, 1, _("Vertical RGB"), -1);
737 738 739
    g_object_unref (G_OBJECT (pixbuf));

    pixbuf = gdk_pixbuf_new_from_xpm_data (rgba_image_vbgr_xpm);
740
    gtk_list_store_insert_with_values (GTK_LIST_STORE (object), NULL, 4, 0, pixbuf, 1, _("Vertical BGR"), -1);
741 742
    g_object_unref (G_OBJECT (pixbuf));

743 744 745
    object = gtk_builder_get_object (builder, "xft_rgba_combo_box");
    appearance_settings_dialog_channel_property_changed (xsettings_channel, "/Xft/RGBA", NULL, builder);
    g_signal_connect (G_OBJECT (object), "changed", G_CALLBACK (cb_rgba_style_combo_changed), NULL);
746 747

    /* Enable editable menu accelerators */
748
    object = gtk_builder_get_object (builder, "gtk_caneditaccels_check_button");
749
    xfconf_g_property_bind (xsettings_channel, "/Gtk/CanChangeAccels", G_TYPE_BOOLEAN,
750
                            G_OBJECT (object), "active");
751 752

    /* Show menu images */
753
    object = gtk_builder_get_object (builder, "gtk_menu_images_check_button");
754
    xfconf_g_property_bind (xsettings_channel, "/Gtk/MenuImages", G_TYPE_BOOLEAN,
755
                            G_OBJECT (object), "active");
756 757

    /* Show button images */
758
    object = gtk_builder_get_object (builder, "gtk_button_images_check_button");
759
    xfconf_g_property_bind (xsettings_channel, "/Gtk/ButtonImages", G_TYPE_BOOLEAN,
760
                            G_OBJECT (object), "active");
761 762

    /* Font name */
763
    object = gtk_builder_get_object (builder, "gtk_fontname_button");
764
    xfconf_g_property_bind (xsettings_channel,  "/Gtk/FontName", G_TYPE_STRING,
765
                            G_OBJECT (object), "font-name");
766 767

    /* Toolbar style */
768 769 770
    object = gtk_builder_get_object (builder, "gtk_toolbar_style_combo_box");
    appearance_settings_dialog_channel_property_changed (xsettings_channel, "/Gtk/ToolbarStyle", NULL, builder);
    g_signal_connect (G_OBJECT (object), "changed", G_CALLBACK(cb_toolbar_style_combo_changed), NULL);
771

772
    /* Hinting style */
773 774 775
    object = gtk_builder_get_object (builder, "xft_hinting_style_combo_box");
    appearance_settings_dialog_channel_property_changed (xsettings_channel, "/Xft/HintStyle", NULL, builder);
    g_signal_connect (G_OBJECT (object), "changed", G_CALLBACK (cb_hinting_style_combo_changed), NULL);
776 777

    /* Hinting */
778 779 780
    object = gtk_builder_get_object (builder, "xft_antialias_check_button");
    appearance_settings_dialog_channel_property_changed (xsettings_channel, "/Xft/Antialias", NULL, builder);
    g_signal_connect (G_OBJECT (object), "toggled", G_CALLBACK (cb_antialias_check_button_toggled), NULL);
781 782

    /* DPI */
783 784 785 786 787
    object = gtk_builder_get_object (builder, "xft_custom_dpi_check_button");
    object2 = gtk_builder_get_object (builder, "xft_custom_dpi_spin_button");
    appearance_settings_dialog_channel_property_changed (xsettings_channel, "/Xft/DPI", NULL, builder);
    g_signal_connect (G_OBJECT (object), "toggled", G_CALLBACK (cb_custom_dpi_check_button_toggled), object2);
    g_signal_connect (G_OBJECT (object2), "value-changed", G_CALLBACK (cb_custom_dpi_spin_button_changed), object);
788 789 790

#ifdef ENABLE_SOUND_SETTINGS
    /* Sounds */
791 792 793 794 795 796 797 798 799
    object = gtk_builder_get_object (builder, "event_sounds_frame");
    gtk_widget_show (GTK_WIDGET (object));

    object = gtk_builder_get_object (builder, "enable_event_sounds_check_button");
    object2  = gtk_builder_get_object (builder, "enable_input_feedback_sounds_button");

    g_signal_connect (G_OBJECT (object), "toggled",
                      G_CALLBACK (cb_enable_event_sounds_check_button_toggled), object2);

800
    xfconf_g_property_bind (xsettings_channel, "/Net/EnableEventSounds", G_TYPE_BOOLEAN,
801
                            G_OBJECT (object), "active");
802
    xfconf_g_property_bind (xsettings_channel, "/Net/EnableInputFeedbackSounds", G_TYPE_BOOLEAN,
803 804 805
                            G_OBJECT (object2), "active");

    gtk_widget_set_sensitive (GTK_WIDGET (object), gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (object2)));
806
#endif
807 808
}

809 810
gint
main(gint argc, gchar **argv)
811
{
812 813 814 815
    GObject    *dialog, *plug_child;
    GtkWidget  *plug;
    GtkBuilder *builder;
    GError     *error = NULL;
816

817 818
    /* setup translation domain */
    xfce_textdomain (GETTEXT_PACKAGE, LOCALEDIR, "UTF-8");
819

820 821
    /* initialize Gtk+ */
    if (!gtk_init_with_args (&argc, &argv, "", option_entries, GETTEXT_PACKAGE, &error))
822
    {
823
        if (G_LIKELY (error))
824
        {
825
            /* print error */
826 827
            g_print ("%s: %s.\n", G_LOG_DOMAIN, error->message);
            g_print (_("Type '%s --help' for usage."), G_LOG_DOMAIN);
828
            g_print ("\n");
829 830 831

            /* cleanup */
            g_error_free (error);
832
        }
833 834 835 836
        else
        {
            g_error ("Unable to open display.");
        }
837 838

        return EXIT_FAILURE;
839 840
    }

841 842
    /* print version information */
    if (G_UNLIKELY (opt_version))
843
    {
844
        g_print ("%s %s (Xfce %s)\n\n", G_LOG_DOMAIN, PACKAGE_VERSION, xfce_version_string ());
Nick Schermer's avatar
Nick Schermer committed
845
        g_print ("%s\n", "Copyright (c) 2008-2010");
846 847 848 849 850
        g_print ("\t%s\n\n", _("The Xfce development team. All rights reserved."));
        g_print (_("Please report bugs to <%s>."), PACKAGE_BUGREPORT);
        g_print ("\n");

        return EXIT_SUCCESS;
851 852
    }

853
    /* initialize xfconf */
854 855 856 857 858 859 860 861
    if (!xfconf_init (&error))
    {
        /* print error and exit */
        g_error ("Failed to connect to xfconf daemon: %s.", error->message);
        g_error_free (error);

        return EXIT_FAILURE;
    }
862

863 864 865 866
    /* open the xsettings channel */
    xsettings_channel = xfconf_channel_new ("xsettings");
    if (G_LIKELY (xsettings_channel))
    {
867 868 869 870
        /* hook to make sure the libxfce4ui library is linked */
        if (xfce_titled_dialog_get_type () == 0)
            return EXIT_FAILURE;

Stephan Arts's avatar
Stephan Arts committed
871
        /* load the gtk user interface file*/
872
        builder = gtk_builder_new ();
Stephan Arts's avatar
Stephan Arts committed
873 874
        if (gtk_builder_add_from_string (builder, appearance_dialog_ui,
                                         appearance_dialog_ui_length, &error) != 0)
875
          {
876
            /* connect signal to monitor the channel */
877 878
            g_signal_connect (G_OBJECT (xsettings_channel), "property-changed",