main.c 33.6 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
                }
                else
                {
                    /* Set defaults */
                    theme_name = file;
451
                    comment_escaped = NULL;
452
                }
453

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

461
                /* Cleanup */
462
463
                if (G_LIKELY (index_file != NULL))
                    xfce_rc_close (index_file);
464
                g_free (comment_escaped);
465
466

                /* Check if this is the active theme, if so, select it */
467
                if (G_UNLIKELY (g_utf8_collate (file, active_theme_name) == 0))
468
469
470
                {
                    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);
471
                    gtk_tree_view_scroll_to_cell (tree_view, tree_path, NULL, TRUE, 0.5, 0);
472
473
474
475
476
477
                    gtk_tree_path_free (tree_path);
                }

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

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

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

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

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

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

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

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

    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)
            {
523
524
                object = gtk_builder_get_object (builder, "xft_rgba_combo_box");
                gtk_combo_box_set_active (GTK_COMBO_BOX (object), i);
525
526
527
528
529
530
531
532
533
534
535
536
                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)
            {
537
538
                object = gtk_builder_get_object (builder, "gtk_toolbar_style_combo_box");
                gtk_combo_box_set_active (GTK_COMBO_BOX (object), i);
539
540
541
542
543
544
545
546
547
548
549
550
                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)
            {
551
552
                object = gtk_builder_get_object (builder, "xft_hinting_style_combo_box");
                gtk_combo_box_set_active (GTK_COMBO_BOX (object), i);
553
554
555
556
557
558
559
                break;
            }
        }
        g_free (str);
    }
    else if (strcmp (property_name, "/Xft/Antialias") == 0)
    {
560
        object = gtk_builder_get_object (builder, "xft_antialias_check_button");
561
562
563
564
        antialias = xfconf_channel_get_int (xsettings_channel, property_name, -1);
        switch (antialias)
        {
            case 1:
565
                gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (object), TRUE);
566
567
568
                break;

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

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

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

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

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

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

609
610
        object = gtk_builder_get_object (builder, "gtk_theme_treeview");
        model = gtk_tree_view_get_model (GTK_TREE_VIEW (object));
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
        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));
        }
635
636
637
    }
    else if (strcmp (property_name, "/Net/IconThemeName") == 0)
    {
638
639
640
641
642
        GtkTreeIter iter;
        gboolean    reload;

        reload = TRUE;

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

        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));
        }
669
670
671
    }
}

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

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

684
685
    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);
686
687
    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);
688
689

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

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

    g_object_unref (G_OBJECT (list_store));

696
697
698
    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);
699

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

703
704
    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);
705
706
    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);
707
708

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

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

    g_object_unref (G_OBJECT (list_store));

715
716
717
    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);
718
719

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

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

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

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

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

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

742
743
744
    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);
745
746

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

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

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

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

    /* Toolbar style */
767
768
769
    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);
770

771
    /* Hinting style */
772
773
774
    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);
775
776

    /* Hinting */
777
778
779
    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);
780
781

    /* DPI */
782
783
784
    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);
785
    gtk_widget_set_sensitive (GTK_WIDGET (object2), gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (object)));
786
787
    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
                            G_OBJECT (object2), "active");

805
    gtk_widget_set_sensitive (GTK_WIDGET (object2), gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (object)));
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-2011");
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",
                G_CALLBACK (appearance_settings_dialog_channel_property_changed), builder);
879

880
            appearance_settings_dialog_configure_widgets (builder);
881

882
883
884
            if (G_UNLIKELY (opt_socket_id == 0))
            {
                /* build the dialog */
885
                dialog = gtk_builder_get_object (builder, "dialog");
886

887
                gtk_widget_show (GTK_WIDGET (dialog));
888
                g_signal_connect (dialog, "response", G_CALLBACK (gtk_main_quit), NULL);
889
890
891
892
893
894
895

                /* To prevent the settings dialog to be saved in the session */
                gdk_set_sm_client_id ("FAKE ID");

                gtk_main ();

                gtk_widget_destroy (GTK_WIDGET (dialog));
896
897
898
899
900
            }
            else
            {
                /* Create plug widget */
                plug = gtk_plug_new (opt_socket_id);
901
                g_signal_connect (plug, "delete-event", G_CALLBACK (gtk_main_quit), NULL);
902
                gtk_widget_show (plug);