2 * GTKBlistThemeLoader for Pidgin
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
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.
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.
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
32 #include "gtkblist-theme-loader.h"
33 #include "gtkblist-theme.h"
35 /******************************************************************************
37 *****************************************************************************/
39 #define DEFAULT_TEXT_COLOR "black"
41 /*****************************************************************************
42 * Buddy List Theme Builder
43 *****************************************************************************/
45 static PidginThemeFont
*
46 pidgin_theme_font_parse(xmlnode
*node
)
49 const char *colordesc
;
52 font
= xmlnode_get_attrib(node
, "font");
54 if ((colordesc
= xmlnode_get_attrib(node
, "color")) == NULL
||
55 !gdk_color_parse(colordesc
, &color
))
56 gdk_color_parse(DEFAULT_TEXT_COLOR
, &color
);
58 return pidgin_theme_font_new(font
, &color
);
62 parse_color(xmlnode
*node
, const char *tag
)
64 const char *temp
= xmlnode_get_attrib(node
, tag
);
67 if (temp
&& gdk_color_parse(temp
, &color
)) {
68 gdk_colormap_alloc_color(gdk_colormap_get_system(), &color
, FALSE
, TRUE
);
69 return gdk_color_copy(&color
);
76 pidgin_blist_loader_build(const gchar
*dir
)
78 xmlnode
*root_node
= NULL
, *sub_node
, *sub_sub_node
;
79 gchar
*filename_full
, *data
= NULL
;
80 const gchar
*temp
, *name
;
81 gboolean success
= TRUE
;
82 GdkColor
*bgcolor
, *expanded_bgcolor
, *collapsed_bgcolor
, *contact_color
;
83 PidginThemeFont
*expanded
, *collapsed
, *contact
, *online
, *away
, *offline
, *idle
, *message
, *message_nick_said
, *status
;
84 PidginBlistLayout layout
;
85 PidginBlistTheme
*theme
;
89 PidginThemeFont
**font
;
91 {"contact_text", &contact
},
92 {"online_text", &online
},
94 {"offline_text", &offline
},
96 {"message_text", &message
},
97 {"message_nick_said_text", &message_nick_said
},
98 {"status_text", &status
},
102 bgcolor
= expanded_bgcolor
= collapsed_bgcolor
= contact_color
= NULL
;
111 message_nick_said
= NULL
;
114 /* Find the theme file */
115 g_return_val_if_fail(dir
!= NULL
, NULL
);
116 filename_full
= g_build_filename(dir
, "theme.xml", NULL
);
118 if (g_file_test(filename_full
, G_FILE_TEST_IS_REGULAR
))
119 root_node
= xmlnode_from_file(dir
, "theme.xml", "buddy list themes", "blist-loader");
121 g_free(filename_full
);
122 if (root_node
== NULL
)
125 sub_node
= xmlnode_get_child(root_node
, "description");
126 data
= xmlnode_get_data(sub_node
);
128 name
= xmlnode_get_attrib(root_node
, "name");
131 success
= name
&& purple_strequal(xmlnode_get_attrib(root_node
, "type"), "pidgin buddy list");
134 purple_debug_warning("gtkblist-theme-loader", "Missing attribute or problem with the root element\n");
137 if ((success
= (sub_node
= xmlnode_get_child(root_node
, "blist")) != NULL
))
138 bgcolor
= parse_color(sub_node
, "color");
140 purple_debug_warning("gtkblist-theme-loader", "Missing or problem with tags: <blist>.\n");
145 if ((success
= (sub_node
= xmlnode_get_child(root_node
, "groups")) != NULL
146 && (sub_sub_node
= xmlnode_get_child(sub_node
, "expanded")) != NULL
)) {
147 expanded
= pidgin_theme_font_parse(sub_sub_node
);
148 expanded_bgcolor
= parse_color(sub_sub_node
, "background");
150 purple_debug_warning("gtkblist-theme-loader", "Missing or problem with tags: <groups> <expanded>.\n");
154 if ((success
= sub_node
!= NULL
&& (sub_sub_node
= xmlnode_get_child(sub_node
, "collapsed")) != NULL
)) {
155 collapsed
= pidgin_theme_font_parse(sub_sub_node
);
156 collapsed_bgcolor
= parse_color(sub_sub_node
, "background");
158 purple_debug_warning("gtkblist-theme-loader", "Missing or problem with tags: <groups> <collapsed>.\n");
163 if ((success
= (sub_node
= xmlnode_get_child(root_node
, "buddys")) != NULL
&&
164 (sub_sub_node
= xmlnode_get_child(sub_node
, "placement")) != NULL
)) {
166 layout
.status_icon
= (temp
= xmlnode_get_attrib(sub_sub_node
, "status_icon")) != NULL
? atoi(temp
) : 0;
167 layout
.text
= (temp
= xmlnode_get_attrib(sub_sub_node
, "name")) != NULL
? atoi(temp
) : 1;
168 layout
.emblem
= (temp
= xmlnode_get_attrib(sub_sub_node
, "emblem")) != NULL
? atoi(temp
) : 2;
169 layout
.protocol_icon
= (temp
= xmlnode_get_attrib(sub_sub_node
, "protocol_icon")) != NULL
? atoi(temp
) : 3;
170 layout
.buddy_icon
= (temp
= xmlnode_get_attrib(sub_sub_node
, "buddy_icon")) != NULL
? atoi(temp
) : 4;
171 layout
.show_status
= (temp
= xmlnode_get_attrib(sub_sub_node
, "status_icon")) != NULL
? atoi(temp
) != 0 : 1;
173 } else purple_debug_warning("gtkblist-theme-loader", "Missing or problem with tags: <buddys> <placement>.\n");
177 if ((success
= (sub_node
!= NULL
&& (sub_sub_node
= xmlnode_get_child(sub_node
, "background")) != NULL
)))
178 contact_color
= parse_color(sub_sub_node
, "color");
180 purple_debug_warning("gtkblist-theme-loader", "Missing or problem with tags: <buddys> <background>.\n");
183 for (i
= 0; success
&& lookups
[i
].tag
; i
++) {
184 if ((success
= (sub_node
!= NULL
&&
185 (sub_sub_node
= xmlnode_get_child(sub_node
, lookups
[i
].tag
)) != NULL
))) {
186 *(lookups
[i
].font
) = pidgin_theme_font_parse(sub_sub_node
);
188 *(lookups
[i
].font
) = NULL
;
192 /* name is required for theme manager */
193 success
= (success
&& xmlnode_get_attrib(root_node
, "name") != NULL
);
196 theme
= g_object_new(PIDGIN_TYPE_BLIST_THEME
,
199 "author", xmlnode_get_attrib(root_node
, "author"),
200 "image", xmlnode_get_attrib(root_node
, "image"),
203 "background-color", bgcolor
,
205 "expanded-color", expanded_bgcolor
,
206 "expanded-text", expanded
,
207 "collapsed-color", collapsed_bgcolor
,
208 "collapsed-text", collapsed
,
209 "contact-color", contact_color
,
216 "message_nick_said", message_nick_said
,
217 "status", status
, NULL
);
219 for (i
= 0; lookups
[i
].tag
; i
++) {
220 if (*lookups
[i
].font
) {
221 pidgin_theme_font_free(*lookups
[i
].font
);
225 pidgin_theme_font_free(expanded
);
226 pidgin_theme_font_free(collapsed
);
228 xmlnode_free(root_node
);
231 /* malformed xml file - also frees all partial data*/
233 g_object_unref(theme
);
238 gdk_color_free(bgcolor
);
239 if (expanded_bgcolor
)
240 gdk_color_free(expanded_bgcolor
);
241 if (collapsed_bgcolor
)
242 gdk_color_free(collapsed_bgcolor
);
244 gdk_color_free(contact_color
);
246 return PURPLE_THEME(theme
);
249 /******************************************************************************
251 *****************************************************************************/
254 pidgin_blist_theme_loader_class_init(PidginBlistThemeLoaderClass
*klass
)
256 PurpleThemeLoaderClass
*loader_klass
= PURPLE_THEME_LOADER_CLASS(klass
);
258 loader_klass
->purple_theme_loader_build
= pidgin_blist_loader_build
;
262 pidgin_blist_theme_loader_get_type(void)
264 static GType type
= 0;
266 static const GTypeInfo info
= {
267 sizeof(PidginBlistThemeLoaderClass
),
268 NULL
, /* base_init */
269 NULL
, /* base_finalize */
270 (GClassInitFunc
)pidgin_blist_theme_loader_class_init
, /* class_init */
271 NULL
, /* class_finalize */
272 NULL
, /* class_data */
273 sizeof(PidginBlistThemeLoader
),
275 NULL
, /* instance_init */
276 NULL
, /* value table */
278 type
= g_type_register_static(PURPLE_TYPE_THEME_LOADER
,
279 "PidginBlistThemeLoader", &info
, 0);