1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * Copyright (C) 2004-2009 Shaun McCance <shaunm@gnome.org>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
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 GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public
16 * License along with this program; if not, see <http://www.gnu.org/licenses/>.
18 * Author: Shaun McCance <shaunm@gnome.org>
28 #include <glib/gi18n.h>
30 #include "yelp-settings.h"
32 struct _YelpSettingsPriv
{
35 gchar colors
[YELP_SETTINGS_NUM_COLORS
][8];
36 gchar
*setfonts
[YELP_SETTINGS_NUM_FONTS
];
37 gchar
*fonts
[YELP_SETTINGS_NUM_FONTS
];
38 gchar
*icons
[YELP_SETTINGS_NUM_ICONS
];
41 GtkSettings
*gtk_settings
;
42 GtkIconTheme
*gtk_icon_theme
;
46 gulong gtk_theme_changed
;
47 gulong gtk_font_changed
;
48 gulong icon_theme_changed
;
50 gboolean show_text_cursor
;
63 static guint settings_signals
[LAST_SIGNAL
] = {0,};
70 PROP_SHOW_TEXT_CURSOR
,
74 gchar
*icon_names
[YELP_SETTINGS_NUM_ICONS
];
76 G_DEFINE_TYPE (YelpSettings
, yelp_settings
, G_TYPE_OBJECT
);
77 #define GET_PRIV(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), YELP_TYPE_SETTINGS, YelpSettingsPriv))
79 static void yelp_settings_class_init (YelpSettingsClass
*klass
);
80 static void yelp_settings_init (YelpSettings
*settings
);
81 static void yelp_settings_constructed (GObject
*object
);
82 static void yelp_settings_dispose (GObject
*object
);
83 static void yelp_settings_finalize (GObject
*object
);
84 static void yelp_settings_get_property (GObject
*object
,
88 static void yelp_settings_set_property (GObject
*object
,
92 static void yelp_settings_set_if_token (YelpSettings
*settings
,
95 static void gtk_theme_changed (GtkSettings
*gtk_settings
,
97 YelpSettings
*settings
);
98 static void gtk_font_changed (GtkSettings
*gtk_settings
,
100 YelpSettings
*settings
);
101 static void icon_theme_changed (GtkIconTheme
*theme
,
102 YelpSettings
*settings
);
104 static void rgb_to_hsv (GdkRGBA color
,
108 static void hsv_to_hex (gdouble h
,
113 /******************************************************************************/
116 yelp_settings_class_init (YelpSettingsClass
*klass
)
118 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
121 object_class
->constructed
= yelp_settings_constructed
;
122 object_class
->dispose
= yelp_settings_dispose
;
123 object_class
->finalize
= yelp_settings_finalize
;
124 object_class
->get_property
= yelp_settings_get_property
;
125 object_class
->set_property
= yelp_settings_set_property
;
127 for (i
= 0; i
< YELP_SETTINGS_NUM_ICONS
; i
++) {
129 case YELP_SETTINGS_ICON_BUG
:
130 icon_names
[i
] = "yelp-note-bug";
132 case YELP_SETTINGS_ICON_IMPORTANT
:
133 icon_names
[i
] = "yelp-note-important";
135 case YELP_SETTINGS_ICON_NOTE
:
136 icon_names
[i
] = "yelp-note";
138 case YELP_SETTINGS_ICON_TIP
:
139 icon_names
[i
] = "yelp-note-tip";
141 case YELP_SETTINGS_ICON_WARNING
:
142 icon_names
[i
] = "yelp-note-warning";
145 g_assert_not_reached ();
149 g_object_class_install_property (object_class
,
151 g_param_spec_object ("gtk-settings",
153 _("A GtkSettings object to get settings from"),
155 G_PARAM_READWRITE
| G_PARAM_STATIC_NAME
|
156 G_PARAM_STATIC_NICK
| G_PARAM_STATIC_BLURB
));
158 g_object_class_install_property (object_class
,
160 g_param_spec_object ("gtk-icon-theme",
162 _("A GtkIconTheme object to get icons from"),
164 G_PARAM_READWRITE
| G_PARAM_STATIC_NAME
|
165 G_PARAM_STATIC_NICK
| G_PARAM_STATIC_BLURB
));
167 g_object_class_install_property (object_class
,
168 PROP_FONT_ADJUSTMENT
,
169 g_param_spec_int ("font-adjustment",
170 _("Font Adjustment"),
171 _("A size adjustment to add to font sizes"),
173 G_PARAM_READWRITE
| G_PARAM_STATIC_NAME
|
174 G_PARAM_STATIC_NICK
| G_PARAM_STATIC_BLURB
));
176 g_object_class_install_property (object_class
,
177 PROP_SHOW_TEXT_CURSOR
,
178 g_param_spec_boolean ("show-text-cursor",
179 _("Show Text Cursor"),
180 _("Show the text cursor or caret for accessible navigation"),
182 G_PARAM_READWRITE
| G_PARAM_STATIC_NAME
|
183 G_PARAM_STATIC_NICK
| G_PARAM_STATIC_BLURB
));
185 g_object_class_install_property (object_class
,
187 g_param_spec_boolean ("editor-mode",
189 _("Enable features useful to editors"),
191 G_PARAM_READWRITE
| G_PARAM_STATIC_NAME
|
192 G_PARAM_STATIC_NICK
| G_PARAM_STATIC_BLURB
));
194 settings_signals
[COLORS_CHANGED
] =
195 g_signal_new ("colors-changed",
196 G_OBJECT_CLASS_TYPE (klass
),
199 g_cclosure_marshal_VOID__VOID
,
202 settings_signals
[FONTS_CHANGED
] =
203 g_signal_new ("fonts-changed",
204 G_OBJECT_CLASS_TYPE (klass
),
207 g_cclosure_marshal_VOID__VOID
,
210 settings_signals
[ICONS_CHANGED
] =
211 g_signal_new ("icons-changed",
212 G_OBJECT_CLASS_TYPE (klass
),
215 g_cclosure_marshal_VOID__VOID
,
218 g_type_class_add_private (klass
, sizeof (YelpSettingsPriv
));
222 yelp_settings_init (YelpSettings
*settings
)
226 settings
->priv
= GET_PRIV (settings
);
227 g_mutex_init (&settings
->priv
->mutex
);
228 settings
->priv
->icon_size
= 24;
230 for (i
= 0; i
< YELP_SETTINGS_NUM_ICONS
; i
++)
231 settings
->priv
->icons
[i
] = NULL
;
232 for (i
= 0; i
< YELP_SETTINGS_NUM_FONTS
; i
++) {
233 settings
->priv
->setfonts
[i
] = NULL
;
234 settings
->priv
->fonts
[i
] = NULL
;
237 settings
->priv
->tokens
= g_hash_table_new_full (g_str_hash
, g_str_equal
,
242 yelp_settings_constructed (GObject
*object
)
244 YelpSettings
*settings
= YELP_SETTINGS (object
);
245 GDBusConnection
*connection
;
246 GVariant
*ret
, *names
;
250 gboolean env_shell
, env_classic
, env_panel
, env_unity
, env_xfce
;
251 GError
*error
= NULL
;
253 connection
= g_bus_get_sync (G_BUS_TYPE_SESSION
, NULL
, &error
);
254 if (connection
== NULL
) {
255 g_warning ("Unable to connect to dbus: %s", error
->message
);
256 g_error_free (error
);
260 ret
= g_dbus_connection_call_sync (connection
,
261 "org.freedesktop.DBus",
262 "/org/freedesktop/DBus",
263 "org.freedesktop.DBus",
266 G_VARIANT_TYPE ("(as)"),
267 G_DBUS_CALL_FLAGS_NONE
,
270 g_warning ("Unable to query dbus: %s", error
->message
);
271 g_error_free (error
);
274 env_shell
= env_classic
= env_panel
= env_unity
= env_xfce
= FALSE
;
275 names
= g_variant_get_child_value (ret
, 0);
276 g_variant_iter_init (&iter
, names
);
277 while (g_variant_iter_loop (&iter
, "&s", &name
)) {
278 if (g_str_equal (name
, "org.gnome.Panel"))
280 else if (g_str_equal (name
, "org.gnome.Shell"))
282 else if (g_str_equal (name
, "com.canonical.Unity"))
284 else if (g_str_equal (name
, "org.xfce.Panel"))
287 g_variant_unref (names
);
288 g_variant_unref (ret
);
290 ret
= g_dbus_connection_call_sync (connection
,
293 "org.freedesktop.DBus.Properties",
295 g_variant_new ("(ss)",
298 G_VARIANT_TYPE ("(v)"),
299 G_DBUS_CALL_FLAGS_NONE
,
302 g_warning ("Failed to get GNOME shell mode: %s", error
->message
);
303 g_error_free (error
);
306 g_variant_get (ret
, "(v)", &v
);
307 if (g_variant_is_of_type (v
, G_VARIANT_TYPE_STRING
) &&
308 g_str_equal (g_variant_get_string (v
, NULL
), "classic")) {
312 g_variant_unref (ret
);
317 yelp_settings_set_if_token (settings
, "platform:gnome-classic");
319 /* order is important:
320 gnome-shell also provides org.gnome.Panel
321 unity also provides org.gnome.Shell
324 yelp_settings_set_if_token (settings
, "platform:unity");
326 yelp_settings_set_if_token (settings
, "platform:gnome-shell");
328 yelp_settings_set_if_token (settings
, "platform:xfce");
330 yelp_settings_set_if_token (settings
, "platform:gnome-panel");
332 yelp_settings_set_if_token (settings
, "action:install");
336 yelp_settings_dispose (GObject
*object
)
338 YelpSettings
*settings
= YELP_SETTINGS (object
);
340 G_OBJECT_CLASS (yelp_settings_parent_class
)->dispose (object
);
344 yelp_settings_finalize (GObject
*object
)
346 YelpSettings
*settings
= YELP_SETTINGS (object
);
348 g_mutex_clear (&settings
->priv
->mutex
);
350 g_hash_table_destroy (settings
->priv
->tokens
);
352 G_OBJECT_CLASS (yelp_settings_parent_class
)->finalize (object
);
356 yelp_settings_get_property (GObject
*object
,
361 YelpSettings
*settings
= YELP_SETTINGS (object
);
364 case PROP_GTK_SETTINGS
:
365 g_value_set_object (value
, settings
->priv
->gtk_settings
);
367 case PROP_GTK_ICON_THEME
:
368 g_value_set_object (value
, settings
->priv
->gtk_icon_theme
);
370 case PROP_FONT_ADJUSTMENT
:
371 g_value_set_int (value
, settings
->priv
->font_adjustment
);
373 case PROP_SHOW_TEXT_CURSOR
:
374 g_value_set_boolean (value
, settings
->priv
->show_text_cursor
);
376 case PROP_EDITOR_MODE
:
377 g_value_set_boolean (value
, settings
->priv
->editor_mode
);
380 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
386 yelp_settings_set_property (GObject
*object
,
391 YelpSettings
*settings
= YELP_SETTINGS (object
);
394 case PROP_GTK_SETTINGS
:
395 if (settings
->priv
->gtk_settings
) {
396 g_signal_handler_disconnect (settings
->priv
->gtk_settings
,
397 settings
->priv
->gtk_theme_changed
);
398 g_signal_handler_disconnect (settings
->priv
->gtk_settings
,
399 settings
->priv
->gtk_font_changed
);
400 g_object_unref (settings
->priv
->gtk_settings
);
402 settings
->priv
->gtk_settings
= g_value_get_object (value
);
403 if (settings
->priv
->gtk_settings
!= NULL
) {
404 g_object_ref (settings
->priv
->gtk_settings
);
405 settings
->priv
->gtk_theme_changed
=
406 g_signal_connect (settings
->priv
->gtk_settings
,
407 "notify::gtk-theme-name",
408 (GCallback
) gtk_theme_changed
,
410 settings
->priv
->gtk_font_changed
=
411 g_signal_connect (settings
->priv
->gtk_settings
,
412 "notify::gtk-font-name",
413 (GCallback
) gtk_font_changed
,
415 gtk_theme_changed (settings
->priv
->gtk_settings
, NULL
, settings
);
416 gtk_font_changed (settings
->priv
->gtk_settings
, NULL
, settings
);
419 settings
->priv
->gtk_theme_changed
= 0;
420 settings
->priv
->gtk_font_changed
= 0;
423 case PROP_GTK_ICON_THEME
:
424 if (settings
->priv
->gtk_icon_theme
) {
425 g_signal_handler_disconnect (settings
->priv
->gtk_icon_theme
,
426 settings
->priv
->icon_theme_changed
);
427 g_object_unref (settings
->priv
->gtk_icon_theme
);
429 settings
->priv
->gtk_icon_theme
= g_value_get_object (value
);
430 if (settings
->priv
->gtk_icon_theme
!= NULL
) {
432 gint search_path_len
, i
;
433 gboolean append_search_path
= TRUE
;
434 gtk_icon_theme_get_search_path (settings
->priv
->gtk_icon_theme
,
435 &search_path
, &search_path_len
);
436 for (i
= search_path_len
- 1; i
>= 0; i
--)
437 if (g_str_equal (search_path
[i
], YELP_ICON_PATH
)) {
438 append_search_path
= FALSE
;
441 if (append_search_path
)
442 gtk_icon_theme_append_search_path (settings
->priv
->gtk_icon_theme
,
444 append_search_path
= TRUE
;
445 for (i
= search_path_len
- 1; i
>= 0; i
--)
446 if (g_str_equal (search_path
[i
], DATADIR
"/yelp/icons")) {
447 append_search_path
= FALSE
;
450 if (append_search_path
)
451 gtk_icon_theme_append_search_path (settings
->priv
->gtk_icon_theme
,
452 DATADIR
"/yelp/icons");
453 g_strfreev (search_path
);
454 g_object_ref (settings
->priv
->gtk_icon_theme
);
455 settings
->priv
->icon_theme_changed
=
456 g_signal_connect (settings
->priv
->gtk_icon_theme
,
458 (GCallback
) icon_theme_changed
,
460 icon_theme_changed (settings
->priv
->gtk_icon_theme
, settings
);
463 settings
->priv
->icon_theme_changed
= 0;
466 case PROP_FONT_ADJUSTMENT
:
467 settings
->priv
->font_adjustment
= g_value_get_int (value
);
468 gtk_font_changed (settings
->priv
->gtk_settings
, NULL
, settings
);
470 case PROP_SHOW_TEXT_CURSOR
:
471 settings
->priv
->show_text_cursor
= g_value_get_boolean (value
);
473 case PROP_EDITOR_MODE
:
474 settings
->priv
->editor_mode
= g_value_get_boolean (value
);
477 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
482 /******************************************************************************/
485 yelp_settings_get_default (void)
488 static YelpSettings
*settings
= NULL
;
489 g_mutex_lock (&mutex
);
490 if (settings
== NULL
)
491 settings
= g_object_new (YELP_TYPE_SETTINGS
,
492 "gtk-settings", gtk_settings_get_default (),
493 "gtk-icon-theme", gtk_icon_theme_get_default (),
495 g_mutex_unlock (&mutex
);
499 /******************************************************************************/
502 yelp_settings_get_color (YelpSettings
*settings
,
503 YelpSettingsColor color
)
506 g_return_val_if_fail (color
< YELP_SETTINGS_NUM_COLORS
, NULL
);
508 g_mutex_lock (&settings
->priv
->mutex
);
509 colorstr
= g_strdup (settings
->priv
->colors
[color
]);
510 g_mutex_unlock (&settings
->priv
->mutex
);
516 yelp_settings_get_colors (YelpSettings
*settings
)
518 gchar
**colors
= g_new0 (gchar
*, YELP_SETTINGS_NUM_COLORS
+ 1);
520 for (i
= 0; i
< YELP_SETTINGS_NUM_COLORS
; i
++)
521 colors
[i
] = yelp_settings_get_color (settings
, i
);
526 yelp_settings_set_colors (YelpSettings
*settings
,
527 YelpSettingsColor first_color
,
530 YelpSettingsColor color
;
533 g_mutex_lock (&settings
->priv
->mutex
);
534 va_start (args
, first_color
);
537 while ((gint
) color
>= 0) {
538 gchar
*colorstr
= va_arg (args
, gchar
*);
540 for (i
= 0; i
< 7; i
++) {
541 settings
->priv
->colors
[color
][i
] = colorstr
[i
];
542 if (colorstr
[i
] == '\0')
545 settings
->priv
->colors
[color
][7] = '\0';
546 color
= va_arg (args
, YelpSettingsColor
);
550 g_mutex_unlock (&settings
->priv
->mutex
);
552 g_signal_emit (settings
, settings_signals
[COLORS_CHANGED
], 0);
556 yelp_settings_get_color_param (YelpSettingsColor color
)
558 static const gchar
*params
[YELP_SETTINGS_NUM_COLORS
] = {
564 "color.gray_background",
565 "color.dark_background",
567 "color.blue_background",
569 "color.red_background",
571 "color.yellow_background",
572 "color.yellow_border"
574 g_return_val_if_fail (color
< YELP_SETTINGS_NUM_COLORS
, NULL
);
575 return params
[color
];
578 /******************************************************************************/
581 yelp_settings_get_font (YelpSettings
*settings
,
582 YelpSettingsFont font
)
585 g_return_val_if_fail (font
< YELP_SETTINGS_NUM_FONTS
, NULL
);
587 g_mutex_lock (&settings
->priv
->mutex
);
588 if (settings
->priv
->setfonts
[font
])
589 ret
= g_strdup (settings
->priv
->setfonts
[font
]);
591 ret
= g_strdup (settings
->priv
->fonts
[font
]);
592 g_mutex_unlock (&settings
->priv
->mutex
);
598 yelp_settings_get_font_family (YelpSettings
*settings
,
599 YelpSettingsFont font
)
601 const gchar
*def
= (font
== YELP_SETTINGS_FONT_VARIABLE
) ? "Sans" : "Monospace";
602 gchar
*desc
, *ret
, *c
; /* do not free */
603 g_return_val_if_fail (font
< YELP_SETTINGS_NUM_FONTS
, NULL
);
605 g_mutex_lock (&settings
->priv
->mutex
);
607 if (settings
->priv
->setfonts
[font
])
608 desc
= g_strdup (settings
->priv
->setfonts
[font
]);
610 desc
= g_strdup (settings
->priv
->fonts
[font
]);
613 ret
= g_strdup (def
);
617 c
= strrchr (desc
, ' ');
619 g_warning ("Cannot parse font: %s", desc
);
620 ret
= g_strdup (def
);
624 ret
= g_strndup (desc
, c
- desc
);
627 g_mutex_unlock (&settings
->priv
->mutex
);
632 yelp_settings_get_font_size (YelpSettings
*settings
,
633 YelpSettingsFont font
)
635 gchar
*desc
, *c
; /* do not free */
637 g_return_val_if_fail (font
< YELP_SETTINGS_NUM_FONTS
, 0);
639 g_mutex_lock (&settings
->priv
->mutex
);
641 if (settings
->priv
->setfonts
[font
])
642 desc
= g_strdup (settings
->priv
->setfonts
[font
]);
644 desc
= g_strdup (settings
->priv
->fonts
[font
]);
651 c
= strrchr (desc
, ' ');
653 g_warning ("Cannot parse font %s", desc
);
658 ret
= g_ascii_strtod (c
, NULL
);
661 g_mutex_unlock (&settings
->priv
->mutex
);
662 ret
+= settings
->priv
->font_adjustment
;
663 ret
= (ret
< 5) ? 5 : ret
;
668 yelp_settings_set_fonts (YelpSettings
*settings
,
669 YelpSettingsFont first_font
,
672 YelpSettingsFont font
;
675 g_mutex_lock (&settings
->priv
->mutex
);
676 va_start (args
, first_font
);
679 while ((gint
) font
>= 0) {
680 gchar
*fontname
= va_arg (args
, gchar
*);
681 if (settings
->priv
->setfonts
[font
] != NULL
)
682 g_free (settings
->priv
->setfonts
[font
]);
683 settings
->priv
->setfonts
[font
] = g_strdup (fontname
);
684 font
= va_arg (args
, YelpSettingsFont
);
688 g_mutex_unlock (&settings
->priv
->mutex
);
690 g_signal_emit (settings
, settings_signals
[FONTS_CHANGED
], 0);
694 yelp_settings_get_font_adjustment (YelpSettings
*settings
)
696 return settings
->priv
->font_adjustment
;
700 yelp_settings_set_font_adjustment (YelpSettings
*settings
,
703 g_object_set (settings
, "font-adjustment", adjustment
, NULL
);
706 /******************************************************************************/
709 yelp_settings_get_icon_size (YelpSettings
*settings
)
711 return settings
->priv
->icon_size
;
715 yelp_settings_set_icon_size (YelpSettings
*settings
,
718 settings
->priv
->icon_size
= size
;
719 if (settings
->priv
->gtk_icon_theme
!= NULL
)
720 icon_theme_changed (settings
->priv
->gtk_icon_theme
, settings
);
724 yelp_settings_get_icon (YelpSettings
*settings
,
725 YelpSettingsIcon icon
)
728 g_return_val_if_fail (icon
< YELP_SETTINGS_NUM_ICONS
, NULL
);
730 g_mutex_lock (&settings
->priv
->mutex
);
731 ret
= g_strdup (settings
->priv
->icons
[icon
]);
732 g_mutex_unlock (&settings
->priv
->mutex
);
738 yelp_settings_set_icons (YelpSettings
*settings
,
739 YelpSettingsIcon first_icon
,
742 YelpSettingsIcon icon
;
745 g_mutex_lock (&settings
->priv
->mutex
);
746 va_start (args
, first_icon
);
749 while ((gint
) icon
>= 0) {
750 gchar
*filename
= va_arg (args
, gchar
*);
751 if (settings
->priv
->icons
[icon
] != NULL
)
752 g_free (settings
->priv
->icons
[icon
]);
753 settings
->priv
->icons
[icon
] = g_filename_to_uri (filename
, NULL
, NULL
);
754 icon
= va_arg (args
, YelpSettingsIcon
);
758 g_mutex_unlock (&settings
->priv
->mutex
);
760 g_signal_emit (settings
, settings_signals
[ICONS_CHANGED
], 0);
764 yelp_settings_get_icon_param (YelpSettingsIcon icon
)
766 static const gchar
*params
[YELP_SETTINGS_NUM_ICONS
] = {
768 "icons.note.important",
773 g_return_val_if_fail (icon
< YELP_SETTINGS_NUM_ICONS
, NULL
);
777 /******************************************************************************/
780 yelp_settings_get_show_text_cursor (YelpSettings
*settings
)
782 return settings
->priv
->show_text_cursor
;
786 yelp_settings_set_show_text_cursor (YelpSettings
*settings
,
789 g_object_set (settings
, "show-text-cursor", show
, NULL
);
793 yelp_settings_get_editor_mode (YelpSettings
*settings
)
795 return settings
->priv
->editor_mode
;
799 yelp_settings_set_editor_mode (YelpSettings
*settings
,
800 gboolean editor_mode
)
802 g_object_set (settings
, "editor-mode", editor_mode
, NULL
);
805 /******************************************************************************/
808 yelp_settings_set_if_token (YelpSettings
*settings
,
811 if (g_hash_table_lookup (settings
->priv
->tokens
, token
) == NULL
) {
812 gchar
*ins
= g_strdup (token
);
813 g_hash_table_insert (settings
->priv
->tokens
, ins
, ins
);
817 /******************************************************************************/
820 yelp_settings_get_all_params (YelpSettings
*settings
,
826 GString
*malstr
, *dbstr
;
829 params
= g_new0 (gchar
*,
830 (2*YELP_SETTINGS_NUM_COLORS
) + (2*YELP_SETTINGS_NUM_ICONS
) + extra
+ 9);
832 for (i
= 0; i
< YELP_SETTINGS_NUM_COLORS
; i
++) {
835 params
[ix
] = g_strdup (yelp_settings_get_color_param (i
));
836 val
= yelp_settings_get_color (settings
, i
);
837 params
[ix
+ 1] = g_strdup_printf ("\"%s\"", val
);
840 for (i
= 0; i
< YELP_SETTINGS_NUM_ICONS
; i
++) {
842 ix
= 2 * (YELP_SETTINGS_NUM_COLORS
+ i
);
843 params
[ix
] = g_strdup (yelp_settings_get_icon_param (i
));
844 val
= yelp_settings_get_icon (settings
, i
);
845 params
[ix
+ 1] = g_strdup_printf ("\"%s\"", val
);
848 ix
= 2 * (YELP_SETTINGS_NUM_COLORS
+ YELP_SETTINGS_NUM_ICONS
);
849 params
[ix
++] = g_strdup ("icons.size.note");
850 params
[ix
++] = g_strdup_printf ("%i", yelp_settings_get_icon_size (settings
));
851 params
[ix
++] = g_strdup ("yelp.editor_mode");
852 if (settings
->priv
->editor_mode
)
853 params
[ix
++] = g_strdup ("true()");
855 params
[ix
++] = g_strdup ("false()");
857 malstr
= g_string_new ("'");
858 dbstr
= g_string_new ("'");
859 envs
= g_hash_table_get_keys (settings
->priv
->tokens
);
860 for (envi
= envs
; envi
!= NULL
; envi
= envi
->next
) {
861 g_string_append_c (malstr
, ' ');
862 g_string_append (malstr
, (gchar
*) envi
->data
);
863 if (g_str_has_prefix ((gchar
*) envi
->data
, "platform:")) {
864 g_string_append_c (dbstr
, ';');
865 g_string_append (dbstr
, (gchar
*) (envi
->data
+ 9));
868 g_string_append_c (malstr
, '\'');
869 g_string_append_c (dbstr
, '\'');
871 params
[ix
++] = g_strdup ("mal.if.custom");
872 params
[ix
++] = g_string_free (malstr
, FALSE
);
873 params
[ix
++] = g_strdup ("db.profile.os");
874 params
[ix
++] = g_string_free (dbstr
, FALSE
);
883 /******************************************************************************/
886 gtk_theme_changed (GtkSettings
*gtk_settings
,
888 YelpSettings
*settings
)
890 GtkStyleContext
*context
;
891 GtkWidget
*tmpwin
, *tmpview
;
892 GdkRGBA base
, text
, link
;
893 gdouble base_h
, base_s
, base_v
;
894 gdouble text_h
, text_s
, text_v
;
896 g_mutex_lock (&settings
->priv
->mutex
);
898 tmpwin
= gtk_offscreen_window_new ();
899 tmpview
= gtk_text_view_new ();
900 gtk_container_add (GTK_CONTAINER (tmpwin
), tmpview
);
901 gtk_widget_show_all (tmpwin
);
902 context
= gtk_widget_get_style_context (tmpview
);
903 /* I have to do this for some reason. Don't ask me why. Ain't in the docs. */
904 gtk_style_context_add_class (context
, GTK_STYLE_CLASS_VIEW
);
906 gtk_style_context_get_color (context
, GTK_STATE_FLAG_NORMAL
, &text
);
907 gtk_style_context_get_background_color (context
, GTK_STATE_FLAG_ACTIVE
, &base
);
909 rgb_to_hsv (text
, &text_h
, &text_s
, &text_v
);
910 rgb_to_hsv (base
, &base_h
, &base_s
, &base_v
);
912 /* YELP_SETTINGS_COLOR_BASE */
913 g_snprintf (settings
->priv
->colors
[YELP_SETTINGS_COLOR_BASE
], 8, "#%02X%02X%02X",
914 (gint
) (base
.red
* 255), (gint
) (base
.green
* 255), (gint
) (base
.blue
* 255));
916 /* YELP_SETTINGS_COLOR_TEXT */
917 g_snprintf (settings
->priv
->colors
[YELP_SETTINGS_COLOR_TEXT
], 8, "#%02X%02X%02X",
918 (gint
) (text
.red
* 255), (gint
) (text
.green
* 255), (gint
) (text
.blue
* 255));
920 /* YELP_SETTINGS_COLOR_LINK */
921 gtk_style_context_get_color (context
, GTK_STATE_FLAG_LINK
, &link
);
922 g_snprintf (settings
->priv
->colors
[YELP_SETTINGS_COLOR_LINK
], 8, "#%02X%02X%02X",
923 (gint
) (text
.red
* 255), (gint
) (text
.green
* 255), (gint
) (text
.blue
* 255));
925 /* YELP_SETTINGS_COLOR_LINK_VISITED */
926 gtk_style_context_get_color (context
, GTK_STATE_FLAG_VISITED
, &link
);
927 g_snprintf (settings
->priv
->colors
[YELP_SETTINGS_COLOR_LINK_VISITED
], 8, "#%02X%02X%02X",
928 (gint
) (text
.red
* 255), (gint
) (text
.green
* 255), (gint
) (text
.blue
* 255));
930 /* YELP_SETTINGS_COLOR_TEXT_LIGHT */
931 hsv_to_hex (text_h
, text_s
, text_v
- ((text_v
- base_v
) * 0.25),
932 settings
->priv
->colors
[YELP_SETTINGS_COLOR_TEXT_LIGHT
]);
934 /* YELP_SETTINGS_COLOR_GRAY */
935 hsv_to_hex (base_h
, base_s
,
936 base_v
- ((base_v
- text_v
) * 0.05),
937 settings
->priv
->colors
[YELP_SETTINGS_COLOR_GRAY_BASE
]);
938 hsv_to_hex (base_h
, base_s
,
939 base_v
- ((base_v
- text_v
) * 0.1),
940 settings
->priv
->colors
[YELP_SETTINGS_COLOR_DARK_BASE
]);
941 hsv_to_hex (base_h
, base_s
,
942 base_v
- ((base_v
- text_v
) * 0.26),
943 settings
->priv
->colors
[YELP_SETTINGS_COLOR_GRAY_BORDER
]);
945 /* YELP_SETTINGS_COLOR_BLUE */
946 hsv_to_hex (211, 0.1,
947 base_v
- ((base_v
- text_v
) * 0.01),
948 settings
->priv
->colors
[YELP_SETTINGS_COLOR_BLUE_BASE
]);
949 hsv_to_hex (211, 0.45,
950 base_v
- ((base_v
- text_v
) * 0.19),
951 settings
->priv
->colors
[YELP_SETTINGS_COLOR_BLUE_BORDER
]);
953 /* YELP_SETTINGS_COLOR_RED */
955 base_v
- ((base_v
- text_v
) * 0.01),
956 settings
->priv
->colors
[YELP_SETTINGS_COLOR_RED_BASE
]);
958 base_v
- ((base_v
- text_v
) * 0.06),
959 settings
->priv
->colors
[YELP_SETTINGS_COLOR_RED_BORDER
]);
961 /* YELP_SETTINGS_COLOR_YELLOW */
962 hsv_to_hex (60, 0.25,
963 base_v
- ((base_v
- text_v
) * 0.01),
964 settings
->priv
->colors
[YELP_SETTINGS_COLOR_YELLOW_BASE
]);
966 base_v
- ((base_v
- text_v
) * 0.07),
967 settings
->priv
->colors
[YELP_SETTINGS_COLOR_YELLOW_BORDER
]);
969 gtk_widget_destroy (tmpwin
);
971 g_mutex_unlock (&settings
->priv
->mutex
);
973 g_signal_emit (settings
, settings_signals
[COLORS_CHANGED
], 0);
977 gtk_font_changed (GtkSettings
*gtk_settings
,
979 YelpSettings
*settings
)
983 /* This happens when font_adjustment is set during init */
984 if (gtk_settings
== NULL
)
987 g_free (settings
->priv
->fonts
[YELP_SETTINGS_FONT_VARIABLE
]);
988 g_object_get (gtk_settings
, "gtk-font-name", &font
, NULL
);
989 settings
->priv
->fonts
[YELP_SETTINGS_FONT_VARIABLE
] = font
;
991 c
= strrchr (font
, ' ');
993 g_warning ("Cannot parse font: %s", font
);
994 font
= g_strdup ("Monospace 10");
997 font
= g_strconcat ("Monospace", c
, NULL
);
1000 g_free (settings
->priv
->fonts
[YELP_SETTINGS_FONT_FIXED
]);
1001 settings
->priv
->fonts
[YELP_SETTINGS_FONT_FIXED
] = font
;
1003 g_signal_emit (settings
, settings_signals
[FONTS_CHANGED
], 0);
1007 icon_theme_changed (GtkIconTheme
*theme
,
1008 YelpSettings
*settings
)
1013 g_mutex_lock (&settings
->priv
->mutex
);
1015 for (i
= 0; i
< YELP_SETTINGS_NUM_ICONS
; i
++) {
1016 if (settings
->priv
->icons
[i
] != NULL
)
1017 g_free (settings
->priv
->icons
[i
]);
1018 info
= gtk_icon_theme_lookup_icon (theme
,
1020 settings
->priv
->icon_size
,
1021 GTK_ICON_LOOKUP_NO_SVG
);
1023 settings
->priv
->icons
[i
] = g_filename_to_uri (gtk_icon_info_get_filename (info
),
1025 g_object_unref (info
);
1028 settings
->priv
->icons
[i
] = NULL
;
1032 g_mutex_unlock (&settings
->priv
->mutex
);
1034 g_signal_emit (settings
, settings_signals
[ICONS_CHANGED
], 0);
1038 yelp_settings_cmp_icons (const gchar
*icon1
,
1041 static const gchar
*icons
[] = {
1042 "yelp-page-search-symbolic",
1043 "yelp-page-video-symbolic",
1044 "yelp-page-task-symbolic",
1045 "yelp-page-tip-symbolic",
1046 "yelp-page-problem-symbolic",
1047 "yelp-page-ui-symbolic",
1048 "yelp-page-symbolic",
1052 for (i
= 0; icons
[i
] != NULL
; i
++) {
1053 gboolean eq1
= icon1
? g_str_has_prefix (icon1
, icons
[i
]) : FALSE
;
1054 gboolean eq2
= icon2
? g_str_has_prefix (icon2
, icons
[i
]) : FALSE
;
1062 if (icon1
== NULL
&& icon2
== NULL
)
1064 else if (icon2
== NULL
)
1066 else if (icon1
== NULL
)
1069 return strcmp (icon1
, icon2
);
1072 /******************************************************************************/
1075 rgb_to_hsv (GdkRGBA color
, gdouble
*h
, gdouble
*s
, gdouble
*v
)
1077 gdouble min
, max
, delta
;
1079 max
= (color
.red
> color
.green
) ? color
.red
: color
.green
;
1080 max
= (max
> color
.blue
) ? max
: color
.blue
;
1081 min
= (color
.red
< color
.green
) ? color
.red
: color
.green
;
1082 min
= (min
< color
.blue
) ? min
: color
.blue
;
1093 if (color
.red
== max
)
1094 *h
= (color
.green
- color
.blue
) / delta
;
1095 else if (color
.green
== max
)
1096 *h
= 2 + (color
.blue
- color
.red
) / delta
;
1097 else if (color
.blue
== max
)
1098 *h
= 4 + (color
.red
- color
.green
) / delta
;
1107 hsv_to_hex (gdouble h
, gdouble s
, gdouble v
, gchar
*str
)
1113 guint8 red
, green
, blue
;
1119 m2
= v
* (1 - s
* (h
- hue
));
1120 m3
= v
* (1 - s
* (-h
+ hue
+ 1));
1125 b
= m1
; g
= m3
; break;
1127 b
= m1
; r
= m2
; break;
1129 r
= m1
; b
= m3
; break;
1131 r
= m1
; g
= m2
; break;
1133 g
= m1
; r
= m3
; break;
1135 g
= m1
; b
= m2
; break;
1141 g_snprintf (str
, 8, "#%02X%02X%02X", red
, green
, blue
);