#define SKINS_DTD_VERSION "2.0"
-SkinParser::SkinParser( intf_thread_t *pIntf, const string &rFileName ):
- XMLParser( pIntf, rFileName ), m_xOffset( 0 ), m_yOffset( 0 )
+SkinParser::SkinParser( intf_thread_t *pIntf, const string &rFileName,
+ const string &rPath ):
+ XMLParser( pIntf, rFileName ), m_xOffset( 0 ), m_yOffset( 0 ),
+ m_path( rPath )
{
}
else if( rName == "Bitmap" )
{
- const BuilderData::Bitmap bitmap( attr["id"] , attr["file"],
+ const BuilderData::Bitmap bitmap( attr["id"] ,
+ ConvertFileName( attr["file"] ),
ConvertColor( attr["alphacolor"] ) );
m_data.m_listBitmap.push_back( bitmap );
}
else if( rName == "BitmapFont" )
{
- const BuilderData::BitmapFont font( attr["id"] , attr["file"],
+ const BuilderData::BitmapFont font( attr["id"],
+ ConvertFileName( attr["file"] ),
attr["type"] );
m_data.m_listBitmapFont.push_back( font );
}
else if( rName == "Font" )
{
- const BuilderData::Font fontData( attr["id"], attr["file"],
+ const BuilderData::Font fontData( attr["id"],
+ ConvertFileName( attr["file"] ),
atoi( attr["size"] ) );
m_data.m_listFont.push_back( fontData );
}
return ( iRed << 16 | iGreen << 8 | iBlue );
}
+string SkinParser::ConvertFileName( const char *fileName ) const
+{
+ return m_path + string( fileName );
+}
+
const string SkinParser::generateId() const
{
static int i = 1;
* skin_parser.hpp
*****************************************************************************
* Copyright (C) 2004 VideoLAN
- * $Id: skin_parser.hpp,v 1.2 2004/03/01 18:33:31 asmax Exp $
+ * $Id$
*
* Authors: Cyril Deguet <asmax@via.ecp.fr>
*
class SkinParser: public XMLParser
{
public:
- SkinParser( intf_thread_t *pIntf, const string &rFileName );
+ SkinParser( intf_thread_t *pIntf, const string &rFileName,
+ const string &rPath );
virtual ~SkinParser() {}
const BuilderData &getData() const { return m_data; }
int m_curLayer;
/// Set of used id
set<string> m_idSet;
+ /// Path of the XML file being parsed
+ const string m_path;
/// Callbacks
- virtual void handleBeginElement( const string &rName, AttrList_t &attr );
+ virtual void handleBeginElement( const string &rName,
+ AttrList_t &attr );
virtual void handleEndElement( const string &rName );
/// Helper functions
bool ConvertBoolean( const char *value ) const;
int ConvertColor( const char *transcolor ) const;
+ string ConvertFileName( const char *fileName ) const;
/// Generate a new id
const string generateId() const;
#include "../src/os_factory.hpp"
#include "../src/window_manager.hpp"
-#include <fcntl.h>
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
#if !defined( WIN32 )
# include <unistd.h>
#else
# include <direct.h>
#endif
+#if (!defined( WIN32 ) || defined(__MINGW32__))
+/* Mingw has its own version of dirent */
+# include <dirent.h>
+#endif
+
#if defined( HAVE_ZLIB_H )
# include <zlib.h>
if( ! extractTarGz( fileName, tempPath ) )
return false;
- // Parse the extracted XML file
- const string &sep = OSFactory::instance( getIntf() )->getDirSeparator();
- if( ! parse( tempPath + sep + string( DEFAULT_XML_FILE ) ) )
+ // Find the XML file and parse it
+ string xmlFile;
+ if( ! findThemeFile( tempPath, xmlFile ) || ! parse( xmlFile ) )
{
msg_Err( getIntf(), "%s doesn't contain a " DEFAULT_XML_FILE " file",
fileName.c_str() );
// File loaded
msg_Dbg( getIntf(), "Using skin file: %s", xmlFile.c_str() );
- // Save current working directory
- char *cwd = new char[PATH_MAX];
- getcwd( cwd, PATH_MAX );
-
- // Change current working directory to xml file
+ // Extract the path of the XML file
+ string path;
const string &sep = OSFactory::instance( getIntf() )->getDirSeparator();
unsigned int p = xmlFile.rfind( sep, xmlFile.size() );
if( p != string::npos )
{
- string path = xmlFile.substr( 0, p );
- chdir( path.c_str() );
+ path = xmlFile.substr( 0, p + 1 );
+ }
+ else
+ {
+ path = "";
}
// Start the parser
- SkinParser parser( getIntf(), xmlFile );
- bool ret = parser.parse();
- if( !ret )
+ SkinParser parser( getIntf(), xmlFile, path );
+ if( ! parser.parse() )
{
msg_Err( getIntf(), "Failed to parse %s", xmlFile.c_str() );
- // Set old working directory to current
- chdir( cwd );
- delete[] cwd;
return false;
}
Builder builder( getIntf(), parser.getData() );
getIntf()->p_sys->p_theme = builder.build();
- // Set old working directory to current.
- // We need to do that _after_ calling Builder:build(), otherwise the
- // opening of the files will fail
- chdir( cwd );
- delete[] cwd;
-
return true;
}
+bool ThemeLoader::findThemeFile( const string &rootDir, string &themeFilePath )
+{
+ // Path separator
+ const string &sep = OSFactory::instance( getIntf() )->getDirSeparator();
+
+ DIR *pCurrDir;
+ struct dirent *pDirContent;
+
+ // Open the dir
+ pCurrDir = opendir( rootDir.c_str() );
+
+ if( pCurrDir == NULL )
+ {
+ // An error occurred
+ msg_Dbg( getIntf(), "Cannot open directory %s", rootDir.c_str() );
+ return false;
+ }
+
+ // Get the first directory entry
+ pDirContent = readdir( pCurrDir );
+
+ // While we still have entries in the directory
+ while( pDirContent != NULL )
+ {
+ string newURI = rootDir + sep + pDirContent->d_name;
+
+ // Skip . and ..
+ if( string( pDirContent->d_name ) != "." &&
+ string( pDirContent->d_name ) != ".." )
+ {
+#if defined( S_ISDIR )
+ struct stat stat_data;
+ stat( newURI.c_str(), &stat_data );
+ if( S_ISDIR(stat_data.st_mode) )
+#elif defined( DT_DIR )
+ if( pDirContent->d_type == DT_DIR )
+#else
+ if( 0 )
+#endif
+ {
+ // Can we find the theme file in this subdirectory?
+ if( findThemeFile( newURI, themeFilePath ) )
+ {
+ return true;
+ }
+ }
+ else
+ {
+ // Found the theme file?
+ if( string( DEFAULT_XML_FILE ) ==
+ string( pDirContent->d_name ) )
+ {
+ themeFilePath = newURI;
+ return true;
+ }
+ }
+ }
+
+ pDirContent = readdir( pCurrDir );
+ }
+
+ return false;
+}
+
+
#if !defined( HAVE_LIBTAR_H ) && defined( HAVE_ZLIB_H )
#ifdef WIN32
* theme_loader.hpp
*****************************************************************************
* Copyright (C) 2003 VideoLAN
- * $Id: theme_loader.hpp,v 1.1 2004/01/03 23:31:34 asmax Exp $
+ * $Id$
*
* Authors: Cyril Deguet <asmax@via.ecp.fr>
* Olivier Teulière <ipkiss@via.ecp.fr>
private:
#if defined( HAVE_ZLIB_H )
- bool extractTarGz( const string &tarFile, const string &rootDir );
+ /// Extract files from an archive (currently only handles tar.gz)
bool extract( const string &fileName );
+
+ /// Extract files from a tar.gz archive
+ bool extractTarGz( const string &tarFile, const string &rootDir );
+
+ /// Clean up the temporary files created by the extraction
void deleteTempFiles( const string &path );
#endif
+
+ /// Parse the XML file given as a parameter and build the skin
bool parse( const string &xmlFile );
+
+ /// Recursively look for the XML file from rootDir.
+ /// The first corresponding file found will be chosen and themeFilePath
+ /// will be updated accordingly.
+ /// The method returns true if a theme file was found, false otherwise
+ bool findThemeFile( const string &rootDir, string &themeFilePath );
};
#endif