~ubuntu-branches/ubuntu/precise/fluxbox/precise

« back to all changes in this revision

Viewing changes to src/FbTk/Theme.cc

  • Committer: Bazaar Package Importer
  • Author(s): Dmitry E. Oboukhov
  • Date: 2008-07-01 10:38:14 UTC
  • mfrom: (2.1.12 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080701103814-khx2b6il152x9p93
Tags: 1.0.0+deb1-8
* x-dev has been removed from build-depends (out-of-date package).
* Standards-Version bumped to 3.8.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Theme.cc for FbTk - Fluxbox ToolKit
2
 
// Copyright (c) 2002 - 2005 Henrik Kinnunen (fluxgen at fluxbox dot org)
3
 
//
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:
10
 
//
11
 
// The above copyright notice and this permission notice shall be included in
12
 
// all copies or substantial portions of the Software.
13
 
//
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.
21
 
 
22
 
// $Id: Theme.cc 3915 2005-03-16 22:44:48Z mathias $
23
 
 
24
 
#include "Theme.hh"
25
 
 
26
 
#include "XrmDatabaseHelper.hh"
27
 
#include "App.hh"
28
 
#include "StringUtil.hh"
29
 
#include "FileUtil.hh"
30
 
#include "I18n.hh"
31
 
#include "Image.hh"
32
 
 
33
 
#ifdef HAVE_CSTDIO
34
 
  #include <cstdio>
35
 
#else
36
 
  #include <stdio.h>
37
 
#endif
38
 
#include <memory>
39
 
#include <iostream>
40
 
 
41
 
using namespace std;
42
 
 
43
 
namespace FbTk {
44
 
 
45
 
Theme::Theme(int screen_num):m_screen_num(screen_num) {
46
 
    ThemeManager::instance().registerTheme(*this);
47
 
}
48
 
 
49
 
Theme::~Theme() {
50
 
    ThemeManager::instance().unregisterTheme(*this);
51
 
}
52
 
 
53
 
ThemeManager &ThemeManager::instance() {
54
 
    static ThemeManager tm;
55
 
    return tm;
56
 
}
57
 
 
58
 
ThemeManager::ThemeManager():
59
 
    // max_screens: we initialize this later so we can set m_verbose 
60
 
    // without having a display connection
61
 
    m_max_screens(-1), 
62
 
    m_verbose(false),
63
 
    m_themelocation("") {
64
 
 
65
 
}
66
 
 
67
 
bool ThemeManager::registerTheme(Theme &tm) {
68
 
    if (m_max_screens < 0)
69
 
        m_max_screens = ScreenCount(FbTk::App::instance()->display());
70
 
 
71
 
    // valid screen num?
72
 
    if (m_max_screens < tm.screenNum() || tm.screenNum() < 0)
73
 
        return false;
74
 
    // TODO: use find and return false if it's already there
75
 
    // instead of unique 
76
 
    m_themelist.push_back(&tm);
77
 
    m_themelist.unique(); 
78
 
    return true;
79
 
}
80
 
 
81
 
bool ThemeManager::unregisterTheme(Theme &tm) {
82
 
    m_themelist.remove(&tm);
83
 
    return true;
84
 
}
85
 
 
86
 
bool ThemeManager::load(const std::string &filename, int screen_num) {
87
 
    std::string location = FbTk::StringUtil::expandFilename(filename);
88
 
    std::string prefix = "";
89
 
 
90
 
    if (FileUtil::isDirectory(filename.c_str())) {
91
 
        prefix = location;
92
 
 
93
 
        location.append("/theme.cfg");
94
 
        if (!FileUtil::isRegularFile(location.c_str())) {
95
 
            location = prefix;
96
 
            location.append("/style.cfg");
97
 
            if (!FileUtil::isRegularFile(location.c_str())) {
98
 
                cerr<<"Error loading theme file "<<location<<": not a regular file"<<endl;
99
 
                return false;
100
 
            }
101
 
        }
102
 
    } else {
103
 
        // dirname
104
 
        prefix = location.substr(0, location.find_last_of('/'));
105
 
    }
106
 
 
107
 
    if (!m_database.load(location.c_str()))
108
 
        return false;
109
 
 
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);
115
 
    }
116
 
 
117
 
    m_themelocation = prefix;
118
 
 
119
 
    location = prefix;
120
 
    Image::addSearchPath(location);
121
 
    location.append("/pixmaps");
122
 
    Image::addSearchPath(location);
123
 
 
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) {
128
 
        if (screen_num < 0)
129
 
            loadTheme(**theme_it);
130
 
        else if (screen_num == (*theme_it)->screenNum()) // specified screen
131
 
            loadTheme(**theme_it);
132
 
            
133
 
    }
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();
141
 
        }
142
 
    }
143
 
    return true;
144
 
}
145
 
 
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)) {
154
 
                if (verbose()) {
155
 
                    _FB_USES_NLS;
156
 
                    cerr<<_FBTKTEXT(Error, ThemeItem, "Failed to read theme item", "When reading a style, couldn't read a specific item (following)")<<": "<<resource->name()<<endl;
157
 
                }
158
 
                resource->setDefaultValue();
159
 
            }
160
 
        }
161
 
    }
162
 
    // send reconfiguration signal to theme and listeners
163
 
}
164
 
 
165
 
bool ThemeManager::loadItem(ThemeItem_base &resource) {
166
 
    return loadItem(resource, resource.name(), resource.altName());
167
 
}
168
 
 
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) {
171
 
    XrmValue value;
172
 
    char *value_type;
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
177
 
    } else
178
 
        return false;
179
 
 
180
 
    return true;
181
 
}
182
 
 
183
 
std::string ThemeManager::resourceValue(const std::string &name, const std::string &altname) {
184
 
    XrmValue value;
185
 
    char *value_type;
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);
189
 
 
190
 
    return "";
191
 
}
192
 
 
193
 
/*
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) {
201
 
            
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;
219
 
            } else {
220
 
                cerr<<(*item)->name()<<":"<<endl;
221
 
            }
222
 
        }
223
 
    }
224
 
             
225
 
}
226
 
*/
227
 
}; // end namespace FbTk