| 26 |
28 |
| 27 #include <debug.h> |
29 #include <debug.h> |
| 28 #include <util.h> |
30 #include <util.h> |
| 29 |
31 |
| 30 static void |
32 static void |
| 31 glist_free_all_string (GList *list) |
33 glist_free_all_string(GList *list) |
| 32 { |
34 { |
| 33 GList *first = list; |
35 GList *first = list; |
| 34 for (; list; list = g_list_next (list)) |
36 for (; list; list = g_list_next(list)) |
| 35 g_free (list->data); |
37 g_free(list->data); |
| 36 g_list_free (first); |
38 g_list_free(first); |
| 37 } |
39 } |
| 38 |
40 |
| 39 static |
41 static PidginMessageStyle * |
| 40 PidginMessageStyle* pidgin_message_style_new (const char* styledir) |
42 pidgin_message_style_new(const char *styledir) |
| 41 { |
43 { |
| 42 PidginMessageStyle* ret = g_new0 (PidginMessageStyle, 1); |
44 PidginMessageStyle *ret = g_new0(PidginMessageStyle, 1); |
| 43 |
45 |
| 44 ret->ref_counter = 1; |
46 ret->ref_counter = 1; |
| 45 ret->style_dir = g_strdup (styledir); |
47 ret->style_dir = g_strdup(styledir); |
| 46 |
48 |
| 47 return ret; |
49 return ret; |
| 48 } |
50 } |
| 49 |
51 |
| 50 /** |
52 /** |
| 51 * deallocate any memory used for info.plist options |
53 * deallocate any memory used for info.plist options |
| 52 */ |
54 */ |
| 53 static void |
55 static void |
| 54 pidgin_message_style_unset_info_plist (PidginMessageStyle *style) |
56 pidgin_message_style_unset_info_plist(PidginMessageStyle *style) |
| 55 { |
57 { |
| 56 style->message_view_version = 0; |
58 style->message_view_version = 0; |
| 57 g_free (style->cf_bundle_name); |
59 g_free(style->cf_bundle_name); |
| 58 style->cf_bundle_name = NULL; |
60 style->cf_bundle_name = NULL; |
| 59 |
61 |
| 60 g_free (style->cf_bundle_identifier); |
62 g_free(style->cf_bundle_identifier); |
| 61 style->cf_bundle_identifier = NULL; |
63 style->cf_bundle_identifier = NULL; |
| 62 |
64 |
| 63 g_free (style->cf_bundle_get_info_string); |
65 g_free(style->cf_bundle_get_info_string); |
| 64 style->cf_bundle_get_info_string = NULL; |
66 style->cf_bundle_get_info_string = NULL; |
| 65 |
67 |
| 66 g_free (style->default_font_family); |
68 g_free(style->default_font_family); |
| 67 style->default_font_family = NULL; |
69 style->default_font_family = NULL; |
| 68 |
70 |
| 69 style->default_font_size = 0; |
71 style->default_font_size = 0; |
| 70 style->shows_user_icons = TRUE; |
72 style->shows_user_icons = TRUE; |
| 71 style->disable_combine_consecutive = FALSE; |
73 style->disable_combine_consecutive = FALSE; |
| 72 style->default_background_is_transparent = FALSE; |
74 style->default_background_is_transparent = FALSE; |
| 73 style->disable_custom_background = FALSE; |
75 style->disable_custom_background = FALSE; |
| 74 |
76 |
| 75 g_free (style->default_background_color); |
77 g_free(style->default_background_color); |
| 76 style->default_background_color = NULL; |
78 style->default_background_color = NULL; |
| 77 |
79 |
| 78 style->allow_text_colors = TRUE; |
80 style->allow_text_colors = TRUE; |
| 79 |
81 |
| 80 g_free (style->image_mask); |
82 g_free(style->image_mask); |
| 81 style->image_mask = NULL; |
83 style->image_mask = NULL; |
| 82 g_free (style->default_variant); |
84 g_free(style->default_variant); |
| 83 style->default_variant = NULL; |
85 style->default_variant = NULL; |
| 84 } |
86 } |
| 85 |
87 |
| 86 |
88 |
| 87 void pidgin_message_style_unref (PidginMessageStyle *style) |
89 void |
| 88 { |
90 pidgin_message_style_unref(PidginMessageStyle *style) |
| 89 if (!style) return; |
91 { |
| |
92 if (!style) |
| |
93 return; |
| 90 g_assert (style->ref_counter > 0); |
94 g_assert (style->ref_counter > 0); |
| 91 |
95 |
| 92 style->ref_counter--; |
96 style->ref_counter--; |
| 93 if (style->ref_counter) return; |
97 if (style->ref_counter) |
| 94 |
98 return; |
| 95 g_free (style->style_dir); |
99 |
| 96 g_free (style->template_path); |
100 g_free(style->style_dir); |
| 97 |
101 g_free(style->template_path); |
| 98 g_free (style->template_html); |
102 |
| 99 g_free (style->incoming_content_html); |
103 g_free(style->template_html); |
| 100 g_free (style->outgoing_content_html); |
104 g_free(style->incoming_content_html); |
| 101 g_free (style->outgoing_next_content_html); |
105 g_free(style->outgoing_content_html); |
| 102 g_free (style->status_html); |
106 g_free(style->outgoing_next_content_html); |
| 103 g_free (style->basestyle_css); |
107 g_free(style->status_html); |
| 104 |
108 g_free(style->basestyle_css); |
| 105 g_free (style); |
109 |
| 106 |
110 g_free(style); |
| 107 pidgin_message_style_unset_info_plist (style); |
111 |
| |
112 pidgin_message_style_unset_info_plist(style); |
| 108 } |
113 } |
| 109 |
114 |
| 110 void |
115 void |
| 111 pidgin_message_style_save_state (const PidginMessageStyle *style) |
116 pidgin_message_style_save_state(const PidginMessageStyle *style) |
| 112 { |
117 { |
| 113 char *prefname = g_strdup_printf ("/plugins/gtk/adiumthemes/%s", style->cf_bundle_identifier); |
118 char *prefname = g_strdup_printf("/plugins/gtk/adiumthemes/%s", style->cf_bundle_identifier); |
| 114 char *variant = g_strdup_printf ("%s/variant", prefname); |
119 char *variant = g_strdup_printf("%s/variant", prefname); |
| 115 |
120 |
| 116 purple_debug_info ("webkit", "saving state with variant %s\n", style->variant); |
121 purple_debug_info("webkit", "saving state with variant %s\n", style->variant); |
| 117 purple_prefs_add_none (prefname); |
122 purple_prefs_add_none(prefname); |
| 118 purple_prefs_add_string (variant, ""); |
123 purple_prefs_add_string(variant, ""); |
| 119 purple_prefs_set_string (variant, style->variant); |
124 purple_prefs_set_string(variant, style->variant); |
| 120 |
125 |
| 121 g_free (prefname); |
126 g_free(prefname); |
| 122 g_free (variant); |
127 g_free(variant); |
| 123 } |
128 } |
| 124 |
129 |
| 125 static void |
130 static void |
| 126 pidgin_message_style_load_state (PidginMessageStyle *style) |
131 pidgin_message_style_load_state(PidginMessageStyle *style) |
| 127 { |
132 { |
| 128 char *prefname = g_strdup_printf ("/plugins/gtk/adiumthemes/%s", style->cf_bundle_identifier); |
133 char *prefname = g_strdup_printf("/plugins/gtk/adiumthemes/%s", style->cf_bundle_identifier); |
| 129 char *variant = g_strdup_printf ("%s/variant", prefname); |
134 char *variant = g_strdup_printf("%s/variant", prefname); |
| 130 |
135 |
| 131 const char* value = purple_prefs_get_string (variant); |
136 const char* value = purple_prefs_get_string(variant); |
| 132 gboolean changed = !style->variant || !g_str_equal (style->variant, value); |
137 gboolean changed = !style->variant || !g_str_equal(style->variant, value); |
| 133 |
138 |
| 134 g_free (style->variant); |
139 g_free(style->variant); |
| 135 style->variant = g_strdup (value); |
140 style->variant = g_strdup(value); |
| 136 |
141 |
| 137 if (changed) pidgin_message_style_read_info_plist (style, style->variant); |
142 if (changed) |
| 138 |
143 pidgin_message_style_read_info_plist(style, style->variant); |
| 139 g_free (prefname); |
144 |
| |
145 g_free(prefname); |
| 140 g_free(variant); |
146 g_free(variant); |
| 141 } |
147 } |
| 142 |
148 |
| 143 |
149 |
| 144 static gboolean |
150 static gboolean |
| 145 parse_info_plist_key_value (xmlnode* key, gpointer destination, const char* expected) |
151 parse_info_plist_key_value(xmlnode* key, gpointer destination, const char* expected) |
| 146 { |
152 { |
| 147 xmlnode *val = key->next; |
153 xmlnode *val = key->next; |
| 148 |
154 |
| 149 for (; val && val->type != XMLNODE_TYPE_TAG; val = val->next); |
155 for (; val && val->type != XMLNODE_TYPE_TAG; val = val->next) |
| 150 if (!val) return FALSE; |
156 ; |
| 151 |
157 if (!val) |
| 152 if (expected == NULL || g_str_equal (expected, "string")) { |
158 return FALSE; |
| 153 char** dest = (char**) destination; |
159 |
| 154 if (!g_str_equal (val->name, "string")) return FALSE; |
160 if (expected == NULL || g_str_equal(expected, "string")) { |
| 155 if (*dest) g_free (*dest); |
161 char **dest = (char **)destination; |
| 156 *dest = xmlnode_get_data_unescaped (val); |
162 if (!g_str_equal(val->name, "string")) |
| 157 } else if (g_str_equal (expected, "integer")) { |
163 return FALSE; |
| 158 int* dest = (int*) destination; |
164 if (*dest) |
| 159 char* value = xmlnode_get_data_unescaped (val); |
165 g_free(*dest); |
| 160 |
166 *dest = xmlnode_get_data_unescaped(val); |
| 161 if (!g_str_equal (val->name, "integer")) return FALSE; |
167 } else if (g_str_equal(expected, "integer")) { |
| 162 *dest = atoi (value); |
168 int *dest = (int *)destination; |
| 163 g_free (value); |
169 char *value = xmlnode_get_data_unescaped(val); |
| 164 } else if (g_str_equal (expected, "boolean")) { |
170 |
| 165 gboolean *dest = (gboolean*) destination; |
171 if (!g_str_equal(val->name, "integer")) |
| 166 if (g_str_equal (val->name, "true")) *dest = TRUE; |
172 return FALSE; |
| 167 else if (g_str_equal (val->name, "false")) *dest = FALSE; |
173 *dest = atoi(value); |
| 168 else return FALSE; |
174 g_free(value); |
| |
175 } else if (g_str_equal(expected, "boolean")) { |
| |
176 gboolean *dest = (gboolean *)destination; |
| |
177 if (g_str_equal(val->name, "true")) |
| |
178 *dest = TRUE; |
| |
179 else if (g_str_equal(val->name, "false")) |
| |
180 *dest = FALSE; |
| |
181 else |
| |
182 return FALSE; |
| 169 } else return FALSE; |
183 } else return FALSE; |
| 170 |
184 |
| 171 return TRUE; |
185 return TRUE; |
| 172 } |
186 } |
| 173 |
187 |
| 174 static |
188 static gboolean |
| 175 gboolean str_for_key (const char *key, const char *found, const char *variant){ |
189 str_for_key(const char *key, const char *found, const char *variant) |
| 176 if (g_str_equal (key, found)) return TRUE; |
190 { |
| 177 if (!variant) return FALSE; |
191 if (g_str_equal(key, found)) |
| 178 return (g_str_has_prefix (found, key) |
192 return TRUE; |
| 179 && g_str_has_suffix (found, variant) |
193 if (!variant) |
| 180 && strlen (found) == strlen (key) + strlen (variant) + 1); |
194 return FALSE; |
| |
195 return (g_str_has_prefix(found, key) |
| |
196 && g_str_has_suffix(found, variant) |
| |
197 && strlen(found) == strlen(key) + strlen(variant) + 1); |
| 181 } |
198 } |
| 182 |
199 |
| 183 /** |
200 /** |
| 184 * Info.plist should be re-read every time the variant changes, this is because |
201 * Info.plist should be re-read every time the variant changes, this is because |
| 185 * the keys that take precedence depend on the value of the current variant. |
202 * the keys that take precedence depend on the value of the current variant. |
| 186 */ |
203 */ |
| 187 void |
204 void |
| 188 pidgin_message_style_read_info_plist (PidginMessageStyle *style, const char* variant) |
205 pidgin_message_style_read_info_plist(PidginMessageStyle *style, const char *variant) |
| 189 { |
206 { |
| 190 /* note that if a variant is used the option:VARIANTNAME takes precedence */ |
207 /* note that if a variant is used the option:VARIANTNAME takes precedence */ |
| 191 char *contents = g_build_filename (style->style_dir, "Contents", NULL); |
208 char *contents = g_build_filename(style->style_dir, "Contents", NULL); |
| 192 xmlnode *plist = xmlnode_from_file (contents, "Info.plist", "Info.plist", "webkit"), *iter; |
209 xmlnode *plist = xmlnode_from_file(contents, "Info.plist", "Info.plist", "webkit"), *iter; |
| 193 xmlnode *dict = xmlnode_get_child (plist, "dict"); |
210 xmlnode *dict = xmlnode_get_child(plist, "dict"); |
| 194 |
211 |
| 195 g_assert (dict); |
212 g_assert (dict); |
| 196 for (iter = xmlnode_get_child (dict, "key"); iter; iter = xmlnode_get_next_twin (iter)) { |
213 for (iter = xmlnode_get_child(dict, "key"); iter; iter = xmlnode_get_next_twin(iter)) { |
| 197 char* key = xmlnode_get_data_unescaped (iter); |
214 char* key = xmlnode_get_data_unescaped(iter); |
| 198 gboolean pr = TRUE; |
215 gboolean pr = TRUE; |
| 199 |
216 |
| 200 if (g_str_equal ("MessageViewVersion", key)) |
217 if (g_str_equal("MessageViewVersion", key)) |
| 201 pr = parse_info_plist_key_value (iter, &style->message_view_version, "integer"); |
218 pr = parse_info_plist_key_value(iter, &style->message_view_version, "integer"); |
| 202 else if (g_str_equal ("CFBundleName", key)) |
219 else if (g_str_equal("CFBundleName", key)) |
| 203 pr = parse_info_plist_key_value (iter, &style->cf_bundle_name, "string"); |
220 pr = parse_info_plist_key_value(iter, &style->cf_bundle_name, "string"); |
| 204 else if (g_str_equal ("CFBundleIdentifier", key)) |
221 else if (g_str_equal("CFBundleIdentifier", key)) |
| 205 pr = parse_info_plist_key_value (iter, &style->cf_bundle_identifier, "string"); |
222 pr = parse_info_plist_key_value(iter, &style->cf_bundle_identifier, "string"); |
| 206 else if (g_str_equal ("CFBundleGetInfoString", key)) |
223 else if (g_str_equal("CFBundleGetInfoString", key)) |
| 207 pr = parse_info_plist_key_value (iter, &style->cf_bundle_get_info_string, "string"); |
224 pr = parse_info_plist_key_value(iter, &style->cf_bundle_get_info_string, "string"); |
| 208 else if (str_for_key ("DefaultFontFamily", key, variant)) |
225 else if (str_for_key("DefaultFontFamily", key, variant)) |
| 209 pr = parse_info_plist_key_value (iter, &style->default_font_family, "string"); |
226 pr = parse_info_plist_key_value(iter, &style->default_font_family, "string"); |
| 210 else if (str_for_key ("DefaultFontSize", key, variant)) |
227 else if (str_for_key("DefaultFontSize", key, variant)) |
| 211 pr = parse_info_plist_key_value (iter, &style->default_font_size, "integer"); |
228 pr = parse_info_plist_key_value(iter, &style->default_font_size, "integer"); |
| 212 else if (str_for_key ("ShowsUserIcons", key, variant)) |
229 else if (str_for_key("ShowsUserIcons", key, variant)) |
| 213 pr = parse_info_plist_key_value (iter, &style->shows_user_icons, "boolean"); |
230 pr = parse_info_plist_key_value(iter, &style->shows_user_icons, "boolean"); |
| 214 else if (str_for_key ("DisableCombineConsecutive", key, variant)) |
231 else if (str_for_key("DisableCombineConsecutive", key, variant)) |
| 215 pr = parse_info_plist_key_value (iter, &style->disable_combine_consecutive, "boolean"); |
232 pr = parse_info_plist_key_value(iter, &style->disable_combine_consecutive, "boolean"); |
| 216 else if (str_for_key ("DefaultBackgroundIsTransparent", key, variant)) |
233 else if (str_for_key("DefaultBackgroundIsTransparent", key, variant)) |
| 217 pr = parse_info_plist_key_value (iter, &style->default_background_is_transparent, "boolean"); |
234 pr = parse_info_plist_key_value(iter, &style->default_background_is_transparent, "boolean"); |
| 218 else if (str_for_key ("DisableCustomBackground", key, variant)) |
235 else if (str_for_key("DisableCustomBackground", key, variant)) |
| 219 pr = parse_info_plist_key_value (iter, &style->disable_custom_background, "boolean"); |
236 pr = parse_info_plist_key_value(iter, &style->disable_custom_background, "boolean"); |
| 220 else if (str_for_key ("DefaultBackgroundColor", key, variant)) |
237 else if (str_for_key("DefaultBackgroundColor", key, variant)) |
| 221 pr = parse_info_plist_key_value (iter, &style->default_background_color, "string"); |
238 pr = parse_info_plist_key_value(iter, &style->default_background_color, "string"); |
| 222 else if (str_for_key ("AllowTextColors", key, variant)) |
239 else if (str_for_key("AllowTextColors", key, variant)) |
| 223 pr = parse_info_plist_key_value (iter, &style->allow_text_colors, "integer"); |
240 pr = parse_info_plist_key_value(iter, &style->allow_text_colors, "integer"); |
| 224 else if (str_for_key ("ImageMask", key, variant)) |
241 else if (str_for_key("ImageMask", key, variant)) |
| 225 pr = parse_info_plist_key_value (iter, &style->image_mask, "string"); |
242 pr = parse_info_plist_key_value(iter, &style->image_mask, "string"); |
| 226 |
243 |
| 227 if (!pr) |
244 if (!pr) |
| 228 purple_debug_warning ("webkit", "Failed to parse key %s\n", key); |
245 purple_debug_warning("webkit", "Failed to parse key %s\n", key); |
| 229 g_free (key); |
246 g_free(key); |
| 230 } |
247 } |
| 231 |
248 |
| 232 xmlnode_free (plist); |
249 xmlnode_free(plist); |
| 233 } |
250 } |
| 234 |
251 |
| 235 PidginMessageStyle* |
252 PidginMessageStyle * |
| 236 pidgin_message_style_load (const char* styledir) |
253 pidgin_message_style_load(const char *styledir) |
| 237 { |
254 { |
| 238 /* |
255 /* |
| 239 * the loading process described: |
256 * the loading process described: |
| 240 * |
257 * |
| 241 * First we load all the style .html files, etc. |
258 * First we load all the style .html files, etc. |
| 245 * At this point, if we find that variants exist, yet |
262 * At this point, if we find that variants exist, yet |
| 246 * we don't have a variant selected, we choose DefaultVariant |
263 * we don't have a variant selected, we choose DefaultVariant |
| 247 * and if that does not exist, we choose the first one in the |
264 * and if that does not exist, we choose the first one in the |
| 248 * directory. |
265 * directory. |
| 249 */ |
266 */ |
| 250 |
267 char *file; |
| 251 /* is this style already loaded? */ |
|
| 252 char *file; /* temporary variable */ |
|
| 253 PidginMessageStyle *style = NULL; |
268 PidginMessageStyle *style = NULL; |
| 254 |
269 |
| 255 /* else we need to load it */ |
270 style = pidgin_message_style_new(styledir); |
| 256 style = pidgin_message_style_new (styledir); |
271 |
| 257 |
|
| 258 /* load all other files */ |
272 /* load all other files */ |
| 259 |
273 |
| 260 /* The template path can either come from the theme, or can |
274 /* The template path can either come from the theme, or can |
| 261 * be stock Template.html that comes with the plugin */ |
275 * be stock Template.html that comes with the plugin */ |
| 262 style->template_path = g_build_filename(styledir, "Contents", "Resources", "Template.html", NULL); |
276 style->template_path = g_build_filename(styledir, "Contents", "Resources", "Template.html", NULL); |
| 263 |
277 |
| 264 if (!g_file_test(style->template_path, G_FILE_TEST_EXISTS)) { |
278 if (!g_file_test(style->template_path, G_FILE_TEST_EXISTS)) { |
| 265 g_free (style->template_path); |
279 g_free(style->template_path); |
| 266 style->template_path = g_build_filename(DATADIR, "pidgin", "webkit", "Template.html", NULL); |
280 style->template_path = g_build_filename(DATADIR, "pidgin", "webkit", "Template.html", NULL); |
| 267 } |
281 } |
| 268 |
282 |
| 269 if (!g_file_get_contents(style->template_path, &style->template_html, NULL, NULL)) { |
283 if (!g_file_get_contents(style->template_path, &style->template_html, NULL, NULL)) { |
| 270 purple_debug_error ("webkit", "Could not locate a Template.html (%s)\n", style->template_path); |
284 purple_debug_error("webkit", "Could not locate a Template.html (%s)\n", style->template_path); |
| 271 pidgin_message_style_unref (style); |
285 pidgin_message_style_unref(style); |
| 272 return NULL; |
286 return NULL; |
| 273 } |
287 } |
| 274 |
288 |
| 275 file = g_build_filename(styledir, "Contents", "Resources", "Status.html", NULL); |
289 file = g_build_filename(styledir, "Contents", "Resources", "Status.html", NULL); |
| 276 if (!g_file_get_contents(file, &style->status_html, NULL, NULL)) { |
290 if (!g_file_get_contents(file, &style->status_html, NULL, NULL)) { |
| 277 purple_debug_info ("webkit", "%s could not find Resources/Status.html", styledir); |
291 purple_debug_info("webkit", "%s could not find Resources/Status.html", styledir); |
| 278 pidgin_message_style_unref (style); |
292 pidgin_message_style_unref(style); |
| 279 g_free (file); |
293 g_free(file); |
| 280 return NULL; |
294 return NULL; |
| 281 } |
295 } |
| 282 g_free (file); |
296 g_free(file); |
| 283 |
297 |
| 284 file = g_build_filename(styledir, "Contents", "Resources", "main.css", NULL); |
298 file = g_build_filename(styledir, "Contents", "Resources", "main.css", NULL); |
| 285 if (!g_file_get_contents(file, &style->basestyle_css, NULL, NULL)) |
299 if (!g_file_get_contents(file, &style->basestyle_css, NULL, NULL)) |
| 286 style->basestyle_css = g_strdup (""); |
300 style->basestyle_css = g_strdup(""); |
| 287 g_free (file); |
301 g_free(file); |
| 288 |
302 |
| 289 file = g_build_filename(styledir, "Contents", "Resources", "Header.html", NULL); |
303 file = g_build_filename(styledir, "Contents", "Resources", "Header.html", NULL); |
| 290 if (!g_file_get_contents(file, &style->header_html, NULL, NULL)) |
304 if (!g_file_get_contents(file, &style->header_html, NULL, NULL)) |
| 291 style->header_html = g_strdup (""); |
305 style->header_html = g_strdup(""); |
| 292 g_free (file); |
306 g_free(file); |
| 293 |
307 |
| 294 file = g_build_filename(styledir, "Contents", "Resources", "Footer.html", NULL); |
308 file = g_build_filename(styledir, "Contents", "Resources", "Footer.html", NULL); |
| 295 if (!g_file_get_contents(file, &style->footer_html, NULL, NULL)) |
309 if (!g_file_get_contents(file, &style->footer_html, NULL, NULL)) |
| 296 style->footer_html = g_strdup (""); |
310 style->footer_html = g_strdup(""); |
| 297 g_free (file); |
311 g_free(file); |
| 298 |
312 |
| 299 file = g_build_filename(styledir, "Contents", "Resources", "Incoming", "Content.html", NULL); |
313 file = g_build_filename(styledir, "Contents", "Resources", "Incoming", "Content.html", NULL); |
| 300 if (!g_file_get_contents(file, &style->incoming_content_html, NULL, NULL)) { |
314 if (!g_file_get_contents(file, &style->incoming_content_html, NULL, NULL)) { |
| 301 purple_debug_info ("webkit", "%s did not have a Incoming/Content.html\n", styledir); |
315 purple_debug_info("webkit", "%s did not have a Incoming/Content.html\n", styledir); |
| 302 pidgin_message_style_unref (style); |
316 pidgin_message_style_unref(style); |
| 303 g_free (file); |
317 g_free(file); |
| 304 return NULL; |
318 return NULL; |
| 305 } |
319 } |
| 306 g_free (file); |
320 g_free(file); |
| 307 |
321 |
| 308 |
322 |
| 309 /* according to the spec, the following are optional files */ |
323 /* according to the spec, the following are optional files */ |
| 310 file = g_build_filename(styledir, "Contents", "Resources", "Incoming", "NextContent.html", NULL); |
324 file = g_build_filename(styledir, "Contents", "Resources", "Incoming", "NextContent.html", NULL); |
| 311 if (!g_file_get_contents(file, &style->incoming_next_content_html, NULL, NULL)) { |
325 if (!g_file_get_contents(file, &style->incoming_next_content_html, NULL, NULL)) { |
| 312 style->incoming_next_content_html = g_strdup (style->incoming_content_html); |
326 style->incoming_next_content_html = g_strdup(style->incoming_content_html); |
| 313 } |
327 } |
| 314 g_free (file); |
328 g_free(file); |
| 315 |
329 |
| 316 file = g_build_filename(styledir, "Contents", "Resources", "Outgoing", "Content.html", NULL); |
330 file = g_build_filename(styledir, "Contents", "Resources", "Outgoing", "Content.html", NULL); |
| 317 if (!g_file_get_contents(file, &style->outgoing_content_html, NULL, NULL)) { |
331 if (!g_file_get_contents(file, &style->outgoing_content_html, NULL, NULL)) { |
| 318 style->outgoing_content_html = g_strdup(style->incoming_content_html); |
332 style->outgoing_content_html = g_strdup(style->incoming_content_html); |
| 319 } |
333 } |
| 320 g_free (file); |
334 g_free(file); |
| 321 |
335 |
| 322 file = g_build_filename(styledir, "Contents", "Resources", "Outgoing", "NextContent.html", NULL); |
336 file = g_build_filename(styledir, "Contents", "Resources", "Outgoing", "NextContent.html", NULL); |
| 323 if (!g_file_get_contents(file, &style->outgoing_next_content_html, NULL, NULL)) { |
337 if (!g_file_get_contents(file, &style->outgoing_next_content_html, NULL, NULL)) { |
| 324 style->outgoing_next_content_html = g_strdup (style->outgoing_content_html); |
338 style->outgoing_next_content_html = g_strdup(style->outgoing_content_html); |
| 325 } |
339 } |
| 326 |
340 |
| 327 pidgin_message_style_read_info_plist (style, NULL); |
341 pidgin_message_style_read_info_plist(style, NULL); |
| 328 pidgin_message_style_load_state (style); |
342 pidgin_message_style_load_state(style); |
| 329 |
343 |
| 330 /* non variant dependent Info.plist checks */ |
344 /* non variant dependent Info.plist checks */ |
| 331 if (style->message_view_version < 3) { |
345 if (style->message_view_version < 3) { |
| 332 purple_debug_info ("webkit", "%s is a legacy style (version %d) and will not be loaded\n", style->cf_bundle_name, style->message_view_version); |
346 purple_debug_info("webkit", "%s is a legacy style (version %d) and will not be loaded\n", style->cf_bundle_name, style->message_view_version); |
| 333 pidgin_message_style_unref (style); |
347 pidgin_message_style_unref(style); |
| 334 return NULL; |
348 return NULL; |
| 335 } |
349 } |
| 336 |
350 |
| 337 if (!style->variant) |
351 if (!style->variant) |
| 338 { |
352 { |
| 339 GList *variants = pidgin_message_style_get_variants (style); |
353 GList *variants = pidgin_message_style_get_variants(style); |
| 340 |
354 |
| 341 if (variants) |
355 if (variants) |
| 342 pidgin_message_style_set_variant (style, variants->data); |
356 pidgin_message_style_set_variant(style, variants->data); |
| 343 |
357 |
| 344 glist_free_all_string (variants); |
358 glist_free_all_string(variants); |
| 345 } |
359 } |
| 346 |
360 |
| 347 return style; |
361 return style; |
| 348 } |
362 } |
| 349 |
363 |
| 350 PidginMessageStyle* |
364 PidginMessageStyle * |
| 351 pidgin_message_style_copy (const PidginMessageStyle *style) |
365 pidgin_message_style_copy(const PidginMessageStyle *style) |
| 352 { |
366 { |
| 353 /* it's at times like this that I miss C++ */ |
367 PidginMessageStyle *ret = pidgin_message_style_new(style->style_dir); |
| 354 PidginMessageStyle *ret = pidgin_message_style_new (style->style_dir); |
368 |
| 355 |
369 ret->variant = g_strdup(style->variant); |
| 356 ret->variant = g_strdup (style->variant); |
|
| 357 ret->message_view_version = style->message_view_version; |
370 ret->message_view_version = style->message_view_version; |
| 358 ret->cf_bundle_name = g_strdup (style->cf_bundle_name); |
371 ret->cf_bundle_name = g_strdup(style->cf_bundle_name); |
| 359 ret->cf_bundle_identifier = g_strdup (style->cf_bundle_identifier); |
372 ret->cf_bundle_identifier = g_strdup(style->cf_bundle_identifier); |
| 360 ret->cf_bundle_get_info_string = g_strdup (style->cf_bundle_get_info_string); |
373 ret->cf_bundle_get_info_string = g_strdup(style->cf_bundle_get_info_string); |
| 361 ret->default_font_family = g_strdup (style->default_font_family); |
374 ret->default_font_family = g_strdup(style->default_font_family); |
| 362 ret->default_font_size = style->default_font_size; |
375 ret->default_font_size = style->default_font_size; |
| 363 ret->shows_user_icons = style->shows_user_icons; |
376 ret->shows_user_icons = style->shows_user_icons; |
| 364 ret->disable_combine_consecutive = style->disable_combine_consecutive; |
377 ret->disable_combine_consecutive = style->disable_combine_consecutive; |
| 365 ret->default_background_is_transparent = style->default_background_is_transparent; |
378 ret->default_background_is_transparent = style->default_background_is_transparent; |
| 366 ret->disable_custom_background = style->disable_custom_background; |
379 ret->disable_custom_background = style->disable_custom_background; |
| 367 ret->default_background_color = g_strdup (style->default_background_color); |
380 ret->default_background_color = g_strdup(style->default_background_color); |
| 368 ret->allow_text_colors = style->allow_text_colors; |
381 ret->allow_text_colors = style->allow_text_colors; |
| 369 ret->image_mask = g_strdup (style->image_mask); |
382 ret->image_mask = g_strdup(style->image_mask); |
| 370 ret->default_variant = g_strdup (style->default_variant); |
383 ret->default_variant = g_strdup(style->default_variant); |
| 371 |
384 |
| 372 ret->template_path = g_strdup (style->template_path); |
385 ret->template_path = g_strdup(style->template_path); |
| 373 ret->template_html = g_strdup (style->template_html); |
386 ret->template_html = g_strdup(style->template_html); |
| 374 ret->header_html = g_strdup (style->header_html); |
387 ret->header_html = g_strdup(style->header_html); |
| 375 ret->footer_html = g_strdup (style->footer_html); |
388 ret->footer_html = g_strdup(style->footer_html); |
| 376 ret->incoming_content_html = g_strdup (style->incoming_content_html); |
389 ret->incoming_content_html = g_strdup(style->incoming_content_html); |
| 377 ret->outgoing_content_html = g_strdup (style->outgoing_content_html); |
390 ret->outgoing_content_html = g_strdup(style->outgoing_content_html); |
| 378 ret->incoming_next_content_html = g_strdup (style->incoming_next_content_html); |
391 ret->incoming_next_content_html = g_strdup(style->incoming_next_content_html); |
| 379 ret->outgoing_next_content_html = g_strdup (style->outgoing_next_content_html); |
392 ret->outgoing_next_content_html = g_strdup(style->outgoing_next_content_html); |
| 380 ret->status_html = g_strdup (style->status_html); |
393 ret->status_html = g_strdup(style->status_html); |
| 381 ret->basestyle_css = g_strdup (style->basestyle_css); |
394 ret->basestyle_css = g_strdup(style->basestyle_css); |
| 382 return ret; |
395 return ret; |
| 383 } |
396 } |
| 384 |
397 |
| 385 void |
398 void |
| 386 pidgin_message_style_set_variant (PidginMessageStyle *style, const char *variant) |
399 pidgin_message_style_set_variant(PidginMessageStyle *style, const char *variant) |
| 387 { |
400 { |
| 388 /* I'm not going to test whether this variant is valid! */ |
401 /* I'm not going to test whether this variant is valid! */ |
| 389 g_free (style->variant); |
402 g_free(style->variant); |
| 390 style->variant = g_strdup (variant); |
403 style->variant = g_strdup(variant); |
| 391 |
404 |
| 392 pidgin_message_style_read_info_plist (style, variant); |
405 pidgin_message_style_read_info_plist(style, variant); |
| 393 |
406 |
| 394 /* todo, the style has "changed". Ideally, I would like to use signals at this point. */ |
407 /* todo, the style has "changed". Ideally, I would like to use signals at this point. */ |
| 395 } |
408 } |
| 396 |
409 |
| 397 char* pidgin_message_style_get_variant (PidginMessageStyle *style) |
410 char * |
| 398 { |
411 pidgin_message_style_get_variant(PidginMessageStyle *style) |
| 399 return g_strdup (style->variant); |
412 { |
| |
413 return g_strdup(style->variant); |
| 400 } |
414 } |
| 401 |
415 |
| 402 /** |
416 /** |
| 403 * Get a list of variants supported by the style. |
417 * Get a list of variants supported by the style. |
| 404 */ |
418 */ |
| 405 GList* |
419 GList* |
| 406 pidgin_message_style_get_variants (PidginMessageStyle *style) |
420 pidgin_message_style_get_variants(PidginMessageStyle *style) |
| 407 { |
421 { |
| 408 GList *ret = NULL; |
422 GList *ret = NULL; |
| 409 GDir *variants; |
423 GDir *variants; |
| 410 const char *css_file; |
424 const char *css_file; |
| 411 char *css; |
425 char *css; |
| 412 char *variant_dir; |
426 char *variant_dir; |
| 413 |
427 |
| 414 g_assert (style->style_dir); |
428 g_assert(style->style_dir); |
| 415 variant_dir = g_build_filename(style->style_dir, "Contents", "Resources", "Variants", NULL); |
429 variant_dir = g_build_filename(style->style_dir, "Contents", "Resources", "Variants", NULL); |
| 416 |
430 |
| 417 variants = g_dir_open(variant_dir, 0, NULL); |
431 variants = g_dir_open(variant_dir, 0, NULL); |
| 418 if (!variants) return NULL; |
432 if (!variants) |
| |
433 return NULL; |
| 419 |
434 |
| 420 while ((css_file = g_dir_read_name(variants)) != NULL) { |
435 while ((css_file = g_dir_read_name(variants)) != NULL) { |
| 421 if (!g_str_has_suffix (css_file, ".css")) |
436 if (!g_str_has_suffix(css_file, ".css")) |
| 422 continue; |
437 continue; |
| 423 |
438 |
| 424 css = g_strndup (css_file, strlen (css_file) - 4); |
439 css = g_strndup(css_file, strlen(css_file) - 4); |
| 425 ret = g_list_append(ret, css); |
440 ret = g_list_append(ret, css); |
| 426 } |
441 } |
| 427 |
442 |
| 428 g_dir_close(variants); |
443 g_dir_close(variants); |
| 429 g_free(variant_dir); |
444 g_free(variant_dir); |
| 430 |
445 |
| 431 ret = g_list_sort (ret, (GCompareFunc)g_strcmp0); |
446 ret = g_list_sort(ret, (GCompareFunc)g_strcmp0); |
| 432 return ret; |
447 return ret; |
| 433 } |
448 } |
| 434 |
449 |
| 435 |
450 char * |
| 436 char* pidgin_message_style_get_css (PidginMessageStyle *style) |
451 pidgin_message_style_get_css(PidginMessageStyle *style) |
| 437 { |
452 { |
| 438 if (!style->variant) { |
453 if (!style->variant) { |
| 439 return g_build_filename (style->style_dir, "Contents", "Resources", "main.css", NULL); |
454 return g_build_filename(style->style_dir, "Contents", "Resources", "main.css", NULL); |
| 440 } else { |
455 } else { |
| 441 char *file = g_strdup_printf ("%s.css", style->variant); |
456 char *file = g_strdup_printf("%s.css", style->variant); |
| 442 char *ret = g_build_filename (style->style_dir, "Contents", "Resources", "Variants", file, NULL); |
457 char *ret = g_build_filename(style->style_dir, "Contents", "Resources", "Variants", file, NULL); |
| 443 g_free (file); |
458 g_free(file); |
| 444 return ret; |
459 return ret; |
| 445 } |
460 } |
| 446 } |
461 } |
| 447 |
462 |
| 448 |
|