20130313
[gdash.git] / src / framework / thememanager.cpp
blob79254ac98441b920893b1d7534290667f58b423d
1 /*
2 * Copyright (c) 2007-2013, Czirkos Zoltan http://code.google.com/p/gdash/
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 #include "config.h"
19 #include "misc/logger.hpp"
20 #include "gfx/pixbuffactory.hpp"
21 #include "gfx/cellrenderer.hpp"
22 #include "settings.hpp"
24 static void add_file_to_themes(PixbufFactory &pf, std::vector<std::string> &themes, const char *filename) {
25 g_assert(filename!=NULL);
27 /* if file name already in themes list, remove. */
28 for (unsigned i=0; i<themes.size(); i++)
29 if (themes[i]!="" && themes[i]==filename) {
30 themes.erase(themes.begin()+i);
31 i--;
34 if (CellRenderer::is_image_ok_for_theme(pf, filename))
35 themes.push_back(filename);
38 static void add_dir_to_themes(PixbufFactory &pf, std::vector<std::string> &themes, const char *directory_name) {
39 Logger l(true); /* do not report error messages */
41 GDir *dir=g_dir_open(directory_name, 0, NULL);
42 if (!dir)
43 /* silently ignore unable-to-open directories */
44 return;
45 char const *name;
46 while ((name=g_dir_read_name(dir)) != NULL) {
47 char *filename=g_build_filename(directory_name, name, NULL);
48 char *lower=g_ascii_strdown(filename, -1);
50 /* we only allow bmp and png files. converted to lowercase, to be able to check for .bmp */
51 if ((g_str_has_suffix(lower, ".bmp") || g_str_has_suffix(lower, ".png")) && g_file_test(filename, G_FILE_TEST_IS_REGULAR))
52 /* try to add the file. */
53 add_file_to_themes(pf, themes, filename);
55 g_free(lower);
56 g_free(filename);
58 g_dir_close(dir);
61 /* will create a list of file names which can be used as themes. */
62 /* the first item will be an empty string to represent the default, built-in theme. */
63 static std::vector<std::string> settings_create_themes_list(PixbufFactory &pf) {
64 std::vector<std::string> themes;
66 themes.push_back(""); /* this symbolizes the default theme */
67 if (gd_theme!="")
68 add_file_to_themes(pf, themes, gd_theme.c_str());
70 for (unsigned i=0; i<gd_themes_dirs.size(); ++i)
71 add_dir_to_themes(pf, themes, gd_themes_dirs[i].c_str());
73 return themes;
77 void load_themes_list(PixbufFactory &pf, std::vector<std::string> &themes, int &themenum) {
78 themes = settings_create_themes_list(pf);
79 themenum = -1;
80 if (gd_theme != "") {
81 for (unsigned n = 1; n < themes.size(); n++)
82 if (themes[n] == gd_theme)
83 themenum = n;
85 else
86 themenum = 0;
87 if (themenum == -1) {
88 gd_warning(CPrintf("theme %s not found in array") % gd_theme);
89 themenum = 0;
94 std::string filename_for_new_theme(const char *theme_to_install) {
95 // create a new filename, with all lowercase letters
96 char *basename=g_path_get_basename(theme_to_install);
97 char *utf8=g_filename_to_utf8(basename, -1, NULL, NULL, NULL);
98 char *lowercase=g_utf8_strdown(utf8, -1);
99 char *lowercase_sys=g_filename_from_utf8(lowercase, -1, NULL, NULL, NULL);
101 // first dir in themes_dirs is the themes dir of the user
102 char *new_filename = g_build_path(G_DIR_SEPARATOR_S, gd_themes_dirs[0].c_str(), lowercase_sys, NULL);
103 g_free(lowercase_sys);
104 g_free(lowercase);
105 g_free(utf8);
106 g_free(basename);
108 std::string ret = new_filename;
109 g_free(new_filename);
110 return ret;
114 bool install_theme(const char *from, const char *to) {
115 // first dir in themes_dirs is the themes dir of the user
116 g_mkdir_with_parents(gd_themes_dirs[0].c_str(), 0700);
117 GError *error=NULL;
118 gchar *contents = NULL;
119 gsize length;
120 gboolean result = g_file_get_contents(from, &contents, &length, &error) && g_file_set_contents(to, contents, length, &error);
121 if (error) {
122 gd_critical(error->message);
123 g_error_free(error);
125 g_free(contents);
126 return result;