2002-12-02 19:34:54 +00:00
// Theme.cc for FbTk - Fluxbox ToolKit
2003-05-18 22:12:25 +00:00
// Copyright (c) 2002 - 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net)
2002-12-02 19:34:54 +00:00
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
2004-08-26 18:26:39 +00:00
// $Id: Theme.cc,v 1.28 2004/08/26 18:26:39 akir Exp $
2002-12-02 19:34:54 +00:00
# include "Theme.hh"
2003-05-18 22:12:25 +00:00
# include "XrmDatabaseHelper.hh"
2002-12-02 19:34:54 +00:00
# include "App.hh"
2003-08-28 15:12:36 +00:00
# include "StringUtil.hh"
2003-10-13 22:57:14 +00:00
# include "ThemeItems.hh"
2003-11-16 22:33:56 +00:00
# include "Directory.hh"
2004-06-07 11:46:05 +00:00
# include "I18n.hh"
2003-04-28 22:25:13 +00:00
2003-08-22 22:17:30 +00:00
# include <cstdio>
# include <memory>
2002-12-02 19:34:54 +00:00
# include <iostream>
2003-11-16 22:33:56 +00:00
2002-12-02 19:34:54 +00:00
using namespace std ;
2003-08-22 22:17:30 +00:00
2002-12-02 19:34:54 +00:00
namespace FbTk {
Theme : : Theme ( int screen_num ) : m_screen_num ( screen_num ) {
2003-08-28 23:06:27 +00:00
ThemeManager : : instance ( ) . registerTheme ( * this ) ;
2002-12-02 19:34:54 +00:00
}
Theme : : ~ Theme ( ) {
2003-08-28 23:06:27 +00:00
ThemeManager : : instance ( ) . unregisterTheme ( * this ) ;
2002-12-02 19:34:54 +00:00
}
ThemeManager & ThemeManager : : instance ( ) {
static ThemeManager tm ;
return tm ;
}
ThemeManager : : ThemeManager ( ) :
2004-01-02 22:55:35 +00:00
// max_screens: we initialize this later so we can set m_verbose
// without having a display connection
m_max_screens ( - 1 ) ,
2003-11-16 22:33:56 +00:00
m_verbose ( false ) ,
m_themelocation ( " " ) {
2002-12-02 19:34:54 +00:00
}
bool ThemeManager : : registerTheme ( Theme & tm ) {
2004-01-02 22:55:35 +00:00
if ( m_max_screens < 0 )
m_max_screens = ScreenCount ( FbTk : : App : : instance ( ) - > display ( ) ) ;
2002-12-02 19:34:54 +00:00
// valid screen num?
if ( m_max_screens < tm . screenNum ( ) | | tm . screenNum ( ) < 0 )
return false ;
// TODO: use find and return false if it's already there
// instead of unique
m_themelist . push_back ( & tm ) ;
m_themelist . unique ( ) ;
return true ;
}
bool ThemeManager : : unregisterTheme ( Theme & tm ) {
m_themelist . remove ( & tm ) ;
return true ;
}
2003-12-29 11:04:09 +00:00
bool ThemeManager : : load ( const std : : string & filename , int screen_num ) {
2003-12-03 00:18:58 +00:00
std : : string location = FbTk : : StringUtil : : expandFilename ( filename ) ;
2003-11-16 22:33:56 +00:00
std : : string prefix = " " ;
if ( Directory : : isDirectory ( filename ) ) {
prefix = location ;
location . append ( " /theme.cfg " ) ;
if ( ! Directory : : isRegularFile ( location ) ) {
2004-08-26 18:26:39 +00:00
location = prefix ;
location . append ( " /style.cfg " ) ;
if ( ! Directory : : isRegularFile ( location ) ) {
cerr < < " Error loading theme file " < < location < < " : not a regular file " < < endl ;
return false ;
}
2003-11-16 22:33:56 +00:00
}
} else {
// dirname
prefix = location . substr ( 0 , location . find_last_of ( ' / ' ) ) ;
}
if ( ! m_database . load ( location . c_str ( ) ) )
2002-12-02 19:34:54 +00:00
return false ;
2003-11-16 22:33:56 +00:00
// relies on the fact that load_rc clears search paths each time
if ( m_themelocation ! = " " ) {
Image : : removeSearchPath ( m_themelocation ) ;
m_themelocation . append ( " /pixmaps " ) ;
Image : : removeSearchPath ( m_themelocation ) ;
}
m_themelocation = prefix ;
location = prefix ;
Image : : addSearchPath ( location ) ;
location . append ( " /pixmaps " ) ;
Image : : addSearchPath ( location ) ;
2003-12-29 11:04:09 +00:00
// get list and go throu all the resources and load them
2002-12-02 19:34:54 +00:00
ThemeList : : iterator theme_it = m_themelist . begin ( ) ;
const ThemeList : : iterator theme_it_end = m_themelist . end ( ) ;
for ( ; theme_it ! = theme_it_end ; + + theme_it ) {
2003-12-29 11:04:09 +00:00
if ( screen_num < 0 )
loadTheme ( * * theme_it ) ;
else if ( screen_num = = ( * theme_it ) - > screenNum ( ) ) // specified screen
loadTheme ( * * theme_it ) ;
2002-12-02 19:34:54 +00:00
}
2003-08-11 14:54:18 +00:00
// notify all themes that we reconfigured
theme_it = m_themelist . begin ( ) ;
for ( ; theme_it ! = theme_it_end ; + + theme_it ) {
// send reconfiguration signal to theme and listeners
( * theme_it ) - > reconfigTheme ( ) ;
( * theme_it ) - > reconfigSig ( ) . notify ( ) ;
}
2002-12-02 19:34:54 +00:00
return true ;
}
void ThemeManager : : loadTheme ( Theme & tm ) {
std : : list < ThemeItem_base * > : : iterator i = tm . itemList ( ) . begin ( ) ;
std : : list < ThemeItem_base * > : : iterator i_end = tm . itemList ( ) . end ( ) ;
for ( ; i ! = i_end ; + + i ) {
ThemeItem_base * resource = * i ;
2003-08-19 21:25:26 +00:00
if ( ! loadItem ( * resource ) ) {
// try fallback resource in theme
if ( ! tm . fallback ( * resource ) ) {
2004-06-07 11:46:05 +00:00
if ( verbose ( ) ) {
_FB_USES_NLS ;
cerr < < _FBTKTEXT ( Error , ThemeItem , " Failed to read theme item " , " When reading a style, couldn't read a specific item (following) " ) < < " : " < < resource - > name ( ) < < endl ;
}
resource - > setDefaultValue ( ) ;
2003-08-19 21:25:26 +00:00
}
}
2002-12-02 19:34:54 +00:00
}
2003-08-11 14:54:18 +00:00
// send reconfiguration signal to theme and listeners
2002-12-02 19:34:54 +00:00
}
2003-08-19 21:25:26 +00:00
bool ThemeManager : : loadItem ( ThemeItem_base & resource ) {
return loadItem ( resource , resource . name ( ) , resource . altName ( ) ) ;
}
/// handles resource item loading with specific name/altname
bool ThemeManager : : loadItem ( ThemeItem_base & resource , const std : : string & name , const std : : string & alt_name ) {
2003-08-13 09:24:02 +00:00
XrmValue value ;
char * value_type ;
2003-08-19 21:25:26 +00:00
if ( XrmGetResource ( * m_database , name . c_str ( ) ,
alt_name . c_str ( ) , & value_type , & value ) ) {
2003-08-13 09:24:02 +00:00
resource . setFromString ( value . addr ) ;
2004-04-26 15:04:37 +00:00
resource . load ( & name , & alt_name ) ; // load additional stuff by the ThemeItem
2003-08-19 21:25:26 +00:00
} else
return false ;
return true ;
2003-08-13 09:24:02 +00:00
}
2002-12-02 19:34:54 +00:00
std : : string ThemeManager : : resourceValue ( const std : : string & name , const std : : string & altname ) {
XrmValue value ;
char * value_type ;
if ( * m_database ! = 0 & & XrmGetResource ( * m_database , name . c_str ( ) ,
2004-04-26 15:04:37 +00:00
altname . c_str ( ) , & value_type , & value ) & & value . addr ! = 0 )
2002-12-02 19:34:54 +00:00
return string ( value . addr ) ;
2004-04-26 15:04:37 +00:00
2002-12-02 19:34:54 +00:00
return " " ;
}
2003-08-22 22:17:30 +00:00
/*
2003-09-14 11:17:21 +00:00
void ThemeManager : : listItems ( ) {
ThemeList : : iterator it = m_themelist . begin ( ) ;
ThemeList : : iterator it_end = m_themelist . end ( ) ;
for ( ; it ! = it_end ; + + it ) {
std : : list < ThemeItem_base * > : : iterator item = ( * it ) - > itemList ( ) . begin ( ) ;
std : : list < ThemeItem_base * > : : iterator item_end = ( * it ) - > itemList ( ) . end ( ) ;
for ( ; item ! = item_end ; + + item ) {
if ( typeid ( * * item ) = = typeid ( ThemeItem < Texture > ) ) {
cerr < < ( * item ) - > name ( ) < < " : <texture type> " < < endl ;
cerr < < ( * item ) - > name ( ) < < " .pixmap: <filename> " < < endl ;
cerr < < ( * item ) - > name ( ) < < " .color: <color> " < < endl ;
cerr < < ( * item ) - > name ( ) < < " .colorTo: <color> " < < endl ;
} else if ( typeid ( * * item ) = = typeid ( ThemeItem < Color > ) ) {
cerr < < ( * item ) - > name ( ) < < " : <color> " < < endl ;
} else if ( typeid ( * * item ) = = typeid ( ThemeItem < int > ) ) {
cerr < < ( * item ) - > name ( ) < < " : <integer> " < < endl ;
} else if ( typeid ( * * item ) = = typeid ( ThemeItem < bool > ) ) {
cerr < < ( * item ) - > name ( ) < < " : <boolean> " < < endl ;
} else if ( typeid ( * * item ) = = typeid ( ThemeItem < PixmapWithMask > ) ) {
cerr < < ( * item ) - > name ( ) < < " : <filename> " < < endl ;
} else if ( typeid ( * * item ) = = typeid ( ThemeItem < std : : string > ) ) {
cerr < < ( * item ) - > name ( ) < < " : <string> " < < endl ;
} else if ( typeid ( * * item ) = = typeid ( ThemeItem < Font > ) ) {
cerr < < ( * item ) - > name ( ) < < " : <font> " < < endl ;
} else {
cerr < < ( * item ) - > name ( ) < < " : " < < endl ;
}
}
}
2003-08-22 22:17:30 +00:00
2003-09-14 11:17:21 +00:00
}
2003-08-22 22:17:30 +00:00
*/
2002-12-02 19:34:54 +00:00
} ; // end namespace FbTk