1
// Theme.cc for FbTk - Fluxbox ToolKit
2
// Copyright (c) 2002 - 2005 Henrik Kinnunen (fluxgen at fluxbox dot org)
4
// Permission is hereby granted, free of charge, to any person obtaining a
5
// copy of this software and associated documentation files (the "Software"),
6
// to deal in the Software without restriction, including without limitation
7
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
// and/or sell copies of the Software, and to permit persons to whom the
9
// Software is furnished to do so, subject to the following conditions:
11
// The above copyright notice and this permission notice shall be included in
12
// all copies or substantial portions of the Software.
14
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20
// DEALINGS IN THE SOFTWARE.
22
// $Id: Theme.cc 3915 2005-03-16 22:44:48Z mathias $
26
#include "XrmDatabaseHelper.hh"
28
#include "StringUtil.hh"
29
#include "FileUtil.hh"
45
Theme::Theme(int screen_num):m_screen_num(screen_num) {
46
ThemeManager::instance().registerTheme(*this);
50
ThemeManager::instance().unregisterTheme(*this);
53
ThemeManager &ThemeManager::instance() {
54
static ThemeManager tm;
58
ThemeManager::ThemeManager():
59
// max_screens: we initialize this later so we can set m_verbose
60
// without having a display connection
67
bool ThemeManager::registerTheme(Theme &tm) {
68
if (m_max_screens < 0)
69
m_max_screens = ScreenCount(FbTk::App::instance()->display());
72
if (m_max_screens < tm.screenNum() || tm.screenNum() < 0)
74
// TODO: use find and return false if it's already there
76
m_themelist.push_back(&tm);
81
bool ThemeManager::unregisterTheme(Theme &tm) {
82
m_themelist.remove(&tm);
86
bool ThemeManager::load(const std::string &filename, int screen_num) {
87
std::string location = FbTk::StringUtil::expandFilename(filename);
88
std::string prefix = "";
90
if (FileUtil::isDirectory(filename.c_str())) {
93
location.append("/theme.cfg");
94
if (!FileUtil::isRegularFile(location.c_str())) {
96
location.append("/style.cfg");
97
if (!FileUtil::isRegularFile(location.c_str())) {
98
cerr<<"Error loading theme file "<<location<<": not a regular file"<<endl;
104
prefix = location.substr(0, location.find_last_of('/'));
107
if (!m_database.load(location.c_str()))
110
// relies on the fact that load_rc clears search paths each time
111
if (m_themelocation != "") {
112
Image::removeSearchPath(m_themelocation);
113
m_themelocation.append("/pixmaps");
114
Image::removeSearchPath(m_themelocation);
117
m_themelocation = prefix;
120
Image::addSearchPath(location);
121
location.append("/pixmaps");
122
Image::addSearchPath(location);
124
// get list and go throu all the resources and load them
125
ThemeList::iterator theme_it = m_themelist.begin();
126
const ThemeList::iterator theme_it_end = m_themelist.end();
127
for (; theme_it != theme_it_end; ++theme_it) {
129
loadTheme(**theme_it);
130
else if (screen_num == (*theme_it)->screenNum()) // specified screen
131
loadTheme(**theme_it);
134
// notify all themes that we reconfigured
135
theme_it = m_themelist.begin();
136
for (; theme_it != theme_it_end; ++theme_it) {
137
// send reconfiguration signal to theme and listeners
138
if (screen_num < 0 || (*theme_it)->screenNum() == screen_num) {
139
(*theme_it)->reconfigTheme();
140
(*theme_it)->reconfigSig().notify();
146
void ThemeManager::loadTheme(Theme &tm) {
147
std::list<ThemeItem_base *>::iterator i = tm.itemList().begin();
148
std::list<ThemeItem_base *>::iterator i_end = tm.itemList().end();
149
for (; i != i_end; ++i) {
150
ThemeItem_base *resource = *i;
151
if (!loadItem(*resource)) {
152
// try fallback resource in theme
153
if (!tm.fallback(*resource)) {
156
cerr<<_FBTKTEXT(Error, ThemeItem, "Failed to read theme item", "When reading a style, couldn't read a specific item (following)")<<": "<<resource->name()<<endl;
158
resource->setDefaultValue();
162
// send reconfiguration signal to theme and listeners
165
bool ThemeManager::loadItem(ThemeItem_base &resource) {
166
return loadItem(resource, resource.name(), resource.altName());
169
/// handles resource item loading with specific name/altname
170
bool ThemeManager::loadItem(ThemeItem_base &resource, const std::string &name, const std::string &alt_name) {
173
if (XrmGetResource(*m_database, name.c_str(),
174
alt_name.c_str(), &value_type, &value)) {
175
resource.setFromString(value.addr);
176
resource.load(&name, &alt_name); // load additional stuff by the ThemeItem
183
std::string ThemeManager::resourceValue(const std::string &name, const std::string &altname) {
186
if (*m_database != 0 && XrmGetResource(*m_database, name.c_str(),
187
altname.c_str(), &value_type, &value) && value.addr != 0)
188
return string(value.addr);
194
void ThemeManager::listItems() {
195
ThemeList::iterator it = m_themelist.begin();
196
ThemeList::iterator it_end = m_themelist.end();
197
for (; it != it_end; ++it) {
198
std::list<ThemeItem_base *>::iterator item = (*it)->itemList().begin();
199
std::list<ThemeItem_base *>::iterator item_end = (*it)->itemList().end();
200
for (; item != item_end; ++item) {
202
if (typeid(**item) == typeid(ThemeItem<Texture>)) {
203
cerr<<(*item)->name()<<": <texture type>"<<endl;
204
cerr<<(*item)->name()<<".pixmap: <filename>"<<endl;
205
cerr<<(*item)->name()<<".color: <color>"<<endl;
206
cerr<<(*item)->name()<<".colorTo: <color>"<<endl;
207
} else if (typeid(**item) == typeid(ThemeItem<Color>)) {
208
cerr<<(*item)->name()<<": <color>"<<endl;
209
} else if (typeid(**item) == typeid(ThemeItem<int>)) {
210
cerr<<(*item)->name()<<": <integer>"<<endl;
211
} else if (typeid(**item) == typeid(ThemeItem<bool>)) {
212
cerr<<(*item)->name()<<": <boolean>"<<endl;
213
} else if (typeid(**item) == typeid(ThemeItem<PixmapWithMask>)) {
214
cerr<<(*item)->name()<<": <filename>"<<endl;
215
} else if (typeid(**item) == typeid(ThemeItem<std::string>)) {
216
cerr<<(*item)->name()<<": <string>"<<endl;
217
} else if (typeid(**item) == typeid(ThemeItem<Font>)) {
218
cerr<<(*item)->name()<<": <font>"<<endl;
220
cerr<<(*item)->name()<<":"<<endl;
227
}; // end namespace FbTk