]> git.sesse.net Git - vlc/blob - modules/gui/skins2/src/theme_repository.cpp
5e4819bdbd4817f46f0e0ac3cd1878a3d6fe5458
[vlc] / modules / gui / skins2 / src / theme_repository.cpp
1 /*****************************************************************************
2  * theme_repository.cpp
3  *****************************************************************************
4  * Copyright (C) 2004 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Cyril Deguet     <asmax@via.ecp.fr>
8  *
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.
13  *
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.
18  *
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  *****************************************************************************/
23
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
36
37
38
39 ThemeRepository *ThemeRepository::instance( intf_thread_t *pIntf )
40 {
41     if( pIntf->p_sys->p_repository == NULL )
42     {
43         pIntf->p_sys->p_repository = new ThemeRepository( pIntf );
44     }
45
46     return pIntf->p_sys->p_repository;
47 }
48
49
50 void ThemeRepository::destroy( intf_thread_t *pIntf )
51 {
52     delete pIntf->p_sys->p_repository;
53     pIntf->p_sys->p_repository = NULL;
54 }
55
56
57 ThemeRepository::ThemeRepository( intf_thread_t *pIntf ): SkinObject( pIntf )
58 {
59     vlc_value_t val, text;
60
61     // Create a variable to add items in wxwindows popup menu
62     var_Create( pIntf, "intf-skins", VLC_VAR_STRING |
63                 VLC_VAR_HASCHOICE | VLC_VAR_ISCOMMAND );
64     text.psz_string = _("Select skin");
65     var_Change( pIntf, "intf-skins", VLC_VAR_SETTEXT, &text, NULL );
66
67     // Scan vlt files in the resource path
68     OSFactory *pOsFactory = OSFactory::instance( pIntf );
69     list<string> resPath = pOsFactory->getResourcePath();
70     list<string>::const_iterator it;
71     for( it = resPath.begin(); it != resPath.end(); it++ )
72     {
73         parseDirectory( *it );
74     }
75
76     // Set the callback
77     var_AddCallback( pIntf, "intf-skins", changeSkin, this );
78
79
80     // variable for opening a dialog box to change skins
81     var_Create( pIntf, "intf-skins-interactive", VLC_VAR_VOID |
82                 VLC_VAR_ISCOMMAND );
83     text.psz_string = _("Open skin ...");
84     var_Change( pIntf, "intf-skins-interactive", VLC_VAR_SETTEXT, &text, NULL );
85
86     // Set the callback
87     var_AddCallback( pIntf, "intf-skins-interactive", changeSkin, this );
88
89 }
90
91
92 ThemeRepository::~ThemeRepository()
93 {
94     var_Destroy( getIntf(), "intf-skins" );
95 }
96
97
98 void ThemeRepository::parseDirectory( const string &rDir_locale )
99 {
100     DIR *pDir;
101     char *pszDirContent;
102     vlc_value_t val, text;
103     // Path separator
104     const string &sep = OSFactory::instance( getIntf() )->getDirSeparator();
105
106     // Open the dir
107     // FIXME: parseDirectory should be invoked with UTF-8 input instead!!
108     string rDir = sFromLocale( rDir_locale );
109     pDir = utf8_opendir( rDir.c_str() );
110
111     if( pDir == NULL )
112     {
113         // An error occurred
114         msg_Dbg( getIntf(), "cannot open directory %s", rDir.c_str() );
115         return;
116     }
117
118     // While we still have entries in the directory
119     while( ( pszDirContent = utf8_readdir( pDir ) ) != NULL )
120     {
121         string name = pszDirContent;
122         string extension;
123         if( name.size() > 4 )
124         {
125             extension = name.substr( name.size() - 4, 4 );
126         }
127         if( extension == ".vlt" || extension == ".wsz" )
128         {
129             string path = rDir + sep + name;
130             msg_Dbg( getIntf(), "found skin %s", path.c_str() );
131
132             // Add the theme in the popup menu
133             string shortname = name.substr( 0, name.size() - 4 );
134             val.psz_string = strdup( path.c_str() );
135             text.psz_string = strdup( shortname.c_str() );
136             var_Change( getIntf(), "intf-skins", VLC_VAR_ADDCHOICE, &val,
137                         &text );
138             free( val.psz_string );
139             free( text.psz_string );
140         }
141
142         free( pszDirContent );
143     }
144
145     closedir( pDir );
146 }
147
148
149
150 int ThemeRepository::changeSkin( vlc_object_t *pIntf, char const *pVariable,
151                                  vlc_value_t oldval, vlc_value_t newval,
152                                  void *pData )
153 {
154     ThemeRepository *pThis = (ThemeRepository*)(pData);
155
156     if( !strcmp( pVariable, "intf-skins-interactive" ) )
157     {
158         CmdDlgChangeSkin cmd( pThis->getIntf() );
159         cmd.execute();
160     }
161     else if( !strcmp( pVariable, "intf-skins" ) )
162     {
163         // Try to load the new skin
164         CmdChangeSkin *pCmd = new CmdChangeSkin( pThis->getIntf(),
165                                                  newval.psz_string );
166         AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
167         pQueue->push( CmdGenericPtr( pCmd ) );
168     }
169
170     return VLC_SUCCESS;
171 }
172