skins2: fix RadialSlider
[vlc/asuraparaju-public.git] / modules / gui / skins2 / src / theme_repository.cpp
blob1dc83b1c594b4be84a159f4c208a3ef3e759ffac
1 /*****************************************************************************
2 * theme_repository.cpp
3 *****************************************************************************
4 * Copyright (C) 2004 the VideoLAN team
5 * $Id$
7 * Authors: Cyril Deguet <asmax@via.ecp.fr>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 #include "theme_repository.hpp"
25 #include "os_factory.hpp"
26 #include "../commands/async_queue.hpp"
27 #include "../commands/cmd_dialogs.hpp"
28 #ifdef HAVE_UNISTD_H
29 # include <unistd.h>
30 #elif defined( WIN32 ) && !defined( UNDER_CE )
31 # include <direct.h>
32 #endif
33 #ifdef HAVE_DIRENT_H
34 # include <dirent.h>
35 #endif
37 #include <fstream>
40 ThemeRepository *ThemeRepository::instance( intf_thread_t *pIntf )
42 if( pIntf->p_sys->p_repository == NULL )
44 pIntf->p_sys->p_repository = new ThemeRepository( pIntf );
47 return pIntf->p_sys->p_repository;
51 void ThemeRepository::destroy( intf_thread_t *pIntf )
53 delete pIntf->p_sys->p_repository;
54 pIntf->p_sys->p_repository = NULL;
58 ThemeRepository::ThemeRepository( intf_thread_t *pIntf ): SkinObject( pIntf )
60 vlc_value_t val, text;
62 // Create a variable to add items in wxwindows popup menu
63 var_Create( pIntf, "intf-skins", VLC_VAR_STRING |
64 VLC_VAR_HASCHOICE | VLC_VAR_ISCOMMAND );
65 text.psz_string = _("Select skin");
66 var_Change( pIntf, "intf-skins", VLC_VAR_SETTEXT, &text, NULL );
68 // Scan vlt files in the resource path
69 OSFactory *pOsFactory = OSFactory::instance( pIntf );
70 list<string> resPath = pOsFactory->getResourcePath();
71 list<string>::const_iterator it;
72 for( it = resPath.begin(); it != resPath.end(); it++ )
74 parseDirectory( *it );
77 // retrieve skins from skins directories and locate default skins
78 map<string,string>::const_iterator itmap, itdefault;
79 for( itmap = m_skinsMap.begin(); itmap != m_skinsMap.end(); itmap++ )
81 string name = itmap->first;
82 string path = itmap->second;
83 val.psz_string = (char*) path.c_str();
84 text.psz_string = (char*) name.c_str();
85 var_Change( getIntf(), "intf-skins", VLC_VAR_ADDCHOICE, &val,
86 &text );
88 if( name == "Default" )
89 itdefault = itmap;
92 // retrieve last skins stored or skins requested by user
93 char* psz_current = var_InheritString( getIntf(), "skins2-last" );
94 string current = string( psz_current ? psz_current : "" );
95 free( psz_current );
97 // check if skins exists and is readable
98 bool b_readable = !ifstream( current.c_str() ).fail();
100 msg_Dbg( getIntf(), "requested skins %s is %s accessible",
101 current.c_str(), b_readable ? "" : "NOT" );
103 // set the default skins if given skins not accessible
104 if( !b_readable )
105 current = itdefault->second;
107 // save this valid skins for reuse
108 config_PutPsz( getIntf(), "skins2-last", current.c_str() );
110 // Update repository
111 updateRepository();
113 // Set the callback
114 var_AddCallback( pIntf, "intf-skins", changeSkin, this );
116 // variable for opening a dialog box to change skins
117 var_Create( pIntf, "intf-skins-interactive", VLC_VAR_VOID |
118 VLC_VAR_ISCOMMAND );
119 text.psz_string = _("Open skin ...");
120 var_Change( pIntf, "intf-skins-interactive", VLC_VAR_SETTEXT, &text, NULL );
122 // Set the callback
123 var_AddCallback( pIntf, "intf-skins-interactive", changeSkin, this );
128 ThemeRepository::~ThemeRepository()
130 m_skinsMap.clear();
132 var_DelCallback( getIntf(), "intf-skins", changeSkin, this );
133 var_DelCallback( getIntf(), "intf-skins-interactive", changeSkin, this );
135 var_Destroy( getIntf(), "intf-skins" );
136 var_Destroy( getIntf(), "intf-skins-interactive" );
140 void ThemeRepository::parseDirectory( const string &rDir_locale )
142 DIR *pDir;
143 char *pszDirContent;
144 vlc_value_t val, text;
145 // Path separator
146 const string &sep = OSFactory::instance( getIntf() )->getDirSeparator();
148 // Open the dir
149 // FIXME: parseDirectory should be invoked with UTF-8 input instead!!
150 string rDir = sFromLocale( rDir_locale );
151 pDir = vlc_opendir( rDir.c_str() );
153 if( pDir == NULL )
155 // An error occurred
156 msg_Dbg( getIntf(), "cannot open directory %s", rDir.c_str() );
157 return;
160 // While we still have entries in the directory
161 while( ( pszDirContent = vlc_readdir( pDir ) ) != NULL )
163 string name = pszDirContent;
164 string extension;
165 if( name.size() > 4 )
167 extension = name.substr( name.size() - 4, 4 );
169 if( extension == ".vlt" || extension == ".wsz" )
171 string path = rDir + sep + name;
172 string shortname = name.substr( 0, name.size() - 4 );
173 for( int i = 0; i < shortname.size(); i++ )
174 shortname[i] = ( i == 0 ) ?
175 toupper( shortname[i] ) :
176 tolower( shortname[i] );
177 m_skinsMap[shortname] = path;
179 msg_Dbg( getIntf(), "found skin %s", path.c_str() );
182 free( pszDirContent );
185 closedir( pDir );
190 int ThemeRepository::changeSkin( vlc_object_t *pIntf, char const *pVariable,
191 vlc_value_t oldval, vlc_value_t newval,
192 void *pData )
194 ThemeRepository *pThis = (ThemeRepository*)(pData);
196 if( !strcmp( pVariable, "intf-skins-interactive" ) )
198 CmdDlgChangeSkin cmd( pThis->getIntf() );
199 cmd.execute();
201 else if( !strcmp( pVariable, "intf-skins" ) )
203 // Try to load the new skin
204 CmdChangeSkin *pCmd = new CmdChangeSkin( pThis->getIntf(),
205 newval.psz_string );
206 AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
207 pQueue->push( CmdGenericPtr( pCmd ) );
210 return VLC_SUCCESS;
214 void ThemeRepository::updateRepository()
216 vlc_value_t val, text;
218 // retrieve the current skin
219 char* psz_current = config_GetPsz( getIntf(), "skins2-last" );
220 if( !psz_current )
221 return;
223 val.psz_string = psz_current;
224 text.psz_string = psz_current;
226 // add this new skins if not yet present in repository
227 string current( psz_current );
228 map<string,string>::const_iterator it;
229 for( it = m_skinsMap.begin(); it != m_skinsMap.end(); it++ )
231 if( it->second == current )
232 break;
234 if( it == m_skinsMap.end() )
236 var_Change( getIntf(), "intf-skins", VLC_VAR_ADDCHOICE, &val,
237 &text );
238 string name = psz_current;
239 m_skinsMap[name] = name;
242 // mark this current skins as 'checked' in list
243 var_Change( getIntf(), "intf-skins", VLC_VAR_SETVALUE, &val, NULL );
245 free( psz_current );