Bug Summary

File:capplets/appearance/appearance-themes.c
Warning:line 601, column 21
Null pointer passed to 1st parameter expecting 'nonnull'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name appearance-themes.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/capplets/appearance -resource-dir /usr/lib/llvm-16/lib/clang/16 -D HAVE_CONFIG_H -I . -I ../.. -I /usr/include/croma-1 -I /usr/include/ctk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/gio-unix-2.0 -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I ../../capplets/common -I /usr/include/ctk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/gio-unix-2.0 -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/libxml2 -I /usr/include/cafe-desktop-2.0 -I /usr/include/startup-notification-1.0 -I /usr/include/dconf -I ../../ -D G_LOG_DOMAIN="appearance-properties" -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/polkit-1 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/gio-unix-2.0 -I /usr/include/ctk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/gio-unix-2.0 -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/libxml2 -I /usr/include/cafe-desktop-2.0 -I /usr/include/startup-notification-1.0 -I /usr/include/dconf -D CAFECC_DATA_DIR="/usr/share/cafe-control-center" -D CAFECC_PIXMAP_DIR="/usr/share/cafe-control-center/pixmaps" -D WALLPAPER_DATADIR="/usr/share/cafe-background-properties" -D BACKGROUND_DATADIR="/usr/share/backgrounds" -D CAFE_DESKTOP_USE_UNSTABLE_API -internal-isystem /usr/lib/llvm-16/lib/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir=/rootdir/capplets/appearance -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2024-04-16-091552-112930-1 -x c appearance-themes.c
1/*
2 * Copyright (C) 2007, 2010 The GNOME Foundation
3 * Written by Thomas Wood <thos@gnome.org>
4 * Jens Granseuer <jensgr@gmx.net>
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22#include "appearance.h"
23#include "theme-thumbnail.h"
24#include "cafe-theme-apply.h"
25#include "theme-installer.h"
26#include "theme-save.h"
27#include "theme-util.h"
28#include "ctkrc-utils.h"
29
30#include <glib/gi18n.h>
31#include <libwindow-settings/cafe-wm-manager.h>
32#include <string.h>
33#include <libcafe-desktop/cafe-desktop-thumbnail.h>
34#include <libcafe-desktop/cafe-gsettings.h>
35
36#define CUSTOM_THEME_NAME"__custom__" "__custom__"
37
38enum {
39 RESPONSE_APPLY_BG,
40 RESPONSE_REVERT_FONT,
41 RESPONSE_APPLY_FONT,
42 RESPONSE_INSTALL_ENGINE
43};
44
45enum {
46 TARGET_URI_LIST,
47 TARGET_NS_URL
48};
49
50static const CtkTargetEntry drop_types[] =
51{
52 {"text/uri-list", 0, TARGET_URI_LIST},
53 {"_NETSCAPE_URL", 0, TARGET_NS_URL}
54};
55
56static void theme_message_area_update(AppearanceData* data);
57
58static time_t theme_get_mtime(const char* name)
59{
60 CafeThemeMetaInfo* theme;
61 time_t mtime = -1;
62
63 theme = cafe_theme_meta_info_find(name);
64 if (theme != NULL((void*)0))
65 {
66 GFile* file;
67 GFileInfo* file_info;
68
69 file = g_file_new_for_path(theme->path);
70 file_info = g_file_query_info(file, G_FILE_ATTRIBUTE_TIME_MODIFIED"time::modified", G_FILE_QUERY_INFO_NONE, NULL((void*)0), NULL((void*)0));
71 g_object_unref(file);
72
73 if (file_info != NULL((void*)0))
74 {
75 mtime = g_file_info_get_attribute_uint64(file_info, G_FILE_ATTRIBUTE_TIME_MODIFIED"time::modified");
76 g_object_unref(file_info);
77 }
78 }
79
80 return mtime;
81}
82
83static void theme_thumbnail_update(GdkPixbuf* pixbuf, gchar* theme_name, AppearanceData* data, gboolean cache)
84{
85 CtkTreeIter iter;
86 CtkTreeModel* model = CTK_TREE_MODEL(data->theme_store)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((data->theme_store)), ((ctk_tree_model_get_type ()))))
))
;
87
88 /* find item in model and update thumbnail */
89 if (!pixbuf)
90 return;
91
92 if (theme_find_in_model(model, theme_name, &iter))
93 {
94 time_t mtime;
95
96 ctk_list_store_set(data->theme_store, &iter, COL_THUMBNAIL, pixbuf, -1);
97
98 /* cache thumbnail */
99 if (cache && (mtime = theme_get_mtime(theme_name)) != -1)
100 {
101 gchar* path;
102
103 /* try to share thumbs with baul, use themes:/// */
104 path = g_strconcat("themes:///", theme_name, NULL((void*)0));
105
106 cafe_desktop_thumbnail_factory_save_thumbnail(data->thumb_factory, pixbuf, path, mtime);
107
108 g_free(path);
109 }
110 }
111}
112
113static GdkPixbuf* theme_get_thumbnail_from_cache(CafeThemeMetaInfo* info, AppearanceData* data)
114{
115 GdkPixbuf* thumb = NULL((void*)0);
116 gchar* path, *thumb_filename;
117 time_t mtime;
118
119 if (info == data->theme_custom)
120 return NULL((void*)0);
121
122 mtime = theme_get_mtime(info->name);
123
124 if (mtime == -1)
125 return NULL((void*)0);
126
127 /* try to share thumbs with baul, use themes:/// */
128 path = g_strconcat ("themes:///", info->name, NULL((void*)0));
129 thumb_filename = cafe_desktop_thumbnail_factory_lookup(data->thumb_factory, path, mtime);
130 g_free(path);
131
132 if (thumb_filename != NULL((void*)0))
133 {
134 thumb = gdk_pixbuf_new_from_file(thumb_filename, NULL((void*)0));
135 g_free(thumb_filename);
136 }
137
138 return thumb;
139}
140
141static void
142theme_thumbnail_done_cb (GdkPixbuf *pixbuf, gchar *theme_name, AppearanceData *data)
143{
144 theme_thumbnail_update (pixbuf, theme_name, data, TRUE(!(0)));
145}
146
147static void theme_thumbnail_generate(CafeThemeMetaInfo* info, AppearanceData* data)
148{
149 GdkPixbuf* thumb = theme_get_thumbnail_from_cache(info, data);
150
151 if (thumb != NULL((void*)0))
152 {
153 theme_thumbnail_update(thumb, info->name, data, FALSE(0));
154 g_object_unref(thumb);
155 }
156 else
157 {
158 generate_meta_theme_thumbnail_async(info, (ThemeThumbnailFunc) theme_thumbnail_done_cb, data, NULL((void*)0));
159 }
160}
161
162static void theme_changed_on_disk_cb(CafeThemeCommonInfo* theme, CafeThemeChangeType change_type, CafeThemeElement element_type, AppearanceData* data)
163{
164 if (theme->type == CAFE_THEME_TYPE_METATHEME)
165 {
166 CafeThemeMetaInfo* meta = (CafeThemeMetaInfo*) theme;
167
168 if (change_type == CAFE_THEME_CHANGE_CREATED)
169 {
170 ctk_list_store_insert_with_values (data->theme_store, NULL((void*)0), 0, COL_LABEL, meta->readable_name, COL_NAME, meta->name, COL_THUMBNAIL, data->theme_icon, -1);
171 theme_thumbnail_generate(meta, data);
172 }
173 else if (change_type == CAFE_THEME_CHANGE_DELETED)
174 {
175 CtkTreeIter iter;
176
177 if (theme_find_in_model(CTK_TREE_MODEL(data->theme_store)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((data->theme_store)), ((ctk_tree_model_get_type ()))))
))
, meta->name, &iter))
178 {
179 ctk_list_store_remove(data->theme_store, &iter);
180 }
181 }
182 else if (change_type == CAFE_THEME_CHANGE_CHANGED)
183 {
184 theme_thumbnail_generate(meta, data);
185 }
186 }
187}
188
189/* Find out if the lockdown key has been set. */
190static gboolean is_locked_down()
191{
192 gboolean is_locked;
193 GSettings *settings;
194 settings = g_settings_new (LOCKDOWN_SCHEMA"org.cafe.lockdown");
195 is_locked = g_settings_get_boolean (settings, DISABLE_THEMES_SETTINGS_KEY"disable-theme-settings");
196 g_object_unref (settings);
197 return is_locked;
198}
199
200static CafeThemeMetaInfo *
201theme_load_from_gsettings (AppearanceData *data)
202{
203 CafeThemeMetaInfo *theme;
204 gchar *scheme;
205
206 theme = cafe_theme_meta_info_new ();
207
208 theme->ctk_theme_name = g_settings_get_string (data->interface_settings, CTK_THEME_KEY"ctk-theme");
209 if (theme->ctk_theme_name == NULL((void*)0))
210 theme->ctk_theme_name = g_strdup ("ClassicOk")g_strdup_inline ("ClassicOk");
211
212 scheme = g_settings_get_string (data->interface_settings, COLOR_SCHEME_KEY"ctk-color-scheme");
213 if (scheme == NULL((void*)0) || !strcmp (scheme, "")) {
214 g_free (scheme);
215 scheme = ctkrc_get_color_scheme_for_theme (theme->ctk_theme_name);
216 }
217 theme->ctk_color_scheme = scheme;
218
219 theme->croma_theme_name = g_settings_get_string (data->croma_settings, CROMA_THEME_KEY"theme");
220 if (theme->croma_theme_name == NULL((void*)0))
221 theme->croma_theme_name = g_strdup ("ClassicOk")g_strdup_inline ("ClassicOk");
222
223 theme->icon_theme_name = g_settings_get_string (data->interface_settings, ICON_THEME_KEY"icon-theme");
224 if (theme->icon_theme_name == NULL((void*)0))
225 theme->icon_theme_name = g_strdup ("cafe")g_strdup_inline ("cafe");
226
227 if (cafe_gsettings_schema_exists (NOTIFICATION_SCHEMA"org.cafe.NotificationDaemon")) {
228 GSettings *notification_settings;
229 notification_settings = g_settings_new (NOTIFICATION_SCHEMA"org.cafe.NotificationDaemon");
230 theme->notification_theme_name = g_settings_get_string (notification_settings, NOTIFICATION_THEME_KEY"theme");
231 g_object_unref (notification_settings);
232 }
233 else
234 theme->notification_theme_name = NULL((void*)0);
235
236 theme->cursor_theme_name = g_settings_get_string (data->mouse_settings, CURSOR_THEME_KEY"cursor-theme");
237 theme->cursor_size = g_settings_get_int (data->mouse_settings, CURSOR_SIZE_KEY"cursor-size");
238
239 if (theme->cursor_theme_name == NULL((void*)0))
240 theme->cursor_theme_name = g_strdup ("default")g_strdup_inline ("default");
241
242 theme->application_font = g_settings_get_string (data->interface_settings, CTK_FONT_KEY"font-name");
243
244 return theme;
245}
246
247static gchar *
248theme_get_selected_name (CtkIconView *icon_view, AppearanceData *data)
249{
250 gchar *name = NULL((void*)0);
251 GList *selected = ctk_icon_view_get_selected_items (icon_view);
252
253 if (selected) {
254 CtkTreePath *path = selected->data;
255 CtkTreeModel *model = ctk_icon_view_get_model (icon_view);
256 CtkTreeIter iter;
257
258 if (ctk_tree_model_get_iter (model, &iter, path))
259 ctk_tree_model_get (model, &iter, COL_NAME, &name, -1);
260
261 g_list_foreach (selected, (GFunc) ctk_tree_path_free, NULL((void*)0));
262 g_list_free (selected);
263 }
264
265 return name;
266}
267
268static const CafeThemeMetaInfo *
269theme_get_selected (CtkIconView *icon_view, AppearanceData *data)
270{
271 CafeThemeMetaInfo *theme = NULL((void*)0);
272 gchar *name = theme_get_selected_name (icon_view, data);
273
274 if (name != NULL((void*)0)) {
3
Assuming 'name' is not equal to NULL
4
Taking true branch
275 if (!strcmp (name, data->theme_custom->name)) {
5
Taking true branch
276 theme = data->theme_custom;
277 } else {
278 theme = cafe_theme_meta_info_find (name);
279 }
280
281 g_free (name);
282 }
283
284 return theme;
6
Returning pointer (loaded from 'theme'), which participates in a condition later
285}
286
287static void
288theme_select_iter (CtkIconView *icon_view, CtkTreeIter *iter)
289{
290 CtkTreePath *path;
291
292 path = ctk_tree_model_get_path (ctk_icon_view_get_model (icon_view), iter);
293 ctk_icon_view_select_path (icon_view, path);
294 ctk_icon_view_scroll_to_path (icon_view, path, FALSE(0), 0.5, 0.0);
295 ctk_tree_path_free (path);
296}
297
298static void
299theme_select_name (CtkIconView *icon_view, const gchar *theme)
300{
301 CtkTreeIter iter;
302 CtkTreeModel *model = ctk_icon_view_get_model (icon_view);
303
304 if (theme_find_in_model (model, theme, &iter))
305 theme_select_iter (icon_view, &iter);
306}
307
308static gboolean
309theme_is_equal (const CafeThemeMetaInfo *a, const CafeThemeMetaInfo *b)
310{
311 gboolean a_set, b_set;
312
313 if (!(a->ctk_theme_name && b->ctk_theme_name) ||
314 strcmp (a->ctk_theme_name, b->ctk_theme_name))
315 return FALSE(0);
316
317 if (!(a->icon_theme_name && b->icon_theme_name) ||
318 strcmp (a->icon_theme_name, b->icon_theme_name))
319 return FALSE(0);
320
321 if (!(a->croma_theme_name && b->croma_theme_name) ||
322 strcmp (a->croma_theme_name, b->croma_theme_name))
323 return FALSE(0);
324
325 if (!(a->cursor_theme_name && b->cursor_theme_name) ||
326 strcmp (a->cursor_theme_name, b->cursor_theme_name))
327 return FALSE(0);
328
329 if (a->cursor_size != b->cursor_size)
330 return FALSE(0);
331
332 a_set = a->ctk_color_scheme && strcmp (a->ctk_color_scheme, "");
333 b_set = b->ctk_color_scheme && strcmp (b->ctk_color_scheme, "");
334 if ((a_set != b_set) ||
335 (a_set && !cafe_theme_color_scheme_equal (a->ctk_color_scheme, b->ctk_color_scheme)))
336 return FALSE(0);
337
338 return TRUE(!(0));
339}
340
341static void
342theme_set_custom_from_theme (const CafeThemeMetaInfo *info, AppearanceData *data)
343{
344 CafeThemeMetaInfo *custom = data->theme_custom;
345 CtkIconView *icon_view = CTK_ICON_VIEW (appearance_capplet_get_widget (data, "theme_list"))((((CtkIconView*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((CtkWidget*) ctk_builder_get_object(data->ui, "theme_list"
))), ((ctk_icon_view_get_type ()))))))
;
346 CtkTreeModel *model;
347 CtkTreeIter iter;
348 CtkTreePath *path;
349
350 if (info == custom)
351 return;
352
353 /* if info is not NULL, we'll copy those theme settings over */
354 if (info != NULL((void*)0)) {
355 g_free (custom->ctk_theme_name);
356 g_free (custom->icon_theme_name);
357 g_free (custom->croma_theme_name);
358 g_free (custom->ctk_color_scheme);
359 g_free (custom->cursor_theme_name);
360 g_free (custom->application_font);
361 custom->ctk_color_scheme = NULL((void*)0);
362 custom->application_font = NULL((void*)0);
363
364 /* these settings are guaranteed to be non-NULL */
365 custom->ctk_theme_name = g_strdup (info->ctk_theme_name)g_strdup_inline (info->ctk_theme_name);
366 custom->icon_theme_name = g_strdup (info->icon_theme_name)g_strdup_inline (info->icon_theme_name);
367 custom->croma_theme_name = g_strdup (info->croma_theme_name)g_strdup_inline (info->croma_theme_name);
368 custom->cursor_theme_name = g_strdup (info->cursor_theme_name)g_strdup_inline (info->cursor_theme_name);
369 custom->cursor_size = info->cursor_size;
370
371 /* these can be NULL */
372 if (info->ctk_color_scheme)
373 custom->ctk_color_scheme = g_strdup (info->ctk_color_scheme)g_strdup_inline (info->ctk_color_scheme);
374 else
375 custom->ctk_color_scheme = g_strdup ("")g_strdup_inline ("");
376
377 if (info->application_font)
378 custom->application_font = g_strdup (info->application_font)g_strdup_inline (info->application_font);
379 else
380 custom->application_font = g_strdup (CTK_FONT_DEFAULT_VALUE)g_strdup_inline ("Sans 10");
381 }
382
383 /* select the custom theme */
384 model = ctk_icon_view_get_model (icon_view);
385 if (!theme_find_in_model (model, custom->name, &iter)) {
386 CtkTreeIter child;
387
388 ctk_list_store_insert_with_values (data->theme_store, &child, 0,
389 COL_LABEL, custom->readable_name,
390 COL_NAME, custom->name,
391 COL_THUMBNAIL, data->theme_icon,
392 -1);
393 ctk_tree_model_sort_convert_child_iter_to_iter (
394 CTK_TREE_MODEL_SORT (model)((((CtkTreeModelSort*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((model)), ((ctk_tree_model_sort_get_type ())
)))))
, &iter, &child);
395 }
396
397 path = ctk_tree_model_get_path (model, &iter);
398 ctk_icon_view_select_path (icon_view, path);
399 ctk_icon_view_scroll_to_path (icon_view, path, FALSE(0), 0.5, 0.0);
400 ctk_tree_path_free (path);
401
402 /* update the theme thumbnail */
403 theme_thumbnail_generate (custom, data);
404}
405
406/** GUI Callbacks **/
407
408static void custom_font_cb(CtkWidget* button, AppearanceData* data)
409{
410 g_free(data->revert_application_font);
411 g_free(data->revert_documents_font);
412 g_free(data->revert_desktop_font);
413 g_free(data->revert_windowtitle_font);
414 g_free(data->revert_monospace_font);
415 data->revert_application_font = NULL((void*)0);
416 data->revert_documents_font = NULL((void*)0);
417 data->revert_desktop_font = NULL((void*)0);
418 data->revert_windowtitle_font = NULL((void*)0);
419 data->revert_monospace_font = NULL((void*)0);
420}
421
422static void
423theme_message_area_response_cb (CtkWidget *w,
424 gint response_id,
425 AppearanceData *data)
426{
427 const CafeThemeMetaInfo *theme;
428 gchar *tmpfont;
429 gchar *engine_path;
430
431 theme = theme_get_selected (CTK_ICON_VIEW (appearance_capplet_get_widget (data, "theme_list"))((((CtkIconView*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((CtkWidget*) ctk_builder_get_object(data->ui, "theme_list"
))), ((ctk_icon_view_get_type ()))))))
, data);
432 if (!theme)
433 return;
434
435 switch (response_id)
436 {
437 case RESPONSE_APPLY_BG:
438 g_settings_set_string (data->wp_settings, WP_FILE_KEY"picture-filename", theme->background_image);
439 break;
440
441 case RESPONSE_REVERT_FONT:
442 if (data->revert_application_font != NULL((void*)0)) {
443 g_settings_set_string (data->interface_settings, CTK_FONT_KEY"font-name", data->revert_application_font);
444 g_free (data->revert_application_font);
445 data->revert_application_font = NULL((void*)0);
446 }
447
448 if (data->revert_documents_font != NULL((void*)0)) {
449 g_settings_set_string (data->interface_settings, DOCUMENT_FONT_KEY"document-font-name", data->revert_documents_font);
450 g_free (data->revert_documents_font);
451 data->revert_documents_font = NULL((void*)0);
452 }
453
454 if (data->baul_settings && data->revert_desktop_font != NULL((void*)0)) {
455 g_settings_set_string (data->baul_settings, DESKTOP_FONT_KEY"font", data->revert_desktop_font);
456 g_free (data->revert_desktop_font);
457 data->revert_desktop_font = NULL((void*)0);
458 }
459
460 if (data->revert_windowtitle_font != NULL((void*)0)) {
461 g_settings_set_string (data->croma_settings, WINDOW_TITLE_FONT_KEY"titlebar-font", data->revert_windowtitle_font);
462 g_free (data->revert_windowtitle_font);
463 data->revert_windowtitle_font = NULL((void*)0);
464 }
465
466 if (data->revert_monospace_font != NULL((void*)0)) {
467 g_settings_set_string (data->interface_settings, MONOSPACE_FONT_KEY"monospace-font-name", data->revert_monospace_font);
468 g_free (data->revert_monospace_font);
469 data->revert_monospace_font = NULL((void*)0);
470 }
471 break;
472
473 case RESPONSE_APPLY_FONT:
474 if (theme->application_font) {
475 tmpfont = g_settings_get_string (data->interface_settings, CTK_FONT_KEY"font-name");
476 if (tmpfont != NULL((void*)0)) {
477 g_free (data->revert_application_font);
478
479 if (strcmp (theme->application_font, tmpfont) == 0) {
480 g_free (tmpfont);
481 data->revert_application_font = NULL((void*)0);
482 } else
483 data->revert_application_font = tmpfont;
484 }
485 g_settings_set_string (data->interface_settings, CTK_FONT_KEY"font-name", theme->application_font);
486 }
487
488 if (theme->documents_font) {
489 tmpfont = g_settings_get_string (data->interface_settings, DOCUMENT_FONT_KEY"document-font-name");
490 if (tmpfont != NULL((void*)0)) {
491 g_free (data->revert_documents_font);
492
493 if (strcmp (theme->documents_font, tmpfont) == 0) {
494 g_free (tmpfont);
495 data->revert_documents_font = NULL((void*)0);
496 } else
497 data->revert_documents_font = tmpfont;
498 }
499 g_settings_set_string (data->interface_settings, DOCUMENT_FONT_KEY"document-font-name", theme->documents_font);
500 }
501
502 if (data->baul_settings && theme->desktop_font) {
503 tmpfont = g_settings_get_string (data->baul_settings, DESKTOP_FONT_KEY"font");
504 if (tmpfont != NULL((void*)0)) {
505 g_free (data->revert_desktop_font);
506
507 if (strcmp (theme->desktop_font, tmpfont) == 0) {
508 g_free (tmpfont);
509 data->revert_desktop_font = NULL((void*)0);
510 } else
511 data->revert_desktop_font = tmpfont;
512 }
513 g_settings_set_string (data->baul_settings, DESKTOP_FONT_KEY"font", theme->desktop_font);
514 }
515
516 if (theme->windowtitle_font) {
517 tmpfont = g_settings_get_string (data->croma_settings, WINDOW_TITLE_FONT_KEY"titlebar-font");
518 if (tmpfont != NULL((void*)0)) {
519 g_free (data->revert_windowtitle_font);
520
521 if (strcmp (theme->windowtitle_font, tmpfont) == 0) {
522 g_free (tmpfont);
523 data->revert_windowtitle_font = NULL((void*)0);
524 } else
525 data->revert_windowtitle_font = tmpfont;
526 }
527 g_settings_set_string (data->croma_settings, WINDOW_TITLE_FONT_KEY"titlebar-font", theme->windowtitle_font);
528 }
529
530 if (theme->monospace_font) {
531 tmpfont = g_settings_get_string (data->interface_settings, MONOSPACE_FONT_KEY"monospace-font-name");
532 if (tmpfont != NULL((void*)0)) {
533 g_free (data->revert_monospace_font);
534
535 if (strcmp (theme->monospace_font, tmpfont) == 0) {
536 g_free (tmpfont);
537 data->revert_monospace_font = NULL((void*)0);
538 } else
539 data->revert_monospace_font = tmpfont;
540 }
541 g_settings_set_string (data->interface_settings, MONOSPACE_FONT_KEY"monospace-font-name", theme->monospace_font);
542 }
543 break;
544
545 case RESPONSE_INSTALL_ENGINE:
546 engine_path = ctk_theme_info_missing_engine(theme->ctk_theme_name, FALSE(0));
547
548 if (engine_path != NULL((void*)0)) {
549 theme_install_file(CTK_WINDOW(ctk_widget_get_toplevel(data->install_button))((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_widget_get_toplevel(data->install_button))), ((ctk_window_get_type
()))))))
, engine_path);
550 g_free (engine_path);
551 }
552
553 theme_message_area_update(data);
554 break;
555 }
556}
557
558static void
559theme_message_area_update (AppearanceData *data)
560{
561 const CafeThemeMetaInfo *theme;
562 gboolean show_apply_background = FALSE(0);
563 gboolean show_apply_font = FALSE(0);
564 gboolean show_revert_font = FALSE(0);
565 gboolean show_error;
566 const gchar *message;
567 GError *error = NULL((void*)0);
568
569 theme = theme_get_selected (CTK_ICON_VIEW (appearance_capplet_get_widget (data, "theme_list"))((((CtkIconView*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((CtkWidget*) ctk_builder_get_object(data->ui, "theme_list"
))), ((ctk_icon_view_get_type ()))))))
, data)
;
2
Calling 'theme_get_selected'
7
Returning from 'theme_get_selected'
570
571 if (!theme
7.1
'theme' is non-null
) {
8
Taking false branch
572 if (data->theme_message_area != NULL((void*)0))
573 ctk_widget_hide (data->theme_message_area);
574 return;
575 }
576
577 show_error = !cafe_theme_meta_info_validate (theme, &error);
9
Assuming the condition is false
578
579 if (!show_error
9.1
'show_error' is 0
) {
10
Taking true branch
580 gchar *font;
581
582 if (theme->background_image != NULL((void*)0)) {
11
Assuming field 'background_image' is equal to NULL
12
Taking false branch
583 gchar *background;
584
585 background = g_settings_get_string (data->wp_settings, WP_FILE_KEY"picture-filename");
586 show_apply_background =
587 (!background || strcmp (theme->background_image, background) != 0);
588 g_free (background);
589 }
590
591 if (theme->application_font) {
13
Assuming field 'application_font' is null
14
Assuming pointer value is null
592 font = g_settings_get_string (data->interface_settings, CTK_FONT_KEY"font-name");
593 show_apply_font =
594 (!font || strcmp (theme->application_font, font) != 0);
595 g_free (font);
596 }
597
598 if (!show_apply_font
14.1
'show_apply_font' is 0
&& theme->documents_font) {
15
Assuming field 'documents_font' is non-null
16
Taking true branch
599 font = g_settings_get_string (data->interface_settings, DOCUMENT_FONT_KEY"document-font-name");
600 show_apply_font =
601 (!font || strcmp (theme->application_font, font) != 0);
17
Assuming 'font' is non-null
18
Null pointer passed to 1st parameter expecting 'nonnull'
602 g_free (font);
603 }
604
605 if (data->baul_settings && !show_apply_font && theme->desktop_font) {
606 font = g_settings_get_string (data->baul_settings, DESKTOP_FONT_KEY"font");
607 show_apply_font =
608 (!font || strcmp (theme->application_font, font) != 0);
609 g_free (font);
610 }
611
612 if (!show_apply_font && theme->windowtitle_font) {
613 font = g_settings_get_string (data->croma_settings, WINDOW_TITLE_FONT_KEY"titlebar-font");
614 show_apply_font =
615 (!font || strcmp (theme->application_font, font) != 0);
616 g_free (font);
617 }
618
619 if (!show_apply_font && theme->monospace_font) {
620 font = g_settings_get_string (data->interface_settings, MONOSPACE_FONT_KEY"monospace-font-name");
621 show_apply_font =
622 (!font || strcmp (theme->application_font, font) != 0);
623 g_free (font);
624 }
625
626 show_revert_font = (data->revert_application_font != NULL((void*)0) ||
627 data->revert_documents_font != NULL((void*)0) || data->revert_desktop_font != NULL((void*)0) ||
628 data->revert_windowtitle_font != NULL((void*)0) || data->revert_monospace_font != NULL((void*)0));
629 }
630
631 if (data->theme_message_area == NULL((void*)0)) {
632 CtkWidget *hbox;
633 CtkWidget *parent;
634 CtkWidget *content;
635
636 if (!show_apply_background && !show_revert_font && !show_apply_font && !show_error)
637 return;
638
639 data->theme_message_area = ctk_info_bar_new ();
640 ctk_widget_set_no_show_all (data->theme_message_area, TRUE(!(0)));
641
642 g_signal_connect (data->theme_message_area, "response",g_signal_connect_data ((data->theme_message_area), ("response"
), ((GCallback) theme_message_area_response_cb), (data), ((void
*)0), (GConnectFlags) 0)
643 (GCallback) theme_message_area_response_cb, data)g_signal_connect_data ((data->theme_message_area), ("response"
), ((GCallback) theme_message_area_response_cb), (data), ((void
*)0), (GConnectFlags) 0)
;
644
645 data->apply_background_button = ctk_info_bar_add_button (
646 CTK_INFO_BAR (data->theme_message_area)((((CtkInfoBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((data->theme_message_area)), ((ctk_info_bar_get_type()
))))))
,
647 _("Apply Background")gettext ("Apply Background"),
648 RESPONSE_APPLY_BG);
649 data->apply_font_button = ctk_info_bar_add_button (
650 CTK_INFO_BAR (data->theme_message_area)((((CtkInfoBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((data->theme_message_area)), ((ctk_info_bar_get_type()
))))))
,
651 _("Apply Font")gettext ("Apply Font"),
652 RESPONSE_APPLY_FONT);
653 data->revert_font_button = ctk_info_bar_add_button (
654 CTK_INFO_BAR (data->theme_message_area)((((CtkInfoBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((data->theme_message_area)), ((ctk_info_bar_get_type()
))))))
,
655 _("Revert Font")gettext ("Revert Font"),
656 RESPONSE_REVERT_FONT);
657 data->install_button = ctk_info_bar_add_button (
658 CTK_INFO_BAR (data->theme_message_area)((((CtkInfoBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((data->theme_message_area)), ((ctk_info_bar_get_type()
))))))
,
659 _("Install")gettext ("Install"),
660 RESPONSE_INSTALL_ENGINE);
661
662 data->theme_message_label = ctk_label_new (NULL((void*)0));
663 ctk_widget_show (data->theme_message_label);
664 ctk_label_set_line_wrap (CTK_LABEL (data->theme_message_label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((data->theme_message_label)), ((ctk_label_get_type ())
)))))
, TRUE(!(0)));
665 ctk_label_set_xalign (CTK_LABEL (data->theme_message_label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((data->theme_message_label)), ((ctk_label_get_type ())
)))))
, 0.0);
666
667 hbox = ctk_box_new (CTK_ORIENTATION_HORIZONTAL, 9);
668 ctk_widget_show (hbox);
669 data->theme_info_icon = ctk_image_new_from_icon_name ("dialog-information", CTK_ICON_SIZE_DIALOG);
670 data->theme_error_icon = ctk_image_new_from_icon_name ("dialog-warning", CTK_ICON_SIZE_DIALOG);
671 ctk_widget_set_halign (data->theme_info_icon, CTK_ALIGN_CENTER);
672 ctk_widget_set_valign (data->theme_info_icon, CTK_ALIGN_START);
673 ctk_widget_set_halign (data->theme_error_icon, CTK_ALIGN_CENTER);
674 ctk_widget_set_valign (data->theme_error_icon, CTK_ALIGN_START);
675 ctk_box_pack_start (CTK_BOX (hbox)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((hbox)), ((ctk_box_get_type ()))))))
, data->theme_info_icon, FALSE(0), FALSE(0), 0);
676 ctk_box_pack_start (CTK_BOX (hbox)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((hbox)), ((ctk_box_get_type ()))))))
, data->theme_error_icon, FALSE(0), FALSE(0), 0);
677 ctk_box_pack_start (CTK_BOX (hbox)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((hbox)), ((ctk_box_get_type ()))))))
, data->theme_message_label, TRUE(!(0)), TRUE(!(0)), 0);
678 content = ctk_info_bar_get_content_area (CTK_INFO_BAR (data->theme_message_area)((((CtkInfoBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((data->theme_message_area)), ((ctk_info_bar_get_type()
))))))
);
679 ctk_container_add (CTK_CONTAINER (content)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((content)), ((ctk_container_get_type ()))))))
, hbox);
680
681 parent = appearance_capplet_get_widget (data, "theme_list_vbox")(CtkWidget*) ctk_builder_get_object(data->ui, "theme_list_vbox"
)
;
682 ctk_box_pack_start (CTK_BOX (parent)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((parent)), ((ctk_box_get_type ()))))))
, data->theme_message_area, FALSE(0), FALSE(0), 0);
683 }
684
685 if (show_error)
686 message = error->message;
687 else if (show_apply_background && show_apply_font && show_revert_font)
688 message = _("The current theme suggests a background and a font. Also, the last applied font suggestion can be reverted.")gettext ("The current theme suggests a background and a font. Also, the last applied font suggestion can be reverted."
)
;
689 else if (show_apply_background && show_revert_font)
690 message = _("The current theme suggests a background. Also, the last applied font suggestion can be reverted.")gettext ("The current theme suggests a background. Also, the last applied font suggestion can be reverted."
)
;
691 else if (show_apply_background && show_apply_font)
692 message = _("The current theme suggests a background and a font.")gettext ("The current theme suggests a background and a font."
)
;
693 else if (show_apply_font && show_revert_font)
694 message = _("The current theme suggests a font. Also, the last applied font suggestion can be reverted.")gettext ("The current theme suggests a font. Also, the last applied font suggestion can be reverted."
)
;
695 else if (show_apply_background)
696 message = _("The current theme suggests a background.")gettext ("The current theme suggests a background.");
697 else if (show_revert_font)
698 message = _("The last applied font suggestion can be reverted.")gettext ("The last applied font suggestion can be reverted.");
699 else if (show_apply_font)
700 message = _("The current theme suggests a font.")gettext ("The current theme suggests a font.");
701 else
702 message = NULL((void*)0);
703
704 if (show_apply_background)
705 ctk_widget_show (data->apply_background_button);
706 else
707 ctk_widget_hide (data->apply_background_button);
708
709 if (show_apply_font)
710 ctk_widget_show (data->apply_font_button);
711 else
712 ctk_widget_hide (data->apply_font_button);
713
714 if (show_revert_font)
715 ctk_widget_show (data->revert_font_button);
716 else
717 ctk_widget_hide (data->revert_font_button);
718
719 if (show_error
720 && g_error_matches (error, CAFE_THEME_ERRORcafe_theme_info_error_quark(), CAFE_THEME_ERROR_CTK_ENGINE_NOT_AVAILABLE)
721 && packagekit_available ())
722 ctk_widget_show (data->install_button);
723 else
724 ctk_widget_hide (data->install_button);
725
726 if (show_error || show_apply_background || show_apply_font || show_revert_font) {
727 ctk_widget_show (data->theme_message_area);
728 ctk_widget_queue_draw (data->theme_message_area);
729
730 if (show_error) {
731 ctk_widget_show (data->theme_error_icon);
732 ctk_widget_hide (data->theme_info_icon);
733 } else {
734 ctk_widget_show (data->theme_info_icon);
735 ctk_widget_hide (data->theme_error_icon);
736 }
737 } else {
738 ctk_widget_hide (data->theme_message_area);
739 }
740
741 ctk_label_set_text (CTK_LABEL (data->theme_message_label)((((CtkLabel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((data->theme_message_label)), ((ctk_label_get_type ())
)))))
, message);
742 g_clear_error (&error);
743}
744
745static void
746theme_selection_changed_cb (CtkWidget *icon_view, AppearanceData *data)
747{
748 GList *selection;
749 CafeThemeMetaInfo *theme = NULL((void*)0);
750
751 selection = ctk_icon_view_get_selected_items (CTK_ICON_VIEW (icon_view)((((CtkIconView*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon_view)), ((ctk_icon_view_get_type ()))))))
);
752
753 if (selection) {
754 CtkTreeModel *model;
755 CtkTreeIter iter;
756 gchar *name;
757 gboolean is_custom;
758
759 model = ctk_icon_view_get_model (CTK_ICON_VIEW (icon_view)((((CtkIconView*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon_view)), ((ctk_icon_view_get_type ()))))))
);
760 ctk_tree_model_get_iter (model, &iter, selection->data);
761 ctk_tree_model_get (model, &iter, COL_NAME, &name, -1);
762
763 is_custom = !strcmp (name, CUSTOM_THEME_NAME"__custom__");
764
765 if (is_custom)
766 theme = data->theme_custom;
767 else
768 theme = cafe_theme_meta_info_find (name);
769
770 if (theme) {
771 cafe_meta_theme_set (theme);
772 theme_message_area_update (data);
773 }
774
775 g_free (name);
776 g_list_foreach (selection, (GFunc) ctk_tree_path_free, NULL((void*)0));
777 g_list_free (selection);
778
779 ctk_widget_set_sensitive (appearance_capplet_get_widget (data, "theme_delete")(CtkWidget*) ctk_builder_get_object(data->ui, "theme_delete"
)
,
780 theme_is_writable (theme));
781 ctk_widget_set_sensitive (appearance_capplet_get_widget (data, "theme_save")(CtkWidget*) ctk_builder_get_object(data->ui, "theme_save"
)
, is_custom);
782 }
783}
784
785static void
786theme_custom_cb (CtkWidget *button, AppearanceData *data)
787{
788 CtkWidget *w, *parent;
789
790 w = appearance_capplet_get_widget (data, "theme_details")(CtkWidget*) ctk_builder_get_object(data->ui, "theme_details"
)
;
791 parent = appearance_capplet_get_widget (data, "appearance_window")(CtkWidget*) ctk_builder_get_object(data->ui, "appearance_window"
)
;
792 ctk_window_set_transient_for (CTK_WINDOW (w)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((w)), ((ctk_window_get_type ()))))))
, CTK_WINDOW (parent)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((parent)), ((ctk_window_get_type ()))))))
);
793 ctk_widget_show_all (w);
794}
795
796static void
797theme_save_cb (CtkWidget *button, AppearanceData *data)
798{
799 theme_save_dialog_run (data->theme_custom, data);
800}
801
802static void
803theme_install_cb (CtkWidget *button, AppearanceData *data)
804{
805 cafe_theme_installer_run (
806 CTK_WINDOW (appearance_capplet_get_widget (data, "appearance_window"))((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((CtkWidget*) ctk_builder_get_object(data->ui, "appearance_window"
))), ((ctk_window_get_type ()))))))
);
807}
808
809static void
810theme_delete_cb (CtkWidget *button, AppearanceData *data)
811{
812 CtkIconView *icon_view = CTK_ICON_VIEW (appearance_capplet_get_widget (data, "theme_list"))((((CtkIconView*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((CtkWidget*) ctk_builder_get_object(data->ui, "theme_list"
))), ((ctk_icon_view_get_type ()))))))
;
813 GList *selected = ctk_icon_view_get_selected_items (icon_view);
814
815 if (selected) {
816 CtkTreePath *path = selected->data;
817 CtkTreeModel *model = ctk_icon_view_get_model (icon_view);
818 CtkTreeIter iter;
819 gchar *name = NULL((void*)0);
820
821 if (ctk_tree_model_get_iter (model, &iter, path))
822 ctk_tree_model_get (model, &iter, COL_NAME, &name, -1);
823
824 if (name != NULL((void*)0) &&
825 strcmp (name, data->theme_custom->name) &&
826 theme_delete (name, THEME_TYPE_META)) {
827 /* remove theme from the model, too */
828 CtkTreeIter child;
829
830 if (ctk_tree_model_iter_next (model, &iter) ||
831 theme_model_iter_last (model, &iter))
832 theme_select_iter (icon_view, &iter);
833
834 ctk_tree_model_get_iter (model, &iter, path);
835 ctk_tree_model_sort_convert_iter_to_child_iter (
836 CTK_TREE_MODEL_SORT (model)((((CtkTreeModelSort*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((model)), ((ctk_tree_model_sort_get_type ())
)))))
, &child, &iter);
837 ctk_list_store_remove (data->theme_store, &child);
838 }
839
840 g_list_foreach (selected, (GFunc) ctk_tree_path_free, NULL((void*)0));
841 g_list_free (selected);
842 g_free (name);
843 }
844}
845
846static void
847theme_details_changed_cb (AppearanceData *data)
848{
849 CafeThemeMetaInfo *gsettings_theme;
850 const CafeThemeMetaInfo *selected;
851 CtkIconView *icon_view;
852 gboolean done = FALSE(0);
853
854 /* load new state from gsettings */
855 gsettings_theme = theme_load_from_gsettings (data);
856
857 /* check if it's our currently selected theme */
858 icon_view = CTK_ICON_VIEW (appearance_capplet_get_widget (data, "theme_list"))((((CtkIconView*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((CtkWidget*) ctk_builder_get_object(data->ui, "theme_list"
))), ((ctk_icon_view_get_type ()))))))
;
859 selected = theme_get_selected (icon_view, data);
860
861 if (!selected || !(done = theme_is_equal (selected, gsettings_theme))) {
862 /* look for a matching metatheme */
863 GList *theme_list, *l;
864
865 theme_list = cafe_theme_meta_info_find_all ();
866
867 for (l = theme_list; l; l = l->next) {
868 CafeThemeMetaInfo *info = l->data;
869
870 if (theme_is_equal (gsettings_theme, info)) {
871 theme_select_name (icon_view, info->name);
872 done = TRUE(!(0));
873 break;
874 }
875 }
876 g_list_free (theme_list);
877 }
878
879 if (!done)
880 /* didn't find a match, set or update custom */
881 theme_set_custom_from_theme (gsettings_theme, data);
882
883 cafe_theme_meta_info_free (gsettings_theme);
884}
885
886static void
887theme_setting_changed_cb (GObject *settings,
888 GParamSpec *pspec,
889 AppearanceData *data)
890{
891 theme_details_changed_cb (data);
892}
893
894static void
895theme_gsettings_changed (GSettings *settings,
896 gchar *key,
897 AppearanceData *data)
898{
899 theme_details_changed_cb (data);
900}
901
902static gint
903theme_list_sort_func (CafeThemeMetaInfo *a,
904 CafeThemeMetaInfo *b)
905{
906 return strcmp (a->readable_name, b->readable_name);
907}
908
909static gint
910theme_store_sort_func (CtkTreeModel *model,
911 CtkTreeIter *a,
912 CtkTreeIter *b,
913 gpointer user_data)
914{
915 gchar *a_name, *a_label;
916 gint rc;
917
918 ctk_tree_model_get (model, a, COL_NAME, &a_name, COL_LABEL, &a_label, -1);
919
920 if (!strcmp (a_name, CUSTOM_THEME_NAME"__custom__")) {
921 rc = -1;
922 } else {
923 gchar *b_name, *b_label;
924
925 ctk_tree_model_get (model, b, COL_NAME, &b_name, COL_LABEL, &b_label, -1);
926
927 if (!strcmp (b_name, CUSTOM_THEME_NAME"__custom__")) {
928 rc = 1;
929 } else {
930 gchar *a_case, *b_case;
931
932 a_case = g_utf8_casefold (a_label, -1);
933 b_case = g_utf8_casefold (b_label, -1);
934 rc = g_utf8_collate (a_case, b_case);
935 g_free (a_case);
936 g_free (b_case);
937 }
938
939 g_free (b_name);
940 g_free (b_label);
941 }
942
943 g_free (a_name);
944 g_free (a_label);
945
946 return rc;
947}
948
949static void
950theme_drag_data_received_cb (CtkWidget *widget,
951 CdkDragContext *context,
952 gint x, gint y,
953 CtkSelectionData *selection_data,
954 guint info, guint time,
955 AppearanceData *data)
956{
957 gchar **uris;
958
959 if (!(info == TARGET_URI_LIST || info == TARGET_NS_URL))
960 return;
961
962 uris = g_uri_list_extract_uris ((gchar *) ctk_selection_data_get_data (selection_data));
963
964 if (uris != NULL((void*)0) && uris[0] != NULL((void*)0)) {
965 GFile *f = g_file_new_for_uri (uris[0]);
966
967 cafe_theme_install (f,
968 CTK_WINDOW (appearance_capplet_get_widget (data, "appearance_window"))((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((CtkWidget*) ctk_builder_get_object(data->ui, "appearance_window"
))), ((ctk_window_get_type ()))))))
);
969 g_object_unref (f);
970 }
971
972 g_strfreev (uris);
973}
974
975static void background_or_font_changed(GSettings *settings, gchar *key, AppearanceData* data)
976{
977 theme_message_area_update(data);
1
Calling 'theme_message_area_update'
978}
979
980void themes_init(AppearanceData* data)
981{
982 CtkWidget *w, *del_button;
983 GList *theme_list, *l;
984 CtkListStore *theme_store;
985 CtkTreeModel *sort_model;
986 CafeThemeMetaInfo *meta_theme = NULL((void*)0);
987 CtkIconView *icon_view;
988 CtkCellRenderer *renderer;
989 CtkSettings *settings;
990 char *url;
991
992 /* initialise some stuff */
993 cafe_theme_init ();
994 cafe_wm_manager_init ();
995
996 data->revert_application_font = NULL((void*)0);
997 data->revert_documents_font = NULL((void*)0);
998 data->revert_desktop_font = NULL((void*)0);
999 data->revert_windowtitle_font = NULL((void*)0);
1000 data->revert_monospace_font = NULL((void*)0);
1001 data->theme_save_dialog = NULL((void*)0);
1002 data->theme_message_area = NULL((void*)0);
1003 data->theme_info_icon = NULL((void*)0);
1004 data->theme_error_icon = NULL((void*)0);
1005 data->theme_icon = gdk_pixbuf_new_from_file (CAFECC_PIXMAP_DIR"/usr/share/cafe-control-center/pixmaps" "/theme-thumbnailing.png", NULL((void*)0));
1006 data->theme_store = theme_store =
1007 ctk_list_store_new (NUM_COLS, GDK_TYPE_PIXBUF(gdk_pixbuf_get_type ()), G_TYPE_STRING((GType) ((16) << (2))), G_TYPE_STRING((GType) ((16) << (2))));
1008
1009 /* set up theme list */
1010 theme_list = cafe_theme_meta_info_find_all ();
1011 cafe_theme_info_register_theme_change ((ThemeChangedCallback) theme_changed_on_disk_cb, data);
1012
1013 data->theme_custom = theme_load_from_gsettings (data);
1014 data->theme_custom->name = g_strdup (CUSTOM_THEME_NAME)g_strdup_inline ("__custom__");
1015 data->theme_custom->readable_name = g_strdup_printf ("<i>%s</i>", _("Custom")gettext ("Custom"));
1016
1017 for (l = theme_list; l; l = l->next) {
1018 CafeThemeMetaInfo *info = l->data;
1019
1020 ctk_list_store_insert_with_values (theme_store, NULL((void*)0), 0,
1021 COL_LABEL, info->readable_name,
1022 COL_NAME, info->name,
1023 COL_THUMBNAIL, data->theme_icon,
1024 -1);
1025
1026 if (!meta_theme && theme_is_equal (data->theme_custom, info))
1027 meta_theme = info;
1028 }
1029
1030 if (!meta_theme) {
1031 /* add custom theme */
1032 meta_theme = data->theme_custom;
1033
1034 ctk_list_store_insert_with_values (theme_store, NULL((void*)0), 0,
1035 COL_LABEL, meta_theme->readable_name,
1036 COL_NAME, meta_theme->name,
1037 COL_THUMBNAIL, data->theme_icon,
1038 -1);
1039
1040 theme_thumbnail_generate (meta_theme, data);
1041 }
1042
1043 theme_list = g_list_sort (theme_list, (GCompareFunc) theme_list_sort_func);
1044
1045 g_list_foreach (theme_list, (GFunc) theme_thumbnail_generate, data);
1046 g_list_free (theme_list);
1047
1048 icon_view = CTK_ICON_VIEW (appearance_capplet_get_widget (data, "theme_list"))((((CtkIconView*) (void *) g_type_check_instance_cast ((GTypeInstance
*) (((CtkWidget*) ctk_builder_get_object(data->ui, "theme_list"
))), ((ctk_icon_view_get_type ()))))))
;
1049
1050 renderer = ctk_cell_renderer_pixbuf_new ();
1051 g_object_set (renderer, "xpad", 5, "ypad", 5,
1052 "xalign", 0.5, "yalign", 1.0, NULL((void*)0));
1053 ctk_cell_layout_pack_start (CTK_CELL_LAYOUT (icon_view)((((CtkCellLayout*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon_view)), ((ctk_cell_layout_get_type ()))))))
, renderer, FALSE(0));
1054 ctk_cell_layout_set_attributes (CTK_CELL_LAYOUT (icon_view)((((CtkCellLayout*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon_view)), ((ctk_cell_layout_get_type ()))))))
, renderer,
1055 "pixbuf", COL_THUMBNAIL, NULL((void*)0));
1056
1057 renderer = ctk_cell_renderer_text_new ();
1058 g_object_set (renderer, "alignment", PANGO_ALIGN_CENTER,
1059 "wrap-mode", PANGO_WRAP_WORD_CHAR,
1060 "wrap-width", ctk_icon_view_get_item_width (icon_view),
1061 "width", ctk_icon_view_get_item_width (icon_view),
1062 "xalign", 0.5, "yalign", 0.0, NULL((void*)0));
1063
1064 ctk_cell_layout_pack_end (CTK_CELL_LAYOUT (icon_view)((((CtkCellLayout*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon_view)), ((ctk_cell_layout_get_type ()))))))
, renderer, FALSE(0));
1065 ctk_cell_layout_set_attributes (CTK_CELL_LAYOUT (icon_view)((((CtkCellLayout*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((icon_view)), ((ctk_cell_layout_get_type ()))))))
, renderer,
1066 "markup", COL_LABEL, NULL((void*)0));
1067
1068 sort_model = ctk_tree_model_sort_new_with_model (CTK_TREE_MODEL (theme_store)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((theme_store)), ((ctk_tree_model_get_type ()))))))
);
1069 ctk_tree_sortable_set_sort_func (CTK_TREE_SORTABLE (sort_model)((((CtkTreeSortable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sort_model)), ((ctk_tree_sortable_get_type ()))))))
, COL_LABEL, theme_store_sort_func, NULL((void*)0), NULL((void*)0));
1070 ctk_tree_sortable_set_sort_column_id (CTK_TREE_SORTABLE (sort_model)((((CtkTreeSortable*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sort_model)), ((ctk_tree_sortable_get_type ()))))))
, COL_LABEL, CTK_SORT_ASCENDING);
1071 ctk_icon_view_set_model (icon_view, CTK_TREE_MODEL (sort_model)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sort_model)), ((ctk_tree_model_get_type ()))))))
);
1072
1073 g_signal_connect (icon_view, "selection-changed", (GCallback) theme_selection_changed_cb, data)g_signal_connect_data ((icon_view), ("selection-changed"), ((
GCallback) theme_selection_changed_cb), (data), ((void*)0), (
GConnectFlags) 0)
;
1074 g_signal_connect_after (icon_view, "realize", (GCallback) theme_select_name, meta_theme->name)g_signal_connect_data ((icon_view), ("realize"), ((GCallback)
theme_select_name), (meta_theme->name), ((void*)0), G_CONNECT_AFTER
)
;
1075
1076 w = appearance_capplet_get_widget (data, "theme_install")(CtkWidget*) ctk_builder_get_object(data->ui, "theme_install"
)
;
1077 ctk_button_set_image (CTK_BUTTON (w)((((CtkButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((w)), ((ctk_button_get_type ()))))))
,
1078 ctk_image_new_from_icon_name ("document-open", CTK_ICON_SIZE_BUTTON));
1079 g_signal_connect (w, "clicked", (GCallback) theme_install_cb, data)g_signal_connect_data ((w), ("clicked"), ((GCallback) theme_install_cb
), (data), ((void*)0), (GConnectFlags) 0)
;
1080
1081 w = appearance_capplet_get_widget (data, "theme_save")(CtkWidget*) ctk_builder_get_object(data->ui, "theme_save"
)
;
1082 ctk_button_set_image (CTK_BUTTON (w)((((CtkButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((w)), ((ctk_button_get_type ()))))))
,
1083 ctk_image_new_from_icon_name ("document-save-as", CTK_ICON_SIZE_BUTTON));
1084 g_signal_connect (w, "clicked", (GCallback) theme_save_cb, data)g_signal_connect_data ((w), ("clicked"), ((GCallback) theme_save_cb
), (data), ((void*)0), (GConnectFlags) 0)
;
1085
1086 w = appearance_capplet_get_widget (data, "theme_custom")(CtkWidget*) ctk_builder_get_object(data->ui, "theme_custom"
)
;
1087 ctk_button_set_image (CTK_BUTTON (w)((((CtkButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((w)), ((ctk_button_get_type ()))))))
,
1088 ctk_image_new_from_icon_name ("ctk-edit", CTK_ICON_SIZE_BUTTON));
1089 g_signal_connect (w, "clicked", (GCallback) theme_custom_cb, data)g_signal_connect_data ((w), ("clicked"), ((GCallback) theme_custom_cb
), (data), ((void*)0), (GConnectFlags) 0)
;
1090
1091 del_button = appearance_capplet_get_widget (data, "theme_delete")(CtkWidget*) ctk_builder_get_object(data->ui, "theme_delete"
)
;
1092 g_signal_connect (del_button, "clicked", (GCallback) theme_delete_cb, data)g_signal_connect_data ((del_button), ("clicked"), ((GCallback
) theme_delete_cb), (data), ((void*)0), (GConnectFlags) 0)
;
1093
1094 w = appearance_capplet_get_widget (data, "theme_vbox")(CtkWidget*) ctk_builder_get_object(data->ui, "theme_vbox"
)
;
1095 ctk_drag_dest_set (w, CTK_DEST_DEFAULT_ALL,
1096 drop_types, G_N_ELEMENTS (drop_types)(sizeof (drop_types) / sizeof ((drop_types)[0])),
1097 CDK_ACTION_COPY | CDK_ACTION_LINK | CDK_ACTION_MOVE);
1098 g_signal_connect (w, "drag-data-received", (GCallback) theme_drag_data_received_cb, data)g_signal_connect_data ((w), ("drag-data-received"), ((GCallback
) theme_drag_data_received_cb), (data), ((void*)0), (GConnectFlags
) 0)
;
1099 if (is_locked_down ())
1100 ctk_widget_set_sensitive (w, FALSE(0));
1101
1102 w = appearance_capplet_get_widget (data, "more_themes_linkbutton")(CtkWidget*) ctk_builder_get_object(data->ui, "more_themes_linkbutton"
)
;
1103 url = g_settings_get_string (data->settings, MORE_THEMES_URL_KEY"more-themes-url");
1104 if (url != NULL((void*)0) && url[0] != '\0') {
1105 ctk_link_button_set_uri (CTK_LINK_BUTTON (w)((((CtkLinkButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((w)), ((ctk_link_button_get_type ()))))))
, url);
1106 ctk_widget_show (w);
1107 } else {
1108 ctk_widget_hide (w);
1109 }
1110 g_free (url);
1111
1112 /* listen to gsettings changes, too */
1113 g_signal_connect (data->croma_settings, "changed::" CROMA_THEME_KEY, G_CALLBACK (theme_gsettings_changed), data)g_signal_connect_data ((data->croma_settings), ("changed::"
"theme"), (((GCallback) (theme_gsettings_changed))), (data),
((void*)0), (GConnectFlags) 0)
;
1114 g_signal_connect (data->mouse_settings, "changed::" CURSOR_THEME_KEY, G_CALLBACK (theme_gsettings_changed), data)g_signal_connect_data ((data->mouse_settings), ("changed::"
"cursor-theme"), (((GCallback) (theme_gsettings_changed))), (
data), ((void*)0), (GConnectFlags) 0)
;
1115 g_signal_connect (data->mouse_settings, "changed::" CURSOR_SIZE_KEY, G_CALLBACK (theme_gsettings_changed), data)g_signal_connect_data ((data->mouse_settings), ("changed::"
"cursor-size"), (((GCallback) (theme_gsettings_changed))), (
data), ((void*)0), (GConnectFlags) 0)
;
1116 g_signal_connect (data->wp_settings, "changed::" WP_FILE_KEY, G_CALLBACK (background_or_font_changed), data)g_signal_connect_data ((data->wp_settings), ("changed::" "picture-filename"
), (((GCallback) (background_or_font_changed))), (data), ((void
*)0), (GConnectFlags) 0)
;
1117 g_signal_connect (data->interface_settings, "changed::" CTK_FONT_KEY, G_CALLBACK (background_or_font_changed), data)g_signal_connect_data ((data->interface_settings), ("changed::"
"font-name"), (((GCallback) (background_or_font_changed))), (
data), ((void*)0), (GConnectFlags) 0)
;
1118 g_signal_connect (data->interface_settings, "changed::" DOCUMENT_FONT_KEY, G_CALLBACK (background_or_font_changed), data)g_signal_connect_data ((data->interface_settings), ("changed::"
"document-font-name"), (((GCallback) (background_or_font_changed
))), (data), ((void*)0), (GConnectFlags) 0)
;
1119
1120 if (data->baul_settings)
1121 g_signal_connect (data->baul_settings, "changed::" DESKTOP_FONT_KEY, G_CALLBACK (background_or_font_changed), data)g_signal_connect_data ((data->baul_settings), ("changed::"
"font"), (((GCallback) (background_or_font_changed))), (data
), ((void*)0), (GConnectFlags) 0)
;
1122
1123 g_signal_connect (data->croma_settings, "changed::" WINDOW_TITLE_FONT_KEY, G_CALLBACK (background_or_font_changed), data)g_signal_connect_data ((data->croma_settings), ("changed::"
"titlebar-font"), (((GCallback) (background_or_font_changed)
)), (data), ((void*)0), (GConnectFlags) 0)
;
1124 g_signal_connect (data->interface_settings, "changed::" MONOSPACE_FONT_KEY, G_CALLBACK (background_or_font_changed), data)g_signal_connect_data ((data->interface_settings), ("changed::"
"monospace-font-name"), (((GCallback) (background_or_font_changed
))), (data), ((void*)0), (GConnectFlags) 0)
;
1125
1126 settings = ctk_settings_get_default ();
1127 g_signal_connect (settings, "notify::ctk-color-scheme", (GCallback) theme_setting_changed_cb, data)g_signal_connect_data ((settings), ("notify::ctk-color-scheme"
), ((GCallback) theme_setting_changed_cb), (data), ((void*)0)
, (GConnectFlags) 0)
;
1128 g_signal_connect (settings, "notify::ctk-theme-name", (GCallback) theme_setting_changed_cb, data)g_signal_connect_data ((settings), ("notify::ctk-theme-name")
, ((GCallback) theme_setting_changed_cb), (data), ((void*)0),
(GConnectFlags) 0)
;
1129 g_signal_connect (settings, "notify::ctk-icon-theme-name", (GCallback) theme_setting_changed_cb, data)g_signal_connect_data ((settings), ("notify::ctk-icon-theme-name"
), ((GCallback) theme_setting_changed_cb), (data), ((void*)0)
, (GConnectFlags) 0)
;
1130
1131 /* monitor individual font choice buttons, so
1132 "revert font" option (if any) can be cleared */
1133 w = appearance_capplet_get_widget (data, "application_font")(CtkWidget*) ctk_builder_get_object(data->ui, "application_font"
)
;
1134 g_signal_connect (w, "font_set", (GCallback) custom_font_cb, data)g_signal_connect_data ((w), ("font_set"), ((GCallback) custom_font_cb
), (data), ((void*)0), (GConnectFlags) 0)
;
1135 w = appearance_capplet_get_widget (data, "document_font")(CtkWidget*) ctk_builder_get_object(data->ui, "document_font"
)
;
1136 g_signal_connect (w, "font_set", (GCallback) custom_font_cb, data)g_signal_connect_data ((w), ("font_set"), ((GCallback) custom_font_cb
), (data), ((void*)0), (GConnectFlags) 0)
;
1137 w = appearance_capplet_get_widget (data, "desktop_font")(CtkWidget*) ctk_builder_get_object(data->ui, "desktop_font"
)
;
1138 g_signal_connect (w, "font_set", (GCallback) custom_font_cb, data)g_signal_connect_data ((w), ("font_set"), ((GCallback) custom_font_cb
), (data), ((void*)0), (GConnectFlags) 0)
;
1139 w = appearance_capplet_get_widget (data, "window_title_font")(CtkWidget*) ctk_builder_get_object(data->ui, "window_title_font"
)
;
1140 g_signal_connect (w, "font_set", (GCallback) custom_font_cb, data)g_signal_connect_data ((w), ("font_set"), ((GCallback) custom_font_cb
), (data), ((void*)0), (GConnectFlags) 0)
;
1141 w = appearance_capplet_get_widget (data, "monospace_font")(CtkWidget*) ctk_builder_get_object(data->ui, "monospace_font"
)
;
1142 g_signal_connect (w, "font_set", (GCallback) custom_font_cb, data)g_signal_connect_data ((w), ("font_set"), ((GCallback) custom_font_cb
), (data), ((void*)0), (GConnectFlags) 0)
;
1143}
1144
1145void
1146themes_shutdown (AppearanceData *data)
1147{
1148 cafe_theme_meta_info_free (data->theme_custom);
1149
1150 if (data->theme_icon)
1151 g_object_unref (data->theme_icon);
1152 if (data->theme_save_dialog)
1153 ctk_widget_destroy (data->theme_save_dialog);
1154 g_free (data->revert_application_font);
1155 g_free (data->revert_documents_font);
1156 g_free (data->revert_desktop_font);
1157 g_free (data->revert_windowtitle_font);
1158 g_free (data->revert_monospace_font);
1159}