]> git.sesse.net Git - vlc/blob - modules/gui/skins2/src/theme_repository.cpp
* modules/gui/skins2/*: a few portability fixes.
[vlc] / modules / gui / skins2 / src / theme_repository.cpp
1 /*****************************************************************************
2  * theme_repository.cpp
3  *****************************************************************************
4  * Copyright (C) 2004 VideoLAN
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., 59 Temple Place - Suite 330, Boston, MA  02111, 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 = readdir( pDir );
118
119     // While we still have entries in the directory
120     while( pDirContent != NULL )
121     {
122         string name = pDirContent->d_name;
123         if( name.size() > 4 && name.substr( name.size() - 4, 4 ) == ".vlt" )
124         {
125             string path = rDir + sep + name;
126             msg_Dbg( getIntf(), "found skin %s", path.c_str() );
127
128             // Add the theme in the popup menu
129             val.psz_string = (char*)path.c_str();
130             text.psz_string = (char*)name.substr(0, name.size() - 4).c_str();
131             var_Change( getIntf(), "intf-skins", VLC_VAR_ADDCHOICE, &val,
132                         &text );
133         }
134
135         pDirContent = readdir( pDir );
136     }
137
138     closedir( pDir );
139 }
140
141
142
143 int ThemeRepository::changeSkin( vlc_object_t *pIntf, char const *pCmd,
144                                  vlc_value_t oldval, vlc_value_t newval,
145                                  void *pData )
146 {
147     ThemeRepository *pThis = (ThemeRepository*)(pData);
148
149     // Special menu entry for the open skin dialog
150     if( !strcmp( newval.psz_string, kOpenDialog ) )
151     {
152         CmdDlgChangeSkin cmd( pThis->getIntf() );
153         cmd.execute();
154     }
155     else
156     {
157         // Try to load the new skin
158         CmdChangeSkin *pCmd = new CmdChangeSkin( pThis->getIntf(),
159                                                  newval.psz_string );
160         AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
161         pQueue->remove( "change skin" );
162         pQueue->push( CmdGenericPtr( pCmd ) );
163     }
164
165     return VLC_SUCCESS;
166 }
167