| 35 #define DEFAULT_TEXT_COLOR "black" |
35 #define DEFAULT_TEXT_COLOR "black" |
| 36 |
36 |
| 37 /***************************************************************************** |
37 /***************************************************************************** |
| 38 * Buddy List Theme Builder |
38 * Buddy List Theme Builder |
| 39 *****************************************************************************/ |
39 *****************************************************************************/ |
| |
40 |
| |
41 static PidginThemeFont * |
| |
42 pidgin_theme_font_parse(xmlnode *node) |
| |
43 { |
| |
44 const char *font; |
| |
45 const char *colordesc; |
| |
46 GdkColor color; |
| |
47 |
| |
48 font = xmlnode_get_attrib(node, "font"); |
| |
49 |
| |
50 if ((colordesc = xmlnode_get_attrib(node, "color")) == NULL || |
| |
51 !gdk_color_parse(colordesc, &color)) |
| |
52 gdk_color_parse(DEFAULT_TEXT_COLOR, &color); |
| |
53 |
| |
54 return pidgin_theme_font_new(font, &color); |
| |
55 } |
| 40 |
56 |
| 41 static PurpleTheme * |
57 static PurpleTheme * |
| 42 pidgin_blist_loader_build(const gchar *dir) |
58 pidgin_blist_loader_build(const gchar *dir) |
| 43 { |
59 { |
| 44 xmlnode *root_node = NULL, *sub_node, *sub_sub_node; |
60 xmlnode *root_node = NULL, *sub_node, *sub_sub_node; |
| 45 gchar *filename_full, *data; |
61 gchar *filename_full, *data; |
| 46 const gchar *temp; |
62 const gchar *temp; |
| 47 gboolean success = TRUE; |
63 gboolean success = TRUE; |
| 48 GdkColor bgcolor, expanded_bgcolor, collapsed_bgcolor, contact_color; |
64 GdkColor bgcolor, expanded_bgcolor, collapsed_bgcolor, contact_color; |
| 49 GdkColor color; |
65 PidginThemeFont *expanded, *collapsed, *contact, *online, *away, *offline, *idle, *message, *message_nick_said, *status; |
| 50 FontColorPair expanded, collapsed, contact, online, away, offline, idle, message, message_nick_said, status; |
|
| 51 PidginBlistLayout layout; |
66 PidginBlistLayout layout; |
| 52 PidginBlistTheme *theme; |
67 PidginBlistTheme *theme; |
| |
68 int i; |
| |
69 struct { |
| |
70 const char *tag; |
| |
71 PidginThemeFont **font; |
| |
72 } lookups[] = { |
| |
73 {"contact_text", &contact}, |
| |
74 {"online_text", &online}, |
| |
75 {"away_text", &away}, |
| |
76 {"offline_text", &offline}, |
| |
77 {"idle_text", &idle}, |
| |
78 {"message_text", &message}, |
| |
79 {"message_nick_said_text", &message_nick_said}, |
| |
80 {"status_text", &status}, |
| |
81 {NULL, NULL} |
| |
82 }; |
| 53 |
83 |
| 54 /* Find the theme file */ |
84 /* Find the theme file */ |
| 55 g_return_val_if_fail(dir != NULL, NULL); |
85 g_return_val_if_fail(dir != NULL, NULL); |
| 56 filename_full = g_build_filename(dir, "theme.xml", NULL); |
86 filename_full = g_build_filename(dir, "theme.xml", NULL); |
| 57 |
87 |
| 74 |
104 |
| 75 /* <groups> */ |
105 /* <groups> */ |
| 76 if ((success = (success && (sub_node = xmlnode_get_child(root_node, "groups")) != NULL |
106 if ((success = (success && (sub_node = xmlnode_get_child(root_node, "groups")) != NULL |
| 77 && (sub_sub_node = xmlnode_get_child(sub_node, "expanded")) != NULL))) |
107 && (sub_sub_node = xmlnode_get_child(sub_node, "expanded")) != NULL))) |
| 78 { |
108 { |
| 79 expanded.font = xmlnode_get_attrib(sub_sub_node, "font"); |
109 expanded = pidgin_theme_font_parse(sub_sub_node); |
| 80 |
|
| 81 if ((temp = xmlnode_get_attrib(sub_sub_node, "text_color")) != NULL && gdk_color_parse(temp, &color)) |
|
| 82 expanded.color = temp; |
|
| 83 else expanded.color = DEFAULT_TEXT_COLOR; |
|
| 84 |
110 |
| 85 if ((temp = xmlnode_get_attrib(sub_sub_node, "background")) != NULL && gdk_color_parse(temp, &expanded_bgcolor)) |
111 if ((temp = xmlnode_get_attrib(sub_sub_node, "background")) != NULL && gdk_color_parse(temp, &expanded_bgcolor)) |
| 86 gdk_colormap_alloc_color(gdk_colormap_get_system(), &expanded_bgcolor, FALSE, TRUE); |
112 gdk_colormap_alloc_color(gdk_colormap_get_system(), &expanded_bgcolor, FALSE, TRUE); |
| 87 else |
113 else |
| 88 memset(&expanded_bgcolor, 0, sizeof(GdkColor)); |
114 memset(&expanded_bgcolor, 0, sizeof(GdkColor)); |
| 89 } |
115 } |
| 90 |
116 |
| 91 if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "collapsed")) != NULL))) |
117 if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "collapsed")) != NULL))) |
| 92 { |
118 { |
| 93 collapsed.font = xmlnode_get_attrib(sub_sub_node, "font"); |
119 collapsed = pidgin_theme_font_parse(sub_sub_node); |
| 94 |
|
| 95 if((temp = xmlnode_get_attrib(sub_sub_node, "text_color")) != NULL && gdk_color_parse(temp, &color)) |
|
| 96 collapsed.color = temp; |
|
| 97 else collapsed.color = DEFAULT_TEXT_COLOR; |
|
| 98 |
120 |
| 99 if ((temp = xmlnode_get_attrib(sub_sub_node, "background")) != NULL && gdk_color_parse(temp, &collapsed_bgcolor)) |
121 if ((temp = xmlnode_get_attrib(sub_sub_node, "background")) != NULL && gdk_color_parse(temp, &collapsed_bgcolor)) |
| 100 gdk_colormap_alloc_color(gdk_colormap_get_system(), &collapsed_bgcolor, FALSE, TRUE); |
122 gdk_colormap_alloc_color(gdk_colormap_get_system(), &collapsed_bgcolor, FALSE, TRUE); |
| 101 else |
123 else |
| 102 memset(&collapsed_bgcolor, 0, sizeof(GdkColor)); |
124 memset(&collapsed_bgcolor, 0, sizeof(GdkColor)); |
| 119 gdk_colormap_alloc_color(gdk_colormap_get_system(), &contact_color, FALSE, TRUE); |
141 gdk_colormap_alloc_color(gdk_colormap_get_system(), &contact_color, FALSE, TRUE); |
| 120 else |
142 else |
| 121 memset(&contact_color, 0, sizeof(GdkColor)); |
143 memset(&contact_color, 0, sizeof(GdkColor)); |
| 122 } |
144 } |
| 123 |
145 |
| 124 if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "contact_text")) != NULL))) { |
146 for (i = 0; success && lookups[i].tag; i++) { |
| 125 contact.font = xmlnode_get_attrib(sub_sub_node, "font"); |
147 if ((success = (sub_node != NULL && |
| 126 if(gdk_color_parse(temp = xmlnode_get_attrib(sub_sub_node, "color"), &color)) |
148 (sub_sub_node = xmlnode_get_child(sub_node, lookups[i].tag)) != NULL))) { |
| 127 contact.color = temp; |
149 *(lookups[i].font) = pidgin_theme_font_parse(sub_sub_node); |
| 128 else contact.color = DEFAULT_TEXT_COLOR; |
150 } else { |
| 129 } |
151 *(lookups[i].font) = NULL; |
| 130 |
152 } |
| 131 if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "online_text")) != NULL))) { |
|
| 132 online.font = xmlnode_get_attrib(sub_sub_node, "font"); |
|
| 133 if(gdk_color_parse(temp = xmlnode_get_attrib(sub_sub_node, "color"), &color)) |
|
| 134 online.color = temp; |
|
| 135 else online.color = DEFAULT_TEXT_COLOR; |
|
| 136 } |
|
| 137 |
|
| 138 if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "away_text")) != NULL))) { |
|
| 139 away.font = xmlnode_get_attrib(sub_sub_node, "font"); |
|
| 140 if(gdk_color_parse(temp = xmlnode_get_attrib(sub_sub_node, "color"), &color)) |
|
| 141 away.color = temp; |
|
| 142 else away.color = DEFAULT_TEXT_COLOR; |
|
| 143 } |
|
| 144 |
|
| 145 if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "offline_text")) != NULL))) { |
|
| 146 offline.font = xmlnode_get_attrib(sub_sub_node, "font"); |
|
| 147 if(gdk_color_parse(temp = xmlnode_get_attrib(sub_sub_node, "color"), &color)) |
|
| 148 offline.color = temp; |
|
| 149 else offline.color = DEFAULT_TEXT_COLOR; |
|
| 150 } |
|
| 151 |
|
| 152 if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "idle_text")) != NULL))) { |
|
| 153 idle.font = xmlnode_get_attrib(sub_sub_node, "font"); |
|
| 154 if(gdk_color_parse(temp = xmlnode_get_attrib(sub_sub_node, "color"), &color)) |
|
| 155 idle.color = temp; |
|
| 156 else idle.color = DEFAULT_TEXT_COLOR; |
|
| 157 } |
|
| 158 |
|
| 159 if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "message_text")) != NULL))) { |
|
| 160 message.font = xmlnode_get_attrib(sub_sub_node, "font"); |
|
| 161 if(gdk_color_parse(temp = xmlnode_get_attrib(sub_sub_node, "color"), &color)) |
|
| 162 message.color = temp; |
|
| 163 else message.color = DEFAULT_TEXT_COLOR; |
|
| 164 } |
|
| 165 |
|
| 166 if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "message_nick_said_text")) != NULL))) { |
|
| 167 message_nick_said.font = xmlnode_get_attrib(sub_sub_node, "font"); |
|
| 168 if(gdk_color_parse(temp = xmlnode_get_attrib(sub_sub_node, "color"), &color)) |
|
| 169 message_nick_said.color = temp; |
|
| 170 else message_nick_said.color = DEFAULT_TEXT_COLOR; |
|
| 171 } |
|
| 172 |
|
| 173 if ((success = (success && sub_node != NULL && (sub_sub_node = xmlnode_get_child(sub_node, "status_text")) != NULL))) { |
|
| 174 status.font = xmlnode_get_attrib(sub_sub_node, "font"); |
|
| 175 if(gdk_color_parse(temp = xmlnode_get_attrib(sub_sub_node, "color"), &color)) |
|
| 176 status.color = temp; |
|
| 177 else status.color = DEFAULT_TEXT_COLOR; |
|
| 178 } |
153 } |
| 179 |
154 |
| 180 /* name is required for theme manager */ |
155 /* name is required for theme manager */ |
| 181 success = (success && xmlnode_get_attrib(root_node, "name") != NULL); |
156 success = (success && xmlnode_get_attrib(root_node, "name") != NULL); |
| 182 |
157 |
| 189 "directory", dir, |
164 "directory", dir, |
| 190 "description", data, |
165 "description", data, |
| 191 "background-color", &bgcolor, |
166 "background-color", &bgcolor, |
| 192 "layout", &layout, |
167 "layout", &layout, |
| 193 "expanded-color", &expanded_bgcolor, |
168 "expanded-color", &expanded_bgcolor, |
| 194 "expanded-text", &expanded, |
169 "expanded-text", expanded, |
| 195 "collapsed-color", &collapsed_bgcolor, |
170 "collapsed-color", &collapsed_bgcolor, |
| 196 "collapsed-text", &collapsed, |
171 "collapsed-text", collapsed, |
| 197 "contact-color", &contact_color, |
172 "contact-color", &contact_color, |
| 198 "contact", &contact, |
173 "contact", contact, |
| 199 "online", &online, |
174 "online", online, |
| 200 "away", &away, |
175 "away", away, |
| 201 "offline", &offline, |
176 "offline", offline, |
| 202 "idle", &idle, |
177 "idle", idle, |
| 203 "message", &message, |
178 "message", message, |
| 204 "message_nick_said", &message_nick_said, |
179 "message_nick_said", message_nick_said, |
| 205 "status", &status, NULL); |
180 "status", status, NULL); |
| 206 |
181 |
| |
182 for (i = 0; lookups[i].tag; i++) { |
| |
183 if (*lookups[i].font) { |
| |
184 pidgin_theme_font_free(*lookups[i].font); |
| |
185 } |
| |
186 } |
| 207 xmlnode_free(root_node); |
187 xmlnode_free(root_node); |
| 208 g_free(data); |
188 g_free(data); |
| 209 |
189 |
| 210 /* malformed xml file - also frees all partial data*/ |
190 /* malformed xml file - also frees all partial data*/ |
| 211 if (!success) { |
191 if (!success) { |