fixed irreco_theme_read_button_keyfile_foreach() and irreco_theme_read_bg_keyfile_for...
[irreco.git] / irreco / src / core / irreco_theme.c
blobd52936c8bae7dc2f162c9778452544f950683f60
1 /*
2 * irreco - Ir Remote Control
3 * Copyright (C) 2008 Joni Kokko (t5kojo01@students.oamk.fi)
4 * Pekka Gehör (pegu6@msn.com)
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 #include "irreco_theme.h"
23 /**
24 * @addtogroup IrrecoTheme
25 * @ingroup Irreco
27 * Contains information of theme.
29 * @{
32 /**
33 * @file
34 * Source file of @ref IrrecoTheme.
37 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
38 /* Prototypes */
39 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
40 void irreco_theme_read_button_keyfile_foreach(IrrecoDirForeachData * dir_data);
41 void irreco_theme_read_bg_keyfile_foreach(IrrecoDirForeachData * dir_data);
42 void irreco_theme_read(IrrecoTheme *self, const gchar *dir);
44 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
45 /* Construction & Destruction */
46 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
48 /**
49 * @name Construction & Destruction
50 * @{
53 /**
54 * Create new theme
56 IrrecoTheme *irreco_theme_new()
58 IrrecoTheme *self;
59 IRRECO_ENTER
61 self = g_slice_new0(IrrecoTheme);
63 self->name = g_string_new(NULL);
64 self->path = g_string_new(NULL);
65 self->source = g_string_new(NULL);
66 self->author = g_string_new(NULL);
67 self->comment = g_string_new(NULL);
68 self->preview_button_name = g_string_new(NULL);
69 self->version = g_string_new(NULL);
70 self->backgrounds = irreco_string_table_new(
71 (GDestroyNotify)irreco_theme_bg_free, NULL);
72 self->buttons = irreco_string_table_new(
73 (GDestroyNotify)irreco_theme_button_free, NULL);
75 IRRECO_RETURN_PTR(self);
78 void irreco_theme_free(IrrecoTheme *self)
80 IRRECO_ENTER
82 g_assert(self != NULL);
84 g_string_free(self->name, TRUE);
85 self->name = NULL;
87 g_string_free(self->path, TRUE);
88 self->path = NULL;
90 g_string_free(self->source, TRUE);
91 self->source = NULL;
93 g_string_free(self->author, TRUE);
94 self->author = NULL;
96 g_string_free(self->comment, TRUE);
97 self->comment = NULL;
99 g_string_free(self->preview_button_name, TRUE);
100 self->preview_button_name = NULL;
102 irreco_string_table_free(self->backgrounds);
103 self->backgrounds = NULL;
105 irreco_string_table_free(self->buttons);
106 self->buttons = NULL;
108 g_slice_free(IrrecoTheme, self);
109 self = NULL;
111 IRRECO_RETURN
114 /** @} */
116 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
117 /* Private Functions */
118 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
121 * @name Private Functions
122 * @{
126 /** @} */
128 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
129 /* Public Functions */
130 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
133 * @name Public Functions
134 * @{
136 void irreco_theme_update_keyfile(IrrecoTheme *self)
138 GString *keyfile_path = g_string_new(self->path->str);
139 GKeyFile *keyfile = g_key_file_new();
140 IRRECO_ENTER
142 g_string_append(keyfile_path, "/theme.conf");
144 irreco_gkeyfile_set_string(keyfile, "theme" , "name",
145 self->name->str);
147 if (self->source->len > 0) {
148 irreco_gkeyfile_set_string(keyfile, "theme" , "source",
149 self->source->str);
152 if (self->author->len > 0) {
153 irreco_gkeyfile_set_string(keyfile, "theme", "author",
154 self->author->str);
157 if (self->preview_button_name->len > 0) {
158 irreco_gkeyfile_set_string(keyfile, "theme", "preview-button",
159 self->preview_button_name->str);
162 if (self->version->len > 0) {
163 irreco_gkeyfile_set_string(keyfile, "theme", "version",
164 self->version->str);
167 if (self->comment->len > 0) {
168 irreco_gkeyfile_set_string(keyfile, "theme", "comment",
169 self->comment->str);
172 irreco_write_keyfile(keyfile, keyfile_path->str);
174 g_key_file_free(keyfile);
175 g_string_free(keyfile_path, TRUE);
176 IRRECO_RETURN
179 void irreco_theme_print(IrrecoTheme *self)
181 IRRECO_ENTER
183 IRRECO_DEBUG("Themename: %s \n", self->name->str);
184 IRRECO_DEBUG("Folder: %s \n", self->path->str);
185 IRRECO_DEBUG("Source: %s \n", self->source->str);
186 IRRECO_DEBUG("Author: %s \n", self->author->str);
187 IRRECO_DEBUG("Comment: %s \n", self->comment->str);
188 IRRECO_DEBUG("Previewbutton: %s \n", self->preview_button_name->str);
189 IRRECO_DEBUG("Version: %s \n", self->version->str);
190 irreco_string_table_print(self->backgrounds);
191 irreco_string_table_print(self->buttons);
193 IRRECO_RETURN
196 void irreco_theme_read_button_keyfile_foreach(IrrecoDirForeachData * dir_data)
198 IrrecoTheme *self = (IrrecoTheme*) dir_data->user_data_1;
199 IrrecoThemeButton *button = NULL;
200 IrrecoThemeButton *old_button = NULL;
201 IRRECO_ENTER
203 button = irreco_theme_button_new_from_dir(dir_data->directory,
204 self->name->str);
206 if (irreco_string_table_exists(self->buttons, button->name->str)) {
207 IRRECO_ERROR("Error: Button %s has already been read. "
208 "You cannot have two buttons with the same name.\n",
209 button->name->str);
210 irreco_string_table_get(self->buttons, button->name->str,
211 (gpointer*) &old_button);
212 irreco_theme_button_read(old_button, dir_data->filepath);
213 irreco_theme_button_free(button);
214 } else {
215 irreco_string_table_add(self->buttons,
216 button->style_name->str, button);
219 IRRECO_RETURN
222 void irreco_theme_read_bg_keyfile_foreach(IrrecoDirForeachData * dir_data)
224 IrrecoTheme *self = (IrrecoTheme*) dir_data->user_data_1;
225 IrrecoThemeBg *bg = NULL;
226 IrrecoThemeBg *old_bg = NULL;
227 IRRECO_ENTER
229 bg = irreco_theme_bg_new_from_dir(dir_data->directory);
231 if (irreco_string_table_exists(self->backgrounds, bg->image_name->str)) {
232 IRRECO_ERROR("Error: Background %s has already been read. "
233 "You cannot have two backgrounds with the same name.\n",
234 bg->image_name->str);
235 irreco_string_table_get(self->backgrounds, bg->image_name->str,
236 (gpointer*) &old_bg);
237 irreco_theme_bg_read(old_bg, dir_data->filepath);
238 irreco_theme_bg_free(bg);
239 } else {
240 irreco_string_table_add(self->backgrounds,
241 bg->image_name->str, bg);
243 IRRECO_RETURN
246 IrrecoStringTable* irreco_theme_get_buttons(IrrecoTheme *self)
248 IRRECO_ENTER
249 IRRECO_RETURN_PTR(self->buttons);
252 IrrecoThemeButton *irreco_theme_get_button(IrrecoTheme *self,
253 const char *button_name)
255 IrrecoThemeButton *button = NULL;
256 IRRECO_ENTER
257 IRRECO_STRING_TABLE_FOREACH_DATA(self->buttons, IrrecoThemeButton *,
258 pointer)
259 if (g_utf8_collate(pointer->name->str, button_name) == 0) {
260 button = pointer;
262 IRRECO_STRING_TABLE_FOREACH_END
263 IRRECO_RETURN_PTR(button);
266 IrrecoStringTable* irreco_theme_get_backgrounds(IrrecoTheme *self)
268 IRRECO_ENTER
269 IRRECO_RETURN_PTR(self->backgrounds);
272 IrrecoThemeBg *irreco_theme_get_background(IrrecoTheme *self,
273 const char *bg_name)
275 IrrecoThemeBg *bg = NULL;
276 IRRECO_ENTER
277 IRRECO_STRING_TABLE_FOREACH_DATA(self->backgrounds, IrrecoThemeBg *,
278 pointer)
279 if (g_utf8_collate(pointer->image_name->str, bg_name) == 0) {
280 bg = pointer;
282 IRRECO_STRING_TABLE_FOREACH_END
283 IRRECO_RETURN_PTR(bg);
286 void irreco_theme_set_author(IrrecoTheme *self, const char * author)
288 IRRECO_ENTER
289 if (author != NULL) {
290 g_string_printf(self->author, "%s", author);
292 irreco_theme_update_keyfile(self);
294 IRRECO_RETURN
297 void irreco_theme_set_comment(IrrecoTheme *self, const char * comment)
299 IRRECO_ENTER
300 if (comment != NULL) {
301 g_string_printf(self->comment, "%s", comment);
303 irreco_theme_update_keyfile(self);
305 IRRECO_RETURN
308 void irreco_theme_set_preview_button(IrrecoTheme *self,
309 const char * button_name)
311 IRRECO_ENTER
312 if (button_name != NULL) {
313 g_string_printf(self->preview_button_name, "%s", button_name);
315 irreco_theme_update_keyfile(self);
317 IRRECO_RETURN
321 #if 0
322 /* This function will work after IrrecoButtonStyle destruction*/
324 void irreco_theme_set_name(IrrecoTheme *self, IrrecoData *irreco_data,
325 const char * name)
327 IRRECO_ENTER
328 if (name != NULL) {
329 GString *style_name = g_string_new("");
332 *TODO Move this part to IrrecoThemeManager and call this
333 *funtion from ThemeManager*/
335 irreco_string_table_change_key(
336 irreco_data->theme_manager->themes,
337 self->name->str, name);
339 g_string_printf(self->name, "%s", name);
341 IRRECO_STRING_TABLE_FOREACH_DATA(self->buttons,
342 IrrecoThemeButton *, button) {
343 g_string_printf(button->style_name,"%s/%s",
344 self->name->str,
345 button->name->str);
346 IRRECO_PRINTF("style: %s\n",button->style_name->str);
347 IRRECO_PAUSE
349 IRRECO_STRING_TABLE_FOREACH_END
351 irreco_theme_update_keyfile(self);
352 irreco_config_save_layouts(irreco_data);
353 g_string_free(style_name, TRUE);
355 IRRECO_RETURN
357 #endif
359 void irreco_theme_set(IrrecoTheme *self, const char *name, const char *path,
360 const char *source, const char *author,
361 const char *comment, const char *preview_button_name,
362 const char *version)
364 IRRECO_ENTER
366 if (name != NULL) {
367 g_string_printf(self->name, "%s", name);
368 } else {
369 g_string_erase(self->name, 0, -1);
372 if (path != NULL) {
373 g_string_printf(self->path, "%s", path);
374 } else {
375 g_string_erase(self->path, 0, -1);
378 if (source != NULL) {
379 g_string_printf(self->source, "%s", source);
380 } else {
381 g_string_erase(self->source, 0, -1);
384 if (author != NULL) {
385 g_string_printf(self->author, "%s", author);
386 } else {
387 g_string_erase(self->author, 0, -1);
390 if (comment != NULL) {
391 g_string_printf(self->comment, "%s", comment);
392 } else {
393 g_string_erase(self->comment, 0, -1);
396 if (preview_button_name != NULL) {
397 g_string_printf(self->preview_button_name, "%s",
398 preview_button_name);
399 } else {
400 g_string_erase(self->preview_button_name, 0, -1);
403 if (version != NULL) {
404 g_string_printf(self->version, "%s", version);
405 } else {
406 g_string_erase(self->version, 0, -1);
409 irreco_theme_update_keyfile(self);
411 /* Update buttons */
413 IrrecoDirForeachData button_styles;
414 GString * directory = g_string_new("");
416 g_string_printf(directory, "%s/buttons/", path);
417 IRRECO_DEBUG("Directory = %s\n", directory->str);
418 button_styles.directory = directory->str;
420 button_styles.filesuffix = "button.conf";
421 button_styles.user_data_1 = self;
423 irreco_dir_foreach_subdirectories(&button_styles,
424 irreco_theme_read_button_keyfile_foreach);
426 g_string_free(directory, TRUE);
427 directory = NULL;
429 irreco_string_table_sort_abc(self->buttons);
432 /* Update backgrounds */
434 IrrecoDirForeachData bg_styles;
435 GString * directory = g_string_new("");
437 g_string_printf(directory, "%s/bg/", path);
438 IRRECO_DEBUG("Directory = %s\n", directory->str);
439 bg_styles.directory = directory->str;
441 bg_styles.filesuffix = "bg.conf";
442 bg_styles.user_data_1 = self;
444 irreco_dir_foreach_subdirectories(&bg_styles,
445 irreco_theme_read_bg_keyfile_foreach);
447 g_string_free(directory, TRUE);
448 directory = NULL;
450 irreco_string_table_sort_abc(self->backgrounds);
453 IRRECO_RETURN
456 void irreco_theme_check(IrrecoTheme *self)
458 IRRECO_ENTER
460 /* Check if some background is deleted */
461 IRRECO_STRING_TABLE_FOREACH(self->backgrounds, key, IrrecoThemeBg *,
462 theme_bg)
463 if(!irreco_is_file(theme_bg->image_path->str)) {
464 irreco_string_table_remove(self->backgrounds, key);
466 IRRECO_STRING_TABLE_FOREACH_END
468 /* Check if some button is deleted */
469 IRRECO_STRING_TABLE_FOREACH(self->buttons, key, IrrecoThemeButton *,
470 theme_button)
471 if(!irreco_is_file(theme_button->image_up->str)) {
472 irreco_string_table_remove(self->buttons, key);
474 IRRECO_STRING_TABLE_FOREACH_END
476 IRRECO_RETURN
479 IrrecoTheme *irreco_theme_copy(IrrecoTheme *self)
481 IrrecoTheme *new = NULL;
483 IRRECO_ENTER
485 new = irreco_theme_new();
487 irreco_theme_set(new, self->name->str, self->path->str,
488 self->source->str, self->author->str,
489 self->comment->str, self->preview_button_name->str,
490 self->version->str);
493 IRRECO_STRING_TABLE_FOREACH(self->backgrounds, key, IrrecoThemeBg *,
494 theme_bg)
495 irreco_string_table_add(new->backgrounds, key,
496 irreco_theme_bg_copy(theme_bg));
498 IRRECO_STRING_TABLE_FOREACH_END
501 IRRECO_STRING_TABLE_FOREACH(self->buttons, key, IrrecoThemeButton *,
502 theme_button)
503 irreco_string_table_add(new->buttons, key,
504 irreco_theme_button_copy(theme_button));
506 IRRECO_STRING_TABLE_FOREACH_END
509 IRRECO_RETURN_PTR(new);
513 * IrrecoTheme new from dir
516 IrrecoTheme *irreco_theme_new_from_dir(const gchar *dir)
518 IrrecoTheme *self = NULL;
520 IRRECO_ENTER
521 self = irreco_theme_new();
522 irreco_theme_read(self, dir);
523 IRRECO_RETURN_PTR(self);
526 void irreco_theme_read(IrrecoTheme *self, const gchar *dir)
528 IrrecoKeyFile *keyfile = NULL;
529 char *name = NULL;
530 char *source = NULL;
531 char *author = NULL;
532 char *comment = NULL;
533 char *preview_button = NULL;
534 char *version = NULL;
535 GString *conf = NULL;
536 IRRECO_ENTER
538 conf = g_string_new(dir);
539 g_string_append_printf(conf, "/theme.conf");
540 keyfile = irreco_keyfile_create(dir,
541 conf->str,
542 "theme");
543 if (keyfile == NULL) goto end;
545 /* Required fields. */
546 if (!irreco_keyfile_get_str(keyfile, "name", &name)) {
547 goto end;
550 /* Optional fields. */
551 irreco_keyfile_get_str(keyfile, "source", &source);
552 irreco_keyfile_get_str(keyfile, "author", &author);
553 irreco_keyfile_get_str(keyfile, "comment", &comment);
554 irreco_keyfile_get_str(keyfile, "preview-button", &preview_button);
555 irreco_keyfile_get_str(keyfile, "version", &version);
557 /* call irreco_theme_set() */
558 irreco_theme_set(self, name, dir, source,
559 author, comment, preview_button, version);
561 end:
562 g_string_free(conf, TRUE);
563 if (keyfile != NULL) irreco_keyfile_destroy(keyfile);
564 if (name != NULL) g_free(name);
565 if (source != NULL) g_free(source);
566 if (author != NULL) g_free(author);
567 if (comment != NULL) g_free(comment);
568 if (preview_button != NULL) g_free(preview_button);
569 if (version != NULL) g_free(version);
570 IRRECO_RETURN
574 gboolean irreco_theme_save(IrrecoTheme *self,
575 const gchar *theme_path)
577 gboolean rvalue = FALSE;
578 IrrecoTheme *theme;
579 GString *path;
580 IrrecoStringTable *bg_list = NULL;
581 IrrecoStringTable *button_list = NULL;
582 IRRECO_ENTER
584 /*Create new theme*/
585 theme = irreco_theme_new();
586 irreco_theme_set(theme,
587 self->name->str,
588 theme_path,
589 self->source->str,
590 self->author->str,
591 self->comment->str,
592 self->preview_button_name->str,
593 NULL);
595 irreco_theme_update_keyfile(theme);
598 /* Get buttons and backgrounds */
599 /* Get backrounds */
600 bg_list = irreco_theme_get_backgrounds(self);
602 path = g_string_new("");
603 g_string_printf(path, "%s/bg", theme_path);
604 g_mkdir(path->str, 0777);
606 IRRECO_STRING_TABLE_FOREACH_DATA(bg_list, IrrecoThemeBg *, background)
608 irreco_theme_bg_print(background);
610 irreco_theme_bg_save(background, path->str);
613 IRRECO_STRING_TABLE_FOREACH_END
615 /* Get buttons */
616 button_list = irreco_theme_get_buttons(self);
618 g_string_printf(path, "%s/buttons", theme_path);
619 g_mkdir(path->str, 0777);
621 IRRECO_STRING_TABLE_FOREACH_DATA(button_list, IrrecoThemeButton *, button)
623 if (g_str_equal(self->preview_button_name->str,
624 button->image_up->str) && !rvalue) {
625 irreco_theme_set_preview_button(theme,
626 button->name->str);
627 rvalue = TRUE;
630 irreco_theme_button_save(button, path->str);
631 irreco_theme_button_print(button);
633 IRRECO_STRING_TABLE_FOREACH_END
637 g_string_free(path, TRUE);
638 irreco_theme_free(theme);
640 IRRECO_RETURN_BOOL(rvalue);
644 /** @} */
646 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
647 /* Events and Callbacks */
648 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
650 /** @} */