// // Theme.cc for pekwm // Copyright (C) 2003-2005 Claes Nasten // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "../config.h" #include "ParseUtil.hh" #include "Theme.hh" #include "PScreen.hh" #include "Config.hh" #include "PWinObj.hh" #include "PFont.hh" #include "PTexture.hh" #include "ColorHandler.hh" #include "FontHandler.hh" #include "ImageHandler.hh" #include "TextureHandler.hh" #include "Util.hh" #include #include using std::cerr; using std::endl; using std::string; using std::list; using std::vector; using std::map; // Theme::PDecorButtonData //! @brief Theme::PDecorButtonData constructor. Theme::PDecorButtonData::PDecorButtonData(void) : _left(false), _width(1), _height(1) { for (uint i = 0; i < BUTTON_STATE_NO; ++i) { _texture[i] = NULL; } } //! @brief Theme::PDecorButtonData destructor. Theme::PDecorButtonData::~PDecorButtonData(void) { unload(); } //! @brief Parses CfgParser::Entry op_section, loads and verifies data. //! @param op_section CfgParser::Entry with button configuration. //! @return True if a valid button was parsed. bool Theme::PDecorButtonData::load (CfgParser::Entry *op_section) { if (*op_section == "LEFT") _left = true; else if (*op_section == "RIGHT") _left = false; else return false; op_section = op_section->get_section (); // Get actions. ActionEvent ae; CfgParser::Entry *op_it; for (op_it = op_section->get_section_next (); op_it; op_it = op_it->get_section_next ()) { if (Config::instance ()->parseActionEvent (op_it, ae, BUTTONCLICK_OK, true)) _ae_list.push_back (ae); } // Got some actions, consider it to be a valid button. if (_ae_list.size() > 0) { TextureHandler *th = TextureHandler::instance(); CfgParser::Entry *op_value; op_value = op_section->find_entry ("FOCUSED"); if (op_value) _texture[BUTTON_STATE_FOCUSED] = th->getTexture (op_value->get_value ()); op_value = op_section->find_entry ("UNFOCUSED"); if (op_value) _texture[BUTTON_STATE_UNFOCUSED] = th->getTexture (op_value->get_value ()); op_value = op_section->find_entry ("PRESSED"); if (op_value) _texture[BUTTON_STATE_PRESSED] = th->getTexture (op_value->get_value ()); op_value = op_section->find_entry ("HOOVER"); if (op_value) _texture[BUTTON_STATE_HOOVER] = th->getTexture (op_value->get_value ()); check (); return true; } return false; } //! @brief Unloads data. void Theme::PDecorButtonData::unload(void) { for (uint i = 0; i < BUTTON_STATE_NO; ++i) { TextureHandler::instance()->returnTexture(_texture[i]); _texture[i] = NULL; } } //! @brief Verifies and makes sure no NULL textures exists. void Theme::PDecorButtonData::check(void) { for (uint i = 0; i < BUTTON_STATE_NO; ++i) { if (_texture[i] == NULL) { _texture[i] = TextureHandler::instance()->getTexture("EMPTY"); } } _width = _texture[BUTTON_STATE_FOCUSED]->getWidth(); _height = _texture[BUTTON_STATE_FOCUSED]->getHeight(); if (_width == 0) { cerr << " *** WARNING: button texture width == 0" << endl; _width = 1; } if (_height == 0) { cerr << " *** WARNING: button texture height == 0" << endl; _height = 1; } } // Theme::PDecorData map Theme::PDecorData::_fs_map = map(); map Theme::PDecorData::_border_map = map(); //! @brief Theme::PDecorData constructor. Theme::PDecorData::PDecorData(void) : _title_height(0), _title_width_min(0), _title_width_max(100), _title_width_symetric(true) { // init static data if (!_fs_map.size()) { _fs_map[FOCUSED_STATE_FOCUSED] = "FOCUSED"; _fs_map[FOCUSED_STATE_UNFOCUSED] = "UNFOCUSED"; _fs_map[FOCUSED_STATE_FOCUSED_SELECTED] = "FOCUSEDSELECTED"; _fs_map[FOCUSED_STATE_UNFOCUSED_SELECTED] = "UNFOCUSEDSELECTED"; } if (!_border_map.size()) { _border_map[BORDER_TOP_LEFT] = "TOPLEFT"; _border_map[BORDER_TOP] = "TOP"; _border_map[BORDER_TOP_RIGHT] = "TOPRIGHT"; _border_map[BORDER_LEFT] = "LEFT"; _border_map[BORDER_RIGHT] = "RIGHT"; _border_map[BORDER_BOTTOM_LEFT] = "BOTTOMLEFT"; _border_map[BORDER_BOTTOM] = "BOTTOM"; _border_map[BORDER_BOTTOM_RIGHT] = "BOTTOMRIGHT"; } // init arrays for (uint i = 0; i < DIRECTION_NO; ++i) { _pad[i] = 0; } for (uint i = 0; i < FOCUSED_STATE_NO; ++i) { _texture_tab[i] = NULL; _font[i] = NULL; _font_color[i] = NULL; } for (uint i = 0; i < FOCUSED_STATE_FOCUSED_SELECTED; ++i) { _texture_main[i] = NULL; _texture_separator[i] = NULL; } for (uint i = 0; i < FOCUSED_STATE_FOCUSED_SELECTED; ++i) { for (uint j = 0; j < BORDER_NO_POS; ++j) { _texture_border[i][j] = NULL; } } } //! @brief Theme::PDecorData destructor. Theme::PDecorData::~PDecorData(void) { unload(); } //! @brief Parses CfgParser::Entry op_section, loads and verifies data. //! @param op_section CfgParser::Entry with pdecor configuration. //! @return True if a valid pdecor was parsed. bool Theme::PDecorData::load (CfgParser::Entry *op_section) { CfgParser::Entry *op_value; _name = op_section->get_value (); if (!_name.size ()) { cerr << " *** WARNING: no name identifying decor" << endl; return false; } op_section = op_section->get_section (); CfgParser::Entry *op_sub, *op_sub_2; op_sub = op_section->find_section ("TITLE"); if (!op_sub) { cerr << " *** WARNING: no title section in decor: " << _name << endl; return false; } op_sub = op_sub->get_section (); TextureHandler *th = TextureHandler::instance(); // convenience vector tok; list o_key_list; string o_value_pad, o_value_focused, o_value_unfocused; o_key_list.push_back (new CfgParserKeyInt ("HEIGHT", _title_height, 10, 0)); o_key_list.push_back (new CfgParserKeyInt ("WIDTHMIN", _title_width_min, 0)); o_key_list.push_back (new CfgParserKeyInt ("WIDTHMAX", _title_width_max, 100, 0, 100)); o_key_list.push_back (new CfgParserKeyBool ("WIDTHSYMETRIC", _title_width_symetric)); o_key_list.push_back (new CfgParserKeyString ("PAD", o_value_pad, "0 0 0 0", 7)); o_key_list.push_back (new CfgParserKeyString ("FOCUSED", o_value_focused, "Empty", th->getLengthMin ())); o_key_list.push_back (new CfgParserKeyString ("UNFOCUSED", o_value_unfocused, "Empty", th->getLengthMin ())); op_sub->parse_key_values (o_key_list.begin (), o_key_list.end ()); for_each (o_key_list.begin (), o_key_list.end (), Util::Free()); // Handle parsed data. _texture_main[FOCUSED_STATE_FOCUSED] = th->getTexture(o_value_focused); _texture_main[FOCUSED_STATE_UNFOCUSED] = th->getTexture(o_value_unfocused); if (Util::splitString(o_value_pad, tok, " \t", 4) == 4) { for (uint i = 0; i < DIRECTION_NO; ++i) _pad[i] = strtol (tok[i].c_str (), NULL, 10); } op_sub_2 = op_sub->find_section ("TAB"); if (op_sub_2) { op_sub_2 = op_sub_2->get_section (); for (uint i = 0; i < FOCUSED_STATE_NO; ++i) { op_value = op_sub_2->find_entry (_fs_map[FocusedState (i)]); if (op_value) _texture_tab[i] = th->getTexture (op_value->get_value ()); } } op_sub_2 = op_sub->find_section ("SEPARATOR"); if (op_sub_2) { op_sub_2 = op_sub_2->get_section (); list o_key_list; string o_value_focused, o_value_unfocused; o_key_list.push_back (new CfgParserKeyString ("FOCUSED", o_value_focused, "Empty", th->getLengthMin ())); o_key_list.push_back (new CfgParserKeyString ("UNFOCUSED", o_value_unfocused, "Empty", th->getLengthMin ())); op_sub_2->parse_key_values (o_key_list.begin (), o_key_list.end ()); for_each (o_key_list.begin (), o_key_list.end (), Util::Free()); // Handle parsed data. _texture_separator[FOCUSED_STATE_FOCUSED] = th->getTexture(o_value_focused); _texture_separator[FOCUSED_STATE_UNFOCUSED] = th->getTexture(o_value_unfocused); } op_sub_2 = op_sub->find_section ("FONT"); if (op_sub_2) { op_sub_2 = op_sub_2->get_section (); for (uint i = 0; i < FOCUSED_STATE_NO; ++i) { op_value = op_sub_2->find_entry (_fs_map[FocusedState(i)]); if (op_value) _font[i] = FontHandler::instance()->getFont(op_value->get_value ()); } } else cerr << " *** WARNING: no font section in decor: " << _name << endl; op_sub_2 = op_sub->find_section ("FONTCOLOR"); if (op_sub_2) { op_sub_2 = op_sub_2->get_section (); for (uint i = 0; i < FOCUSED_STATE_NO; ++i) { op_value = op_sub_2->find_entry (_fs_map[FocusedState(i)]); if (op_value) _font_color[i] = FontHandler::instance()->getColor(op_value->get_value ()); } } loadButtons (op_sub->find_section ("BUTTONS")); loadBorder (op_sub->find_section ("BORDER")); check(); return true; } //! @brief Unloads data. void Theme::PDecorData::unload(void) { TextureHandler *th = TextureHandler::instance(); for (uint i = 0; i < FOCUSED_STATE_NO; ++i) { th->returnTexture(_texture_tab[i]); FontHandler::instance()->returnFont(_font[i]); FontHandler::instance()->returnColor(_font_color[i]); _texture_tab[i] = NULL; _font[i] = NULL; _font_color[i] = NULL; } for (uint i = 0; i < FOCUSED_STATE_FOCUSED_SELECTED; ++i) { th->returnTexture(_texture_main[i]); th->returnTexture(_texture_separator[i]); _texture_main[i] = NULL; _texture_separator[i] = NULL; for (uint j = 0; j < BORDER_NO_POS; ++j) { th->returnTexture(_texture_border[i][j]); _texture_border[i][j] = NULL; } } list::iterator it(_button_list.begin()); for (; it != _button_list.end(); ++it) { delete *it; } _button_list.clear(); } //! @brief Checks data properties, prints warning and tries to fix. void Theme::PDecorData::check(void) { // check values if (_title_width_max > 100) { cerr << " *** WARNING: " << _name << " WIDTHMAX > 100" << endl; _title_width_max = 100; } checkTextures(); checkFonts(); checkBorder(); checkColors(); } //! @brief Loads border data. void Theme::PDecorData::loadBorder (CfgParser::Entry *op_section) { if (!op_section) return; op_section = op_section->get_section (); TextureHandler *th = TextureHandler::instance(); // convenience CfgParser::Entry *op_sub, *op_value; op_sub = op_section->find_section ("FOCUSED"); if (op_sub) { op_sub = op_sub->get_section (); for (uint i = 0; i < BORDER_NO_POS; ++i) { op_value = op_sub->find_entry (_border_map[BorderPosition (i)]); if (op_value) { _texture_border[FOCUSED_STATE_FOCUSED][i] = th->getTexture (op_value->get_value ()); } } } op_sub = op_section->find_section ("UNFOCUSED"); if (op_sub) { op_sub = op_sub->get_section (); for (uint i = 0; i < BORDER_NO_POS; ++i) { op_value = op_sub->find_entry (_border_map[BorderPosition (i)]); if (op_value) { _texture_border[FOCUSED_STATE_UNFOCUSED][i] = th->getTexture (op_value->get_value ()); } } } } //! @brief Loads button data. void Theme::PDecorData::loadButtons (CfgParser::Entry *op_section) { if (!op_section) return; op_section = op_section->get_section (); while ((op_section = op_section->get_section_next ()) != NULL) { Theme::PDecorButtonData *btn = new Theme::PDecorButtonData (); if (btn->load (op_section)) _button_list.push_back(btn); else delete btn; } } //! @brief Checks for NULL textures, prints warning and sets empty texture void Theme::PDecorData::checkTextures(void) { for (uint i = 0; i < FOCUSED_STATE_NO; ++i) { if (_texture_tab[i] == NULL) { cerr << " *** WARNING: " << _name << " missing tab texture state " << _fs_map[FocusedState(i)] << endl; _texture_tab[i] = TextureHandler::instance()->getTexture("EMPTY"); } } for (uint i = 0; i < FOCUSED_STATE_FOCUSED_SELECTED; ++i) { if (_texture_main[i] == NULL) { cerr << " *** WARNING: " << _name << " missing main texture state " << _fs_map[FocusedState(i)] << endl; _texture_main[i] = TextureHandler::instance()->getTexture("EMPTY"); } if (_texture_separator[i] == NULL) { cerr << " *** WARNING: " << _name << " missing tab texture state " << _fs_map[FocusedState(i)] << endl; _texture_separator[i] = TextureHandler::instance()->getTexture("EMPTY"); } } } //! @brief Checks for NULL fonts, prints warning and sets empty font void Theme::PDecorData::checkFonts(void) { // the only font that's "obligatory" is the standard focused font, // others are only used if availible so we only check the focused font. if (_font[FOCUSED_STATE_FOCUSED] == NULL) { cerr << " *** WARNING: " << _name << " missing font state " << _fs_map[FOCUSED_STATE_FOCUSED] << endl; _font[FOCUSED_STATE_FOCUSED] = FontHandler::instance()->getFont(""); } } //! @brief Checks for NULL border PTextures. void Theme::PDecorData::checkBorder(void) { for (uint state = FOCUSED_STATE_FOCUSED; state < FOCUSED_STATE_FOCUSED_SELECTED; ++state) { for (uint i = 0; i < BORDER_NO_POS; ++i) { if (_texture_border[state][i] == NULL) { cerr << " *** WARNING: " << _name << " missing border texture " << _border_map[BorderPosition(i)] << " " << _fs_map[FocusedState(state)] << endl; _texture_border[state][i] = TextureHandler::instance()->getTexture("EMPTY"); } } } } //! @brief Checks for NULL colors, prints warning and sets empty color void Theme::PDecorData::checkColors(void) { for (uint i = 0; i < FOCUSED_STATE_NO; ++i) { if (_font_color[i] == NULL) { cerr << " *** WARNING: " << _name << " missing font color state " << _fs_map[FocusedState(i)] << endl; _font_color[i] = FontHandler::instance()->getColor("#000000"); } } } // Theme::PMenuData //! @brief PMenuData constructor Theme::PMenuData::PMenuData(void) { for (uint i = 0; i <= OBJECT_STATE_NO; ++i) { _font[i] = NULL; _color[i] = NULL; _tex_menu[i] = NULL; _tex_item[i] = NULL; _tex_arrow[i] = NULL; } for (uint i = 0; i < OBJECT_STATE_NO; ++i) { _tex_sep[i] = NULL; } for (uint i = 0; i < DIRECTION_NO; ++i) { _pad[i] = 0; } } //! @brief PMenuData destructor Theme::PMenuData::~PMenuData(void) { unload(); } //! @brief Parses CfgParser::Entry op_section, loads and verifies data. //! @param op_section CfgParser::Entry with pmenu configuration. void Theme::PMenuData::load(CfgParser::Entry *op_section) { op_section = op_section->get_section (); CfgParser::Entry *op_value; op_value = op_section->find_entry ("PAD"); if (op_value) { vector tok; if (Util::splitString (op_value->get_value (), tok, " \t", 4) == 4) { for (int i = 0; i < DIRECTION_NO; ++i) _pad[i] = strtol (tok[i].c_str(), NULL, 10); } } op_value = op_section->find_section ("FOCUSED"); if (op_value) loadState (op_value, OBJECT_STATE_FOCUSED); op_value = op_section->find_section ("UNFOCUSED"); if (op_value) loadState (op_value, OBJECT_STATE_UNFOCUSED); op_value = op_section->find_section ("SELECTED"); if (op_value) loadState (op_value, OBJECT_STATE_SELECTED); check(); } //! @brief Unloads data. void Theme::PMenuData::unload(void) { for (uint i = 0; i <= OBJECT_STATE_NO; ++i) { FontHandler::instance()->returnFont(_font[i]); FontHandler::instance()->returnColor(_color[i]); TextureHandler::instance()->returnTexture(_tex_menu[i]); TextureHandler::instance()->returnTexture(_tex_item[i]); TextureHandler::instance()->returnTexture(_tex_arrow[i]); _font[i] = NULL; _color[i] = NULL; _tex_menu[i] = NULL; _tex_item[i] = NULL; _tex_arrow[i] = NULL; } for (uint i = 0; i < OBJECT_STATE_NO; ++i) { TextureHandler::instance()->returnTexture(_tex_sep[i]); _tex_sep[i] = NULL; } } //! @brief Check data properties, prints warning and tries to fix. void Theme::PMenuData::check(void) { for (uint i = 0; i <= OBJECT_STATE_NO; ++i) { if (_font[i] == NULL) { _font[i] = FontHandler::instance()->getFont(""); } if (_color[i] == NULL) { _color[i] = FontHandler::instance()->getColor("#000000"); } if (_tex_menu[i] == NULL) { _tex_menu[i] = TextureHandler::instance()->getTexture("EMPTY"); } if (_tex_item[i] == NULL) { _tex_item[i] = TextureHandler::instance()->getTexture("EMPTY"); } if (_tex_arrow[i] == NULL) { _tex_arrow[i] = TextureHandler::instance()->getTexture("EMPTY"); } } for (uint i = 0; i < OBJECT_STATE_NO; ++i) { if (_tex_sep[i] == NULL) { _tex_sep[i] = TextureHandler::instance()->getTexture("EMPTY"); } } } //! @brief void Theme::PMenuData::loadState (CfgParser::Entry *op_section, ObjectState state) { op_section = op_section->get_section (); list o_key_list; string o_value_font, o_value_background, o_value_item; string o_value_text, o_value_arrow, o_value_separator; o_key_list.push_back (new CfgParserKeyString ("FONT", o_value_font)); o_key_list.push_back (new CfgParserKeyString ("BACKGROUND", o_value_background, "Solid #ffffff")); o_key_list.push_back (new CfgParserKeyString ("ITEM", o_value_item, "Solid #ffffff")); o_key_list.push_back (new CfgParserKeyString ("TEXT", o_value_text, "Solid #000000")); o_key_list.push_back (new CfgParserKeyString ("ARROW", o_value_arrow, "Solid #000000")); if (state < OBJECT_STATE_SELECTED) { o_key_list.push_back (new CfgParserKeyString ("SEPARATOR", o_value_separator, "Solid #000000")); } op_section->parse_key_values (o_key_list.begin (), o_key_list.end ()); for_each (o_key_list.begin (), o_key_list.end (), Util::Free()); TextureHandler *th = TextureHandler::instance (); // Handle parsed data. _font[state] = FontHandler::instance ()->getFont (o_value_font); _tex_menu[state] = th->getTexture (o_value_background); _tex_item[state] = th->getTexture (o_value_item); _color[state] = FontHandler::instance ()->getColor (o_value_text); _tex_arrow[state] = th->getTexture (o_value_arrow); if (state < OBJECT_STATE_SELECTED) _tex_sep[state] = th->getTexture(o_value_separator); } // Theme::TextDialogData //! @brief TextDialogData constructor. Theme::TextDialogData::TextDialogData(void) : _font(NULL), _color(NULL), _tex(NULL) { for (uint i = 0; i < DIRECTION_NO; ++i) { _pad[i] = 0; } } //! @brief TextDialogData destructor. Theme::TextDialogData::~TextDialogData(void) { unload(); } //! @brief Parses CfgParser::Entry op_section, loads and verifies data. //! @param op_section CfgParser::Entry with textdialog configuration. void Theme::TextDialogData::load (CfgParser::Entry *op_section) { op_section = op_section->get_section (); list o_key_list; string o_value_font, o_value_text, o_value_texture, o_value_pad; o_key_list.push_back (new CfgParserKeyString ("FONT", o_value_font)); o_key_list.push_back (new CfgParserKeyString ("TEXT", o_value_text, "#000000")); o_key_list.push_back (new CfgParserKeyString ("TEXTURE", o_value_texture, "Solid #ffffff")); o_key_list.push_back (new CfgParserKeyString ("PAD", o_value_pad, "0 0 0 0", 7)); op_section->parse_key_values (o_key_list.begin (), o_key_list.end ()); for_each (o_key_list.begin (), o_key_list.end (), Util::Free()); // Handle parsed data. _font = FontHandler::instance ()->getFont (o_value_font); _color = FontHandler::instance ()->getColor (o_value_text); _tex = TextureHandler::instance ()->getTexture (o_value_texture); vector tok; if (Util::splitString (o_value_pad, tok, " \t", 4) == 4) { for (uint i = 0; i < DIRECTION_NO; ++i) _pad[i] = strtol(tok[i].c_str(), NULL, 10); } check(); } //! @brief Unloads data. void Theme::TextDialogData::unload(void) { FontHandler::instance()->returnFont(_font); FontHandler::instance()->returnColor(_color); TextureHandler::instance()->returnTexture(_tex); _font = NULL; _tex = NULL; _color = NULL; } //! @brief Check data properties, prints warning and tries to fix. //! @todo print warnings void Theme::TextDialogData::check(void) { if (_font == NULL) { _font = FontHandler::instance()->getFont(""); } if (_color == NULL) { _color = FontHandler::instance()->getColor("#000000"); } if (_tex == NULL) { _tex = TextureHandler::instance()->getTexture("EMPTY"); } } // Theme //! @brief Theme constructor Theme::Theme(PScreen *scr) : _scr(scr), _image_handler(NULL), _is_loaded(false), _invert_gc(None) { // image handler _image_handler = new ImageHandler(); // window gc's XGCValues gv; gv.function = GXinvert; gv.subwindow_mode = IncludeInferiors; gv.line_width = 1; _invert_gc = XCreateGC(_scr->getDpy(), _scr->getRoot(), GCFunction|GCSubwindowMode|GCLineWidth, &gv); _scr->grabServer(); load(Config::instance()->getThemeFile()); _scr->ungrabServer(true); } //! @brief Theme destructor Theme::~Theme(void) { unload(); // should clean things up XFreeGC(_scr->getDpy(), _invert_gc); delete _image_handler; } //! @brief Loads the "ThemeFile", unloads any previous loaded theme. void Theme::load(const std::string &dir) { if (_is_loaded) unload(); CfgParser theme; _theme_dir = dir; if (_theme_dir.size ()) { if (_theme_dir.at (_theme_dir.size() - 1) != '/') _theme_dir.append("/"); } else { cerr << " *** WARNING: empty theme directory name, using default." << endl; _theme_dir = DATADIR "/pekwm/themes/default/"; } string theme_file = _theme_dir + string("theme"); if (!theme.parse (theme_file, CfgParserSource::SOURCE_FILE)) { _theme_dir = DATADIR "/pekwm/themes/default/"; theme_file = _theme_dir + string ("theme"); if (!theme.parse (theme_file, CfgParserSource::SOURCE_FILE)) { cerr << " *** WARNING: couldn't load " << _theme_dir << " or default theme." << endl; } } CfgParser::Entry *op_section, *op_value; // Set image basedir. _image_handler->setDir(_theme_dir); // Load decor data. op_section = theme.get_entry_root ()->find_section ("PDECOR"); if (op_section) { // Get section data, don't need name or value. op_section = op_section->get_section (); //op_section = op_section->get_section (); while ((op_section = op_section->get_section_next ()) != NULL) { Theme::PDecorData *data = new Theme::PDecorData(); if (data->load (op_section)) _pdecordata_map[data->getName()] = data; else delete data; } } if (!getPDecorData ("DEFAULT")) { cerr << " *** WARNING: theme doesn't contain any DEFAULT decor." << endl; // Create DEFAULT decor, let check fill it up with empty but non-null data. Theme::PDecorData *data = new Theme::PDecorData(); data->setName("DEFAULT"); data->check(); _pdecordata_map[data->getName()] = data; } // Load menu data. op_section = theme.get_entry_root ()->find_section ("MENU"); if (op_section) _menu_data.load(op_section); else { cerr << " *** WARNING: missing menu section" << endl; _menu_data.check (); } // Load StatusWindow data. op_section = theme.get_entry_root ()->find_section ("STATUS"); if (op_section) _status_data.load (op_section); else { cerr << " *** WARNING: missing status section" << endl; _status_data.check (); } // Load CmdDialog data. op_section = theme.get_entry_root ()->find_section ("CMDDIALOG"); if (op_section) _cmd_d_data.load (op_section); else { cerr << " *** WARNING: missing cmddialog section" << endl; _cmd_d_data.check (); } #ifdef HARBOUR // Load Harbour texture. op_section = theme.get_entry_root ()->find_section ("HARBOUR"); if (op_section) { op_section = op_section->get_section (); op_value = op_section->find_entry ("TEXTURE"); if (op_value) _harbour_texture = TextureHandler::instance ()->getTexture (op_value->get_value ()); } else cerr << " *** WARNING: missing harbour section" << endl; if (!_harbour_texture) { cerr << " *** WARNING: missing harbour texture" << endl; _harbour_texture = TextureHandler::instance ()->getTexture("EMPTY"); } #endif // HARBOUR // Exec root command. op_section = theme.get_entry_root ()->find_section ("ROOT"); if (op_section) { op_value = op_section->find_entry ("COMMAND"); if (op_value) Util::forkExec (op_value->get_value ()); } _is_loaded = true; } //! @brief Unloads all pixmaps, fonts, gc and colors allocated by the theme. void Theme::unload(void) { map::iterator it(_pdecordata_map.begin()); for (; it != _pdecordata_map.end(); ++it) { delete it->second; } _pdecordata_map.clear(); #ifdef HARBOUR TextureHandler::instance()->returnTexture(_harbour_texture); _harbour_texture = NULL; #endif // HARBOUR // unload menu _menu_data.unload(); _status_data.unload(); _cmd_d_data.unload(); _is_loaded = false; }