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