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 static const 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_constructed (GObject
*object
);
80 static void yelp_settings_finalize (GObject
*object
);
81 static void yelp_settings_get_property (GObject
*object
,
85 static void yelp_settings_set_property (GObject
*object
,
89 static void yelp_settings_set_if_token (YelpSettings
*settings
,
92 static void gtk_theme_changed (GtkSettings
*gtk_settings
,
94 YelpSettings
*settings
);
95 static void gtk_font_changed (GtkSettings
*gtk_settings
,
97 YelpSettings
*settings
);
98 static void icon_theme_changed (GtkIconTheme
*theme
,
99 YelpSettings
*settings
);
101 static void rgb_to_hsv (GdkRGBA color
,
105 static void hsv_to_hex (gdouble h
,
110 /******************************************************************************/
113 yelp_settings_class_init (YelpSettingsClass
*klass
)
115 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
118 object_class
->constructed
= yelp_settings_constructed
;
119 object_class
->finalize
= yelp_settings_finalize
;
120 object_class
->get_property
= yelp_settings_get_property
;
121 object_class
->set_property
= yelp_settings_set_property
;
123 for (i
= 0; i
< YELP_SETTINGS_NUM_ICONS
; i
++) {
125 case YELP_SETTINGS_ICON_BUG
:
126 icon_names
[i
] = "yelp-note-bug";
128 case YELP_SETTINGS_ICON_IMPORTANT
:
129 icon_names
[i
] = "yelp-note-important";
131 case YELP_SETTINGS_ICON_NOTE
:
132 icon_names
[i
] = "yelp-note";
134 case YELP_SETTINGS_ICON_TIP
:
135 icon_names
[i
] = "yelp-note-tip";
137 case YELP_SETTINGS_ICON_WARNING
:
138 icon_names
[i
] = "yelp-note-warning";
141 g_assert_not_reached ();
145 g_object_class_install_property (object_class
,
147 g_param_spec_object ("gtk-settings",
149 "A GtkSettings object to get settings from",
151 G_PARAM_READWRITE
| G_PARAM_STATIC_NAME
|
152 G_PARAM_STATIC_NICK
| G_PARAM_STATIC_BLURB
));
154 g_object_class_install_property (object_class
,
156 g_param_spec_object ("gtk-icon-theme",
158 "A GtkIconTheme object to get icons from",
160 G_PARAM_READWRITE
| G_PARAM_STATIC_NAME
|
161 G_PARAM_STATIC_NICK
| G_PARAM_STATIC_BLURB
));
163 g_object_class_install_property (object_class
,
164 PROP_FONT_ADJUSTMENT
,
165 g_param_spec_int ("font-adjustment",
167 "A size adjustment to add to font sizes",
169 G_PARAM_READWRITE
| G_PARAM_STATIC_NAME
|
170 G_PARAM_STATIC_NICK
| G_PARAM_STATIC_BLURB
));
172 g_object_class_install_property (object_class
,
173 PROP_SHOW_TEXT_CURSOR
,
174 g_param_spec_boolean ("show-text-cursor",
176 "Show the text cursor or caret for accessible navigation",
178 G_PARAM_READWRITE
| G_PARAM_STATIC_NAME
|
179 G_PARAM_STATIC_NICK
| G_PARAM_STATIC_BLURB
));
181 g_object_class_install_property (object_class
,
183 g_param_spec_boolean ("editor-mode",
185 "Enable features useful to editors",
187 G_PARAM_READWRITE
| G_PARAM_STATIC_NAME
|
188 G_PARAM_STATIC_NICK
| G_PARAM_STATIC_BLURB
));
190 settings_signals
[COLORS_CHANGED
] =
191 g_signal_new ("colors-changed",
192 G_OBJECT_CLASS_TYPE (klass
),
195 g_cclosure_marshal_VOID__VOID
,
198 settings_signals
[FONTS_CHANGED
] =
199 g_signal_new ("fonts-changed",
200 G_OBJECT_CLASS_TYPE (klass
),
203 g_cclosure_marshal_VOID__VOID
,
206 settings_signals
[ICONS_CHANGED
] =
207 g_signal_new ("icons-changed",
208 G_OBJECT_CLASS_TYPE (klass
),
211 g_cclosure_marshal_VOID__VOID
,
214 g_type_class_add_private (klass
, sizeof (YelpSettingsPriv
));
218 yelp_settings_init (YelpSettings
*settings
)
222 settings
->priv
= GET_PRIV (settings
);
223 g_mutex_init (&settings
->priv
->mutex
);
224 settings
->priv
->icon_size
= 24;
226 for (i
= 0; i
< YELP_SETTINGS_NUM_ICONS
; i
++)
227 settings
->priv
->icons
[i
] = NULL
;
228 for (i
= 0; i
< YELP_SETTINGS_NUM_FONTS
; i
++) {
229 settings
->priv
->setfonts
[i
] = NULL
;
230 settings
->priv
->fonts
[i
] = NULL
;
233 settings
->priv
->tokens
= g_hash_table_new_full (g_str_hash
, g_str_equal
,
238 yelp_settings_constructed (GObject
*object
)
240 YelpSettings
*settings
= YELP_SETTINGS (object
);
241 gboolean skip_dbus_checks
= FALSE
;
242 gchar
*os_release
= NULL
;
243 const gchar
*desktop
;
245 yelp_settings_set_if_token (settings
, "action:install");
247 g_file_get_contents ("/etc/os-release", &os_release
, NULL
, NULL
);
248 if (os_release
== NULL
)
249 g_file_get_contents ("/usr/lib/os-release", &os_release
, NULL
, NULL
);
251 if (os_release
!= NULL
) {
253 gchar
**lines
= g_strsplit(os_release
, "\n", -1);
254 gchar
*osid
= NULL
, *osversion
= NULL
, *end
;
257 for (i
= 0; lines
[i
] != NULL
; i
++) {
258 if (g_str_has_prefix (lines
[i
], "ID=")) {
259 if (lines
[i
][3] == '"') {
260 end
= strchr (lines
[i
] + 4, '"');
262 osid
= g_strndup (lines
[i
] + 4, end
- lines
[i
] - 4);
264 else if (lines
[i
][3] == '\'') {
265 end
= strchr (lines
[i
] + 4, '\'');
267 osid
= g_strndup (lines
[i
] + 4, end
- lines
[i
] - 4);
270 osid
= g_strdup (lines
[i
] + 3);
273 else if (g_str_has_prefix (lines
[i
], "VERSION_ID=")) {
274 if (lines
[i
][11] == '"') {
275 end
= strchr (lines
[i
] + 12, '"');
277 osversion
= g_strndup (lines
[i
] + 12, end
- lines
[i
] - 12);
279 else if (lines
[i
][11] == '\'') {
280 end
= strchr (lines
[i
] + 12, '\'');
282 osversion
= g_strndup (lines
[i
] + 12, end
- lines
[i
] - 12);
285 osversion
= g_strdup (lines
[i
] + 11);
291 gchar
*token
= g_strconcat("platform:", osid
, NULL
);
292 yelp_settings_set_if_token (settings
, token
);
295 token
= g_strconcat("platform:", osid
, "-", osversion
, NULL
);
296 yelp_settings_set_if_token (settings
, token
);
306 desktop
= g_getenv ("XDG_CURRENT_DESKTOP");
307 if (desktop
!= NULL
) {
308 gchar
**desktops
= g_strsplit (desktop
, ":", -1);
310 gboolean xdg_gnome
= FALSE
, xdg_gnome_classic
= FALSE
;
311 for (i
= 0; desktops
[i
]; i
++) {
312 if (!g_ascii_strcasecmp (desktops
[i
], "gnome")) {
315 else if (!g_ascii_strcasecmp (desktops
[i
], "gnome-classic")) {
316 xdg_gnome_classic
= TRUE
;
318 else if (!g_ascii_strcasecmp (desktops
[i
], "kde")) {
319 yelp_settings_set_if_token (settings
, "platform:kde");
320 skip_dbus_checks
= TRUE
;
323 else if (!g_ascii_strcasecmp (desktops
[i
], "mate")) {
324 yelp_settings_set_if_token (settings
, "platform:mate");
325 yelp_settings_set_if_token (settings
, "platform:gnome-panel");
326 skip_dbus_checks
= TRUE
;
329 else if (!g_ascii_strcasecmp (desktops
[i
], "pantheon")) {
330 yelp_settings_set_if_token (settings
, "platform:pantheon");
331 yelp_settings_set_if_token (settings
, "platform:gnome-shell");
332 skip_dbus_checks
= TRUE
;
335 else if (!g_ascii_strcasecmp (desktops
[i
], "unity")) {
336 yelp_settings_set_if_token (settings
, "platform:unity");
337 skip_dbus_checks
= TRUE
;
340 else if (!g_ascii_strcasecmp (desktops
[i
], "x-cinnamon")) {
341 yelp_settings_set_if_token (settings
, "platform:cinnamon");
342 yelp_settings_set_if_token (settings
, "platform:gnome-shell");
343 skip_dbus_checks
= TRUE
;
346 else if (!g_ascii_strcasecmp (desktops
[i
], "xfce")) {
347 yelp_settings_set_if_token (settings
, "platform:xfce");
348 skip_dbus_checks
= TRUE
;
353 yelp_settings_set_if_token (settings
, "platform:gnome-shell");
354 if (!xdg_gnome_classic
)
355 yelp_settings_set_if_token (settings
, "platform:gnome-3");
356 skip_dbus_checks
= TRUE
;
358 if (xdg_gnome_classic
) {
359 yelp_settings_set_if_token (settings
, "platform:gnome-classic");
360 yelp_settings_set_if_token (settings
, "platform:gnome-shell");
361 skip_dbus_checks
= TRUE
;
363 g_strfreev (desktops
);
366 if (!skip_dbus_checks
) {
367 GDBusConnection
*connection
;
368 GVariant
*ret
, *names
;
371 gboolean env_shell
, env_classic
, env_panel
, env_unity
, env_xfce
;
372 GError
*error
= NULL
;
374 connection
= g_bus_get_sync (G_BUS_TYPE_SESSION
, NULL
, &error
);
375 if (connection
== NULL
) {
376 g_warning ("Unable to connect to dbus: %s", error
->message
);
377 g_error_free (error
);
381 ret
= g_dbus_connection_call_sync (connection
,
382 "org.freedesktop.DBus",
383 "/org/freedesktop/DBus",
384 "org.freedesktop.DBus",
387 G_VARIANT_TYPE ("(as)"),
388 G_DBUS_CALL_FLAGS_NONE
,
391 g_warning ("Unable to query dbus: %s", error
->message
);
392 g_error_free (error
);
395 env_shell
= env_classic
= env_panel
= env_unity
= env_xfce
= FALSE
;
396 names
= g_variant_get_child_value (ret
, 0);
397 g_variant_iter_init (&iter
, names
);
398 while (g_variant_iter_loop (&iter
, "&s", &name
)) {
399 if (g_str_equal (name
, "org.gnome.Panel"))
401 else if (g_str_equal (name
, "org.gnome.Shell"))
403 else if (g_str_equal (name
, "com.canonical.Unity"))
405 else if (g_str_equal (name
, "org.xfce.Panel"))
408 g_variant_unref (names
);
409 g_variant_unref (ret
);
411 ret
= g_dbus_connection_call_sync (connection
,
414 "org.freedesktop.DBus.Properties",
416 g_variant_new ("(ss)",
419 G_VARIANT_TYPE ("(v)"),
420 G_DBUS_CALL_FLAGS_NONE
,
423 g_warning ("Failed to get GNOME shell mode: %s", error
->message
);
424 g_error_free (error
);
427 g_variant_get (ret
, "(v)", &v
);
428 if (g_variant_is_of_type (v
, G_VARIANT_TYPE_STRING
) &&
429 g_str_equal (g_variant_get_string (v
, NULL
), "classic")) {
433 g_variant_unref (ret
);
438 yelp_settings_set_if_token (settings
, "platform:gnome-classic");
440 /* order is important:
441 gnome-shell also provides org.gnome.Panel
442 unity also provides org.gnome.Shell
445 yelp_settings_set_if_token (settings
, "platform:unity");
447 yelp_settings_set_if_token (settings
, "platform:gnome-shell");
449 yelp_settings_set_if_token (settings
, "platform:xfce");
451 yelp_settings_set_if_token (settings
, "platform:gnome-panel");
456 yelp_settings_finalize (GObject
*object
)
458 YelpSettings
*settings
= YELP_SETTINGS (object
);
460 g_mutex_clear (&settings
->priv
->mutex
);
462 g_hash_table_destroy (settings
->priv
->tokens
);
464 G_OBJECT_CLASS (yelp_settings_parent_class
)->finalize (object
);
468 yelp_settings_get_property (GObject
*object
,
473 YelpSettings
*settings
= YELP_SETTINGS (object
);
476 case PROP_GTK_SETTINGS
:
477 g_value_set_object (value
, settings
->priv
->gtk_settings
);
479 case PROP_GTK_ICON_THEME
:
480 g_value_set_object (value
, settings
->priv
->gtk_icon_theme
);
482 case PROP_FONT_ADJUSTMENT
:
483 g_value_set_int (value
, settings
->priv
->font_adjustment
);
485 case PROP_SHOW_TEXT_CURSOR
:
486 g_value_set_boolean (value
, settings
->priv
->show_text_cursor
);
488 case PROP_EDITOR_MODE
:
489 g_value_set_boolean (value
, settings
->priv
->editor_mode
);
492 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
498 yelp_settings_set_property (GObject
*object
,
503 YelpSettings
*settings
= YELP_SETTINGS (object
);
506 case PROP_GTK_SETTINGS
:
507 if (settings
->priv
->gtk_settings
) {
508 g_signal_handler_disconnect (settings
->priv
->gtk_settings
,
509 settings
->priv
->gtk_theme_changed
);
510 g_signal_handler_disconnect (settings
->priv
->gtk_settings
,
511 settings
->priv
->gtk_font_changed
);
512 g_object_unref (settings
->priv
->gtk_settings
);
514 settings
->priv
->gtk_settings
= g_value_get_object (value
);
515 if (settings
->priv
->gtk_settings
!= NULL
) {
516 g_object_ref (settings
->priv
->gtk_settings
);
517 settings
->priv
->gtk_theme_changed
=
518 g_signal_connect (settings
->priv
->gtk_settings
,
519 "notify::gtk-theme-name",
520 (GCallback
) gtk_theme_changed
,
522 settings
->priv
->gtk_font_changed
=
523 g_signal_connect (settings
->priv
->gtk_settings
,
524 "notify::gtk-font-name",
525 (GCallback
) gtk_font_changed
,
527 gtk_theme_changed (settings
->priv
->gtk_settings
, NULL
, settings
);
528 gtk_font_changed (settings
->priv
->gtk_settings
, NULL
, settings
);
531 settings
->priv
->gtk_theme_changed
= 0;
532 settings
->priv
->gtk_font_changed
= 0;
535 case PROP_GTK_ICON_THEME
:
536 if (settings
->priv
->gtk_icon_theme
) {
537 g_signal_handler_disconnect (settings
->priv
->gtk_icon_theme
,
538 settings
->priv
->icon_theme_changed
);
539 g_object_unref (settings
->priv
->gtk_icon_theme
);
541 settings
->priv
->gtk_icon_theme
= g_value_get_object (value
);
542 if (settings
->priv
->gtk_icon_theme
!= NULL
) {
544 gint search_path_len
, i
;
545 gboolean append_search_path
= TRUE
;
546 gtk_icon_theme_get_search_path (settings
->priv
->gtk_icon_theme
,
547 &search_path
, &search_path_len
);
548 for (i
= search_path_len
- 1; i
>= 0; i
--)
549 if (g_str_equal (search_path
[i
], YELP_ICON_PATH
)) {
550 append_search_path
= FALSE
;
553 if (append_search_path
)
554 gtk_icon_theme_append_search_path (settings
->priv
->gtk_icon_theme
,
556 append_search_path
= TRUE
;
557 for (i
= search_path_len
- 1; i
>= 0; i
--)
558 if (g_str_equal (search_path
[i
], DATADIR
"/yelp/icons")) {
559 append_search_path
= FALSE
;
562 if (append_search_path
)
563 gtk_icon_theme_append_search_path (settings
->priv
->gtk_icon_theme
,
564 DATADIR
"/yelp/icons");
565 g_strfreev (search_path
);
566 g_object_ref (settings
->priv
->gtk_icon_theme
);
567 settings
->priv
->icon_theme_changed
=
568 g_signal_connect (settings
->priv
->gtk_icon_theme
,
570 (GCallback
) icon_theme_changed
,
572 icon_theme_changed (settings
->priv
->gtk_icon_theme
, settings
);
575 settings
->priv
->icon_theme_changed
= 0;
578 case PROP_FONT_ADJUSTMENT
:
579 settings
->priv
->font_adjustment
= g_value_get_int (value
);
580 gtk_font_changed (settings
->priv
->gtk_settings
, NULL
, settings
);
582 case PROP_SHOW_TEXT_CURSOR
:
583 settings
->priv
->show_text_cursor
= g_value_get_boolean (value
);
585 case PROP_EDITOR_MODE
:
586 settings
->priv
->editor_mode
= g_value_get_boolean (value
);
589 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
594 /******************************************************************************/
597 yelp_settings_get_default (void)
600 static YelpSettings
*settings
= NULL
;
601 g_mutex_lock (&mutex
);
602 if (settings
== NULL
)
603 settings
= g_object_new (YELP_TYPE_SETTINGS
,
604 "gtk-settings", gtk_settings_get_default (),
605 "gtk-icon-theme", gtk_icon_theme_get_default (),
607 g_mutex_unlock (&mutex
);
611 /******************************************************************************/
614 yelp_settings_get_color (YelpSettings
*settings
,
615 YelpSettingsColor color
)
618 g_return_val_if_fail (color
< YELP_SETTINGS_NUM_COLORS
, NULL
);
620 g_mutex_lock (&settings
->priv
->mutex
);
621 colorstr
= g_strdup (settings
->priv
->colors
[color
]);
622 g_mutex_unlock (&settings
->priv
->mutex
);
628 yelp_settings_get_colors (YelpSettings
*settings
)
630 gchar
**colors
= g_new0 (gchar
*, YELP_SETTINGS_NUM_COLORS
+ 1);
632 for (i
= 0; i
< YELP_SETTINGS_NUM_COLORS
; i
++)
633 colors
[i
] = yelp_settings_get_color (settings
, i
);
638 yelp_settings_set_colors (YelpSettings
*settings
,
639 YelpSettingsColor first_color
,
642 YelpSettingsColor color
;
645 g_mutex_lock (&settings
->priv
->mutex
);
646 va_start (args
, first_color
);
649 while ((gint
) color
>= 0) {
650 gchar
*colorstr
= va_arg (args
, gchar
*);
652 for (i
= 0; i
< 7; i
++) {
653 settings
->priv
->colors
[color
][i
] = colorstr
[i
];
654 if (colorstr
[i
] == '\0')
657 settings
->priv
->colors
[color
][7] = '\0';
658 color
= va_arg (args
, YelpSettingsColor
);
662 g_mutex_unlock (&settings
->priv
->mutex
);
664 g_signal_emit (settings
, settings_signals
[COLORS_CHANGED
], 0);
668 yelp_settings_get_color_param (YelpSettingsColor color
)
670 static const gchar
*params
[YELP_SETTINGS_NUM_COLORS
] = {
676 "color.gray_background",
677 "color.dark_background",
679 "color.blue_background",
681 "color.red_background",
683 "color.yellow_background",
684 "color.yellow_border"
686 g_return_val_if_fail (color
< YELP_SETTINGS_NUM_COLORS
, NULL
);
687 return params
[color
];
690 /******************************************************************************/
693 yelp_settings_get_font (YelpSettings
*settings
,
694 YelpSettingsFont font
)
697 g_return_val_if_fail (font
< YELP_SETTINGS_NUM_FONTS
, NULL
);
699 g_mutex_lock (&settings
->priv
->mutex
);
700 if (settings
->priv
->setfonts
[font
])
701 ret
= g_strdup (settings
->priv
->setfonts
[font
]);
703 ret
= g_strdup (settings
->priv
->fonts
[font
]);
704 g_mutex_unlock (&settings
->priv
->mutex
);
710 yelp_settings_get_font_family (YelpSettings
*settings
,
711 YelpSettingsFont font
)
713 const gchar
*def
= (font
== YELP_SETTINGS_FONT_VARIABLE
) ? "Sans" : "Monospace";
714 gchar
*desc
, *ret
, *c
; /* do not free */
715 g_return_val_if_fail (font
< YELP_SETTINGS_NUM_FONTS
, NULL
);
717 g_mutex_lock (&settings
->priv
->mutex
);
719 if (settings
->priv
->setfonts
[font
])
720 desc
= g_strdup (settings
->priv
->setfonts
[font
]);
722 desc
= g_strdup (settings
->priv
->fonts
[font
]);
725 ret
= g_strdup (def
);
729 c
= strrchr (desc
, ' ');
731 g_warning ("Cannot parse font: %s", desc
);
732 ret
= g_strdup (def
);
736 ret
= g_strndup (desc
, c
- desc
);
739 g_mutex_unlock (&settings
->priv
->mutex
);
744 yelp_settings_get_font_size (YelpSettings
*settings
,
745 YelpSettingsFont font
)
747 gchar
*desc
, *c
; /* do not free */
749 g_return_val_if_fail (font
< YELP_SETTINGS_NUM_FONTS
, 0);
751 g_mutex_lock (&settings
->priv
->mutex
);
753 if (settings
->priv
->setfonts
[font
])
754 desc
= g_strdup (settings
->priv
->setfonts
[font
]);
756 desc
= g_strdup (settings
->priv
->fonts
[font
]);
763 c
= strrchr (desc
, ' ');
765 g_warning ("Cannot parse font %s", desc
);
770 ret
= g_ascii_strtod (c
, NULL
);
773 g_mutex_unlock (&settings
->priv
->mutex
);
774 ret
+= settings
->priv
->font_adjustment
;
775 ret
= (ret
< 5) ? 5 : ret
;
780 yelp_settings_set_fonts (YelpSettings
*settings
,
781 YelpSettingsFont first_font
,
784 YelpSettingsFont font
;
787 g_mutex_lock (&settings
->priv
->mutex
);
788 va_start (args
, first_font
);
791 while ((gint
) font
>= 0) {
792 gchar
*fontname
= va_arg (args
, gchar
*);
793 if (settings
->priv
->setfonts
[font
] != NULL
)
794 g_free (settings
->priv
->setfonts
[font
]);
795 settings
->priv
->setfonts
[font
] = g_strdup (fontname
);
796 font
= va_arg (args
, YelpSettingsFont
);
800 g_mutex_unlock (&settings
->priv
->mutex
);
802 g_signal_emit (settings
, settings_signals
[FONTS_CHANGED
], 0);
806 yelp_settings_get_font_adjustment (YelpSettings
*settings
)
808 return settings
->priv
->font_adjustment
;
812 yelp_settings_set_font_adjustment (YelpSettings
*settings
,
815 g_object_set (settings
, "font-adjustment", adjustment
, NULL
);
818 /******************************************************************************/
821 yelp_settings_get_icon_size (YelpSettings
*settings
)
823 return settings
->priv
->icon_size
;
827 yelp_settings_set_icon_size (YelpSettings
*settings
,
830 settings
->priv
->icon_size
= size
;
831 if (settings
->priv
->gtk_icon_theme
!= NULL
)
832 icon_theme_changed (settings
->priv
->gtk_icon_theme
, settings
);
836 yelp_settings_get_icon (YelpSettings
*settings
,
837 YelpSettingsIcon icon
)
840 g_return_val_if_fail (icon
< YELP_SETTINGS_NUM_ICONS
, NULL
);
842 g_mutex_lock (&settings
->priv
->mutex
);
843 ret
= g_strdup (settings
->priv
->icons
[icon
]);
844 g_mutex_unlock (&settings
->priv
->mutex
);
850 yelp_settings_set_icons (YelpSettings
*settings
,
851 YelpSettingsIcon first_icon
,
854 YelpSettingsIcon icon
;
857 g_mutex_lock (&settings
->priv
->mutex
);
858 va_start (args
, first_icon
);
861 while ((gint
) icon
>= 0) {
862 gchar
*filename
= va_arg (args
, gchar
*);
863 if (settings
->priv
->icons
[icon
] != NULL
)
864 g_free (settings
->priv
->icons
[icon
]);
865 settings
->priv
->icons
[icon
] = g_filename_to_uri (filename
, NULL
, NULL
);
866 icon
= va_arg (args
, YelpSettingsIcon
);
870 g_mutex_unlock (&settings
->priv
->mutex
);
872 g_signal_emit (settings
, settings_signals
[ICONS_CHANGED
], 0);
876 yelp_settings_get_icon_param (YelpSettingsIcon icon
)
878 static const gchar
*params
[YELP_SETTINGS_NUM_ICONS
] = {
880 "icons.note.important",
885 g_return_val_if_fail (icon
< YELP_SETTINGS_NUM_ICONS
, NULL
);
889 /******************************************************************************/
892 yelp_settings_get_show_text_cursor (YelpSettings
*settings
)
894 return settings
->priv
->show_text_cursor
;
898 yelp_settings_set_show_text_cursor (YelpSettings
*settings
,
901 g_object_set (settings
, "show-text-cursor", show
, NULL
);
905 yelp_settings_get_editor_mode (YelpSettings
*settings
)
907 return settings
->priv
->editor_mode
;
911 yelp_settings_set_editor_mode (YelpSettings
*settings
,
912 gboolean editor_mode
)
914 g_object_set (settings
, "editor-mode", editor_mode
, NULL
);
917 /******************************************************************************/
920 yelp_settings_set_if_token (YelpSettings
*settings
,
923 if (g_hash_table_lookup (settings
->priv
->tokens
, token
) == NULL
) {
924 gchar
*ins
= g_strdup (token
);
925 g_hash_table_insert (settings
->priv
->tokens
, ins
, ins
);
929 /******************************************************************************/
932 yelp_settings_get_all_params (YelpSettings
*settings
,
938 GString
*malstr
, *dbstr
;
941 params
= g_new0 (gchar
*,
942 (2*YELP_SETTINGS_NUM_COLORS
) + (2*YELP_SETTINGS_NUM_ICONS
) + extra
+ 9);
944 for (i
= 0; i
< YELP_SETTINGS_NUM_COLORS
; i
++) {
947 params
[ix
] = g_strdup (yelp_settings_get_color_param (i
));
948 val
= yelp_settings_get_color (settings
, i
);
949 params
[ix
+ 1] = g_strdup_printf ("\"%s\"", val
);
952 for (i
= 0; i
< YELP_SETTINGS_NUM_ICONS
; i
++) {
954 ix
= 2 * (YELP_SETTINGS_NUM_COLORS
+ i
);
955 params
[ix
] = g_strdup (yelp_settings_get_icon_param (i
));
956 val
= yelp_settings_get_icon (settings
, i
);
957 params
[ix
+ 1] = g_strdup_printf ("\"%s\"", val
);
960 ix
= 2 * (YELP_SETTINGS_NUM_COLORS
+ YELP_SETTINGS_NUM_ICONS
);
961 params
[ix
++] = g_strdup ("icons.size.note");
962 params
[ix
++] = g_strdup_printf ("%i", yelp_settings_get_icon_size (settings
));
963 params
[ix
++] = g_strdup ("yelp.editor_mode");
964 if (settings
->priv
->editor_mode
)
965 params
[ix
++] = g_strdup ("true()");
967 params
[ix
++] = g_strdup ("false()");
969 malstr
= g_string_new ("'");
970 dbstr
= g_string_new ("'");
971 envs
= g_hash_table_get_keys (settings
->priv
->tokens
);
972 for (envi
= envs
; envi
!= NULL
; envi
= envi
->next
) {
973 g_string_append_c (malstr
, ' ');
974 g_string_append (malstr
, (gchar
*) envi
->data
);
975 if (g_str_has_prefix ((gchar
*) envi
->data
, "platform:")) {
976 g_string_append_c (dbstr
, ';');
977 g_string_append (dbstr
, (gchar
*) (envi
->data
) + 9);
980 g_string_append_c (malstr
, '\'');
981 g_string_append_c (dbstr
, '\'');
983 params
[ix
++] = g_strdup ("mal.if.custom");
984 params
[ix
++] = g_string_free (malstr
, FALSE
);
985 params
[ix
++] = g_strdup ("db.profile.os");
986 params
[ix
++] = g_string_free (dbstr
, FALSE
);
995 /******************************************************************************/
998 gtk_theme_changed (GtkSettings
*gtk_settings
,
1000 YelpSettings
*settings
)
1002 GtkStyleContext
*context
, *linkcontext
;
1003 GtkWidget
*tmpwin
, *tmpbox
, *tmpview
, *tmplink
;
1004 GdkRGBA base
, text
, link
;
1005 gdouble base_h
, base_s
, base_v
;
1006 gdouble text_h
, text_s
, text_v
;
1008 g_mutex_lock (&settings
->priv
->mutex
);
1010 tmpwin
= gtk_offscreen_window_new ();
1011 tmpbox
= gtk_grid_new ();
1012 tmpview
= gtk_text_view_new ();
1013 tmplink
= gtk_link_button_new ("http://projectmallard.org/");
1014 gtk_container_add (GTK_CONTAINER (tmpwin
), tmpbox
);
1015 gtk_container_add (GTK_CONTAINER (tmpbox
), tmpview
);
1016 gtk_container_add (GTK_CONTAINER (tmpbox
), tmplink
);
1017 gtk_widget_show_all (tmpwin
);
1019 context
= gtk_widget_get_style_context (tmpview
);
1020 gtk_style_context_save (context
);
1022 gtk_style_context_set_state (context
, GTK_STATE_FLAG_NORMAL
);
1023 gtk_style_context_add_class (context
, GTK_STYLE_CLASS_VIEW
);
1024 gtk_style_context_get_color (context
, GTK_STATE_FLAG_NORMAL
, &text
);
1025 gtk_style_context_get_background_color (context
, GTK_STATE_FLAG_NORMAL
, &base
);
1027 gtk_style_context_restore (context
);
1029 rgb_to_hsv (text
, &text_h
, &text_s
, &text_v
);
1030 rgb_to_hsv (base
, &base_h
, &base_s
, &base_v
);
1032 /* YELP_SETTINGS_COLOR_BASE */
1033 g_snprintf (settings
->priv
->colors
[YELP_SETTINGS_COLOR_BASE
], 8, "#%02X%02X%02X",
1034 (guint
) (base
.red
* 255), (guint
) (base
.green
* 255), (guint
) (base
.blue
* 255));
1036 /* YELP_SETTINGS_COLOR_TEXT */
1037 g_snprintf (settings
->priv
->colors
[YELP_SETTINGS_COLOR_TEXT
], 8, "#%02X%02X%02X",
1038 (guint
) (text
.red
* 255), (guint
) (text
.green
* 255), (guint
) (text
.blue
* 255));
1040 linkcontext
= gtk_widget_get_style_context (tmplink
);
1041 gtk_style_context_save (linkcontext
);
1043 /* YELP_SETTINGS_COLOR_LINK */
1044 gtk_style_context_set_state (linkcontext
, GTK_STATE_FLAG_LINK
);
1045 gtk_style_context_get_color (linkcontext
, GTK_STATE_FLAG_LINK
, &link
);
1046 g_snprintf (settings
->priv
->colors
[YELP_SETTINGS_COLOR_LINK
], 8, "#%02X%02X%02X",
1047 (guint
) (link
.red
* 255), (guint
) (link
.green
* 255), (guint
) (link
.blue
* 255));
1049 /* YELP_SETTINGS_COLOR_LINK_VISITED */
1050 gtk_style_context_set_state (linkcontext
, GTK_STATE_FLAG_VISITED
);
1051 gtk_style_context_get_color (linkcontext
, GTK_STATE_FLAG_VISITED
, &link
);
1052 g_snprintf (settings
->priv
->colors
[YELP_SETTINGS_COLOR_LINK_VISITED
], 8, "#%02X%02X%02X",
1053 (guint
) (link
.red
* 255), (guint
) (link
.green
* 255), (guint
) (link
.blue
* 255));
1056 gtk_style_context_restore (linkcontext
);
1058 /* YELP_SETTINGS_COLOR_TEXT_LIGHT */
1059 hsv_to_hex (text_h
, text_s
, text_v
- ((text_v
- base_v
) * 0.25),
1060 settings
->priv
->colors
[YELP_SETTINGS_COLOR_TEXT_LIGHT
]);
1062 /* YELP_SETTINGS_COLOR_GRAY */
1063 hsv_to_hex (base_h
, base_s
,
1064 base_v
- ((base_v
- text_v
) * 0.05),
1065 settings
->priv
->colors
[YELP_SETTINGS_COLOR_GRAY_BASE
]);
1066 hsv_to_hex (base_h
, base_s
,
1067 base_v
- ((base_v
- text_v
) * 0.1),
1068 settings
->priv
->colors
[YELP_SETTINGS_COLOR_DARK_BASE
]);
1069 hsv_to_hex (base_h
, base_s
,
1070 base_v
- ((base_v
- text_v
) * 0.26),
1071 settings
->priv
->colors
[YELP_SETTINGS_COLOR_GRAY_BORDER
]);
1073 /* YELP_SETTINGS_COLOR_BLUE */
1074 hsv_to_hex (211, 0.1,
1075 base_v
- ((base_v
- text_v
) * 0.01),
1076 settings
->priv
->colors
[YELP_SETTINGS_COLOR_BLUE_BASE
]);
1077 hsv_to_hex (211, 0.45,
1078 base_v
- ((base_v
- text_v
) * 0.19),
1079 settings
->priv
->colors
[YELP_SETTINGS_COLOR_BLUE_BORDER
]);
1081 /* YELP_SETTINGS_COLOR_RED */
1082 hsv_to_hex (0, 0.13,
1083 base_v
- ((base_v
- text_v
) * 0.01),
1084 settings
->priv
->colors
[YELP_SETTINGS_COLOR_RED_BASE
]);
1085 hsv_to_hex (0, 0.83,
1086 base_v
- ((base_v
- text_v
) * 0.06),
1087 settings
->priv
->colors
[YELP_SETTINGS_COLOR_RED_BORDER
]);
1089 /* YELP_SETTINGS_COLOR_YELLOW */
1090 hsv_to_hex (60, 0.25,
1091 base_v
- ((base_v
- text_v
) * 0.01),
1092 settings
->priv
->colors
[YELP_SETTINGS_COLOR_YELLOW_BASE
]);
1093 hsv_to_hex (60, 1.0,
1094 base_v
- ((base_v
- text_v
) * 0.07),
1095 settings
->priv
->colors
[YELP_SETTINGS_COLOR_YELLOW_BORDER
]);
1097 gtk_widget_destroy (tmpwin
);
1099 g_mutex_unlock (&settings
->priv
->mutex
);
1101 g_signal_emit (settings
, settings_signals
[COLORS_CHANGED
], 0);
1105 gtk_font_changed (GtkSettings
*gtk_settings
,
1107 YelpSettings
*settings
)
1111 /* This happens when font_adjustment is set during init */
1112 if (gtk_settings
== NULL
)
1115 g_free (settings
->priv
->fonts
[YELP_SETTINGS_FONT_VARIABLE
]);
1116 g_object_get (gtk_settings
, "gtk-font-name", &font
, NULL
);
1117 settings
->priv
->fonts
[YELP_SETTINGS_FONT_VARIABLE
] = font
;
1119 c
= strrchr (font
, ' ');
1121 g_warning ("Cannot parse font: %s", font
);
1122 font
= g_strdup ("Monospace 10");
1125 font
= g_strconcat ("Monospace", c
, NULL
);
1128 g_free (settings
->priv
->fonts
[YELP_SETTINGS_FONT_FIXED
]);
1129 settings
->priv
->fonts
[YELP_SETTINGS_FONT_FIXED
] = font
;
1131 g_signal_emit (settings
, settings_signals
[FONTS_CHANGED
], 0);
1135 icon_theme_changed (GtkIconTheme
*theme
,
1136 YelpSettings
*settings
)
1141 g_mutex_lock (&settings
->priv
->mutex
);
1143 for (i
= 0; i
< YELP_SETTINGS_NUM_ICONS
; i
++) {
1144 if (settings
->priv
->icons
[i
] != NULL
)
1145 g_free (settings
->priv
->icons
[i
]);
1146 info
= gtk_icon_theme_lookup_icon (theme
,
1148 settings
->priv
->icon_size
,
1149 GTK_ICON_LOOKUP_NO_SVG
);
1151 settings
->priv
->icons
[i
] = g_filename_to_uri (gtk_icon_info_get_filename (info
),
1153 g_object_unref (info
);
1156 settings
->priv
->icons
[i
] = NULL
;
1160 g_mutex_unlock (&settings
->priv
->mutex
);
1162 g_signal_emit (settings
, settings_signals
[ICONS_CHANGED
], 0);
1166 yelp_settings_cmp_icons (const gchar
*icon1
,
1169 static const gchar
*icons
[] = {
1170 "yelp-page-search-symbolic",
1171 "yelp-page-video-symbolic",
1172 "yelp-page-task-symbolic",
1173 "yelp-page-tip-symbolic",
1174 "yelp-page-problem-symbolic",
1175 "yelp-page-ui-symbolic",
1176 "yelp-page-symbolic",
1180 for (i
= 0; icons
[i
] != NULL
; i
++) {
1181 gboolean eq1
= icon1
? g_str_has_prefix (icon1
, icons
[i
]) : FALSE
;
1182 gboolean eq2
= icon2
? g_str_has_prefix (icon2
, icons
[i
]) : FALSE
;
1190 if (icon1
== NULL
&& icon2
== NULL
)
1192 else if (icon2
== NULL
)
1194 else if (icon1
== NULL
)
1197 return strcmp (icon1
, icon2
);
1200 /******************************************************************************/
1203 rgb_to_hsv (GdkRGBA color
, gdouble
*h
, gdouble
*s
, gdouble
*v
)
1205 gdouble min
, max
, delta
;
1207 max
= (color
.red
> color
.green
) ? color
.red
: color
.green
;
1208 max
= (max
> color
.blue
) ? max
: color
.blue
;
1209 min
= (color
.red
< color
.green
) ? color
.red
: color
.green
;
1210 min
= (min
< color
.blue
) ? min
: color
.blue
;
1221 if (color
.red
== max
)
1222 *h
= (color
.green
- color
.blue
) / delta
;
1223 else if (color
.green
== max
)
1224 *h
= 2 + (color
.blue
- color
.red
) / delta
;
1225 else if (color
.blue
== max
)
1226 *h
= 4 + (color
.red
- color
.green
) / delta
;
1235 hsv_to_hex (gdouble h
, gdouble s
, gdouble v
, gchar
*str
)
1240 guint red
, green
, blue
;
1245 m2
= v
* (1 - s
* (h
- hue
));
1246 m3
= v
* (1 - s
* (-h
+ hue
+ 1));
1251 b
= m1
; g
= m3
; break;
1253 b
= m1
; r
= m2
; break;
1255 r
= m1
; b
= m3
; break;
1257 r
= m1
; g
= m2
; break;
1259 g
= m1
; r
= m3
; break;
1261 g
= m1
; b
= m2
; break;
1263 g_assert_not_reached (); break;
1269 g_snprintf (str
, 8, "#%02X%02X%02X", red
, green
, blue
);