Modified theme editing.
[irreco.git] / irreco / src / core / irreco_theme.c
blobce91e4b03beccd7d219e947395544117bcb0161b
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);
76 IRRECO_RETURN_PTR(self);
80 # if 0
81 IrrecoTheme *irreco_theme_new()
83 IrrecoTheme *self;
84 IRRECO_ENTER
86 self = g_slice_new0(IrrecoTheme);
88 self->name = g_string_new(name);
89 self->path = g_string_new(path);
90 self->source = g_string_new(source);
91 self->author = g_string_new(author);
92 self->comment = g_string_new(comment);
93 self->preview_button_name = g_string_new(preview_button_name);
94 self->version = g_string_new(version);
95 self->backgrounds = irreco_string_table_new(
96 (GDestroyNotify)irreco_theme_bg_free, NULL);
97 self->buttons = irreco_string_table_new(
98 (GDestroyNotify)irreco_theme_button_free, NULL);
100 IRRECO_DEBUG("Themepath: %s\n", path);
102 /*Get buttons*/
104 IrrecoDirForeachData button_styles;
105 GString * directory = g_string_new("");
107 g_string_printf(directory, "%s/buttons/", path);
108 IRRECO_DEBUG("Directory = %s\n", directory->str);
109 button_styles.directory = directory->str;
111 button_styles.filesuffix = "button.conf";
112 button_styles.user_data_1 = self;
114 irreco_dir_foreach_subdirectories(&button_styles,
115 irreco_theme_read_button_keyfile_foreach);
117 g_string_free(directory, TRUE);
118 directory = NULL;
120 irreco_string_table_sort_abc(self->buttons);
123 /*Get backgrounds*/
125 IrrecoDirForeachData bg_styles;
126 GString * directory = g_string_new("");
128 g_string_printf(directory, "%s/bg/", path);
129 IRRECO_DEBUG("Directory = %s\n", directory->str);
130 bg_styles.directory = directory->str;
132 bg_styles.filesuffix = "bg.conf";
133 bg_styles.user_data_1 = self;
135 irreco_dir_foreach_subdirectories(&bg_styles,
136 irreco_theme_read_bg_keyfile_foreach);
138 g_string_free(directory, TRUE);
139 directory = NULL;
141 irreco_string_table_sort_abc(self->backgrounds);
144 IRRECO_RETURN_PTR(self);
146 #endif
147 void irreco_theme_free(IrrecoTheme *self)
149 IRRECO_ENTER
151 g_assert(self != NULL);
153 g_string_free(self->name, TRUE);
154 self->name = NULL;
156 g_string_free(self->path, TRUE);
157 self->path = NULL;
159 g_string_free(self->source, TRUE);
160 self->source = NULL;
162 g_string_free(self->author, TRUE);
163 self->author = NULL;
165 g_string_free(self->comment, TRUE);
166 self->comment = NULL;
168 g_string_free(self->preview_button_name, TRUE);
169 self->preview_button_name = NULL;
171 irreco_string_table_free(self->backgrounds);
172 self->backgrounds = NULL;
174 irreco_string_table_free(self->buttons);
175 self->buttons = NULL;
177 g_slice_free(IrrecoTheme, self);
178 self = NULL;
180 IRRECO_RETURN
183 /** @} */
185 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
186 /* Private Functions */
187 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
190 * @name Private Functions
191 * @{
195 /** @} */
197 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
198 /* Public Functions */
199 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
202 * @name Public Functions
203 * @{
205 void irreco_theme_update_keyfile(IrrecoTheme *self)
207 GString *keyfile_path = g_string_new(self->path->str);
208 GKeyFile *keyfile = g_key_file_new();
209 IRRECO_ENTER
211 g_string_append(keyfile_path, "/theme.conf");
213 irreco_gkeyfile_set_string(keyfile, "theme" , "name",
214 self->name->str);
216 if (self->source->len > 0) {
217 irreco_gkeyfile_set_string(keyfile, "theme" , "source",
218 self->source->str);
221 if (self->author->len > 0) {
222 irreco_gkeyfile_set_string(keyfile, "theme", "author",
223 self->author->str);
226 if (self->preview_button_name->len > 0) {
227 irreco_gkeyfile_set_string(keyfile, "theme", "preview-button",
228 self->preview_button_name->str);
231 if (self->version->len > 0) {
232 irreco_gkeyfile_set_string(keyfile, "theme", "version",
233 self->version->str);
236 if (self->comment->len > 0) {
237 irreco_gkeyfile_set_string(keyfile, "theme", "comment",
238 self->comment->str);
241 irreco_write_keyfile(keyfile, keyfile_path->str);
243 g_key_file_free(keyfile);
244 g_string_free(keyfile_path, TRUE);
245 IRRECO_RETURN
248 void irreco_theme_print(IrrecoTheme *self)
250 IRRECO_ENTER
252 IRRECO_DEBUG("Themename: %s \n", self->name->str);
253 IRRECO_DEBUG("Folder: %s \n", self->path->str);
254 IRRECO_DEBUG("Source: %s \n", self->source->str);
255 IRRECO_DEBUG("Author: %s \n", self->author->str);
256 IRRECO_DEBUG("Comment: %s \n", self->comment->str);
257 IRRECO_DEBUG("Previewbutton: %s \n", self->preview_button_name->str);
258 IRRECO_DEBUG("Version: %s \n", self->version->str);
259 irreco_string_table_print(self->backgrounds);
260 irreco_string_table_print(self->buttons);
262 IRRECO_RETURN
265 void irreco_theme_read_button_keyfile_foreach(IrrecoDirForeachData * dir_data)
267 IrrecoTheme *self = (IrrecoTheme*) dir_data->user_data_1;
268 IrrecoThemeButton *button = NULL;
269 IRRECO_ENTER
271 button = irreco_theme_button_new_from_dir(dir_data->directory);
273 if (irreco_string_table_exists(self->buttons, button->name->str)) {
274 IRRECO_ERROR("Error: Button %s has already been read. "
275 "You cannot have two buttons with the same name.\n",
276 button->name->str);
277 irreco_theme_button_free(button);
278 } else {
279 irreco_string_table_add(self->buttons,
280 button->name->str, button);
285 IRRECO_RETURN
288 void irreco_theme_read_bg_keyfile_foreach(IrrecoDirForeachData * dir_data)
290 IrrecoTheme *self = (IrrecoTheme*) dir_data->user_data_1;
291 IrrecoThemeBg *bg = NULL;
292 IRRECO_ENTER
294 bg = irreco_theme_bg_new_from_dir(dir_data->directory);
296 if (irreco_string_table_exists(self->backgrounds, bg->image_name->str)) {
297 IRRECO_ERROR("Error: Background %s has already been read. "
298 "You cannot have two backgrounds with the same name.\n",
299 bg->image_name->str);
300 irreco_theme_bg_free(bg);
301 } else {
302 irreco_string_table_add(self->backgrounds,
303 bg->image_name->str, bg);
307 IRRECO_RETURN
310 IrrecoStringTable* irreco_theme_get_buttons(IrrecoTheme *self)
312 IRRECO_ENTER
313 IRRECO_RETURN_PTR(self->buttons);
316 IrrecoThemeButton *irreco_theme_get_button(IrrecoTheme *self,
317 const char *button_name)
319 IrrecoThemeButton *button = NULL;
320 IRRECO_ENTER
321 IRRECO_STRING_TABLE_FOREACH_DATA(self->buttons, IrrecoThemeButton *,
322 pointer)
323 if (g_utf8_collate(pointer->name->str, button_name) == 0) {
324 button = pointer;
326 IRRECO_STRING_TABLE_FOREACH_END
327 IRRECO_RETURN_PTR(button);
330 IrrecoStringTable* irreco_theme_get_backgrounds(IrrecoTheme *self)
332 IRRECO_ENTER
333 IRRECO_RETURN_PTR(self->backgrounds);
336 IrrecoThemeBg *irreco_theme_get_background(IrrecoTheme *self,
337 const char *bg_name)
339 IrrecoThemeBg *bg = NULL;
340 IRRECO_ENTER
341 IRRECO_STRING_TABLE_FOREACH_DATA(self->backgrounds, IrrecoThemeBg *,
342 pointer)
343 if (g_utf8_collate(pointer->image_name->str, bg_name) == 0) {
344 bg = pointer;
346 IRRECO_STRING_TABLE_FOREACH_END
347 IRRECO_RETURN_PTR(bg);
350 void irreco_theme_set_author(IrrecoTheme *self, const char * author)
352 IRRECO_ENTER
353 if (author != NULL) {
354 g_string_printf(self->author, "%s", author);
356 irreco_theme_update_keyfile(self);
358 IRRECO_RETURN
361 void irreco_theme_set_comment(IrrecoTheme *self, const char * comment)
363 IRRECO_ENTER
364 if (comment != NULL) {
365 g_string_printf(self->comment, "%s", comment);
367 irreco_theme_update_keyfile(self);
369 IRRECO_RETURN
372 void irreco_theme_set_preview_button(IrrecoTheme *self,
373 const char * button_name)
375 IRRECO_ENTER
376 if (button_name != NULL) {
377 g_string_printf(self->preview_button_name, "%s", button_name);
379 irreco_theme_update_keyfile(self);
381 IRRECO_RETURN
385 #if 0
386 /* This function will work after IrrecoButtonStyle destruction*/
388 void irreco_theme_set_name(IrrecoTheme *self, IrrecoData *irreco_data,
389 const char * name)
391 IRRECO_ENTER
392 if (name != NULL) {
393 GString *style_name = g_string_new("");
396 *TODO Move this part to IrrecoThemeManager and call this
397 *funtion from ThemeManager*/
399 irreco_string_table_change_key(
400 irreco_data->theme_manager->themes,
401 self->name->str, name);
403 g_string_printf(self->name, "%s", name);
405 IRRECO_STRING_TABLE_FOREACH_DATA(self->buttons,
406 IrrecoThemeButton *, button) {
407 g_string_printf(button->style_name,"%s/%s",
408 self->name->str,
409 button->name->str);
410 IRRECO_PRINTF("style: %s\n",button->style_name->str);
411 IRRECO_PAUSE
413 IRRECO_STRING_TABLE_FOREACH_END
415 irreco_theme_update_keyfile(self);
416 irreco_config_save_layouts(irreco_data);
417 g_string_free(style_name, TRUE);
419 IRRECO_RETURN
421 #endif
423 void irreco_theme_set(IrrecoTheme *self, const char *name, const char *path,
424 const char *source, const char *author,
425 const char *comment, const char *preview_button_name,
426 const char *version)
428 IRRECO_ENTER
430 if (name != NULL) {
431 g_string_printf(self->name, "%s", name);
432 } else {
433 g_string_erase(self->name, 0, -1);
436 if (path != NULL) {
437 g_string_printf(self->path, "%s", path);
438 } else {
439 g_string_erase(self->path, 0, -1);
442 if (source != NULL) {
443 g_string_printf(self->source, "%s", source);
444 } else {
445 g_string_erase(self->source, 0, -1);
448 if (author != NULL) {
449 g_string_printf(self->author, "%s", author);
450 } else {
451 g_string_erase(self->author, 0, -1);
454 if (comment != NULL) {
455 g_string_printf(self->comment, "%s", comment);
456 } else {
457 g_string_erase(self->comment, 0, -1);
460 if (preview_button_name != NULL) {
461 g_string_printf(self->preview_button_name, "%s",
462 preview_button_name);
463 } else {
464 g_string_erase(self->preview_button_name, 0, -1);
467 if (version != NULL) {
468 g_string_printf(self->version, "%s", version);
469 } else {
470 g_string_erase(self->version, 0, -1);
473 irreco_theme_update_keyfile(self);
475 /* Update buttons */
477 IrrecoDirForeachData button_styles;
478 GString * directory = g_string_new("");
480 g_string_printf(directory, "%s/buttons/", path);
481 IRRECO_DEBUG("Directory = %s\n", directory->str);
482 button_styles.directory = directory->str;
484 button_styles.filesuffix = "button.conf";
485 button_styles.user_data_1 = self;
487 irreco_dir_foreach_subdirectories(&button_styles,
488 irreco_theme_read_button_keyfile_foreach);
490 g_string_free(directory, TRUE);
491 directory = NULL;
493 irreco_string_table_sort_abc(self->buttons);
496 /* Update backgrounds */
498 IrrecoDirForeachData bg_styles;
499 GString * directory = g_string_new("");
501 g_string_printf(directory, "%s/bg/", path);
502 IRRECO_DEBUG("Directory = %s\n", directory->str);
503 bg_styles.directory = directory->str;
505 bg_styles.filesuffix = "bg.conf";
506 bg_styles.user_data_1 = self;
508 irreco_dir_foreach_subdirectories(&bg_styles,
509 irreco_theme_read_bg_keyfile_foreach);
511 g_string_free(directory, TRUE);
512 directory = NULL;
514 irreco_string_table_sort_abc(self->backgrounds);
517 IRRECO_RETURN
520 void irreco_theme_check(IrrecoTheme *self)
522 IRRECO_ENTER
524 /* Check if some background is deleted */
525 IRRECO_STRING_TABLE_FOREACH(self->backgrounds, key, IrrecoThemeBg *,
526 theme_bg)
527 if(!irreco_is_file(theme_bg->image_path->str)) {
528 irreco_string_table_remove(self->backgrounds, key);
530 IRRECO_STRING_TABLE_FOREACH_END
532 /* Check if some button is deleted */
533 IRRECO_STRING_TABLE_FOREACH(self->buttons, key, IrrecoThemeButton *,
534 theme_button)
535 if(!irreco_is_file(theme_button->image_up->str)) {
536 irreco_string_table_remove(self->buttons, key);
538 IRRECO_STRING_TABLE_FOREACH_END
540 IRRECO_RETURN
543 IrrecoTheme *irreco_theme_copy(IrrecoTheme *self)
545 IrrecoTheme *new = NULL;
547 IRRECO_ENTER
549 new = irreco_theme_new();
551 irreco_theme_set(new, self->name->str, self->path->str,
552 self->source->str, self->author->str,
553 self->comment->str, self->preview_button_name->str,
554 self->version->str);
557 IRRECO_STRING_TABLE_FOREACH(self->backgrounds, key, IrrecoThemeBg *,
558 theme_bg)
559 irreco_string_table_add(new->backgrounds, key,
560 irreco_theme_bg_copy(theme_bg));
562 IRRECO_STRING_TABLE_FOREACH_END
565 IRRECO_STRING_TABLE_FOREACH(self->buttons, key, IrrecoThemeButton *,
566 theme_button)
567 irreco_string_table_add(new->buttons, key,
568 irreco_theme_button_copy(theme_button));
570 IRRECO_STRING_TABLE_FOREACH_END
573 IRRECO_RETURN_PTR(new);
577 * IrrecoTheme new from dir
580 IrrecoTheme *irreco_theme_new_from_dir(const gchar *dir)
582 IrrecoTheme *self = NULL;
584 IRRECO_ENTER
586 self = irreco_theme_new();
587 irreco_theme_read(self, dir);
588 IRRECO_RETURN_PTR(self);
591 void irreco_theme_read(IrrecoTheme *self, const gchar *dir)
593 IrrecoKeyFile *keyfile = NULL;
594 char *name = NULL;
595 char *source = NULL;
596 char *author = NULL;
597 char *comment = NULL;
598 char *preview_button = NULL;
599 char *version = NULL;
600 GString *conf = NULL;
601 IRRECO_ENTER
603 conf = g_string_new(dir);
604 g_string_append_printf(conf, "/theme.conf");
605 keyfile = irreco_keyfile_create(dir,
606 conf->str,
607 "theme");
609 /* Required fields. */
610 irreco_keyfile_get_str(keyfile, "name", &name);
612 /* Optional fields. */
613 irreco_keyfile_get_str(keyfile, "source", &source);
614 irreco_keyfile_get_str(keyfile, "author", &author);
615 irreco_keyfile_get_str(keyfile, "comment", &comment);
616 irreco_keyfile_get_str(keyfile, "preview-button", &preview_button);
617 irreco_keyfile_get_str(keyfile, "version", &version);
619 /* call irreco_theme_set() */
620 irreco_theme_set(self, name, dir, source,
621 author, comment, preview_button, version);
623 g_string_free(conf, TRUE);
624 if (keyfile != NULL) irreco_keyfile_destroy(keyfile);
625 if (name != NULL) g_free(name);
626 if (source != NULL) g_free(source);
627 if (author != NULL) g_free(author);
628 if (comment != NULL) g_free(comment);
629 if (preview_button != NULL) g_free(preview_button);
630 if (version != NULL) g_free(version);
631 IRRECO_RETURN
635 gboolean irreco_theme_save(IrrecoTheme *self, IrrecoData *irreco_data,
636 const gchar *theme_path)
638 gboolean rvalue = FALSE;
639 IrrecoTheme *theme;
640 GString *path;
641 IrrecoStringTable *bg_list = NULL;
642 IrrecoStringTable *button_list = NULL;
643 IRRECO_ENTER
645 /*Create new theme*/
646 theme = irreco_theme_new();
647 irreco_theme_set(theme,
648 self->name->str,
649 theme_path,
650 self->source->str,
651 self->author->str,
652 self->comment->str,
653 self->preview_button_name->str,
654 NULL);
656 irreco_theme_update_keyfile(theme);
659 /* Get buttons and backgrounds */
660 /* Get backrounds */
661 bg_list = irreco_theme_get_backgrounds(self);
663 path = g_string_new("");
664 g_string_printf(path, "%s/bg", theme_path);
665 g_mkdir(path->str, 0777);
667 IRRECO_STRING_TABLE_FOREACH_DATA(bg_list, IrrecoThemeBg *, background)
669 irreco_theme_bg_print(background);
671 irreco_theme_bg_save(background, path->str);
674 IRRECO_STRING_TABLE_FOREACH_END
676 /* Get buttons */
677 button_list = irreco_theme_get_buttons(self);
679 g_string_printf(path, "%s/buttons", theme_path);
680 g_mkdir(path->str, 0777);
682 IRRECO_STRING_TABLE_FOREACH_DATA(button_list, IrrecoThemeButton *, button)
684 if (g_str_equal(self->preview_button_name->str,
685 button->image_up->str) && !rvalue) {
686 irreco_theme_set_preview_button(theme,
687 button->name->str);
688 rvalue = TRUE;
691 irreco_theme_button_save(button, path->str);
692 irreco_theme_button_print(button);
694 IRRECO_STRING_TABLE_FOREACH_END
698 g_string_free(path, TRUE);
699 irreco_theme_free(theme);
701 IRRECO_RETURN_BOOL(rvalue);
705 /** @} */
707 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
708 /* Events and Callbacks */
709 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
711 /** @} */