~ubuntu-branches/ubuntu/trusty/unity-control-center/trusty

« back to all changes in this revision

Viewing changes to panels/appearance/cc-appearance-panel.c

  • Committer: Package Import Robot
  • Author(s): Robert Ancell
  • Date: 2014-01-08 16:29:18 UTC
  • Revision ID: package-import@ubuntu.com-20140108162918-g29dd08tr913y2qh
Tags: upstream-14.04.0
ImportĀ upstreamĀ versionĀ 14.04.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2010 Intel, Inc
 
3
 *
 
4
 * This program is free software: you can redistribute it and/or modify
 
5
 * it under the terms of the GNU General Public License as published by
 
6
 * the Free Software Foundation, either version 2 of the License, or
 
7
 * (at your option) any later version.
 
8
 * 
 
9
 * This program is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 * GNU General Public License for more details.
 
13
 * 
 
14
 * You should have received a copy of the GNU General Public License
 
15
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
16
 * 
 
17
 * Author: Thomas Wood <thomas.wood@intel.com>
 
18
 *
 
19
 */
 
20
 
 
21
#include <config.h>
 
22
 
 
23
#include <string.h>
 
24
#include <glib/gi18n-lib.h>
 
25
#include <gdesktop-enums.h>
 
26
 
 
27
#include "cc-appearance-panel.h"
 
28
#include "bg-wallpapers-source.h"
 
29
#include "bg-pictures-source.h"
 
30
#include "bg-colors-source.h"
 
31
 
 
32
#ifdef HAVE_LIBSOCIALWEB
 
33
#include "bg-flickr-source.h"
 
34
#endif
 
35
 
 
36
#include "cc-appearance-item.h"
 
37
#include "cc-appearance-xml.h"
 
38
 
 
39
#define WP_PATH_ID "org.gnome.desktop.background"
 
40
#define WP_URI_KEY "picture-uri"
 
41
#define WP_OPTIONS_KEY "picture-options"
 
42
#define WP_SHADING_KEY "color-shading-type"
 
43
#define WP_PCOLOR_KEY "primary-color"
 
44
#define WP_SCOLOR_KEY "secondary-color"
 
45
 
 
46
enum {
 
47
  COL_SOURCE_NAME,
 
48
  COL_SOURCE_TYPE,
 
49
  COL_SOURCE,
 
50
  NUM_COLS
 
51
};
 
52
 
 
53
G_DEFINE_DYNAMIC_TYPE (CcAppearancePanel, cc_appearance_panel, CC_TYPE_PANEL)
 
54
 
 
55
#define APPEARANCE_PANEL_PRIVATE(o) \
 
56
  (G_TYPE_INSTANCE_GET_PRIVATE ((o), CC_TYPE_APPEARANCE_PANEL, CcAppearancePanelPrivate))
 
57
 
 
58
struct _CcAppearancePanelPrivate
 
59
{
 
60
  GtkBuilder *builder;
 
61
 
 
62
  BgWallpapersSource *wallpapers_source;
 
63
  BgPicturesSource *pictures_source;
 
64
  BgColorsSource *colors_source;
 
65
 
 
66
#ifdef HAVE_LIBSOCIALWEB
 
67
  BgFlickrSource *flickr_source;
 
68
#endif
 
69
 
 
70
  GSettings *settings;
 
71
  GSettings *interface_settings;
 
72
  GSettings *canonical_interface_settings;
 
73
  GSettings *wm_theme_settings;
 
74
  GSettings *unity_settings;
 
75
  GSettings *compizcore_settings;
 
76
  GSettings *unity_own_settings;
 
77
 
 
78
  GnomeDesktopThumbnailFactory *thumb_factory;
 
79
 
 
80
  CcAppearanceItem *current_background;
 
81
  gint current_source;
 
82
 
 
83
  GCancellable *copy_cancellable;
 
84
 
 
85
  GtkWidget *spinner;
 
86
 
 
87
  GdkPixbuf *display_base;
 
88
  GdkPixbuf *display_overlay;
 
89
};
 
90
 
 
91
enum
 
92
{
 
93
  SOURCE_WALLPAPERS,
 
94
  SOURCE_PICTURES,
 
95
  SOURCE_COLORS,
 
96
#ifdef HAVE_LIBSOCIALWEB
 
97
  SOURCE_FLICKR
 
98
#endif
 
99
};
 
100
 
 
101
#define UNITY_GSETTINGS_SCHEMA "org.compiz.unityshell"
 
102
#define UNITY_PROFILE_PATH "/org/compiz/profiles/unity/plugins/"
 
103
#define UNITY_GSETTINGS_PATH UNITY_PROFILE_PATH"unityshell/"
 
104
#define UNITY_ICONSIZE_KEY "icon-size"
 
105
#define UNITY_LAUNCHERSENSITIVITY_KEY "edge-responsiveness"
 
106
#define UNITY_LAUNCHERHIDE_KEY "launcher-hide-mode"
 
107
#define UNITY_LAUNCHERREVEAL_KEY "reveal-trigger"
 
108
#define CANONICAL_DESKTOP_INTERFACE "com.canonical.desktop.interface"
 
109
 
 
110
#define COMPIZCORE_GSETTINGS_SCHEMA "org.compiz.core"
 
111
#define COMPIZCORE_GSETTINGS_PATH UNITY_PROFILE_PATH"core/"
 
112
#define COMPIZCORE_HSIZE_KEY "hsize"
 
113
#define COMPIZCORE_VSIZE_KEY "vsize"
 
114
 
 
115
#define UNITY_OWN_GSETTINGS_SCHEMA "com.canonical.Unity.Launcher"
 
116
#define UNITY_FAVORITES_KEY "favorites"
 
117
#define SHOW_DESKTOP_UNITY_FAVORITE_STR "unity://desktop-icon"
 
118
 
 
119
#define MIN_ICONSIZE 32.0
 
120
#define MAX_ICONSIZE 64.0
 
121
 
 
122
#define MIN_LAUNCHER_SENSIVITY 0.2
 
123
#define MAX_LAUNCHER_SENSIVITY 8.0
 
124
 
 
125
typedef struct
 
126
{
 
127
  gdouble min;
 
128
  gdouble max;
 
129
} MinMax;
 
130
static MinMax iconsize_values;
 
131
static MinMax launchersensitivity_values;
 
132
 
 
133
#define WID(y) (GtkWidget *) gtk_builder_get_object (priv->builder, y)
 
134
 
 
135
static void
 
136
cc_appearance_panel_get_property (GObject    *object,
 
137
                                  guint       property_id,
 
138
                                  GValue     *value,
 
139
                                  GParamSpec *pspec)
 
140
{
 
141
  switch (property_id)
 
142
    {
 
143
    default:
 
144
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 
145
    }
 
146
}
 
147
 
 
148
static void
 
149
cc_appearance_panel_set_property (GObject      *object,
 
150
                                  guint         property_id,
 
151
                                  const GValue *value,
 
152
                                  GParamSpec   *pspec)
 
153
{
 
154
  switch (property_id)
 
155
    {
 
156
    default:
 
157
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 
158
    }
 
159
}
 
160
 
 
161
static void
 
162
cc_appearance_panel_dispose (GObject *object)
 
163
{
 
164
  CcAppearancePanelPrivate *priv = CC_APPEARANCE_PANEL (object)->priv;
 
165
 
 
166
  if (priv->builder)
 
167
    {
 
168
      g_object_unref (priv->builder);
 
169
      priv->builder = NULL;
 
170
 
 
171
      /* destroying the builder object will also destroy the spinner */
 
172
      priv->spinner = NULL;
 
173
    }
 
174
 
 
175
  if (priv->wallpapers_source)
 
176
    {
 
177
      g_object_unref (priv->wallpapers_source);
 
178
      priv->wallpapers_source = NULL;
 
179
    }
 
180
 
 
181
  if (priv->pictures_source)
 
182
    {
 
183
      g_object_unref (priv->pictures_source);
 
184
      priv->pictures_source = NULL;
 
185
    }
 
186
 
 
187
  if (priv->colors_source)
 
188
    {
 
189
      g_object_unref (priv->colors_source);
 
190
      priv->colors_source = NULL;
 
191
    }
 
192
#ifdef HAVE_LIBSOCIALWEB
 
193
  if (priv->flickr_source)
 
194
    {
 
195
      g_object_unref (priv->flickr_source);
 
196
      priv->flickr_source = NULL;
 
197
    }
 
198
#endif
 
199
 
 
200
  if (priv->settings)
 
201
    {
 
202
      g_object_unref (priv->settings);
 
203
      priv->settings = NULL;
 
204
    }
 
205
 
 
206
  if (priv->interface_settings)
 
207
    {
 
208
      g_object_unref (priv->interface_settings);
 
209
      priv->interface_settings = NULL;
 
210
    }
 
211
 
 
212
  if (priv->canonical_interface_settings)
 
213
    {
 
214
      g_object_unref (priv->canonical_interface_settings);
 
215
      priv->canonical_interface_settings = NULL;
 
216
    }
 
217
 
 
218
  if (priv->wm_theme_settings)
 
219
    {
 
220
      g_object_unref (priv->wm_theme_settings);
 
221
      priv->wm_theme_settings = NULL;
 
222
    }
 
223
 
 
224
  if (priv->unity_settings)
 
225
    {
 
226
      g_object_unref (priv->unity_settings);
 
227
      priv->unity_settings = NULL;
 
228
    }
 
229
 
 
230
  if (priv->compizcore_settings)
 
231
    {
 
232
      g_object_unref (priv->compizcore_settings);
 
233
      priv->compizcore_settings = NULL;
 
234
    }
 
235
 
 
236
  if (priv->unity_own_settings)
 
237
    {
 
238
      g_object_unref (priv->unity_own_settings);
 
239
      priv->unity_own_settings = NULL;
 
240
    }
 
241
 
 
242
  if (priv->copy_cancellable)
 
243
    {
 
244
      /* cancel any copy operation */
 
245
      g_cancellable_cancel (priv->copy_cancellable);
 
246
 
 
247
      g_object_unref (priv->copy_cancellable);
 
248
      priv->copy_cancellable = NULL;
 
249
    }
 
250
 
 
251
  if (priv->thumb_factory)
 
252
    {
 
253
      g_object_unref (priv->thumb_factory);
 
254
      priv->thumb_factory = NULL;
 
255
    }
 
256
 
 
257
  if (priv->display_base)
 
258
    {
 
259
      g_object_unref (priv->display_base);
 
260
      priv->display_base = NULL;
 
261
    }
 
262
 
 
263
  if (priv->display_overlay)
 
264
    {
 
265
      g_object_unref (priv->display_overlay);
 
266
      priv->display_overlay = NULL;
 
267
    }
 
268
 
 
269
  G_OBJECT_CLASS (cc_appearance_panel_parent_class)->dispose (object);
 
270
}
 
271
 
 
272
static void
 
273
cc_appearance_panel_finalize (GObject *object)
 
274
{
 
275
  CcAppearancePanelPrivate *priv = CC_APPEARANCE_PANEL (object)->priv;
 
276
 
 
277
  if (priv->current_background)
 
278
    {
 
279
      g_object_unref (priv->current_background);
 
280
      priv->current_background = NULL;
 
281
    }
 
282
 
 
283
  G_OBJECT_CLASS (cc_appearance_panel_parent_class)->finalize (object);
 
284
}
 
285
 
 
286
static void
 
287
cc_appearance_panel_class_init (CcAppearancePanelClass *klass)
 
288
{
 
289
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
290
 
 
291
  g_type_class_add_private (klass, sizeof (CcAppearancePanelPrivate));
 
292
 
 
293
  object_class->get_property = cc_appearance_panel_get_property;
 
294
  object_class->set_property = cc_appearance_panel_set_property;
 
295
  object_class->dispose = cc_appearance_panel_dispose;
 
296
  object_class->finalize = cc_appearance_panel_finalize;
 
297
}
 
298
 
 
299
static void
 
300
cc_appearance_panel_class_finalize (CcAppearancePanelClass *klass)
 
301
{
 
302
}
 
303
 
 
304
static void
 
305
source_update_edit_box (CcAppearancePanelPrivate *priv,
 
306
                        gboolean                  initial)
 
307
{
 
308
  CcAppearanceItemFlags flags;
 
309
 
 
310
  flags = cc_appearance_item_get_flags (priv->current_background);
 
311
 
 
312
  if ((flags & CC_APPEARANCE_ITEM_HAS_SCOLOR &&
 
313
       priv->current_source != SOURCE_COLORS) ||
 
314
      cc_appearance_item_get_shading (priv->current_background) == G_DESKTOP_BACKGROUND_SHADING_SOLID)
 
315
    gtk_widget_hide (WID ("style-scolor"));
 
316
  else
 
317
    gtk_widget_show (WID ("style-scolor"));
 
318
 
 
319
  if (flags & CC_APPEARANCE_ITEM_HAS_PCOLOR &&
 
320
      priv->current_source != SOURCE_COLORS)
 
321
    gtk_widget_hide (WID ("style-pcolor"));
 
322
  else
 
323
    gtk_widget_show (WID ("style-pcolor"));
 
324
 
 
325
  if (gtk_widget_get_visible (WID ("style-pcolor")) &&
 
326
      gtk_widget_get_visible (WID ("style-scolor")))
 
327
    gtk_widget_show (WID ("swap-color-button"));
 
328
  else
 
329
    gtk_widget_hide (WID ("swap-color-button"));
 
330
 
 
331
  if (flags & CC_APPEARANCE_ITEM_HAS_PLACEMENT ||
 
332
      cc_appearance_item_get_uri (priv->current_background) == NULL)
 
333
    gtk_widget_hide (WID ("style-combobox"));
 
334
  else
 
335
    gtk_widget_show (WID ("style-combobox"));
 
336
 
 
337
  /* FIXME What to do if the background has a gradient shading
 
338
   * and provides the colours? */
 
339
}
 
340
 
 
341
static void
 
342
source_changed_cb (GtkComboBox              *combo,
 
343
                   CcAppearancePanelPrivate *priv)
 
344
{
 
345
  GtkTreeIter iter;
 
346
  GtkTreeModel *model;
 
347
  GtkIconView *view;
 
348
  guint type;
 
349
  BgSource *source;
 
350
 
 
351
  gtk_combo_box_get_active_iter (combo, &iter);
 
352
  model = gtk_combo_box_get_model (combo);
 
353
  gtk_tree_model_get (model, &iter,
 
354
                      COL_SOURCE_TYPE, &type,
 
355
                      COL_SOURCE, &source, -1);
 
356
 
 
357
  view = (GtkIconView *) gtk_builder_get_object (priv->builder,
 
358
                                                 "backgrounds-iconview");
 
359
 
 
360
  gtk_icon_view_set_model (view,
 
361
                           GTK_TREE_MODEL (bg_source_get_liststore (source)));
 
362
}
 
363
 
 
364
static void
 
365
select_style (GtkComboBox *box,
 
366
              GDesktopBackgroundStyle new_style)
 
367
{
 
368
  GtkTreeModel *model;
 
369
  GtkTreeIter iter;
 
370
  gboolean cont;
 
371
 
 
372
  model = gtk_combo_box_get_model (box);
 
373
  cont = gtk_tree_model_get_iter_first (model, &iter);
 
374
  while (cont != FALSE)
 
375
    {
 
376
      GDesktopBackgroundStyle style;
 
377
 
 
378
      gtk_tree_model_get (model, &iter,
 
379
                          1, &style,
 
380
                          -1);
 
381
 
 
382
      if (style == new_style)
 
383
        {
 
384
          gtk_combo_box_set_active_iter (box, &iter);
 
385
          break;
 
386
        }
 
387
      cont = gtk_tree_model_iter_next (model, &iter);
 
388
    }
 
389
 
 
390
  if (cont == FALSE)
 
391
    gtk_combo_box_set_active (box, -1);
 
392
}
 
393
 
 
394
static void
 
395
update_preview (CcAppearancePanelPrivate *priv,
 
396
                CcAppearanceItem         *item)
 
397
{
 
398
  gchar *markup;
 
399
  gboolean changes_with_time;
 
400
 
 
401
  if (item && priv->current_background)
 
402
    {
 
403
      g_object_unref (priv->current_background);
 
404
      priv->current_background = cc_appearance_item_copy (item);
 
405
      cc_appearance_item_load (priv->current_background, NULL);
 
406
    }
 
407
 
 
408
  source_update_edit_box (priv, FALSE);
 
409
 
 
410
  changes_with_time = FALSE;
 
411
 
 
412
  if (priv->current_background)
 
413
    {
 
414
      GdkColor pcolor, scolor;
 
415
      const char* bgsize = NULL;
 
416
 
 
417
      markup = g_strdup_printf ("<i>%s</i>", cc_appearance_item_get_name (priv->current_background));
 
418
      gtk_label_set_markup (GTK_LABEL (WID ("background-label")), markup);
 
419
      g_free (markup);
 
420
 
 
421
      bgsize = cc_appearance_item_get_size (priv->current_background);
 
422
      if (bgsize && *bgsize != '\0')
 
423
       {
 
424
          markup = g_strdup_printf ("(%s)", bgsize);
 
425
          gtk_label_set_text (GTK_LABEL (WID ("size_label")), markup);
 
426
          g_free (markup);
 
427
       }
 
428
      else
 
429
          gtk_label_set_text (GTK_LABEL (WID ("size_label")), "");
 
430
 
 
431
      gdk_color_parse (cc_appearance_item_get_pcolor (priv->current_background), &pcolor);
 
432
      gdk_color_parse (cc_appearance_item_get_scolor (priv->current_background), &scolor);
 
433
 
 
434
      gtk_color_button_set_color (GTK_COLOR_BUTTON (WID ("style-pcolor")), &pcolor);
 
435
      gtk_color_button_set_color (GTK_COLOR_BUTTON (WID ("style-scolor")), &scolor);
 
436
 
 
437
      select_style (GTK_COMBO_BOX (WID ("style-combobox")),
 
438
                    cc_appearance_item_get_placement (priv->current_background));
 
439
 
 
440
      changes_with_time = cc_appearance_item_changes_with_time (priv->current_background);
 
441
    }
 
442
 
 
443
  gtk_widget_set_visible (WID ("slide_image"), changes_with_time);
 
444
  gtk_widget_set_visible (WID ("slide-label"), changes_with_time);
 
445
 
 
446
  gtk_widget_queue_draw (WID ("preview-area"));
 
447
}
 
448
 
 
449
static char *
 
450
get_save_path (void)
 
451
{
 
452
  return g_build_filename (g_get_user_config_dir (),
 
453
                           "gnome-control-center",
 
454
                           "backgrounds",
 
455
                           "last-edited.xml",
 
456
                           NULL);
 
457
}
 
458
 
 
459
static gboolean
 
460
create_save_dir (void)
 
461
{
 
462
  char *path;
 
463
 
 
464
  path = g_build_filename (g_get_user_config_dir (),
 
465
                           "gnome-control-center",
 
466
                           "backgrounds",
 
467
                           NULL);
 
468
  if (g_mkdir_with_parents (path, 0755) < 0)
 
469
    {
 
470
      g_warning ("Failed to create directory '%s'", path);
 
471
      g_free (path);
 
472
      return FALSE;
 
473
    }
 
474
  g_free (path);
 
475
  return TRUE;
 
476
}
 
477
 
 
478
static void
 
479
copy_finished_cb (GObject      *source_object,
 
480
                  GAsyncResult *result,
 
481
                  gpointer      pointer)
 
482
{
 
483
  GError *err = NULL;
 
484
  CcAppearancePanel *panel = (CcAppearancePanel *) pointer;
 
485
  CcAppearancePanelPrivate *priv = panel->priv;
 
486
  CcAppearanceItem *item;
 
487
 
 
488
  if (!g_file_copy_finish (G_FILE (source_object), result, &err))
 
489
    {
 
490
      if (err->code != G_IO_ERROR_CANCELLED)
 
491
        g_warning ("Failed to copy image to cache location: %s", err->message);
 
492
 
 
493
      g_error_free (err);
 
494
    }
 
495
  item = g_object_get_data (source_object, "item");
 
496
 
 
497
  /* the panel may have been destroyed before the callback is run, so be sure
 
498
   * to check the widgets are not NULL */
 
499
 
 
500
  if (priv->spinner)
 
501
    {
 
502
      gtk_widget_destroy (GTK_WIDGET (priv->spinner));
 
503
      priv->spinner = NULL;
 
504
    }
 
505
 
 
506
  if (priv->current_background)
 
507
    cc_appearance_item_load (priv->current_background, NULL);
 
508
 
 
509
  if (priv->builder)
 
510
    {
 
511
      char *filename;
 
512
 
 
513
      update_preview (priv, item);
 
514
 
 
515
      /* Save the source XML if there is one */
 
516
      filename = get_save_path ();
 
517
      if (create_save_dir ())
 
518
        cc_appearance_xml_save (priv->current_background, filename);
 
519
    }
 
520
 
 
521
  /* remove the reference taken when the copy was set up */
 
522
  g_object_unref (panel);
 
523
}
 
524
 
 
525
static void
 
526
update_remove_button (CcAppearancePanel *panel,
 
527
                      CcAppearanceItem  *item)
 
528
{
 
529
  CcAppearancePanelPrivate *priv;
 
530
  const char *uri;
 
531
  char *cache_path;
 
532
  GFile *bg, *cache, *parent;
 
533
  gboolean sensitive = FALSE;
 
534
 
 
535
  priv = panel->priv;
 
536
 
 
537
  if (priv->current_source != SOURCE_PICTURES)
 
538
    goto bail;
 
539
 
 
540
  uri = cc_appearance_item_get_uri (item);
 
541
  if (uri == NULL)
 
542
    goto bail;
 
543
 
 
544
  bg = g_file_new_for_uri (uri);
 
545
  parent = g_file_get_parent (bg);
 
546
  if (parent == NULL)
 
547
    {
 
548
      g_object_unref (bg);
 
549
      goto bail;
 
550
    }
 
551
  cache_path = bg_pictures_source_get_cache_path ();
 
552
  cache = g_file_new_for_path (cache_path);
 
553
  g_free (cache_path);
 
554
 
 
555
  if (g_file_equal (parent, cache))
 
556
    sensitive = TRUE;
 
557
 
 
558
  g_object_unref (parent);
 
559
  g_object_unref (cache);
 
560
 
 
561
bail:
 
562
  gtk_widget_set_sensitive (WID ("remove_button"), sensitive);
 
563
 
 
564
}
 
565
 
 
566
static CcAppearanceItem *
 
567
get_selected_item (CcAppearancePanel *panel)
 
568
{
 
569
  CcAppearancePanelPrivate *priv = panel->priv;
 
570
  GtkIconView *icon_view;
 
571
  GtkTreeIter iter;
 
572
  GtkTreeModel *model;
 
573
  GList *list;
 
574
  CcAppearanceItem *item;
 
575
 
 
576
  icon_view = GTK_ICON_VIEW (WID ("backgrounds-iconview"));
 
577
  item = NULL;
 
578
  list = gtk_icon_view_get_selected_items (icon_view);
 
579
 
 
580
  if (!list)
 
581
    return NULL;
 
582
 
 
583
  model = gtk_icon_view_get_model (icon_view);
 
584
 
 
585
  if (gtk_tree_model_get_iter (model, &iter, (GtkTreePath*) list->data) == FALSE)
 
586
    goto bail;
 
587
 
 
588
  gtk_tree_model_get (model, &iter, 1, &item, -1);
 
589
 
 
590
bail:
 
591
  g_list_foreach (list, (GFunc)gtk_tree_path_free, NULL);
 
592
  g_list_free (list);
 
593
 
 
594
  return item;
 
595
}
 
596
 
 
597
static void
 
598
backgrounds_changed_cb (GtkIconView       *icon_view,
 
599
                        CcAppearancePanel *panel)
 
600
{
 
601
  GtkTreeIter iter;
 
602
  GtkTreeModel *model;
 
603
  CcAppearanceItem *item;
 
604
  CcAppearancePanelPrivate *priv = panel->priv;
 
605
  char *pcolor, *scolor;
 
606
  gboolean draw_preview = TRUE;
 
607
  const char *uri;
 
608
  CcAppearanceItemFlags flags;
 
609
  char *filename;
 
610
 
 
611
  item = get_selected_item (panel);
 
612
 
 
613
  if (item == NULL)
 
614
    return;
 
615
 
 
616
  /* Update current source */
 
617
  model = gtk_combo_box_get_model (GTK_COMBO_BOX (WID ("sources-combobox")));
 
618
  gtk_combo_box_get_active_iter (GTK_COMBO_BOX (WID ("sources-combobox")),
 
619
                                 &iter);
 
620
  gtk_tree_model_get (model, &iter,
 
621
                      COL_SOURCE_TYPE, &priv->current_source, -1);
 
622
 
 
623
  uri = cc_appearance_item_get_uri (item);
 
624
  flags = cc_appearance_item_get_flags (item);
 
625
 
 
626
  if ((flags & CC_APPEARANCE_ITEM_HAS_URI) && uri == NULL)
 
627
    {
 
628
      g_settings_set_enum (priv->settings, WP_OPTIONS_KEY, G_DESKTOP_BACKGROUND_STYLE_NONE);
 
629
      g_settings_set_string (priv->settings, WP_URI_KEY, "");
 
630
    }
 
631
  else if (cc_appearance_item_get_source_url (item) != NULL &&
 
632
           cc_appearance_item_get_needs_download (item))
 
633
    {
 
634
      GFile *source, *dest;
 
635
      gchar *cache_path, *basename, *dest_path, *display_name, *dest_uri;
 
636
      GdkPixbuf *pixbuf;
 
637
 
 
638
      cache_path = bg_pictures_source_get_cache_path ();
 
639
      if (g_mkdir_with_parents (cache_path, 0755) < 0)
 
640
        {
 
641
          g_warning ("Failed to create directory '%s'", cache_path);
 
642
          g_free (cache_path);
 
643
          return;
 
644
        }
 
645
      g_free (cache_path);
 
646
 
 
647
      dest_path = bg_pictures_source_get_unique_path (cc_appearance_item_get_source_url (item));
 
648
      dest = g_file_new_for_path (dest_path);
 
649
      g_free (dest_path);
 
650
      source = g_file_new_for_uri (cc_appearance_item_get_source_url (item));
 
651
      basename = g_file_get_basename (source);
 
652
      display_name = g_filename_display_name (basename);
 
653
      dest_path = g_file_get_path (dest);
 
654
      g_free (basename);
 
655
 
 
656
      /* create a blank image to use until the source image is ready */
 
657
      pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, 1, 1);
 
658
      gdk_pixbuf_fill (pixbuf, 0x00000000);
 
659
      gdk_pixbuf_save (pixbuf, dest_path, "png", NULL, NULL);
 
660
      g_object_unref (pixbuf);
 
661
      g_free (dest_path);
 
662
 
 
663
      if (priv->copy_cancellable)
 
664
        {
 
665
          g_cancellable_cancel (priv->copy_cancellable);
 
666
          g_cancellable_reset (priv->copy_cancellable);
 
667
        }
 
668
 
 
669
      if (priv->spinner)
 
670
        {
 
671
          gtk_widget_destroy (GTK_WIDGET (priv->spinner));
 
672
          priv->spinner = NULL;
 
673
        }
 
674
 
 
675
      /* create a spinner while the file downloads */
 
676
      priv->spinner = gtk_spinner_new ();
 
677
      gtk_spinner_start (GTK_SPINNER (priv->spinner));
 
678
      gtk_box_pack_start (GTK_BOX (WID ("bottom-hbox")), priv->spinner, FALSE,
 
679
                          FALSE, 6);
 
680
      gtk_widget_show (priv->spinner);
 
681
 
 
682
      /* reference the panel in case it is removed before the copy is
 
683
       * finished */
 
684
      g_object_ref (panel);
 
685
      g_object_set_data_full (G_OBJECT (source), "item", g_object_ref (item), g_object_unref);
 
686
      g_file_copy_async (source, dest, G_FILE_COPY_OVERWRITE,
 
687
                         G_PRIORITY_DEFAULT, priv->copy_cancellable,
 
688
                         NULL, NULL,
 
689
                         copy_finished_cb, panel);
 
690
      g_object_unref (source);
 
691
      dest_uri = g_file_get_uri (dest);
 
692
      g_object_unref (dest);
 
693
 
 
694
      g_settings_set_string (priv->settings, WP_URI_KEY, dest_uri);
 
695
      g_object_set (G_OBJECT (item),
 
696
                    "uri", dest_uri,
 
697
                    "needs-download", FALSE,
 
698
                    "name", display_name,
 
699
                    NULL);
 
700
      g_free (display_name);
 
701
      g_free (dest_uri);
 
702
 
 
703
      /* delay the updated drawing of the preview until the copy finishes */
 
704
      draw_preview = FALSE;
 
705
    }
 
706
  else
 
707
    {
 
708
      g_settings_set_string (priv->settings, WP_URI_KEY, uri);
 
709
    }
 
710
 
 
711
  /* Also set the placement if we have a URI and the previous value was none */
 
712
  if (flags & CC_APPEARANCE_ITEM_HAS_PLACEMENT)
 
713
    {
 
714
      g_settings_set_enum (priv->settings, WP_OPTIONS_KEY, cc_appearance_item_get_placement (item));
 
715
    }
 
716
  else if (uri != NULL)
 
717
    {
 
718
      GDesktopBackgroundStyle style;
 
719
      style = g_settings_get_enum (priv->settings, WP_OPTIONS_KEY);
 
720
      if (style == G_DESKTOP_BACKGROUND_STYLE_NONE)
 
721
        g_settings_set_enum (priv->settings, WP_OPTIONS_KEY, cc_appearance_item_get_placement (item));
 
722
    }
 
723
 
 
724
  if (flags & CC_APPEARANCE_ITEM_HAS_SHADING)
 
725
    g_settings_set_enum (priv->settings, WP_SHADING_KEY, cc_appearance_item_get_shading (item));
 
726
 
 
727
  /* When changing to a background with colours set,
 
728
   * don't overwrite what's in GSettings, but read
 
729
   * from it instead.
 
730
   * We have a hack for the colors source though */
 
731
  if (flags & CC_APPEARANCE_ITEM_HAS_PCOLOR &&
 
732
      priv->current_source != SOURCE_COLORS)
 
733
    {
 
734
      g_settings_set_string (priv->settings, WP_PCOLOR_KEY, cc_appearance_item_get_pcolor (item));
 
735
    }
 
736
  else
 
737
    {
 
738
      pcolor = g_settings_get_string (priv->settings, WP_PCOLOR_KEY);
 
739
      g_object_set (G_OBJECT (item), "primary-color", pcolor, NULL);
 
740
    }
 
741
 
 
742
  if (flags & CC_APPEARANCE_ITEM_HAS_SCOLOR &&
 
743
      priv->current_source != SOURCE_COLORS)
 
744
    {
 
745
      g_settings_set_string (priv->settings, WP_SCOLOR_KEY, cc_appearance_item_get_scolor (item));
 
746
    }
 
747
  else
 
748
    {
 
749
      scolor = g_settings_get_string (priv->settings, WP_SCOLOR_KEY);
 
750
      g_object_set (G_OBJECT (item), "secondary-color", scolor, NULL);
 
751
    }
 
752
 
 
753
  /* Apply all changes */
 
754
  g_settings_apply (priv->settings);
 
755
 
 
756
  update_remove_button (panel, item);
 
757
 
 
758
  /* update the preview information */
 
759
  if (draw_preview != FALSE)
 
760
    {
 
761
      update_preview (priv, item);
 
762
 
 
763
      /* Save the source XML if there is one */
 
764
      filename = get_save_path ();
 
765
      if (create_save_dir ())
 
766
        cc_appearance_xml_save (priv->current_background, filename);
 
767
    }
 
768
}
 
769
 
 
770
static gboolean
 
771
preview_draw_cb (GtkWidget         *widget,
 
772
                 cairo_t           *cr,
 
773
                 CcAppearancePanel *panel)
 
774
{
 
775
  GtkAllocation allocation;
 
776
  CcAppearancePanelPrivate *priv = panel->priv;
 
777
  GdkPixbuf *pixbuf = NULL;
 
778
  const gint preview_width = 416;
 
779
  const gint preview_height = 248;
 
780
  const gint preview_x = 45;
 
781
  const gint preview_y = 84;
 
782
  GdkPixbuf *preview, *temp;
 
783
  gint size;
 
784
 
 
785
  gtk_widget_get_allocation (widget, &allocation);
 
786
 
 
787
  if (priv->current_background)
 
788
    {
 
789
      GIcon *icon;
 
790
      icon = cc_appearance_item_get_frame_thumbnail (priv->current_background,
 
791
                                                     priv->thumb_factory,
 
792
                                                     preview_width,
 
793
                                                     preview_height,
 
794
                                                     -2, TRUE);
 
795
      pixbuf = GDK_PIXBUF (icon);
 
796
    }
 
797
 
 
798
  if (!priv->display_base)
 
799
    return FALSE;
 
800
 
 
801
 
 
802
  preview = gdk_pixbuf_copy (priv->display_base);
 
803
 
 
804
  if (pixbuf)
 
805
    {
 
806
      gdk_pixbuf_composite (pixbuf, preview,
 
807
                            preview_x, preview_y,
 
808
                            preview_width, preview_height,
 
809
                            preview_x, preview_y, 1, 1,
 
810
                            GDK_INTERP_BILINEAR, 255);
 
811
 
 
812
      g_object_unref (pixbuf);
 
813
    }
 
814
 
 
815
 
 
816
  if (priv->display_overlay)
 
817
    {
 
818
      gdk_pixbuf_composite (priv->display_overlay, preview,
 
819
                            0, 0, 512, 512,
 
820
                            0, 0, 1, 1,
 
821
                            GDK_INTERP_BILINEAR, 255);
 
822
    }
 
823
 
 
824
 
 
825
  if (allocation.width < allocation.height)
 
826
    size = allocation.width;
 
827
  else
 
828
    size = allocation.height;
 
829
 
 
830
  temp = gdk_pixbuf_scale_simple (preview, size, size, GDK_INTERP_BILINEAR);
 
831
 
 
832
  gdk_cairo_set_source_pixbuf (cr,
 
833
                               temp,
 
834
                               allocation.width / 2 - (size / 2),
 
835
                               allocation.height / 2 - (size / 2));
 
836
  cairo_paint (cr);
 
837
 
 
838
  g_object_unref (temp);
 
839
  g_object_unref (preview);
 
840
 
 
841
  return TRUE;
 
842
}
 
843
 
 
844
static void
 
845
style_changed_cb (GtkComboBox       *box,
 
846
                  CcAppearancePanel *panel)
 
847
{
 
848
  CcAppearancePanelPrivate *priv = panel->priv;
 
849
  GtkTreeModel *model;
 
850
  GtkTreeIter iter;
 
851
  GDesktopBackgroundStyle value;
 
852
 
 
853
  if (!gtk_combo_box_get_active_iter (box, &iter))
 
854
    {
 
855
      return;
 
856
    }
 
857
 
 
858
  model = gtk_combo_box_get_model (box);
 
859
 
 
860
  gtk_tree_model_get (model, &iter, 1, &value, -1);
 
861
 
 
862
  g_settings_set_enum (priv->settings, WP_OPTIONS_KEY, value);
 
863
 
 
864
  if (priv->current_background)
 
865
    g_object_set (G_OBJECT (priv->current_background), "placement", value, NULL);
 
866
 
 
867
  g_settings_apply (priv->settings);
 
868
 
 
869
  update_preview (priv, NULL);
 
870
}
 
871
 
 
872
static void
 
873
color_changed_cb (GtkColorButton    *button,
 
874
                  CcAppearancePanel *panel)
 
875
{
 
876
  CcAppearancePanelPrivate *priv = panel->priv;
 
877
  GdkColor color;
 
878
  gchar *value;
 
879
  gboolean is_pcolor = FALSE;
 
880
 
 
881
  gtk_color_button_get_color (button, &color);
 
882
  if (WID ("style-pcolor") == GTK_WIDGET (button))
 
883
    is_pcolor = TRUE;
 
884
 
 
885
  value = gdk_color_to_string (&color);
 
886
 
 
887
  if (priv->current_background)
 
888
    {
 
889
      g_object_set (G_OBJECT (priv->current_background),
 
890
                    is_pcolor ? "primary-color" : "secondary-color", value, NULL);
 
891
    }
 
892
 
 
893
  g_settings_set_string (priv->settings,
 
894
                         is_pcolor ? WP_PCOLOR_KEY : WP_SCOLOR_KEY, value);
 
895
 
 
896
  g_settings_apply (priv->settings);
 
897
 
 
898
  g_free (value);
 
899
 
 
900
  update_preview (priv, NULL);
 
901
}
 
902
 
 
903
static void
 
904
swap_colors_clicked (GtkButton         *button,
 
905
                     CcAppearancePanel *panel)
 
906
{
 
907
  CcAppearancePanelPrivate *priv = panel->priv;
 
908
  GdkColor pcolor, scolor;
 
909
  char *new_pcolor, *new_scolor;
 
910
 
 
911
  gtk_color_button_get_color (GTK_COLOR_BUTTON (WID ("style-pcolor")), &pcolor);
 
912
  gtk_color_button_get_color (GTK_COLOR_BUTTON (WID ("style-scolor")), &scolor);
 
913
 
 
914
  gtk_color_button_set_color (GTK_COLOR_BUTTON (WID ("style-scolor")), &pcolor);
 
915
  gtk_color_button_set_color (GTK_COLOR_BUTTON (WID ("style-pcolor")), &scolor);
 
916
 
 
917
  new_pcolor = gdk_color_to_string (&scolor);
 
918
  new_scolor = gdk_color_to_string (&pcolor);
 
919
 
 
920
  g_object_set (priv->current_background,
 
921
                "primary-color", new_pcolor,
 
922
                "secondary-color", new_scolor,
 
923
                NULL);
 
924
 
 
925
  g_settings_set_string (priv->settings, WP_PCOLOR_KEY, new_pcolor);
 
926
  g_settings_set_string (priv->settings, WP_SCOLOR_KEY, new_scolor);
 
927
 
 
928
  g_free (new_pcolor);
 
929
  g_free (new_scolor);
 
930
 
 
931
  g_settings_apply (priv->settings);
 
932
 
 
933
  update_preview (priv, NULL);
 
934
}
 
935
 
 
936
static void
 
937
row_inserted (GtkTreeModel      *tree_model,
 
938
              GtkTreePath       *path,
 
939
              GtkTreeIter       *iter,
 
940
              CcAppearancePanel *panel)
 
941
{
 
942
  GtkListStore *store;
 
943
  CcAppearancePanelPrivate *priv;
 
944
 
 
945
  priv = panel->priv;
 
946
 
 
947
  store = bg_source_get_liststore (BG_SOURCE (panel->priv->pictures_source));
 
948
  g_signal_handlers_disconnect_by_func (G_OBJECT (store), G_CALLBACK (row_inserted), panel);
 
949
 
 
950
  /* Change source */
 
951
  gtk_combo_box_set_active (GTK_COMBO_BOX (WID ("sources-combobox")), SOURCE_PICTURES);
 
952
 
 
953
  /* And select the newly added item */
 
954
  gtk_icon_view_select_path (GTK_ICON_VIEW (WID ("backgrounds-iconview")), path);
 
955
}
 
956
 
 
957
static void
 
958
add_custom_wallpaper (CcAppearancePanel *panel,
 
959
                      const char        *uri)
 
960
{
 
961
  GtkListStore *store;
 
962
 
 
963
  store = bg_source_get_liststore (BG_SOURCE (panel->priv->pictures_source));
 
964
  g_signal_connect (G_OBJECT (store), "row-inserted",
 
965
                    G_CALLBACK (row_inserted), panel);
 
966
 
 
967
  if (bg_pictures_source_add (panel->priv->pictures_source, uri) == FALSE) {
 
968
    g_signal_handlers_disconnect_by_func (G_OBJECT (store), G_CALLBACK (row_inserted), panel);
 
969
    return;
 
970
  }
 
971
 
 
972
  /* Wait for the item to get added */
 
973
}
 
974
 
 
975
static void
 
976
file_chooser_response (GtkDialog         *chooser,
 
977
                       gint               response,
 
978
                       CcAppearancePanel *panel)
 
979
{
 
980
  GSList *selected, *l;
 
981
 
 
982
  if (response != GTK_RESPONSE_ACCEPT)
 
983
    {
 
984
      gtk_widget_destroy (GTK_WIDGET (chooser));
 
985
      return;
 
986
    }
 
987
 
 
988
  selected = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (chooser));
 
989
  gtk_widget_destroy (GTK_WIDGET (chooser));
 
990
 
 
991
  for (l = selected; l != NULL; l = l->next)
 
992
    {
 
993
      char *uri = l->data;
 
994
      add_custom_wallpaper (panel, uri);
 
995
      g_free (uri);
 
996
    }
 
997
  g_slist_free (selected);
 
998
}
 
999
 
 
1000
static void
 
1001
update_chooser_preview (GtkFileChooser    *chooser,
 
1002
                        CcAppearancePanel *panel)
 
1003
{
 
1004
  GnomeDesktopThumbnailFactory *thumb_factory;
 
1005
  char *uri;
 
1006
 
 
1007
  thumb_factory = panel->priv->thumb_factory;
 
1008
 
 
1009
  uri = gtk_file_chooser_get_preview_uri (chooser);
 
1010
 
 
1011
  if (uri)
 
1012
    {
 
1013
      GdkPixbuf *pixbuf = NULL;
 
1014
      const gchar *mime_type = NULL;
 
1015
      GFile *file;
 
1016
      GFileInfo *file_info;
 
1017
      GtkWidget *preview;
 
1018
 
 
1019
      preview = gtk_file_chooser_get_preview_widget (chooser);
 
1020
 
 
1021
      file = g_file_new_for_uri (uri);
 
1022
      file_info = g_file_query_info (file,
 
1023
                                     G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
 
1024
                                     G_FILE_QUERY_INFO_NONE,
 
1025
                                     NULL, NULL);
 
1026
      g_object_unref (file);
 
1027
 
 
1028
      if (file_info != NULL) {
 
1029
              mime_type = g_file_info_get_content_type (file_info);
 
1030
              g_object_unref (file_info);
 
1031
      }
 
1032
 
 
1033
      if (mime_type)
 
1034
        {
 
1035
        pixbuf = gnome_desktop_thumbnail_factory_generate_thumbnail (thumb_factory,
 
1036
                                                                     uri,
 
1037
                                                                     mime_type);
 
1038
        }
 
1039
 
 
1040
      gtk_dialog_set_response_sensitive (GTK_DIALOG (chooser),
 
1041
                                         GTK_RESPONSE_ACCEPT,
 
1042
                                         (pixbuf != NULL));
 
1043
 
 
1044
      if (pixbuf != NULL)
 
1045
        {
 
1046
          gtk_image_set_from_pixbuf (GTK_IMAGE (preview), pixbuf);
 
1047
          g_object_unref (pixbuf);
 
1048
        }
 
1049
      else
 
1050
        {
 
1051
          gtk_image_set_from_stock (GTK_IMAGE (preview),
 
1052
                                    GTK_STOCK_DIALOG_QUESTION,
 
1053
                                    GTK_ICON_SIZE_DIALOG);
 
1054
        }
 
1055
 
 
1056
      if (bg_pictures_source_is_known (panel->priv->pictures_source, uri))
 
1057
        gtk_dialog_set_response_sensitive (GTK_DIALOG (chooser), GTK_RESPONSE_ACCEPT, FALSE);
 
1058
      else
 
1059
        gtk_dialog_set_response_sensitive (GTK_DIALOG (chooser), GTK_RESPONSE_ACCEPT, TRUE);
 
1060
 
 
1061
      g_free (uri);
 
1062
    }
 
1063
 
 
1064
  gtk_file_chooser_set_preview_widget_active (chooser, TRUE);
 
1065
}
 
1066
 
 
1067
static void
 
1068
add_button_clicked (GtkButton         *button,
 
1069
                    CcAppearancePanel *panel)
 
1070
{
 
1071
  GtkWidget *chooser;
 
1072
  const gchar *folder;
 
1073
  GtkWidget *preview;
 
1074
  GtkFileFilter *filter;
 
1075
  CcAppearancePanelPrivate *priv;
 
1076
 
 
1077
  priv = panel->priv;
 
1078
 
 
1079
  filter = gtk_file_filter_new ();
 
1080
  gtk_file_filter_add_mime_type (filter, "image/*");
 
1081
 
 
1082
  chooser = gtk_file_chooser_dialog_new (_("Browse for more pictures"),
 
1083
                                         GTK_WINDOW (gtk_widget_get_toplevel (WID ("appearance-panel"))),
 
1084
                                         GTK_FILE_CHOOSER_ACTION_OPEN,
 
1085
                                         GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
 
1086
                                         GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
 
1087
                                         NULL);
 
1088
  gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (chooser), filter);
 
1089
  gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (chooser), TRUE);
 
1090
 
 
1091
  gtk_window_set_modal (GTK_WINDOW (chooser), TRUE);
 
1092
 
 
1093
  preview = gtk_image_new ();
 
1094
  gtk_widget_set_size_request (preview, 128, -1);
 
1095
  gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER (chooser), preview);
 
1096
  gtk_file_chooser_set_use_preview_label (GTK_FILE_CHOOSER (chooser), FALSE);
 
1097
  gtk_widget_show (preview);
 
1098
  g_signal_connect (chooser, "update-preview",
 
1099
                    G_CALLBACK (update_chooser_preview), panel);
 
1100
 
 
1101
  folder = g_get_user_special_dir (G_USER_DIRECTORY_PICTURES);
 
1102
  if (folder)
 
1103
    gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (chooser),
 
1104
                                         folder);
 
1105
 
 
1106
  g_signal_connect (chooser, "response",
 
1107
                    G_CALLBACK (file_chooser_response), panel);
 
1108
 
 
1109
  gtk_window_present (GTK_WINDOW (chooser));
 
1110
}
 
1111
 
 
1112
static void
 
1113
remove_button_clicked (GtkButton         *button,
 
1114
                       CcAppearancePanel *panel)
 
1115
{
 
1116
  CcAppearanceItem *item;
 
1117
  GtkListStore *store;
 
1118
  GtkTreePath *path;
 
1119
  CcAppearancePanelPrivate *priv;
 
1120
 
 
1121
  priv = panel->priv;
 
1122
 
 
1123
  item = get_selected_item (panel);
 
1124
  if (item == NULL)
 
1125
    g_assert_not_reached ();
 
1126
 
 
1127
  bg_pictures_source_remove (panel->priv->pictures_source, item);
 
1128
  g_object_unref (item);
 
1129
 
 
1130
  /* Are there any items left in the pictures tree store? */
 
1131
  store = bg_source_get_liststore (BG_SOURCE (panel->priv->pictures_source));
 
1132
  if (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 0)
 
1133
    gtk_combo_box_set_active (GTK_COMBO_BOX (WID ("sources-combobox")), SOURCE_WALLPAPERS);
 
1134
 
 
1135
  path = gtk_tree_path_new_from_string ("0");
 
1136
  gtk_icon_view_select_path (GTK_ICON_VIEW (WID ("backgrounds-iconview")), path);
 
1137
  gtk_tree_path_free (path);
 
1138
}
 
1139
 
 
1140
static void
 
1141
load_current_bg (CcAppearancePanel *self)
 
1142
{
 
1143
  CcAppearancePanelPrivate *priv;
 
1144
  CcAppearanceItem *saved, *configured;
 
1145
  gchar *uri, *pcolor, *scolor;
 
1146
 
 
1147
  priv = self->priv;
 
1148
 
 
1149
  /* Load the saved configuration */
 
1150
  uri = get_save_path ();
 
1151
  saved = cc_appearance_xml_get_item (uri);
 
1152
  g_free (uri);
 
1153
 
 
1154
  /* initalise the current background information from settings */
 
1155
  uri = g_settings_get_string (priv->settings, WP_URI_KEY);
 
1156
  if (uri && *uri == '\0')
 
1157
    {
 
1158
      g_free (uri);
 
1159
      uri = NULL;
 
1160
    }
 
1161
  else
 
1162
    {
 
1163
      GFile *file;
 
1164
 
 
1165
      file = g_file_new_for_commandline_arg (uri);
 
1166
      g_object_unref (file);
 
1167
    }
 
1168
  configured = cc_appearance_item_new (uri);
 
1169
  g_free (uri);
 
1170
 
 
1171
  pcolor = g_settings_get_string (priv->settings, WP_PCOLOR_KEY);
 
1172
  scolor = g_settings_get_string (priv->settings, WP_SCOLOR_KEY);
 
1173
  g_object_set (G_OBJECT (configured),
 
1174
                "name", _("Current background"),
 
1175
                "placement", g_settings_get_enum (priv->settings, WP_OPTIONS_KEY),
 
1176
                "shading", g_settings_get_enum (priv->settings, WP_SHADING_KEY),
 
1177
                "primary-color", pcolor,
 
1178
                "secondary-color", scolor,
 
1179
                NULL);
 
1180
  g_free (pcolor);
 
1181
  g_free (scolor);
 
1182
 
 
1183
  if (saved != NULL && cc_appearance_item_compare (saved, configured))
 
1184
    {
 
1185
      CcAppearanceItemFlags flags;
 
1186
      flags = cc_appearance_item_get_flags (saved);
 
1187
      /* Special case for colours */
 
1188
      if (cc_appearance_item_get_placement (saved) == G_DESKTOP_BACKGROUND_STYLE_NONE)
 
1189
        flags &=~ (CC_APPEARANCE_ITEM_HAS_PCOLOR | CC_APPEARANCE_ITEM_HAS_SCOLOR);
 
1190
      g_object_set (G_OBJECT (configured),
 
1191
                    "name", cc_appearance_item_get_name (saved),
 
1192
                    "flags", flags,
 
1193
                    "source-url", cc_appearance_item_get_source_url (saved),
 
1194
                    "source-xml", cc_appearance_item_get_source_xml (saved),
 
1195
                    NULL);
 
1196
    }
 
1197
  if (saved != NULL)
 
1198
    g_object_unref (saved);
 
1199
 
 
1200
  priv->current_background = configured;
 
1201
  cc_appearance_item_load (priv->current_background, NULL);
 
1202
}
 
1203
 
 
1204
static void
 
1205
scrolled_realize_cb (GtkWidget         *scrolled,
 
1206
                     CcAppearancePanel *self)
 
1207
{
 
1208
  /* FIXME, hack for https://bugzilla.gnome.org/show_bug.cgi?id=645649 */
 
1209
  GdkScreen *screen;
 
1210
  GdkRectangle rect;
 
1211
  int monitor;
 
1212
 
 
1213
  screen = gtk_widget_get_screen (scrolled);
 
1214
  monitor = gdk_screen_get_monitor_at_window (screen, gtk_widget_get_window (scrolled));
 
1215
  gdk_screen_get_monitor_geometry (screen, monitor, &rect);
 
1216
  if (rect.height <= 768)
 
1217
    g_object_set (G_OBJECT (scrolled), "height-request", 280, NULL);
 
1218
}
 
1219
 
 
1220
static void
 
1221
cc_appearance_panel_drag_uris (GtkWidget *widget,
 
1222
                               GdkDragContext *context, gint x, gint y,
 
1223
                               GtkSelectionData *data, guint info, guint time,
 
1224
                               CcAppearancePanel *panel)
 
1225
{
 
1226
  gint i;
 
1227
  char *uri;
 
1228
  gchar **uris;
 
1229
 
 
1230
  uris = gtk_selection_data_get_uris (data);
 
1231
  if (!uris)
 
1232
    return;
 
1233
 
 
1234
  gtk_drag_finish (context, TRUE, FALSE, time);
 
1235
 
 
1236
  for (i = 0; uris[i] != NULL; i++) {
 
1237
    uri = uris[i];
 
1238
    if (!bg_pictures_source_is_known (panel->priv->pictures_source, uri)) {
 
1239
      add_custom_wallpaper (panel, uri);
 
1240
    }
 
1241
  }
 
1242
 
 
1243
  g_strfreev(uris);
 
1244
}
 
1245
 
 
1246
static gchar *themes_id[] = { "Adwaita", "Ambiance", "Radiance", "HighContrast" };
 
1247
static gchar *themes_name[] = { "Adwaita", "Ambiance", "Radiance", "High Contrast" };
 
1248
 
 
1249
static gboolean
 
1250
get_theme_data (const gchar *theme_name,
 
1251
                gchar **gtk_theme,
 
1252
                gchar **icon_theme,
 
1253
                gchar **window_theme,
 
1254
                gchar **cursor_theme)
 
1255
{
 
1256
  gchar *path;
 
1257
  GKeyFile *theme_file;
 
1258
  GError *error = NULL;
 
1259
  gboolean result = FALSE;
 
1260
 
 
1261
  *gtk_theme = *icon_theme = *window_theme = *cursor_theme = NULL;
 
1262
 
 
1263
  theme_file = g_key_file_new ();
 
1264
  path = g_build_filename ("/usr/share/themes", theme_name, "index.theme", NULL);
 
1265
  if (g_key_file_load_from_file (theme_file, path, G_KEY_FILE_NONE, &error))
 
1266
    {
 
1267
      *gtk_theme = g_key_file_get_string (theme_file, "X-GNOME-Metatheme", "GtkTheme", NULL);
 
1268
      *icon_theme = g_key_file_get_string (theme_file, "X-GNOME-Metatheme", "IconTheme", NULL);
 
1269
      *window_theme = g_key_file_get_string (theme_file, "X-GNOME-Metatheme", "MetacityTheme", NULL);
 
1270
      *cursor_theme = g_key_file_get_string (theme_file, "X-GNOME-Metatheme", "CursorTheme", NULL);
 
1271
 
 
1272
      result = TRUE;
 
1273
    }
 
1274
  else
 
1275
    {
 
1276
      g_warning ("Could not load %s: %s", path, error->message);
 
1277
      g_error_free (error);
 
1278
    }
 
1279
 
 
1280
  g_key_file_free (theme_file);
 
1281
  g_free (path);
 
1282
 
 
1283
  return result;
 
1284
}
 
1285
 
 
1286
static void
 
1287
theme_selection_changed (GtkComboBox *combo, CcAppearancePanel *self)
 
1288
{
 
1289
  gint active;
 
1290
  gchar *gtk_theme, *icon_theme, *window_theme, *cursor_theme;
 
1291
 
 
1292
  active = gtk_combo_box_get_active (combo);
 
1293
  g_return_if_fail (active >= 0 && active < G_N_ELEMENTS (themes_id));
 
1294
 
 
1295
  if (!get_theme_data (gtk_combo_box_get_active_id (combo),
 
1296
                       &gtk_theme, &icon_theme, &window_theme, &cursor_theme))
 
1297
    return;
 
1298
 
 
1299
  g_settings_delay (self->priv->interface_settings);
 
1300
 
 
1301
  if (self->priv->canonical_interface_settings != NULL)
 
1302
    g_settings_delay (self->priv->canonical_interface_settings);
 
1303
 
 
1304
  g_settings_set_string (self->priv->interface_settings, "gtk-theme", gtk_theme);
 
1305
  g_settings_set_string (self->priv->interface_settings, "icon-theme", icon_theme);
 
1306
  g_settings_set_string (self->priv->interface_settings, "cursor-theme", cursor_theme);
 
1307
  g_settings_set_string (self->priv->wm_theme_settings, "theme", window_theme);
 
1308
 
 
1309
 
 
1310
  /* disable overlay scrollbars for a11y if installed*/
 
1311
  if (self->priv->canonical_interface_settings)
 
1312
    {
 
1313
      if (g_strcmp0 (gtk_theme, "HighContrast") == 0 )
 
1314
        g_settings_set_string (self->priv->canonical_interface_settings, "scrollbar-mode", "normal");
 
1315
      else
 
1316
        g_settings_reset (self->priv->canonical_interface_settings, "scrollbar-mode");
 
1317
      g_settings_apply (self->priv->canonical_interface_settings);
 
1318
    }
 
1319
 
 
1320
  g_settings_apply (self->priv->interface_settings);
 
1321
 
 
1322
  g_free (gtk_theme);
 
1323
  g_free (icon_theme);
 
1324
  g_free (window_theme);
 
1325
  g_free (cursor_theme);
 
1326
}
 
1327
 
 
1328
static void
 
1329
setup_theme_selector (CcAppearancePanel *self)
 
1330
{
 
1331
  gchar *current_gtk_theme;
 
1332
  gchar *default_gtk_theme;
 
1333
  gint i, current_theme_index = 0;
 
1334
  GtkWidget *widget;
 
1335
  GtkWidget *liststore;
 
1336
  GSettingsSchemaSource *source;
 
1337
  CcAppearancePanelPrivate *priv = self->priv;
 
1338
  GSettings *defaults_settings = g_settings_new ("org.gnome.desktop.interface");
 
1339
 
 
1340
  priv->interface_settings = g_settings_new ("org.gnome.desktop.interface");
 
1341
 
 
1342
  source = g_settings_schema_source_get_default ();
 
1343
  if (source != NULL && g_settings_schema_source_lookup (source, CANONICAL_DESKTOP_INTERFACE, TRUE) != NULL)
 
1344
    priv->canonical_interface_settings = g_settings_new (CANONICAL_DESKTOP_INTERFACE);
 
1345
 
 
1346
  priv->wm_theme_settings = g_settings_new ("org.gnome.desktop.wm.preferences");
 
1347
  current_gtk_theme = g_settings_get_string (priv->interface_settings, "gtk-theme");
 
1348
 
 
1349
  /* gettint the default for the theme */
 
1350
  g_settings_delay (defaults_settings);
 
1351
  g_settings_reset (defaults_settings, "gtk-theme");
 
1352
  default_gtk_theme = g_settings_get_string (defaults_settings, "gtk-theme");
 
1353
  g_object_unref (defaults_settings);
 
1354
 
 
1355
  widget = WID ("theme-selector");
 
1356
  liststore = WID ("theme-list-store");
 
1357
 
 
1358
  for (i = 0; i < G_N_ELEMENTS (themes_id); i++, current_theme_index++)
 
1359
    {
 
1360
      gchar *gtk_theme, *icon_theme, *window_theme, *cursor_theme, *new_theme_name;
 
1361
      GtkTreeIter iter;
 
1362
 
 
1363
      if (!get_theme_data (themes_id[i], &gtk_theme, &icon_theme, &window_theme, &cursor_theme))
 
1364
        {
 
1365
          current_theme_index--;
 
1366
          continue;
 
1367
        }
 
1368
 
 
1369
      if (g_strcmp0 (gtk_theme, default_gtk_theme) == 0)
 
1370
        new_theme_name = g_strdup_printf ("%s <small><i>(%s)</i></small>", themes_name[i], _("default"));
 
1371
      else
 
1372
        new_theme_name = g_strdup (themes_name[i]);
 
1373
 
 
1374
      gtk_list_store_append (GTK_LIST_STORE (liststore), &iter);
 
1375
      gtk_list_store_set (GTK_LIST_STORE (liststore), &iter, 0, themes_id[i], 1, new_theme_name, -1);
 
1376
 
 
1377
      if (g_strcmp0 (gtk_theme, current_gtk_theme) == 0)
 
1378
          /* This is the current theme, so select item in the combo box */
 
1379
         gtk_combo_box_set_active (GTK_COMBO_BOX (widget), current_theme_index);
 
1380
 
 
1381
      g_free (gtk_theme);
 
1382
      g_free (new_theme_name);
 
1383
      g_free (icon_theme);
 
1384
      g_free (window_theme);
 
1385
      g_free (cursor_theme);
 
1386
    }
 
1387
    g_free (current_gtk_theme);
 
1388
    g_free (default_gtk_theme);
 
1389
 
 
1390
    g_signal_connect (G_OBJECT (widget), "changed",
 
1391
                      G_CALLBACK (theme_selection_changed), self);
 
1392
}
 
1393
 
 
1394
static void
 
1395
iconsize_widget_refresh (GtkAdjustment *iconsize_adj, GSettings *unity_settings)
 
1396
{
 
1397
  gint value = g_settings_get_int (unity_settings, UNITY_ICONSIZE_KEY);
 
1398
  gtk_adjustment_set_value (iconsize_adj, (gdouble)value);
 
1399
}
 
1400
 
 
1401
static void
 
1402
ext_iconsize_changed_callback (GSettings* settings,
 
1403
                               guint key,
 
1404
                               gpointer user_data)
 
1405
{
 
1406
  iconsize_widget_refresh (GTK_ADJUSTMENT (user_data), settings);
 
1407
}
 
1408
 
 
1409
static void
 
1410
on_iconsize_changed (GtkAdjustment *adj, GSettings *unity_settings)
 
1411
{
 
1412
  g_settings_set_int (unity_settings, UNITY_ICONSIZE_KEY, (gint)gtk_adjustment_get_value (adj));
 
1413
}
 
1414
 
 
1415
static void
 
1416
refresh_was_modified_by_external_tool (CcAppearancePanel *self)
 
1417
{
 
1418
  CcAppearancePanelPrivate *priv = self->priv;
 
1419
  gboolean modified_ext_tool = FALSE;
 
1420
 
 
1421
  // reveal side
 
1422
  modified_ext_tool = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (WID ("unity_reveal_spot_otheroption")));
 
1423
 
 
1424
  // autohide mode
 
1425
  if (!modified_ext_tool && (!gtk_widget_get_sensitive (WID ("unity_launcher_autohide"))))
 
1426
    modified_ext_tool = TRUE;
 
1427
 
 
1428
  gtk_widget_set_visible (WID ("unity-label-external-tool"), modified_ext_tool);
 
1429
}
 
1430
 
 
1431
static void
 
1432
hidelauncher_set_sensitivity_reveal (CcAppearancePanel *self, gboolean autohide)
 
1433
{
 
1434
  CcAppearancePanelPrivate *priv = self->priv;
 
1435
  gtk_widget_set_sensitive (WID ("unity_reveal_label"), autohide);
 
1436
  gtk_widget_set_sensitive (WID ("unity_reveal_spot_topleft"), autohide);
 
1437
  gtk_widget_set_sensitive (WID ("unity_reveal_spot_left"), autohide);
 
1438
  gtk_widget_set_sensitive (WID ("unity-launcher-sensitivity"), autohide);
 
1439
  gtk_widget_set_sensitive (WID ("unity-launcher-sensitivity-label"), autohide);
 
1440
  gtk_widget_set_sensitive (WID ("unity-launcher-sensitivity-low-label"), autohide);
 
1441
  gtk_widget_set_sensitive (WID ("unity-launcher-sensitivity-high-label"), autohide);
 
1442
  gtk_widget_set_sensitive (WID ("unity-launcher-sensitivity-high-label"), autohide);
 
1443
}
 
1444
 
 
1445
static void
 
1446
hidelauncher_widget_refresh (CcAppearancePanel *self)
 
1447
{
 
1448
  CcAppearancePanelPrivate *priv = self->priv;
 
1449
  gint value = g_settings_get_int (priv->unity_settings, UNITY_LAUNCHERHIDE_KEY);
 
1450
  gboolean autohide = (value != 0);
 
1451
 
 
1452
  // handle not supported value
 
1453
  if (value != 0 && value != 1)
 
1454
    {
 
1455
      gtk_widget_set_sensitive (WID ("unity_launcher_autohide"), FALSE);
 
1456
    }
 
1457
  else
 
1458
    {
 
1459
      gtk_widget_set_sensitive (WID ("unity_launcher_autohide"), TRUE);
 
1460
      gtk_switch_set_active (GTK_SWITCH (WID ("unity_launcher_autohide")), autohide);
 
1461
    }
 
1462
 
 
1463
  hidelauncher_set_sensitivity_reveal (self, autohide);
 
1464
  refresh_was_modified_by_external_tool (self);
 
1465
}
 
1466
 
 
1467
static void
 
1468
ext_hidelauncher_changed_callback (GSettings* settings,
 
1469
                                   guint key,
 
1470
                                   gpointer user_data)
 
1471
{
 
1472
  hidelauncher_widget_refresh (CC_APPEARANCE_PANEL (user_data));
 
1473
}
 
1474
 
 
1475
static void
 
1476
on_hidelauncher_changed (GtkSwitch *switcher, gboolean enabled, gpointer user_data)
 
1477
{
 
1478
  gint value = 0;
 
1479
  CcAppearancePanel *self = CC_APPEARANCE_PANEL (user_data);
 
1480
 
 
1481
  gint unity_value = g_settings_get_int (self->priv->unity_settings, UNITY_LAUNCHERHIDE_KEY);
 
1482
  gboolean unity_autohide_enabled;
 
1483
 
 
1484
  unity_autohide_enabled = (unity_value != 0);
 
1485
  if (gtk_switch_get_active (switcher))
 
1486
    {
 
1487
      /* change value to "active" if activation isn't due to gsettings switching to any value */
 
1488
      if (unity_autohide_enabled)
 
1489
        return;
 
1490
      value = 1;
 
1491
    }
 
1492
 
 
1493
  /* 3d */
 
1494
  g_settings_set_int (self->priv->unity_settings, UNITY_LAUNCHERHIDE_KEY, value);
 
1495
  hidelauncher_set_sensitivity_reveal (self, (value != -1));
 
1496
}
 
1497
 
 
1498
static void
 
1499
reveallauncher_widget_refresh (CcAppearancePanel *self)
 
1500
{
 
1501
  CcAppearancePanelPrivate *priv = self->priv;
 
1502
  gint value = g_settings_get_int (priv->unity_settings, UNITY_LAUNCHERREVEAL_KEY);
 
1503
 
 
1504
  if (value == 1)
 
1505
    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (WID ("unity_reveal_spot_topleft")), TRUE);
 
1506
  else if (value == 0)
 
1507
    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (WID ("unity_reveal_spot_left")), TRUE);
 
1508
  else
 
1509
    /* this is a hidden spot when another option is selected (through ccsm) */
 
1510
    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (WID ("unity_reveal_spot_otheroption")), TRUE);
 
1511
 
 
1512
  refresh_was_modified_by_external_tool (self);
 
1513
}
 
1514
 
 
1515
static void
 
1516
ext_reveallauncher_changed_callback (GSettings* settings,
 
1517
                                     guint key,
 
1518
                                     gpointer user_data)
 
1519
{
 
1520
  reveallauncher_widget_refresh (CC_APPEARANCE_PANEL (user_data));
 
1521
}
 
1522
 
 
1523
static void
 
1524
on_reveallauncher_changed (GtkToggleButton *button, gpointer user_data)
 
1525
{
 
1526
  CcAppearancePanel *self = CC_APPEARANCE_PANEL (user_data);
 
1527
  CcAppearancePanelPrivate *priv = self->priv;
 
1528
  gint reveal_spot = 0;
 
1529
 
 
1530
  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (WID ("unity_reveal_spot_topleft"))))
 
1531
    reveal_spot = 1;
 
1532
  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (WID ("unity_reveal_spot_left"))))
 
1533
    reveal_spot = 0;
 
1534
 
 
1535
  g_settings_set_int (priv->unity_settings, UNITY_LAUNCHERREVEAL_KEY, reveal_spot);
 
1536
  reveallauncher_widget_refresh (self);
 
1537
}
 
1538
 
 
1539
static void
 
1540
launcher_sensitivity_widget_refresh (GtkAdjustment *launcher_sensitivity_adj, GSettings *unity_settings)
 
1541
{
 
1542
  gdouble value = g_settings_get_double (unity_settings, UNITY_LAUNCHERSENSITIVITY_KEY);
 
1543
  gtk_adjustment_set_value (launcher_sensitivity_adj, (gdouble)value);
 
1544
}
 
1545
 
 
1546
static void
 
1547
ext_launchersensitivity_changed_callback (GSettings* settings,
 
1548
                                          guint key,
 
1549
                                          gpointer user_data)
 
1550
{
 
1551
  launcher_sensitivity_widget_refresh (GTK_ADJUSTMENT (user_data), settings);
 
1552
}
 
1553
 
 
1554
static void
 
1555
on_launchersensitivity_changed (GtkAdjustment *adj, gpointer user_data)
 
1556
{
 
1557
  CcAppearancePanel *self = CC_APPEARANCE_PANEL (user_data);
 
1558
  CcAppearancePanelPrivate *priv = self->priv;
 
1559
  gdouble value = gtk_adjustment_get_value (adj);
 
1560
 
 
1561
  g_settings_set_double (priv->unity_settings, UNITY_LAUNCHERSENSITIVITY_KEY, value);
 
1562
}
 
1563
 
 
1564
gboolean
 
1565
enable_workspaces_widget_refresh (gpointer user_data)
 
1566
{
 
1567
  CcAppearancePanel *self = CC_APPEARANCE_PANEL (user_data);
 
1568
  CcAppearancePanelPrivate *priv = self->priv;
 
1569
  GtkToggleButton *button = GTK_TOGGLE_BUTTON (WID ("check_enable_workspaces"));
 
1570
 
 
1571
  gint hsize = g_settings_get_int (priv->compizcore_settings, COMPIZCORE_HSIZE_KEY);
 
1572
  gint vsize = g_settings_get_int (priv->compizcore_settings, COMPIZCORE_VSIZE_KEY);
 
1573
 
 
1574
  if (hsize > 1 || vsize > 1)
 
1575
    {
 
1576
      if (!gtk_toggle_button_get_active (button))
 
1577
        gtk_toggle_button_set_active (button, TRUE);
 
1578
    }
 
1579
  else
 
1580
    gtk_toggle_button_set_active (button, FALSE);
 
1581
 
 
1582
  return FALSE;
 
1583
}
 
1584
 
 
1585
static void
 
1586
ext_enableworkspaces_changed_callback (GSettings* settings,
 
1587
                                       guint key,
 
1588
                                       gpointer user_data)
 
1589
{
 
1590
  g_idle_add((GSourceFunc) enable_workspaces_widget_refresh, user_data);
 
1591
}                              
 
1592
 
 
1593
static void
 
1594
on_enable_workspaces_changed (GtkToggleButton *button, gpointer user_data)
 
1595
{
 
1596
  CcAppearancePanel *self = CC_APPEARANCE_PANEL (user_data);
 
1597
  CcAppearancePanelPrivate *priv = self->priv;
 
1598
  gint hsize = 1;
 
1599
  gint vsize = 1;
 
1600
 
 
1601
  if (gtk_toggle_button_get_active (button))
 
1602
  {
 
1603
    hsize = vsize = 2;
 
1604
  }
 
1605
 
 
1606
  g_settings_set_int (priv->compizcore_settings, COMPIZCORE_HSIZE_KEY, hsize);
 
1607
  g_settings_set_int (priv->compizcore_settings, COMPIZCORE_VSIZE_KEY, hsize);
 
1608
}
 
1609
 
 
1610
static void
 
1611
enable_showdesktop_widget_refresh (gpointer user_data)
 
1612
{
 
1613
  CcAppearancePanel *self = CC_APPEARANCE_PANEL (user_data);
 
1614
  CcAppearancePanelPrivate *priv = self->priv;
 
1615
  GtkToggleButton *button = GTK_TOGGLE_BUTTON (WID ("check_showdesktop_in_launcher"));
 
1616
  gchar **favorites = NULL;
 
1617
  gboolean show_desktop_found = FALSE;
 
1618
 
 
1619
  favorites = g_settings_get_strv (priv->unity_own_settings, UNITY_FAVORITES_KEY);
 
1620
  while (*favorites != NULL)
 
1621
    {
 
1622
      if (g_strcmp0 (*favorites, SHOW_DESKTOP_UNITY_FAVORITE_STR) == 0)
 
1623
        show_desktop_found = TRUE;
 
1624
      favorites++;
 
1625
    }
 
1626
 
 
1627
  if (show_desktop_found)
 
1628
    gtk_toggle_button_set_active (button, TRUE);
 
1629
  else
 
1630
    gtk_toggle_button_set_active (button, FALSE);
 
1631
}
 
1632
 
 
1633
static void
 
1634
ext_enableshowdesktop_changed_callback (GSettings* settings,
 
1635
                                        guint key,
 
1636
                                        gpointer user_data)
 
1637
{
 
1638
  enable_showdesktop_widget_refresh (user_data);
 
1639
}
 
1640
 
 
1641
static void
 
1642
on_enable_showdesktop_changed (GtkToggleButton *button, gpointer user_data)
 
1643
{
 
1644
  CcAppearancePanel *self = CC_APPEARANCE_PANEL (user_data);
 
1645
  CcAppearancePanelPrivate *priv = self->priv;
 
1646
 
 
1647
  gchar** favorites;
 
1648
  GPtrArray* newfavorites = g_ptr_array_new ();
 
1649
  gboolean show_desktop_in_array = FALSE;
 
1650
 
 
1651
  favorites = g_settings_get_strv (priv->unity_own_settings, UNITY_FAVORITES_KEY);
 
1652
  if (gtk_toggle_button_get_active (button))
 
1653
    {
 
1654
 
 
1655
      while (*favorites != NULL)
 
1656
        {
 
1657
          // add the current element to the set
 
1658
          g_ptr_array_add (newfavorites, (gpointer) g_strdup (*favorites));
 
1659
 
 
1660
          // if found running-apps, the show desktop element is added after that one
 
1661
          if (g_strcmp0 (*favorites, "unity://running-apps") == 0)
 
1662
            {
 
1663
              favorites++;
 
1664
              if (*favorites != NULL)
 
1665
                {
 
1666
                   // insert the additional element if not the favorite string
 
1667
                   if (g_strcmp0 (*favorites, SHOW_DESKTOP_UNITY_FAVORITE_STR) != 0)
 
1668
                     g_ptr_array_add (newfavorites, (gpointer) g_strdup (SHOW_DESKTOP_UNITY_FAVORITE_STR));
 
1669
                   g_ptr_array_add (newfavorites, (gpointer) g_strdup (*favorites));
 
1670
                   show_desktop_in_array = TRUE;
 
1671
                }
 
1672
              else
 
1673
                break;
 
1674
            }
 
1675
          favorites++;
 
1676
        }
 
1677
        if (!show_desktop_in_array)
 
1678
          g_ptr_array_add (newfavorites, (gpointer) g_strdup (SHOW_DESKTOP_UNITY_FAVORITE_STR));
 
1679
      }
 
1680
  else
 
1681
    {
 
1682
      while (*favorites != NULL)
 
1683
        {
 
1684
          if (g_strcmp0 (*favorites, SHOW_DESKTOP_UNITY_FAVORITE_STR) != 0)
 
1685
            g_ptr_array_add (newfavorites, (gpointer) g_strdup (*favorites));
 
1686
          favorites++;
 
1687
        }
 
1688
    }
 
1689
  g_ptr_array_add (newfavorites, NULL);
 
1690
  g_settings_set_strv (priv->unity_own_settings, UNITY_FAVORITES_KEY, (const gchar **)newfavorites->pdata);
 
1691
  g_ptr_array_free (newfavorites, TRUE);
 
1692
  
 
1693
}
 
1694
 
 
1695
static void
 
1696
on_restore_defaults_page2_clicked (GtkButton *button, gpointer user_data)
 
1697
{
 
1698
  CcAppearancePanel *self = CC_APPEARANCE_PANEL (user_data);
 
1699
  CcAppearancePanelPrivate *priv = self->priv;
 
1700
 
 
1701
  /* reset defaut for the profile and get the default */
 
1702
  g_settings_reset (priv->unity_settings, UNITY_LAUNCHERHIDE_KEY);
 
1703
  g_settings_reset (priv->unity_settings, UNITY_LAUNCHERSENSITIVITY_KEY);
 
1704
  g_settings_reset (priv->unity_settings, UNITY_LAUNCHERREVEAL_KEY);
 
1705
  g_settings_reset (priv->compizcore_settings, COMPIZCORE_HSIZE_KEY);
 
1706
  g_settings_reset (priv->compizcore_settings, COMPIZCORE_VSIZE_KEY);
 
1707
}
 
1708
 
 
1709
/* <hacks> */
 
1710
 
 
1711
/* Get scrolling in the right direction */
 
1712
static gboolean
 
1713
on_scale_scroll_event (GtkWidget      *widget,
 
1714
                       GdkEventScroll *event,
 
1715
                       gpointer *data)
 
1716
{
 
1717
  gdouble value;
 
1718
  GtkAdjustment *adj = gtk_range_get_adjustment (GTK_RANGE (widget));
 
1719
  MinMax *iconsize_values = (MinMax *) data;
 
1720
  gdouble delta = iconsize_values->max - iconsize_values->min;
 
1721
 
 
1722
  value = gtk_adjustment_get_value (adj);
 
1723
 
 
1724
  if ((event->direction == GDK_SCROLL_UP) ||
 
1725
     (event->direction == GDK_SCROLL_SMOOTH && event->delta_y < 0))
 
1726
    {
 
1727
      if (value + delta/8 > iconsize_values->max)
 
1728
        value = iconsize_values->max;
 
1729
      else
 
1730
        value = value + delta/8;
 
1731
      gtk_adjustment_set_value (adj, value);
 
1732
    }
 
1733
  else if ((event->direction == GDK_SCROLL_DOWN) ||
 
1734
           (event->direction == GDK_SCROLL_SMOOTH && event->delta_y > 0))
 
1735
    {
 
1736
      if (value - delta/8 < iconsize_values->min)
 
1737
        value = iconsize_values->min;
 
1738
      else
 
1739
        value = value - delta/8;
 
1740
      gtk_adjustment_set_value (adj, value);
 
1741
    }
 
1742
 
 
1743
  return TRUE;
 
1744
}
 
1745
 
 
1746
/* </hacks> */
 
1747
 
 
1748
static void
 
1749
setup_unity_settings (CcAppearancePanel *self)
 
1750
{
 
1751
  CcAppearancePanelPrivate *priv = self->priv;
 
1752
  GtkAdjustment* iconsize_adj;
 
1753
  GtkAdjustment* launcher_sensitivity_adj;
 
1754
  GtkScale* iconsize_scale;
 
1755
  GtkScale* launcher_sensitivity_scale;
 
1756
  const gchar * const *schemas;
 
1757
 
 
1758
  schemas = g_settings_list_schemas ();
 
1759
  while (*schemas != NULL)
 
1760
    {
 
1761
      if (g_strcmp0 (*schemas, UNITY_OWN_GSETTINGS_SCHEMA) == 0)
 
1762
          priv->unity_own_settings = g_settings_new (UNITY_OWN_GSETTINGS_SCHEMA);
 
1763
      schemas++;
 
1764
    }
 
1765
  schemas = g_settings_list_relocatable_schemas ();
 
1766
  while (*schemas != NULL)
 
1767
    {
 
1768
      if (g_strcmp0 (*schemas, UNITY_GSETTINGS_SCHEMA) == 0)
 
1769
          priv->unity_settings = g_settings_new_with_path (UNITY_GSETTINGS_SCHEMA, UNITY_GSETTINGS_PATH);
 
1770
      if (g_strcmp0 (*schemas, COMPIZCORE_GSETTINGS_SCHEMA) == 0)
 
1771
          priv->compizcore_settings = g_settings_new_with_path (COMPIZCORE_GSETTINGS_SCHEMA, COMPIZCORE_GSETTINGS_PATH);
 
1772
      schemas++;
 
1773
    }
 
1774
 
 
1775
  if (!priv->unity_settings || !priv->compizcore_settings || !priv->unity_own_settings)
 
1776
    return;
 
1777
 
 
1778
  /* Icon size change */
 
1779
  iconsize_values.min = MIN_ICONSIZE;
 
1780
  iconsize_values.max = MAX_ICONSIZE;
 
1781
  iconsize_adj = gtk_adjustment_new (48, iconsize_values.min, iconsize_values.max, 1, 5, 0);
 
1782
  iconsize_scale = GTK_SCALE (WID ("unity-iconsize-scale"));
 
1783
  gtk_range_set_adjustment (GTK_RANGE (iconsize_scale), iconsize_adj);
 
1784
  gtk_scale_add_mark (iconsize_scale, 48, GTK_POS_BOTTOM, NULL);
 
1785
  g_signal_connect (priv->unity_settings, "changed::" UNITY_ICONSIZE_KEY,
 
1786
                    G_CALLBACK (ext_iconsize_changed_callback), iconsize_adj);
 
1787
 
 
1788
  g_signal_connect (iconsize_adj, "value_changed",
 
1789
                    G_CALLBACK (on_iconsize_changed), priv->unity_settings);
 
1790
  g_signal_connect (G_OBJECT (iconsize_scale), "scroll-event",
 
1791
                    G_CALLBACK (on_scale_scroll_event), &iconsize_values);
 
1792
  iconsize_widget_refresh (iconsize_adj, priv->unity_settings);
 
1793
 
 
1794
  /* Reveal spot setting */
 
1795
  g_signal_connect (priv->unity_settings, "changed::" UNITY_LAUNCHERREVEAL_KEY,
 
1796
                    G_CALLBACK (ext_reveallauncher_changed_callback), self);
 
1797
  g_signal_connect (WID ("unity_reveal_spot_topleft"), "toggled",
 
1798
                     G_CALLBACK (on_reveallauncher_changed), self);
 
1799
  g_signal_connect (WID ("unity_reveal_spot_left"), "toggled",
 
1800
                     G_CALLBACK (on_reveallauncher_changed), self);
 
1801
  reveallauncher_widget_refresh (self);
 
1802
 
 
1803
  /* Launcher reveal */
 
1804
  launchersensitivity_values.min = MIN_LAUNCHER_SENSIVITY;
 
1805
  launchersensitivity_values.max = MAX_LAUNCHER_SENSIVITY;
 
1806
  launcher_sensitivity_adj = gtk_adjustment_new (2, launchersensitivity_values.min, launchersensitivity_values.max, 0.1, 1, 0);
 
1807
  launcher_sensitivity_scale = GTK_SCALE (WID ("unity-launcher-sensitivity"));
 
1808
  gtk_range_set_adjustment (GTK_RANGE (launcher_sensitivity_scale), launcher_sensitivity_adj);
 
1809
  gtk_scale_add_mark (launcher_sensitivity_scale, 2, GTK_POS_BOTTOM, NULL);
 
1810
  g_signal_connect (priv->unity_settings, "changed::" UNITY_LAUNCHERSENSITIVITY_KEY,
 
1811
                    G_CALLBACK (ext_launchersensitivity_changed_callback), launcher_sensitivity_adj);
 
1812
  g_signal_connect (launcher_sensitivity_adj, "value_changed",
 
1813
                    G_CALLBACK (on_launchersensitivity_changed), self);
 
1814
  g_signal_connect (G_OBJECT (launcher_sensitivity_scale), "scroll-event",
 
1815
                    G_CALLBACK (on_scale_scroll_event), &launchersensitivity_values);
 
1816
  launcher_sensitivity_widget_refresh (launcher_sensitivity_adj, priv->unity_settings);
 
1817
 
 
1818
  /* Autohide launcher setting */
 
1819
  g_signal_connect (priv->unity_settings, "changed::" UNITY_LAUNCHERHIDE_KEY,
 
1820
                    G_CALLBACK (ext_hidelauncher_changed_callback), self);
 
1821
  g_signal_connect (WID ("unity_launcher_autohide"), "notify::active",
 
1822
                    G_CALLBACK (on_hidelauncher_changed), self);
 
1823
  hidelauncher_widget_refresh (self);
 
1824
 
 
1825
  /* Enabling workspaces */
 
1826
  g_signal_connect (priv->compizcore_settings, "changed::" COMPIZCORE_HSIZE_KEY,
 
1827
                    G_CALLBACK (ext_enableworkspaces_changed_callback), self);
 
1828
  g_signal_connect (priv->compizcore_settings, "changed::" COMPIZCORE_VSIZE_KEY,
 
1829
                    G_CALLBACK (ext_enableworkspaces_changed_callback), self);
 
1830
  g_signal_connect (WID ("check_enable_workspaces"), "toggled",
 
1831
                     G_CALLBACK (on_enable_workspaces_changed), self);
 
1832
  enable_workspaces_widget_refresh (self);
 
1833
 
 
1834
  /* Enabling show desktop icon */
 
1835
  g_signal_connect (priv->unity_own_settings, "changed::" UNITY_FAVORITES_KEY,
 
1836
                    G_CALLBACK (ext_enableshowdesktop_changed_callback), self);
 
1837
  g_signal_connect (WID ("check_showdesktop_in_launcher"), "toggled",
 
1838
                     G_CALLBACK (on_enable_showdesktop_changed), self);
 
1839
  enable_showdesktop_widget_refresh (self);
 
1840
 
 
1841
  /* Restore defaut on second page */
 
1842
  g_signal_connect (WID ("button-restore-unitybehavior"), "clicked",
 
1843
                    G_CALLBACK (on_restore_defaults_page2_clicked), self);
 
1844
}
 
1845
 
 
1846
static void
 
1847
cc_appearance_panel_init (CcAppearancePanel *self)
 
1848
{
 
1849
  CcAppearancePanelPrivate *priv;
 
1850
  gchar *objects_unity[] = { "style-liststore",
 
1851
      "sources-liststore", "theme-list-store", "main-notebook", "sizegroup", NULL };
 
1852
  GError *err = NULL;
 
1853
  GtkWidget *widget;
 
1854
  GtkListStore *store;
 
1855
  GtkStyleContext *context;
 
1856
 
 
1857
  priv = self->priv = APPEARANCE_PANEL_PRIVATE (self);
 
1858
 
 
1859
  priv->builder = gtk_builder_new ();
 
1860
  gtk_builder_set_translation_domain (priv->builder, GETTEXT_PACKAGE);
 
1861
  gtk_builder_add_objects_from_file (priv->builder,
 
1862
                                       PKGDATADIR"/appearance.ui",
 
1863
                                       objects_unity, &err);
 
1864
 
 
1865
  if (err)
 
1866
    {
 
1867
      g_warning ("Could not load ui: %s", err->message);
 
1868
      g_error_free (err);
 
1869
      return;
 
1870
    }
 
1871
 
 
1872
  /* See shell_notify_cb for details */
 
1873
  g_signal_connect (WID ("scrolledwindow1"), "realize",
 
1874
                    G_CALLBACK (scrolled_realize_cb), self);
 
1875
 
 
1876
  priv->settings = g_settings_new (WP_PATH_ID);
 
1877
  g_settings_delay (priv->settings);
 
1878
 
 
1879
  store = (GtkListStore*) gtk_builder_get_object (priv->builder,
 
1880
                                                  "sources-liststore");
 
1881
 
 
1882
  priv->wallpapers_source = bg_wallpapers_source_new ();
 
1883
  gtk_list_store_insert_with_values (store, NULL, G_MAXINT,
 
1884
                                     COL_SOURCE_NAME, _("Wallpapers"),
 
1885
                                     COL_SOURCE_TYPE, SOURCE_WALLPAPERS,
 
1886
                                     COL_SOURCE, priv->wallpapers_source,
 
1887
                                     -1);
 
1888
 
 
1889
  priv->pictures_source = bg_pictures_source_new ();
 
1890
  gtk_list_store_insert_with_values (store, NULL, G_MAXINT,
 
1891
                                     COL_SOURCE_NAME, _("Pictures Folder"),
 
1892
                                     COL_SOURCE_TYPE, SOURCE_PICTURES,
 
1893
                                     COL_SOURCE, priv->pictures_source,
 
1894
                                     -1);
 
1895
 
 
1896
  priv->colors_source = bg_colors_source_new ();
 
1897
  gtk_list_store_insert_with_values (store, NULL, G_MAXINT,
 
1898
                                     COL_SOURCE_NAME, _("Colors & Gradients"),
 
1899
                                     COL_SOURCE_TYPE, SOURCE_COLORS,
 
1900
                                     COL_SOURCE, priv->colors_source,
 
1901
                                     -1);
 
1902
 
 
1903
#ifdef HAVE_LIBSOCIALWEB
 
1904
  priv->flickr_source = bg_flickr_source_new ();
 
1905
  gtk_list_store_insert_with_values (store, NULL, G_MAXINT,
 
1906
                                     COL_SOURCE_NAME, _("Flickr"),
 
1907
                                     COL_SOURCE_TYPE, SOURCE_FLICKR,
 
1908
                                     COL_SOURCE, priv->flickr_source,
 
1909
                                     -1);
 
1910
#endif
 
1911
 
 
1912
 
 
1913
  /* add the top level widget */
 
1914
  widget = WID ("main-notebook");
 
1915
 
 
1916
  gtk_container_add (GTK_CONTAINER (self), widget);
 
1917
  gtk_widget_show_all (GTK_WIDGET (self));
 
1918
 
 
1919
  /* connect to source change signal */
 
1920
  widget = WID ("sources-combobox");
 
1921
  g_signal_connect (widget, "changed", G_CALLBACK (source_changed_cb), priv);
 
1922
 
 
1923
  /* select first item */
 
1924
  gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
 
1925
 
 
1926
  /* connect to the background iconview change signal */
 
1927
  widget = WID ("backgrounds-iconview");
 
1928
  g_signal_connect (widget, "selection-changed",
 
1929
                    G_CALLBACK (backgrounds_changed_cb),
 
1930
                    self);
 
1931
 
 
1932
  /* Join treeview and buttons */
 
1933
  widget = WID ("scrolledwindow1");
 
1934
  context = gtk_widget_get_style_context (widget);
 
1935
  gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM);
 
1936
  widget = WID ("toolbar1");
 
1937
  context = gtk_widget_get_style_context (widget);
 
1938
  gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP);
 
1939
 
 
1940
  g_signal_connect (WID ("add_button"), "clicked",
 
1941
                    G_CALLBACK (add_button_clicked), self);
 
1942
  g_signal_connect (WID ("remove_button"), "clicked",
 
1943
                    G_CALLBACK (remove_button_clicked), self);
 
1944
 
 
1945
  /* Add drag and drop support for bg images */
 
1946
  widget = WID ("scrolledwindow1");
 
1947
  gtk_drag_dest_set (widget, GTK_DEST_DEFAULT_ALL, NULL, 0, GDK_ACTION_COPY);
 
1948
  gtk_drag_dest_add_uri_targets (widget);
 
1949
  g_signal_connect (widget, "drag-data-received",
 
1950
                    G_CALLBACK (cc_appearance_panel_drag_uris), self);
 
1951
 
 
1952
 
 
1953
  /* setup preview area */
 
1954
  gtk_label_set_ellipsize (GTK_LABEL (WID ("background-label")), PANGO_ELLIPSIZE_END);
 
1955
  widget = WID ("preview-area");
 
1956
  g_signal_connect (widget, "draw", G_CALLBACK (preview_draw_cb),
 
1957
                    self);
 
1958
 
 
1959
  priv->display_base = gdk_pixbuf_new_from_file (PKGDATADIR
 
1960
                                                 "/display-base.png",
 
1961
                                                 NULL);
 
1962
  priv->display_overlay = gdk_pixbuf_new_from_file (PKGDATADIR
 
1963
                                                    "/display-overlay.png",
 
1964
                                                    NULL);
 
1965
 
 
1966
  g_signal_connect (WID ("style-combobox"), "changed",
 
1967
                    G_CALLBACK (style_changed_cb), self);
 
1968
 
 
1969
  g_signal_connect (WID ("style-pcolor"), "color-set",
 
1970
                    G_CALLBACK (color_changed_cb), self);
 
1971
  g_signal_connect (WID ("style-scolor"), "color-set",
 
1972
                    G_CALLBACK (color_changed_cb), self);
 
1973
  g_signal_connect (WID ("swap-color-button"), "clicked",
 
1974
                    G_CALLBACK (swap_colors_clicked), self);
 
1975
 
 
1976
  priv->copy_cancellable = g_cancellable_new ();
 
1977
 
 
1978
  priv->thumb_factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL);
 
1979
 
 
1980
  load_current_bg (self);
 
1981
 
 
1982
  update_preview (priv, NULL);
 
1983
 
 
1984
  /* Setup the edit box with our current settings */
 
1985
  source_update_edit_box (priv, TRUE);
 
1986
 
 
1987
  /* Setup theme selector */
 
1988
  setup_theme_selector (self);
 
1989
 
 
1990
  /* Setup unity settings */
 
1991
  setup_unity_settings (self);
 
1992
}
 
1993
 
 
1994
void
 
1995
cc_appearance_panel_register (GIOModule *module)
 
1996
{
 
1997
  cc_appearance_panel_register_type (G_TYPE_MODULE (module));
 
1998
  g_io_extension_point_implement (CC_SHELL_PANEL_EXTENSION_POINT,
 
1999
                                  CC_TYPE_APPEARANCE_PANEL,
 
2000
                                  "appearance", 0);
 
2001
}
 
2002