pidgin/gtkblist-theme-loader.c

changeset 26378
e85d894af8a5
parent 25875
a98b16817658
child 26781
b7275fef68de
equal deleted inserted replaced
26377:9124a345ed3a 26378:e85d894af8a5
1 /*
2 * GTKBlistThemeLoader for Pidgin
3 *
4 * Pidgin is the legal property of its developers, whose names are too numerous
5 * to list here. Please refer to the COPYRIGHT file distributed with this
6 * source distribution.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
21 */
22
23 #include <stdlib.h>
24
25 #include "xmlnode.h"
26
27 #include "gtkblist-theme-loader.h"
28 #include "gtkblist-theme.h"
29
30 /******************************************************************************
31 * Globals
32 *****************************************************************************/
33
34 #define DEFAULT_TEXT_COLOR "black"
35
36 /*****************************************************************************
37 * Buddy List Theme Builder
38 *****************************************************************************/
39
40 static PurpleTheme *
41 pidgin_blist_loader_build(const gchar *dir)
42 {
43 xmlnode *root_node = NULL, *sub_node, *sub_sub_node;
44 gchar *filename_full, *data;
45 const gchar *temp;
46 gboolean success = TRUE;
47 GdkColor *bgcolor, *expanded_bgcolor, *collapsed_bgcolor, *contact_color;
48 GdkColor color;
49 FontColorPair *expanded, *collapsed, *contact, *online, *away, *offline, *idle, *message, *message_nick_said, *status;
50 PidginBlistLayout *layout;
51 PidginBlistTheme *theme;
52
53 /* Find the theme file */
54 g_return_val_if_fail(dir != NULL, NULL);
55 filename_full = g_build_filename(dir, "theme.xml", NULL);
56
57 if (g_file_test(filename_full, G_FILE_TEST_IS_REGULAR))
58 root_node = xmlnode_from_file(dir, "theme.xml", "buddy list themes", "blist-loader");
59
60 g_free(filename_full);
61 g_return_val_if_fail(root_node != NULL, NULL);
62
63 sub_node = xmlnode_get_child(root_node, "description");
64 data = xmlnode_get_data(sub_node);
65
66 /* init all structs and colors */
67 bgcolor = g_new0(GdkColor, 1);
68 expanded_bgcolor = g_new0(GdkColor, 1);
69 collapsed_bgcolor = g_new0(GdkColor, 1);
70
71 layout = g_new0(PidginBlistLayout, 1);
72
73 contact_color = g_new0(GdkColor, 1);
74
75 expanded = g_new0(FontColorPair, 1);
76 collapsed = g_new0(FontColorPair, 1);
77 contact = g_new0(FontColorPair, 1);
78 online = g_new0(FontColorPair, 1);
79 away = g_new0(FontColorPair, 1);
80 offline = g_new0(FontColorPair, 1);
81 idle = g_new0(FontColorPair, 1);
82 message = g_new0(FontColorPair, 1);
83 message_nick_said = g_new0(FontColorPair, 1);
84 status = g_new0(FontColorPair, 1);
85
86 /* <blist> */
87 if ((success = (sub_node = xmlnode_get_child(root_node, "blist")) != NULL)) {
88 if ((temp = xmlnode_get_attrib(sub_node, "color")) != NULL && gdk_color_parse(temp, bgcolor))
89 gdk_colormap_alloc_color(gdk_colormap_get_system(), bgcolor, FALSE, TRUE);
90 else {
91 g_free(bgcolor);
92 bgcolor = NULL;
93 }
94 }
95
96 /* <groups> */
97 if ((success = (success && (sub_node = xmlnode_get_child(root_node, "groups")) != NULL
98 && (sub_sub_node = xmlnode_get_child(sub_node, "expanded")) != NULL)))
99 {
100 expanded->font = g_strdup(xmlnode_get_attrib(sub_sub_node, "font"));
101
102 if ((temp = xmlnode_get_attrib(sub_sub_node, "text_color")) != NULL && gdk_color_parse(temp, &color))
103 expanded->color = g_strdup(temp);
104 else expanded->color = g_strdup(DEFAULT_TEXT_COLOR);
105
106 if ((temp = xmlnode_get_attrib(sub_sub_node, "background")) != NULL && gdk_color_parse(temp, expanded_bgcolor))
107 gdk_colormap_alloc_color(gdk_colormap_get_system(), expanded_bgcolor, FALSE, TRUE);
108 else {
109 g_free(expanded_bgcolor);
110 expanded_bgcolor = NULL;
111 }
112 }
113
114 if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "collapsed")) != NULL)))
115 {
116 collapsed->font = g_strdup(xmlnode_get_attrib(sub_sub_node, "font"));
117
118 if((temp = xmlnode_get_attrib(sub_sub_node, "text_color")) != NULL && gdk_color_parse(temp, &color))
119 collapsed->color = g_strdup(temp);
120 else collapsed->color = g_strdup(DEFAULT_TEXT_COLOR);
121
122 if ((temp = xmlnode_get_attrib(sub_sub_node, "background")) != NULL && gdk_color_parse(temp, collapsed_bgcolor))
123 gdk_colormap_alloc_color(gdk_colormap_get_system(), collapsed_bgcolor, FALSE, TRUE);
124 else {
125 g_free(collapsed_bgcolor);
126 collapsed_bgcolor = NULL;
127 }
128 }
129
130 /* <buddys> */
131 if ((success = (success && (sub_node = xmlnode_get_child(root_node, "buddys")) != NULL &&
132 (sub_sub_node = xmlnode_get_child(sub_node, "placement")) != NULL)))
133 {
134 layout->status_icon = (temp = xmlnode_get_attrib(sub_sub_node, "status_icon")) != NULL ? atoi(temp) : 0;
135 layout->text = (temp = xmlnode_get_attrib(sub_sub_node, "name")) != NULL ? atoi(temp) : 1;
136 layout->emblem = (temp = xmlnode_get_attrib(sub_sub_node, "emblem")) != NULL ? atoi(temp) : 2;
137 layout->protocol_icon = (temp = xmlnode_get_attrib(sub_sub_node, "protocol_icon")) != NULL ? atoi(temp) : 3;
138 layout->buddy_icon = (temp = xmlnode_get_attrib(sub_sub_node, "buddy_icon")) != NULL ? atoi(temp) : 4;
139 layout->show_status = (temp = xmlnode_get_attrib(sub_sub_node, "status_icon")) != NULL ? atoi(temp) != 0 : 1;
140 }
141
142 if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "background")) != NULL))) {
143 if(gdk_color_parse(xmlnode_get_attrib(sub_sub_node, "color"), contact_color))
144 gdk_colormap_alloc_color(gdk_colormap_get_system(), contact_color, FALSE, TRUE);
145 else {
146 g_free(contact_color);
147 contact_color = NULL;
148 }
149 }
150
151 if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "contact_text")) != NULL))) {
152 contact->font = g_strdup(xmlnode_get_attrib(sub_sub_node, "font"));
153 if(gdk_color_parse(temp = xmlnode_get_attrib(sub_sub_node, "color"), &color))
154 contact->color = g_strdup(temp);
155 else contact->color = g_strdup(DEFAULT_TEXT_COLOR);
156 }
157
158 if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "online_text")) != NULL))) {
159 online->font = g_strdup(xmlnode_get_attrib(sub_sub_node, "font"));
160 if(gdk_color_parse(temp = xmlnode_get_attrib(sub_sub_node, "color"), &color))
161 online->color = g_strdup(temp);
162 else online->color = g_strdup(DEFAULT_TEXT_COLOR);
163 }
164
165 if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "away_text")) != NULL))) {
166 away->font = g_strdup(xmlnode_get_attrib(sub_sub_node, "font"));
167 if(gdk_color_parse(temp = xmlnode_get_attrib(sub_sub_node, "color"), &color))
168 away->color = g_strdup(temp);
169 else away->color = g_strdup(DEFAULT_TEXT_COLOR);
170 }
171
172 if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "offline_text")) != NULL))) {
173 offline->font = g_strdup(xmlnode_get_attrib(sub_sub_node, "font"));
174 if(gdk_color_parse(temp = xmlnode_get_attrib(sub_sub_node, "color"), &color))
175 online->color = g_strdup(temp);
176 else online->color = g_strdup(DEFAULT_TEXT_COLOR);
177 }
178
179 if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "idle_text")) != NULL))) {
180 idle->font = g_strdup(xmlnode_get_attrib(sub_sub_node, "font"));
181 if(gdk_color_parse(temp = xmlnode_get_attrib(sub_sub_node, "color"), &color))
182 idle->color = g_strdup(temp);
183 else online->color = g_strdup(DEFAULT_TEXT_COLOR);
184 }
185
186 if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "message_text")) != NULL))) {
187 message->font = g_strdup(xmlnode_get_attrib(sub_sub_node, "font"));
188 if(gdk_color_parse(temp = xmlnode_get_attrib(sub_sub_node, "color"), &color))
189 message->color = g_strdup(temp);
190 else message->color = g_strdup(DEFAULT_TEXT_COLOR);
191 }
192
193 if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "message_nick_said_text")) != NULL))) {
194 message_nick_said->font = g_strdup(xmlnode_get_attrib(sub_sub_node, "font"));
195 if(gdk_color_parse(temp = xmlnode_get_attrib(sub_sub_node, "color"), &color))
196 message_nick_said->color = g_strdup(temp);
197 else message_nick_said->color = g_strdup(DEFAULT_TEXT_COLOR);
198 }
199
200 if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "status_text")) != NULL))) {
201 status->font = g_strdup(xmlnode_get_attrib(sub_sub_node, "font"));
202 if(gdk_color_parse(temp = xmlnode_get_attrib(sub_sub_node, "color"), &color))
203 status->color = g_strdup(temp);
204 else status->color = g_strdup(DEFAULT_TEXT_COLOR);
205 }
206
207 /* name is required for theme manager */
208 success = (success && xmlnode_get_attrib(root_node, "name") != NULL);
209
210 /* the new theme */
211 theme = g_object_new(PIDGIN_TYPE_BLIST_THEME,
212 "type", "blist",
213 "name", xmlnode_get_attrib(root_node, "name"),
214 "author", xmlnode_get_attrib(root_node, "author"),
215 "image", xmlnode_get_attrib(root_node, "image"),
216 "directory", dir,
217 "description", data,
218 "background-color", bgcolor,
219 "layout", layout,
220 "expanded-color", expanded_bgcolor,
221 "expanded-text", expanded,
222 "collapsed-color", collapsed_bgcolor,
223 "collapsed-text", collapsed,
224 "contact-color", contact_color,
225 "contact", contact,
226 "online", online,
227 "away", away,
228 "offline", offline,
229 "idle", idle,
230 "message", message,
231 "message_nick_said", message_nick_said,
232 "status", status, NULL);
233
234 xmlnode_free(root_node);
235 g_free(data);
236
237 /* malformed xml file - also frees all partial data*/
238 if (!success) {
239 g_object_unref(theme);
240 theme = NULL;
241 }
242
243 return PURPLE_THEME(theme);
244 }
245
246 /******************************************************************************
247 * GObject Stuff
248 *****************************************************************************/
249
250 static void
251 pidgin_blist_theme_loader_class_init(PidginBlistThemeLoaderClass *klass)
252 {
253 PurpleThemeLoaderClass *loader_klass = PURPLE_THEME_LOADER_CLASS(klass);
254
255 loader_klass->purple_theme_loader_build = pidgin_blist_loader_build;
256 }
257
258 GType
259 pidgin_blist_theme_loader_get_type(void)
260 {
261 static GType type = 0;
262 if (type == 0) {
263 static const GTypeInfo info = {
264 sizeof(PidginBlistThemeLoaderClass),
265 NULL, /* base_init */
266 NULL, /* base_finalize */
267 (GClassInitFunc)pidgin_blist_theme_loader_class_init, /* class_init */
268 NULL, /* class_finalize */
269 NULL, /* class_data */
270 sizeof(PidginBlistThemeLoader),
271 0, /* n_preallocs */
272 NULL, /* instance_init */
273 NULL, /* value table */
274 };
275 type = g_type_register_static(PURPLE_TYPE_THEME_LOADER,
276 "PidginBlistThemeLoader", &info, 0);
277 }
278 return type;
279 }

mercurial