1 /*
2 * Copyright (c) 2013 Andrzej Radecki <andrzejr@xfce.org>
3 * Copyright (c) 2017 Viktor Odintsev <ninetls@xfce.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25 #ifdef HAVE_STRING_H
26 #include <string.h>
27 #endif
28
29 #include <libxfce4ui/libxfce4ui.h>
30 #include <libxfce4util/libxfce4util.h>
31 #include <libxfce4panel/xfce-panel-plugin.h>
32 #include <xfconf/xfconf.h>
33 #ifdef XFCONF_LEGACY
34 #include <dbus/dbus-glib.h>
35 #endif
36
37 #include "sn-plugin.h"
38 #include "sn-config.h"
39
40
41
42 #define DEFAULT_ICON_SIZE 22
43 #define DEFAULT_SINGLE_ROW FALSE
44 #define DEFAULT_SQUARE_ICONS FALSE
45 #define DEFAULT_SYMBOLIC_ICONS FALSE
46 #define DEFAULT_MENU_IS_PRIMARY FALSE
47 #define DEFAULT_ORIENTATION GTK_ORIENTATION_HORIZONTAL
48 #define DEFAULT_PANEL_ORIENTATION GTK_ORIENTATION_HORIZONTAL
49 #define DEFAULT_PANEL_SIZE 28
50 #define DEFAULT_HIDE_NEW_ITEMS FALSE
51
52
53
54 static void sn_config_finalize (GObject *object);
55
56 static void sn_config_get_property (GObject *object,
57 guint prop_id,
58 GValue *value,
59 GParamSpec *pspec);
60
61 static void sn_config_set_property (GObject *object,
62 guint prop_id,
63 const GValue *value,
64 GParamSpec *pspec);
65
66
67
68 struct _SnConfigClass
69 {
70 GObjectClass __parent__;
71 };
72
73 struct _SnConfig
74 {
75 GObject __parent__;
76
77 gint icon_size;
78 gboolean single_row;
79 gboolean square_icons;
80 gboolean symbolic_icons;
81 gboolean menu_is_primary;
82 gboolean hide_new_items;
83 GList *known_items;
84 GHashTable *hidden_items;
85 GList *known_legacy_items;
86 GHashTable *hidden_legacy_items;
87
88 /* not xfconf properties but it is still convenient to have them here */
89 GtkOrientation orientation;
90 GtkOrientation panel_orientation;
91 gint nrows;
92 gint panel_size;
93 gint panel_icon_size;
94 };
95
96 G_DEFINE_TYPE (SnConfig, sn_config, G_TYPE_OBJECT)
97
98
99
100 enum
101 {
102 PROP_0,
103 PROP_ICON_SIZE,
104 PROP_SINGLE_ROW,
105 PROP_SQUARE_ICONS,
106 PROP_SYMBOLIC_ICONS,
107 PROP_MENU_IS_PRIMARY,
108 PROP_HIDE_NEW_ITEMS,
109 PROP_KNOWN_ITEMS,
110 PROP_HIDDEN_ITEMS,
111 PROP_KNOWN_LEGACY_ITEMS,
112 PROP_HIDDEN_LEGACY_ITEMS
113 };
114
115 enum
116 {
117 CONFIGURATION_CHANGED,
118 ITEM_LIST_CHANGED,
119 COLLECT_KNOWN_ITEMS,
120 LEGACY_ITEM_LIST_CHANGED,
121 ICONS_CHANGED,
122 LAST_SIGNAL
123 };
124
125 static guint sn_config_signals[LAST_SIGNAL] = { 0, };
126
127
128 #ifdef XFCONF_LEGACY
129
130 #define XFCE_TYPE_SN_CONFIG_VALUE_ARRAY (sn_config_value_array_get_type ())
131
132 static GType
sn_config_value_array_get_type(void)133 sn_config_value_array_get_type (void)
134 {
135 static volatile gsize type__volatile = 0;
136 GType type;
137
138 if (g_once_init_enter (&type__volatile))
139 {
140 type = dbus_g_type_get_collection ("GPtrArray", G_TYPE_VALUE);
141 g_once_init_leave (&type__volatile, type);
142 }
143
144 return type__volatile;
145 }
146
147 #else
148
149 #define XFCE_TYPE_SN_CONFIG_VALUE_ARRAY G_TYPE_PTR_ARRAY
150
151 #endif
152
153
154
155 static void
sn_config_class_init(SnConfigClass * klass)156 sn_config_class_init (SnConfigClass *klass)
157 {
158 GObjectClass *object_class;
159
160 object_class = G_OBJECT_CLASS (klass);
161 object_class->finalize = sn_config_finalize;
162 object_class->get_property = sn_config_get_property;
163 object_class->set_property = sn_config_set_property;
164
165 g_object_class_install_property (object_class,
166 PROP_ICON_SIZE,
167 g_param_spec_int ("icon-size", NULL, NULL,
168 0, 64, DEFAULT_ICON_SIZE,
169 G_PARAM_READWRITE |
170 G_PARAM_STATIC_STRINGS));
171
172 g_object_class_install_property (object_class,
173 PROP_SINGLE_ROW,
174 g_param_spec_boolean ("single-row", NULL, NULL,
175 DEFAULT_SINGLE_ROW,
176 G_PARAM_READWRITE |
177 G_PARAM_STATIC_STRINGS));
178
179 g_object_class_install_property (object_class,
180 PROP_SQUARE_ICONS,
181 g_param_spec_boolean ("square-icons", NULL, NULL,
182 DEFAULT_SQUARE_ICONS,
183 G_PARAM_READWRITE |
184 G_PARAM_STATIC_STRINGS));
185
186 g_object_class_install_property (object_class,
187 PROP_SYMBOLIC_ICONS,
188 g_param_spec_boolean ("symbolic-icons", NULL, NULL,
189 DEFAULT_SYMBOLIC_ICONS,
190 G_PARAM_READWRITE |
191 G_PARAM_STATIC_STRINGS));
192
193 g_object_class_install_property (object_class,
194 PROP_MENU_IS_PRIMARY,
195 g_param_spec_boolean ("menu-is-primary", NULL, NULL,
196 DEFAULT_MENU_IS_PRIMARY,
197 G_PARAM_READWRITE |
198 G_PARAM_STATIC_STRINGS));
199
200 g_object_class_install_property (object_class,
201 PROP_HIDE_NEW_ITEMS,
202 g_param_spec_boolean ("hide-new-items", NULL, NULL,
203 DEFAULT_HIDE_NEW_ITEMS,
204 G_PARAM_READWRITE |
205 G_PARAM_STATIC_STRINGS));
206
207 g_object_class_install_property (object_class,
208 PROP_KNOWN_ITEMS,
209 g_param_spec_boxed ("known-items",
210 NULL, NULL,
211 XFCE_TYPE_SN_CONFIG_VALUE_ARRAY,
212 G_PARAM_READWRITE |
213 G_PARAM_STATIC_STRINGS));
214
215 g_object_class_install_property (object_class,
216 PROP_HIDDEN_ITEMS,
217 g_param_spec_boxed ("hidden-items",
218 NULL, NULL,
219 XFCE_TYPE_SN_CONFIG_VALUE_ARRAY,
220 G_PARAM_READWRITE |
221 G_PARAM_STATIC_STRINGS));
222
223 g_object_class_install_property (object_class,
224 PROP_KNOWN_LEGACY_ITEMS,
225 g_param_spec_boxed ("known-legacy-items",
226 NULL, NULL,
227 XFCE_TYPE_SN_CONFIG_VALUE_ARRAY,
228 G_PARAM_READWRITE |
229 G_PARAM_STATIC_STRINGS));
230
231 g_object_class_install_property (object_class,
232 PROP_HIDDEN_LEGACY_ITEMS,
233 g_param_spec_boxed ("hidden-legacy-items",
234 NULL, NULL,
235 XFCE_TYPE_SN_CONFIG_VALUE_ARRAY,
236 G_PARAM_READWRITE |
237 G_PARAM_STATIC_STRINGS));
238
239 sn_config_signals[CONFIGURATION_CHANGED] =
240 g_signal_new (g_intern_static_string ("configuration-changed"),
241 G_TYPE_FROM_CLASS (object_class),
242 G_SIGNAL_RUN_LAST,
243 0, NULL, NULL,
244 g_cclosure_marshal_VOID__VOID,
245 G_TYPE_NONE, 0);
246
247 sn_config_signals[ICONS_CHANGED] =
248 g_signal_new (g_intern_static_string ("icons-changed"),
249 G_TYPE_FROM_CLASS (object_class),
250 G_SIGNAL_RUN_LAST,
251 0, NULL, NULL,
252 g_cclosure_marshal_VOID__VOID,
253 G_TYPE_NONE, 0);
254
255 sn_config_signals[ITEM_LIST_CHANGED] =
256 g_signal_new (g_intern_static_string ("items-list-changed"),
257 G_TYPE_FROM_CLASS (object_class),
258 G_SIGNAL_RUN_LAST,
259 0, NULL, NULL,
260 g_cclosure_marshal_VOID__VOID,
261 G_TYPE_NONE, 0);
262
263 sn_config_signals[COLLECT_KNOWN_ITEMS] =
264 g_signal_new (g_intern_static_string ("collect-known-items"),
265 G_TYPE_FROM_CLASS (object_class),
266 G_SIGNAL_RUN_LAST,
267 0, NULL, NULL,
268 g_cclosure_marshal_generic,
269 G_TYPE_NONE, 1, G_TYPE_POINTER);
270
271 sn_config_signals[LEGACY_ITEM_LIST_CHANGED] =
272 g_signal_new (g_intern_static_string ("legacy-items-list-changed"),
273 G_TYPE_FROM_CLASS (object_class),
274 G_SIGNAL_RUN_LAST,
275 0, NULL, NULL,
276 g_cclosure_marshal_VOID__VOID,
277 G_TYPE_NONE, 0);
278 }
279
280
281
282 static void
sn_config_init(SnConfig * config)283 sn_config_init (SnConfig *config)
284 {
285 config->icon_size = DEFAULT_ICON_SIZE;
286 config->single_row = DEFAULT_SINGLE_ROW;
287 config->square_icons = DEFAULT_SQUARE_ICONS;
288 config->symbolic_icons = DEFAULT_SYMBOLIC_ICONS;
289 config->hide_new_items = DEFAULT_HIDE_NEW_ITEMS;
290 config->known_items = NULL;
291 config->hidden_items = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
292 config->known_legacy_items = NULL;
293 config->hidden_legacy_items = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
294
295 config->orientation = DEFAULT_ORIENTATION;
296 config->panel_orientation = DEFAULT_PANEL_ORIENTATION;
297 config->nrows = 1;
298 config->panel_size = DEFAULT_PANEL_SIZE;
299 }
300
301
302
303 static void
sn_config_finalize(GObject * object)304 sn_config_finalize (GObject *object)
305 {
306 SnConfig *config = XFCE_SN_CONFIG (object);
307
308 xfconf_shutdown ();
309
310 g_list_free_full (config->known_items, g_free);
311 g_hash_table_destroy (config->hidden_items);
312
313 g_list_free_full (config->known_legacy_items, g_free);
314 g_hash_table_destroy (config->hidden_legacy_items);
315
316 G_OBJECT_CLASS (sn_config_parent_class)->finalize (object);
317 }
318
319
320
321 static void
sn_config_free_array_element(gpointer data)322 sn_config_free_array_element (gpointer data)
323 {
324 GValue *value = (GValue *)data;
325
326 g_value_unset (value);
327 g_free (value);
328 }
329
330
331
332 static void
sn_config_collect_keys(gpointer key,gpointer value,gpointer array)333 sn_config_collect_keys (gpointer key,
334 gpointer value,
335 gpointer array)
336 {
337 GValue *tmp;
338
339 tmp = g_new0 (GValue, 1);
340 g_value_init (tmp, G_TYPE_STRING);
341 g_value_set_string (tmp, key);
342 g_ptr_array_add (array, tmp);
343 }
344
345
346
347 static void
sn_config_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)348 sn_config_get_property (GObject *object,
349 guint prop_id,
350 GValue *value,
351 GParamSpec *pspec)
352 {
353 SnConfig *config = XFCE_SN_CONFIG (object);
354 GPtrArray *array;
355 GList *li;
356 GValue *tmp;
357
358 switch (prop_id)
359 {
360 case PROP_ICON_SIZE:
361 g_value_set_int (value, config->icon_size);
362 break;
363
364 case PROP_SINGLE_ROW:
365 g_value_set_boolean (value, config->single_row);
366 break;
367
368 case PROP_SQUARE_ICONS:
369 g_value_set_boolean (value, config->square_icons);
370 break;
371
372 case PROP_SYMBOLIC_ICONS:
373 g_value_set_boolean (value, config->symbolic_icons);
374 break;
375
376 case PROP_MENU_IS_PRIMARY:
377 g_value_set_boolean (value, config->menu_is_primary);
378 break;
379
380 case PROP_HIDE_NEW_ITEMS:
381 g_value_set_boolean (value, config->hide_new_items);
382 break;
383
384 case PROP_KNOWN_ITEMS:
385 array = g_ptr_array_new_full (1, sn_config_free_array_element);
386 for (li = config->known_items; li != NULL; li = li->next)
387 {
388 tmp = g_new0 (GValue, 1);
389 g_value_init (tmp, G_TYPE_STRING);
390 g_value_set_string (tmp, li->data);
391 g_ptr_array_add (array, tmp);
392 }
393 g_value_set_boxed (value, array);
394 g_ptr_array_unref (array);
395 break;
396
397 case PROP_HIDDEN_ITEMS:
398 array = g_ptr_array_new_full (1, sn_config_free_array_element);
399 g_hash_table_foreach (config->hidden_items, sn_config_collect_keys, array);
400 g_value_set_boxed (value, array);
401 g_ptr_array_unref (array);
402 break;
403
404 case PROP_KNOWN_LEGACY_ITEMS:
405 array = g_ptr_array_new_full (1, sn_config_free_array_element);
406 for (li = config->known_legacy_items; li != NULL; li = li->next)
407 {
408 tmp = g_new0 (GValue, 1);
409 g_value_init (tmp, G_TYPE_STRING);
410 g_value_set_string (tmp, li->data);
411 g_ptr_array_add (array, tmp);
412 }
413 g_value_set_boxed (value, array);
414 g_ptr_array_unref (array);
415 break;
416
417 case PROP_HIDDEN_LEGACY_ITEMS:
418 array = g_ptr_array_new_full (1, sn_config_free_array_element);
419 g_hash_table_foreach (config->hidden_legacy_items, sn_config_collect_keys, array);
420 g_value_set_boxed (value, array);
421 g_ptr_array_unref (array);
422 break;
423
424 default:
425 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
426 break;
427 }
428 }
429
430
431
432 static void
sn_config_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)433 sn_config_set_property (GObject *object,
434 guint prop_id,
435 const GValue *value,
436 GParamSpec *pspec)
437 {
438 SnConfig *config = XFCE_SN_CONFIG (object);
439 gint val;
440 GPtrArray *array;
441 const GValue *tmp;
442 gchar *name;
443 guint i;
444
445 switch (prop_id)
446 {
447 case PROP_ICON_SIZE:
448 val = g_value_get_int (value);
449 if (config->icon_size != val)
450 {
451 config->icon_size = val;
452 g_signal_emit (G_OBJECT (config), sn_config_signals[ICONS_CHANGED], 0);
453 g_signal_emit (G_OBJECT (config), sn_config_signals[CONFIGURATION_CHANGED], 0);
454 }
455 break;
456
457 case PROP_SINGLE_ROW:
458 val = g_value_get_boolean (value);
459 if (config->single_row != val)
460 {
461 config->single_row = val;
462 g_signal_emit (G_OBJECT (config), sn_config_signals[CONFIGURATION_CHANGED], 0);
463 }
464 break;
465
466 case PROP_SQUARE_ICONS:
467 val = g_value_get_boolean (value);
468 if (config->square_icons != val)
469 {
470 config->square_icons = val;
471 g_signal_emit (G_OBJECT (config), sn_config_signals[CONFIGURATION_CHANGED], 0);
472 }
473 break;
474
475 case PROP_SYMBOLIC_ICONS:
476 val = g_value_get_boolean (value);
477 if (config->symbolic_icons != val)
478 {
479 config->symbolic_icons = val;
480 g_signal_emit (G_OBJECT (config), sn_config_signals[CONFIGURATION_CHANGED], 0);
481 }
482 break;
483
484 case PROP_MENU_IS_PRIMARY:
485 val = g_value_get_boolean (value);
486 if (config->menu_is_primary != val)
487 {
488 config->menu_is_primary = val;
489 g_signal_emit (G_OBJECT (config), sn_config_signals[CONFIGURATION_CHANGED], 0);
490 }
491 break;
492
493 case PROP_HIDE_NEW_ITEMS:
494 val = g_value_get_boolean (value);
495 if (config->hide_new_items != val)
496 {
497 config->hide_new_items = val;
498 g_signal_emit (G_OBJECT (config), sn_config_signals[ITEM_LIST_CHANGED], 0);
499 g_signal_emit (G_OBJECT (config), sn_config_signals[LEGACY_ITEM_LIST_CHANGED], 0);
500 }
501 break;
502
503 case PROP_KNOWN_ITEMS:
504 g_list_free_full (config->known_items, g_free);
505 config->known_items = NULL;
506 array = g_value_get_boxed (value);
507 if (G_LIKELY (array != NULL))
508 {
509 for (i = 0; i < array->len; i++)
510 {
511 tmp = g_ptr_array_index (array, i);
512 g_assert (G_VALUE_HOLDS_STRING (tmp));
513 name = g_value_dup_string (tmp);
514 config->known_items = g_list_append (config->known_items, name);
515 }
516 }
517 g_signal_emit (G_OBJECT (config), sn_config_signals[ITEM_LIST_CHANGED], 0);
518 break;
519
520 case PROP_HIDDEN_ITEMS:
521 g_hash_table_remove_all (config->hidden_items);
522 array = g_value_get_boxed (value);
523 if (G_LIKELY (array != NULL))
524 {
525 for (i = 0; i < array->len; i++)
526 {
527 tmp = g_ptr_array_index (array, i);
528 g_assert (G_VALUE_HOLDS_STRING (tmp));
529 name = g_value_dup_string (tmp);
530 g_hash_table_replace (config->hidden_items, name, name);
531 }
532 }
533 g_signal_emit (G_OBJECT (config), sn_config_signals[ITEM_LIST_CHANGED], 0);
534 break;
535
536 case PROP_KNOWN_LEGACY_ITEMS:
537 g_list_free_full (config->known_legacy_items, g_free);
538 config->known_legacy_items = NULL;
539 array = g_value_get_boxed (value);
540 if (G_LIKELY (array != NULL))
541 {
542 for (i = 0; i < array->len; i++)
543 {
544 tmp = g_ptr_array_index (array, i);
545 g_assert (G_VALUE_HOLDS_STRING (tmp));
546 name = g_value_dup_string (tmp);
547 config->known_legacy_items = g_list_append (config->known_legacy_items, name);
548 }
549 }
550 g_signal_emit (G_OBJECT (config), sn_config_signals[LEGACY_ITEM_LIST_CHANGED], 0);
551 break;
552
553 case PROP_HIDDEN_LEGACY_ITEMS:
554 g_hash_table_remove_all (config->hidden_legacy_items);
555 array = g_value_get_boxed (value);
556 if (G_LIKELY (array != NULL))
557 {
558 for (i = 0; i < array->len; i++)
559 {
560 tmp = g_ptr_array_index (array, i);
561 g_assert (G_VALUE_HOLDS_STRING (tmp));
562 name = g_value_dup_string (tmp);
563 g_hash_table_replace (config->hidden_legacy_items, name, name);
564 }
565 }
566 g_signal_emit (G_OBJECT (config), sn_config_signals[LEGACY_ITEM_LIST_CHANGED], 0);
567 break;
568
569 default:
570 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
571 break;
572 }
573 }
574
575
576
577 gint
sn_config_get_icon_size(SnConfig * config)578 sn_config_get_icon_size (SnConfig *config)
579 {
580 g_return_val_if_fail (XFCE_IS_SN_CONFIG (config), DEFAULT_ICON_SIZE);
581
582 if (config->icon_size > 0)
583 return config->icon_size;
584
585 return config->panel_icon_size;
586 }
587
588
589
590 gboolean
sn_config_get_icon_size_is_automatic(SnConfig * config)591 sn_config_get_icon_size_is_automatic (SnConfig *config)
592 {
593 g_return_val_if_fail (XFCE_IS_SN_CONFIG (config), FALSE);
594
595 return config->icon_size == 0;
596 }
597
598
599
600 void
sn_config_get_dimensions(SnConfig * config,gint * ret_icon_size,gint * ret_n_rows,gint * ret_row_size,gint * ret_padding)601 sn_config_get_dimensions (SnConfig *config,
602 gint *ret_icon_size,
603 gint *ret_n_rows,
604 gint *ret_row_size,
605 gint *ret_padding)
606 {
607 gint panel_size, config_nrows, icon_size, hx_size, hy_size, nrows, row_size, padding;
608 gboolean single_row, square_icons;
609
610 panel_size = sn_config_get_panel_size(config);
611 config_nrows = sn_config_get_nrows(config);
612 icon_size = sn_config_get_icon_size(config);
613 single_row = sn_config_get_single_row(config);
614 square_icons = sn_config_get_square_icons(config);
615 if (square_icons)
616 {
617 single_row = TRUE;
618 nrows = single_row ? 1 : MAX(1, config_nrows);
619 hx_size = hy_size = panel_size / nrows;
620 }
621 else
622 {
623 hx_size = MIN(icon_size + 2, panel_size);
624 nrows = single_row ? 1 : MAX(1, panel_size / hx_size);
625 hy_size = panel_size / nrows;
626 }
627 icon_size = MIN(icon_size, MIN(hx_size, hy_size));
628
629 if (icon_size % 2 != 0)
630 {
631 icon_size--;
632 }
633
634 row_size = hy_size;
635 padding = (hy_size - icon_size) / 2;
636
637 if (square_icons)
638 padding = 0;
639
640 if (ret_icon_size != NULL)
641 *ret_icon_size = icon_size;
642
643 if (ret_n_rows != NULL)
644 *ret_n_rows = nrows;
645
646 if (ret_row_size != NULL)
647 *ret_row_size = row_size;
648
649 if (ret_padding != NULL)
650 *ret_padding = padding;
651 }
652
653
654
655 gboolean
sn_config_get_single_row(SnConfig * config)656 sn_config_get_single_row (SnConfig *config)
657 {
658 g_return_val_if_fail (XFCE_IS_SN_CONFIG (config), DEFAULT_SINGLE_ROW);
659
660 return config->single_row;
661 }
662
663
664
665 gboolean
sn_config_get_square_icons(SnConfig * config)666 sn_config_get_square_icons (SnConfig *config)
667 {
668 g_return_val_if_fail (XFCE_IS_SN_CONFIG (config), DEFAULT_SQUARE_ICONS);
669
670 return config->square_icons;
671 }
672
673
674
675 gboolean
sn_config_get_symbolic_icons(SnConfig * config)676 sn_config_get_symbolic_icons (SnConfig *config)
677 {
678 g_return_val_if_fail (XFCE_IS_SN_CONFIG (config), DEFAULT_SYMBOLIC_ICONS);
679
680 return config->symbolic_icons;
681 }
682
683
684
685 gboolean
sn_config_get_menu_is_primary(SnConfig * config)686 sn_config_get_menu_is_primary (SnConfig *config)
687 {
688 g_return_val_if_fail (XFCE_IS_SN_CONFIG (config), DEFAULT_MENU_IS_PRIMARY);
689
690 return config->menu_is_primary;
691 }
692
693
694
695 void
sn_config_set_orientation(SnConfig * config,GtkOrientation panel_orientation,GtkOrientation orientation)696 sn_config_set_orientation (SnConfig *config,
697 GtkOrientation panel_orientation,
698 GtkOrientation orientation)
699 {
700 gboolean needs_update = FALSE;
701
702 g_return_if_fail (XFCE_IS_SN_CONFIG (config));
703
704 if (config->orientation != orientation)
705 {
706 config->orientation = orientation;
707 needs_update = TRUE;
708 }
709
710 if (config->panel_orientation != panel_orientation)
711 {
712 config->panel_orientation = panel_orientation;
713 needs_update = TRUE;
714 }
715
716 if (needs_update)
717 g_signal_emit (G_OBJECT (config), sn_config_signals[CONFIGURATION_CHANGED], 0);
718 }
719
720
721
722 GtkOrientation
sn_config_get_orientation(SnConfig * config)723 sn_config_get_orientation (SnConfig *config)
724 {
725 g_return_val_if_fail (XFCE_IS_SN_CONFIG (config), DEFAULT_ORIENTATION);
726
727 return config->orientation;
728 }
729
730
731
732 GtkOrientation
sn_config_get_panel_orientation(SnConfig * config)733 sn_config_get_panel_orientation (SnConfig *config)
734 {
735 g_return_val_if_fail (XFCE_IS_SN_CONFIG (config), DEFAULT_PANEL_ORIENTATION);
736
737 return config->panel_orientation;
738 }
739
740
741
742 void
sn_config_set_size(SnConfig * config,gint panel_size,gint nrows,gint icon_size)743 sn_config_set_size (SnConfig *config,
744 gint panel_size,
745 gint nrows,
746 gint icon_size)
747 {
748 gboolean needs_update = FALSE;
749
750 g_return_if_fail (XFCE_IS_SN_CONFIG (config));
751
752 if (config->nrows != nrows)
753 {
754 config->nrows = nrows;
755 needs_update = TRUE;
756 }
757
758 if (config->panel_size != panel_size)
759 {
760 config->panel_size = panel_size;
761 needs_update = TRUE;
762 }
763
764 if (config->panel_icon_size != icon_size)
765 {
766 config->panel_icon_size = icon_size;
767 needs_update = TRUE;
768 g_signal_emit (G_OBJECT (config), sn_config_signals[ICONS_CHANGED], 0);
769 }
770
771 if (needs_update)
772 g_signal_emit (G_OBJECT (config), sn_config_signals[CONFIGURATION_CHANGED], 0);
773 }
774
775
776
777 gint
sn_config_get_nrows(SnConfig * config)778 sn_config_get_nrows (SnConfig *config)
779 {
780 g_return_val_if_fail (XFCE_IS_SN_CONFIG (config), 1);
781
782 return config->nrows;
783 }
784
785
786
787 gint
sn_config_get_panel_size(SnConfig * config)788 sn_config_get_panel_size (SnConfig *config)
789 {
790 g_return_val_if_fail (XFCE_IS_SN_CONFIG (config), DEFAULT_PANEL_SIZE);
791
792 return config->panel_size;
793 }
794
795
796
797 gboolean
sn_config_is_hidden(SnConfig * config,const gchar * name)798 sn_config_is_hidden (SnConfig *config,
799 const gchar *name)
800 {
801 g_return_val_if_fail (XFCE_IS_SN_CONFIG (config), FALSE);
802
803 return g_hash_table_lookup_extended (config->hidden_items, name, NULL, NULL);
804 }
805
806
807
808 void
sn_config_set_hidden(SnConfig * config,const gchar * name,gboolean hidden)809 sn_config_set_hidden (SnConfig *config,
810 const gchar *name,
811 gboolean hidden)
812 {
813 gchar *name_copy;
814
815 g_return_if_fail (XFCE_IS_SN_CONFIG (config));
816
817 if (hidden)
818 {
819 name_copy = g_strdup (name);
820 g_hash_table_replace (config->hidden_items, name_copy, name_copy);
821 }
822 else
823 {
824 g_hash_table_remove (config->hidden_items, name);
825 }
826 g_object_notify (G_OBJECT (config), "hidden-items");
827 g_signal_emit (G_OBJECT (config), sn_config_signals[ITEM_LIST_CHANGED], 0);
828 }
829
830
831
832 gboolean
sn_config_is_legacy_hidden(SnConfig * config,const gchar * name)833 sn_config_is_legacy_hidden (SnConfig *config,
834 const gchar *name)
835 {
836 g_return_val_if_fail (XFCE_IS_SN_CONFIG (config), FALSE);
837
838 return g_hash_table_lookup_extended (config->hidden_legacy_items, name, NULL, NULL);
839 }
840
841
842
843 void
sn_config_set_legacy_hidden(SnConfig * config,const gchar * name,gboolean hidden)844 sn_config_set_legacy_hidden (SnConfig *config,
845 const gchar *name,
846 gboolean hidden)
847 {
848 gchar *name_copy;
849
850 g_return_if_fail (XFCE_IS_SN_CONFIG (config));
851
852 if (hidden)
853 {
854 name_copy = g_strdup (name);
855 g_hash_table_replace (config->hidden_legacy_items, name_copy, name_copy);
856 }
857 else
858 {
859 g_hash_table_remove (config->hidden_legacy_items, name);
860 }
861 g_object_notify (G_OBJECT (config), "hidden-legacy-items");
862 g_signal_emit (G_OBJECT (config), sn_config_signals[LEGACY_ITEM_LIST_CHANGED], 0);
863 }
864
865
866
867 GList*
sn_config_get_known_items(SnConfig * config)868 sn_config_get_known_items (SnConfig *config)
869 {
870 g_return_val_if_fail (XFCE_IS_SN_CONFIG (config), NULL);
871
872 return config->known_items;
873 }
874
875
876
877 GList*
sn_config_get_known_legacy_items(SnConfig * config)878 sn_config_get_known_legacy_items (SnConfig *config)
879 {
880 g_return_val_if_fail (XFCE_IS_SN_CONFIG (config), NULL);
881
882 return config->known_legacy_items;
883 }
884
885
886
887 GList*
sn_config_get_hidden_legacy_items(SnConfig * config)888 sn_config_get_hidden_legacy_items (SnConfig *config)
889 {
890 GList *list = NULL;
891
892 g_return_val_if_fail (XFCE_IS_SN_CONFIG (config), NULL);
893
894 list = g_hash_table_get_values (config->hidden_legacy_items);
895
896 return list;
897 }
898
899
900
901 void
sn_config_add_known_item(SnConfig * config,const gchar * name)902 sn_config_add_known_item (SnConfig *config,
903 const gchar *name)
904 {
905 GList *li;
906 gchar *name_copy;
907
908 g_return_if_fail (XFCE_IS_SN_CONFIG (config));
909
910 /* check if item is already known */
911 for(li = config->known_items; li != NULL; li = li->next)
912 if (g_strcmp0 (li->data, name) == 0)
913 return;
914
915 config->known_items = g_list_prepend (config->known_items, g_strdup (name));
916
917 if (config->hide_new_items)
918 {
919 name_copy = g_strdup (name);
920 g_hash_table_replace (config->hidden_items, name_copy, name_copy);
921 g_object_notify (G_OBJECT (config), "hidden-items");
922 }
923
924 g_object_notify (G_OBJECT (config), "known-items");
925 g_signal_emit (G_OBJECT (config), sn_config_signals[ITEM_LIST_CHANGED], 0);
926 }
927
928
929
930 gboolean
sn_config_add_known_legacy_item(SnConfig * config,const gchar * name)931 sn_config_add_known_legacy_item (SnConfig *config,
932 const gchar *name)
933 {
934 GList *li;
935 gchar *name_copy;
936
937 g_return_val_if_fail (XFCE_IS_SN_CONFIG (config), TRUE);
938
939 /* check if item is already known */
940 for(li = config->known_legacy_items; li != NULL; li = li->next)
941 if (g_strcmp0 (li->data, name) == 0)
942 return g_hash_table_contains (config->hidden_legacy_items, name);
943
944 config->known_legacy_items = g_list_prepend (config->known_legacy_items, g_strdup (name));
945
946 if (config->hide_new_items)
947 {
948 name_copy = g_strdup (name);
949 g_hash_table_replace (config->hidden_legacy_items, name_copy, name_copy);
950 g_object_notify (G_OBJECT (config), "hidden-legacy-items");
951 }
952
953 g_object_notify (G_OBJECT (config), "known-legacy-items");
954 g_signal_emit (G_OBJECT (config), sn_config_signals[LEGACY_ITEM_LIST_CHANGED], 0);
955
956 return config->hide_new_items;
957 }
958
959
960
961 void
sn_config_swap_known_items(SnConfig * config,const gchar * name1,const gchar * name2)962 sn_config_swap_known_items (SnConfig *config,
963 const gchar *name1,
964 const gchar *name2)
965 {
966 GList *li, *li_tmp;
967
968 g_return_if_fail (XFCE_IS_SN_CONFIG (config));
969
970 for(li = config->known_items; li != NULL; li = li->next)
971 if (g_strcmp0 (li->data, name1) == 0)
972 break;
973
974 /* make sure that the list contains name1 followed by name2 */
975 if (li == NULL || li->next == NULL || g_strcmp0 (li->next->data, name2) != 0)
976 {
977 g_debug("Couldn't swap items: %s and %s", name1, name2);
978 return;
979 }
980
981 /* li_tmp will contain only the removed element (name2) */
982 li_tmp = li->next;
983 config->known_items = g_list_remove_link (config->known_items, li_tmp);
984
985 /* not strictly necessary (in testing the list contents was preserved)
986 * but searching for the index again should be safer */
987 for(li = config->known_items; li != NULL; li = li->next)
988 if (g_strcmp0 (li->data, name1) == 0)
989 break;
990
991 config->known_items = g_list_insert_before (config->known_items, li, li_tmp->data);
992 g_list_free (li_tmp);
993
994 g_object_notify (G_OBJECT (config), "known-items");
995 g_signal_emit (G_OBJECT (config), sn_config_signals[ITEM_LIST_CHANGED], 0);
996 }
997
998
999
sn_config_swap_known_legacy_items(SnConfig * config,const gchar * name1,const gchar * name2)1000 void sn_config_swap_known_legacy_items(SnConfig *config,
1001 const gchar *name1,
1002 const gchar *name2)
1003 {
1004 GList *li, *li_tmp;
1005
1006 g_return_if_fail(XFCE_IS_SN_CONFIG(config));
1007
1008 for (li = config->known_legacy_items; li != NULL; li = li->next)
1009 if (g_strcmp0(li->data, name1) == 0)
1010 break;
1011
1012 /* make sure that the list contains name1 followed by name2 */
1013 if (li == NULL || li->next == NULL || g_strcmp0(li->next->data, name2) != 0)
1014 {
1015 g_debug("Couldn't swap items: %s and %s", name1, name2);
1016 return;
1017 }
1018
1019 /* li_tmp will contain only the removed element (name2) */
1020 li_tmp = li->next;
1021 config->known_legacy_items = g_list_remove_link(config->known_legacy_items, li_tmp);
1022
1023 /* not strictly necessary (in testing the list contents was preserved)
1024 * but searching for the index again should be safer */
1025 for (li = config->known_legacy_items; li != NULL; li = li->next)
1026 if (g_strcmp0(li->data, name1) == 0)
1027 break;
1028
1029 config->known_legacy_items = g_list_insert_before(config->known_legacy_items, li, li_tmp->data);
1030 g_list_free(li_tmp);
1031
1032 g_object_notify(G_OBJECT(config), "known-legacy-items");
1033 g_signal_emit(G_OBJECT(config), sn_config_signals[LEGACY_ITEM_LIST_CHANGED], 0);
1034 }
1035
1036
1037
1038 static gboolean
sn_config_items_clear_callback(gpointer key,gpointer value,gpointer user_data)1039 sn_config_items_clear_callback (gpointer key,
1040 gpointer value,
1041 gpointer user_data)
1042 {
1043 GHashTable *collected_known_items = user_data;
1044 return !g_hash_table_contains (collected_known_items, key);
1045 }
1046
1047
1048
1049 gboolean
sn_config_items_clear(SnConfig * config)1050 sn_config_items_clear (SnConfig *config)
1051 {
1052 GHashTable *collected_known_items;
1053 guint initial_size;
1054 GList *new_list, *li;
1055
1056 collected_known_items = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
1057
1058 g_signal_emit (G_OBJECT (config), sn_config_signals[COLLECT_KNOWN_ITEMS],
1059 0, collected_known_items);
1060
1061 initial_size = g_list_length (config->known_items);
1062 new_list = NULL;
1063 for (li = config->known_items; li != NULL; li = li->next)
1064 {
1065 if (g_hash_table_contains (collected_known_items, li->data))
1066 {
1067 new_list = g_list_append (new_list, g_strdup (li->data));
1068 }
1069 }
1070 g_list_free_full (config->known_items, g_free);
1071 config->known_items = new_list;
1072
1073 g_hash_table_foreach_remove (config->hidden_items,
1074 sn_config_items_clear_callback,
1075 collected_known_items);
1076 g_hash_table_destroy (collected_known_items);
1077
1078 if (initial_size != g_list_length (config->known_items))
1079 {
1080 g_object_notify (G_OBJECT (config), "known-items");
1081 g_object_notify (G_OBJECT (config), "hidden-items");
1082 g_signal_emit (G_OBJECT (config), sn_config_signals[ITEM_LIST_CHANGED], 0);
1083
1084 return TRUE;
1085 }
1086 else
1087 {
1088 return FALSE;
1089 }
1090 }
1091
1092
1093
1094 gboolean
sn_config_legacy_items_clear(SnConfig * config)1095 sn_config_legacy_items_clear(SnConfig *config)
1096 {
1097 g_list_free_full(config->known_legacy_items, g_free);
1098 config->known_legacy_items = NULL;
1099 g_hash_table_remove_all (config->hidden_legacy_items);
1100
1101 g_object_notify(G_OBJECT(config), "known-legacy-items");
1102 g_object_notify(G_OBJECT(config), "hidden-legacy-items");
1103
1104 g_signal_emit(G_OBJECT(config), sn_config_signals[LEGACY_ITEM_LIST_CHANGED], 0);
1105
1106 return TRUE;
1107 }
1108
1109
1110
1111 SnConfig *
sn_config_new(const gchar * property_base)1112 sn_config_new (const gchar *property_base)
1113 {
1114 SnConfig *config;
1115 XfconfChannel *channel;
1116 gchar *property;
1117
1118 config = g_object_new (XFCE_TYPE_SN_CONFIG, NULL);
1119
1120 if (xfconf_init (NULL))
1121 {
1122 channel = xfconf_channel_get ("xfce4-panel");
1123
1124 property = g_strconcat (property_base, "/icon-size", NULL);
1125 xfconf_g_property_bind (channel, property, G_TYPE_INT, config, "icon-size");
1126 g_free (property);
1127
1128 property = g_strconcat (property_base, "/single-row", NULL);
1129 xfconf_g_property_bind (channel, property, G_TYPE_BOOLEAN, config, "single-row");
1130 g_free (property);
1131
1132 property = g_strconcat (property_base, "/square-icons", NULL);
1133 xfconf_g_property_bind (channel, property, G_TYPE_BOOLEAN, config, "square-icons");
1134 g_free (property);
1135
1136 property = g_strconcat (property_base, "/symbolic-icons", NULL);
1137 xfconf_g_property_bind (channel, property, G_TYPE_BOOLEAN, config, "symbolic-icons");
1138 g_free (property);
1139
1140 property = g_strconcat (property_base, "/menu-is-primary", NULL);
1141 xfconf_g_property_bind (channel, property, G_TYPE_BOOLEAN, config, "menu-is-primary");
1142 g_free (property);
1143
1144 property = g_strconcat (property_base, "/hide-new-items", NULL);
1145 xfconf_g_property_bind (channel, property, G_TYPE_BOOLEAN, config, "hide-new-items");
1146 g_free (property);
1147
1148 property = g_strconcat (property_base, "/known-items", NULL);
1149 xfconf_g_property_bind (channel, property, XFCE_TYPE_SN_CONFIG_VALUE_ARRAY, config, "known-items");
1150 g_free (property);
1151
1152 property = g_strconcat (property_base, "/hidden-items", NULL);
1153 xfconf_g_property_bind (channel, property, XFCE_TYPE_SN_CONFIG_VALUE_ARRAY, config, "hidden-items");
1154 g_free (property);
1155
1156 property = g_strconcat (property_base, "/known-legacy-items", NULL);
1157 xfconf_g_property_bind (channel, property, XFCE_TYPE_SN_CONFIG_VALUE_ARRAY, config, "known-legacy-items");
1158 g_free (property);
1159
1160 property = g_strconcat (property_base, "/hidden-legacy-items", NULL);
1161 xfconf_g_property_bind (channel, property, XFCE_TYPE_SN_CONFIG_VALUE_ARRAY, config, "hidden-legacy-items");
1162 g_free (property);
1163
1164 g_signal_emit (G_OBJECT (config), sn_config_signals[CONFIGURATION_CHANGED], 0);
1165 }
1166
1167 return config;
1168 }
1169