Commit 4ad69b4e authored by Olivier Teulière's avatar Olivier Teulière

* skins2: experimental support for the <Include file="foo.xml"/> tag.

   Be warned, no DTD validation is done on the included XML file, and the
   loading will fail if it contains several top-level tags.
parent 2887c4ad
...@@ -26,10 +26,24 @@ ...@@ -26,10 +26,24 @@
#include <math.h> #include <math.h>
SkinParser::SkinParser( intf_thread_t *pIntf, const string &rFileName, SkinParser::SkinParser( intf_thread_t *pIntf, const string &rFileName,
const string &rPath ): const string &rPath, bool useDTD, BuilderData *pData ):
XMLParser( pIntf, rFileName ), m_xOffset( 0 ), m_yOffset( 0 ), XMLParser( pIntf, rFileName, useDTD ), m_pData(pData),
m_path( rPath ) m_ownData(pData == NULL), m_xOffset( 0 ), m_yOffset( 0 ), m_path( rPath )
{ {
// Make sure the data is allocated
if( m_pData == NULL )
{
m_pData = new BuilderData();
}
}
SkinParser::~SkinParser()
{
if( m_ownData )
{
delete m_pData;
}
} }
...@@ -45,7 +59,19 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr ) ...@@ -45,7 +59,19 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
m_errors = true; return; \ m_errors = true; return; \
} }
if( rName == "Anchor" ) if( rName == "Include" )
{
RequireDefault( "file" );
msg_Dbg( getIntf(), "Opening included XML file: %s",
convertFileName( attr["file"] ).c_str() );
// FIXME: We do not use the DTD to validate the included XML file,
// as the parser seems to dislike it otherwise...
SkinParser subParser( getIntf(), convertFileName( attr["file"] ),
m_path, false, m_pData );
subParser.parse();
}
else if( rName == "Anchor" )
{ {
RequireDefault( "priority" ); RequireDefault( "priority" );
CheckDefault( "x", "0" ); CheckDefault( "x", "0" );
...@@ -56,7 +82,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr ) ...@@ -56,7 +82,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
const BuilderData::Anchor anchor( atoi( attr["x"] ) + m_xOffset, const BuilderData::Anchor anchor( atoi( attr["x"] ) + m_xOffset,
atoi( attr["y"] ) + m_yOffset, atoi( attr["range"] ), atoi( attr["y"] ) + m_yOffset, atoi( attr["range"] ),
atoi( attr["priority"] ), attr["points"], m_curLayoutId ); atoi( attr["priority"] ), attr["points"], m_curLayoutId );
m_data.m_listAnchor.push_back( anchor ); m_pData->m_listAnchor.push_back( anchor );
} }
else if( rName == "Bitmap" ) else if( rName == "Bitmap" )
...@@ -69,7 +95,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr ) ...@@ -69,7 +95,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
const BuilderData::Bitmap bitmap( m_curBitmapId, const BuilderData::Bitmap bitmap( m_curBitmapId,
convertFileName( attr["file"] ), convertFileName( attr["file"] ),
convertColor( attr["alphacolor"] ) ); convertColor( attr["alphacolor"] ) );
m_data.m_listBitmap.push_back( bitmap ); m_pData->m_listBitmap.push_back( bitmap );
} }
else if( rName == "SubBitmap" ) else if( rName == "SubBitmap" )
...@@ -83,7 +109,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr ) ...@@ -83,7 +109,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
const BuilderData::SubBitmap bitmap( uniqueId( attr["id"] ), const BuilderData::SubBitmap bitmap( uniqueId( attr["id"] ),
m_curBitmapId, atoi( attr["x"] ), atoi( attr["y"] ), m_curBitmapId, atoi( attr["x"] ), atoi( attr["y"] ),
atoi( attr["width"] ), atoi( attr["height"] ) ); atoi( attr["width"] ), atoi( attr["height"] ) );
m_data.m_listSubBitmap.push_back( bitmap ); m_pData->m_listSubBitmap.push_back( bitmap );
} }
else if( rName == "BitmapFont" ) else if( rName == "BitmapFont" )
...@@ -95,7 +121,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr ) ...@@ -95,7 +121,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
const BuilderData::BitmapFont font( attr["id"], const BuilderData::BitmapFont font( attr["id"],
convertFileName( attr["file"] ), convertFileName( attr["file"] ),
attr["type"] ); attr["type"] );
m_data.m_listBitmapFont.push_back( font ); m_pData->m_listBitmapFont.push_back( font );
} }
else if( rName == "Button" ) else if( rName == "Button" )
...@@ -120,7 +146,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr ) ...@@ -120,7 +146,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
attr["tooltiptext"], attr["help"], attr["tooltiptext"], attr["help"],
m_curLayer, m_curWindowId, m_curLayoutId ); m_curLayer, m_curWindowId, m_curLayoutId );
m_curLayer++; m_curLayer++;
m_data.m_listButton.push_back( button ); m_pData->m_listButton.push_back( button );
} }
else if( rName == "Checkbox" ) else if( rName == "Checkbox" )
...@@ -153,7 +179,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr ) ...@@ -153,7 +179,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
attr["tooltiptext2"], attr["help"], m_curLayer, m_curWindowId, attr["tooltiptext2"], attr["help"], m_curLayer, m_curWindowId,
m_curLayoutId ); m_curLayoutId );
m_curLayer++; m_curLayer++;
m_data.m_listCheckbox.push_back( checkbox ); m_pData->m_listCheckbox.push_back( checkbox );
} }
else if( rName == "Font" ) else if( rName == "Font" )
...@@ -165,7 +191,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr ) ...@@ -165,7 +191,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
const BuilderData::Font fontData( uniqueId( attr["id"] ), const BuilderData::Font fontData( uniqueId( attr["id"] ),
convertFileName( attr["file"] ), convertFileName( attr["file"] ),
atoi( attr["size"] ) ); atoi( attr["size"] ) );
m_data.m_listFont.push_back( fontData ); m_pData->m_listFont.push_back( fontData );
} }
else if( rName == "Group" ) else if( rName == "Group" )
...@@ -198,7 +224,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr ) ...@@ -198,7 +224,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
attr["image"], attr["action"], attr["resize"], attr["help"], attr["image"], attr["action"], attr["resize"], attr["help"],
m_curLayer, m_curWindowId, m_curLayoutId ); m_curLayer, m_curWindowId, m_curLayoutId );
m_curLayer++; m_curLayer++;
m_data.m_listImage.push_back( imageData ); m_pData->m_listImage.push_back( imageData );
} }
else if( rName == "Layout" ) else if( rName == "Layout" )
...@@ -216,7 +242,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr ) ...@@ -216,7 +242,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
atoi( attr["height"] ), atoi( attr["minwidth"] ), atoi( attr["height"] ), atoi( attr["minwidth"] ),
atoi( attr["maxwidth"] ), atoi( attr["minheight"] ), atoi( attr["maxwidth"] ), atoi( attr["minheight"] ),
atoi( attr["maxheight"] ), m_curWindowId ); atoi( attr["maxheight"] ), m_curWindowId );
m_data.m_listLayout.push_back( layout ); m_pData->m_listLayout.push_back( layout );
m_curLayer = 0; m_curLayer = 0;
} }
...@@ -252,7 +278,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr ) ...@@ -252,7 +278,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
convertColor( attr["selcolor"] ), attr["help"], convertColor( attr["selcolor"] ), attr["help"],
m_curLayer, m_curWindowId, m_curLayoutId ); m_curLayer, m_curWindowId, m_curLayoutId );
m_curLayer++; m_curLayer++;
m_data.m_listList.push_back( listData ); m_pData->m_listList.push_back( listData );
} }
else if( rName == "Playtree" ) else if( rName == "Playtree" )
...@@ -292,7 +318,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr ) ...@@ -292,7 +318,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
convertColor( attr["selcolor"] ), attr["help"], convertColor( attr["selcolor"] ), attr["help"],
m_curLayer, m_curWindowId, m_curLayoutId ); m_curLayer, m_curWindowId, m_curLayoutId );
m_curLayer++; m_curLayer++;
m_data.m_listTree.push_back( treeData ); m_pData->m_listTree.push_back( treeData );
} }
else if( rName == "RadialSlider" ) else if( rName == "RadialSlider" )
...@@ -320,7 +346,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr ) ...@@ -320,7 +346,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
attr["tooltiptext"], attr["help"], m_curLayer, m_curWindowId, attr["tooltiptext"], attr["help"], m_curLayer, m_curWindowId,
m_curLayoutId ); m_curLayoutId );
m_curLayer++; m_curLayer++;
m_data.m_listRadialSlider.push_back( radial ); m_pData->m_listRadialSlider.push_back( radial );
} }
else if( rName == "Slider" ) else if( rName == "Slider" )
...@@ -364,7 +390,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr ) ...@@ -364,7 +390,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
attr["tooltiptext"], attr["help"], m_curLayer, attr["tooltiptext"], attr["help"], m_curLayer,
m_curWindowId, m_curLayoutId ); m_curWindowId, m_curLayoutId );
m_curLayer++; m_curLayer++;
m_data.m_listSlider.push_back( slider ); m_pData->m_listSlider.push_back( slider );
} }
else if( rName == "Text" ) else if( rName == "Text" )
...@@ -389,7 +415,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr ) ...@@ -389,7 +415,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
convertColor( attr["color"] ), attr["help"], m_curLayer, convertColor( attr["color"] ), attr["help"], m_curLayer,
m_curWindowId, m_curLayoutId ); m_curWindowId, m_curLayoutId );
m_curLayer++; m_curLayer++;
m_data.m_listText.push_back( textData ); m_pData->m_listText.push_back( textData );
} }
else if( rName == "Theme" ) else if( rName == "Theme" )
...@@ -412,7 +438,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr ) ...@@ -412,7 +438,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
atoi( attr["magnet"] ), atoi( attr["magnet"] ),
convertInRange( attr["alpha"], 1, 255, "alpha" ), convertInRange( attr["alpha"], 1, 255, "alpha" ),
convertInRange( attr["movealpha"], 1, 255, "movealpha" ) ); convertInRange( attr["movealpha"], 1, 255, "movealpha" ) );
m_data.m_listTheme.push_back( theme ); m_pData->m_listTheme.push_back( theme );
} }
else if( rName == "ThemeInfo" ) else if( rName == "ThemeInfo" )
...@@ -441,7 +467,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr ) ...@@ -441,7 +467,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
attr["visible"], convertBoolean( attr["autoresize"] ), attr["visible"], convertBoolean( attr["autoresize"] ),
attr["help"], m_curLayer, m_curWindowId, m_curLayoutId ); attr["help"], m_curLayer, m_curWindowId, m_curLayoutId );
m_curLayer++; m_curLayer++;
m_data.m_listVideo.push_back( videoData ); m_pData->m_listVideo.push_back( videoData );
} }
else if( rName == "Window" ) else if( rName == "Window" )
...@@ -459,7 +485,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr ) ...@@ -459,7 +485,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
convertBoolean( attr["visible"] ), convertBoolean( attr["visible"] ),
convertBoolean( attr["dragdrop"] ), convertBoolean( attr["dragdrop"] ),
convertBoolean( attr["playondrop"] ) ); convertBoolean( attr["playondrop"] ) );
m_data.m_listWindow.push_back( window ); m_pData->m_listWindow.push_back( window );
} }
} }
......
...@@ -34,14 +34,17 @@ class SkinParser: public XMLParser ...@@ -34,14 +34,17 @@ class SkinParser: public XMLParser
{ {
public: public:
SkinParser( intf_thread_t *pIntf, const string &rFileName, SkinParser( intf_thread_t *pIntf, const string &rFileName,
const string &rPath ); const string &rPath, bool useDTD = true,
virtual ~SkinParser() {} BuilderData *pData = NULL );
virtual ~SkinParser();
const BuilderData &getData() const { return m_data; } const BuilderData &getData() const { return *m_pData; }
private: private:
/// Container for mapping data from the XML /// Container for mapping data from the XML
BuilderData m_data; BuilderData *m_pData;
/// Indicate whether the class owns the data
bool m_ownData;
/// Current IDs /// Current IDs
string m_curBitmapId; string m_curBitmapId;
string m_curWindowId; string m_curWindowId;
......
...@@ -31,7 +31,8 @@ ...@@ -31,7 +31,8 @@
// Static variable to avoid initializing catalogs twice // Static variable to avoid initializing catalogs twice
static bool m_initialized = false; static bool m_initialized = false;
XMLParser::XMLParser( intf_thread_t *pIntf, const string &rFileName ): XMLParser::XMLParser( intf_thread_t *pIntf, const string &rFileName,
bool useDTD ):
SkinObject( pIntf ) SkinObject( pIntf )
{ {
m_pReader = NULL; m_pReader = NULL;
...@@ -66,7 +67,7 @@ XMLParser::XMLParser( intf_thread_t *pIntf, const string &rFileName ): ...@@ -66,7 +67,7 @@ XMLParser::XMLParser( intf_thread_t *pIntf, const string &rFileName ):
return; return;
} }
xml_ReaderUseDTD( m_pReader, VLC_TRUE ); xml_ReaderUseDTD( m_pReader, useDTD ? VLC_TRUE : VLC_FALSE );
} }
......
...@@ -37,7 +37,8 @@ ...@@ -37,7 +37,8 @@
class XMLParser: public SkinObject class XMLParser: public SkinObject
{ {
public: public:
XMLParser( intf_thread_t *pIntf, const string &rFileName ); XMLParser( intf_thread_t *pIntf, const string &rFileName,
bool useDTD = true );
virtual ~XMLParser(); virtual ~XMLParser();
/// Parse the file. Returns true on success /// Parse the file. Returns true on success
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
--> -->
<!ELEMENT Theme (ThemeInfo,(Bitmap|BitmapFont|Font|Window)*)> <!ELEMENT Theme (ThemeInfo,(Include|Bitmap|BitmapFont|Font|Window)*)>
<!ATTLIST Theme <!ATTLIST Theme
version CDATA #REQUIRED version CDATA #REQUIRED
tooltipfont CDATA "defaultfont" tooltipfont CDATA "defaultfont"
...@@ -12,6 +12,10 @@ ...@@ -12,6 +12,10 @@
> >
<!-- main elements --> <!-- main elements -->
<!ELEMENT Include EMPTY>
<!ATTLIST Include
file CDATA #REQUIRED
>
<!ELEMENT Bitmap (SubBitmap)*> <!ELEMENT Bitmap (SubBitmap)*>
<!ATTLIST Bitmap <!ATTLIST Bitmap
id CDATA #REQUIRED id CDATA #REQUIRED
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment