@ -23,6 +23,7 @@
# ifdef HAVE_XML
# include <QDomDocument>
# include <QDomNodeList>
# include <QFile>
# endif
@ -98,7 +99,12 @@ PackageItem::PackageItem::PackageItem( const QVariantMap& item_map )
}
# ifdef HAVE_XML
QDomDocument
/** @brief try to load the given @p fileName XML document
*
* Returns a QDomDocument , which will be valid iff the file can
* be read and contains valid XML data .
*/
static inline QDomDocument
loadAppData ( const QString & fileName )
{
QFile file ( fileName ) ;
@ -116,12 +122,138 @@ loadAppData( const QString& fileName )
return doc ;
}
QString
/** @brief gets the text of child element @p tagName
*/
static inline QString
getChildText ( const QDomNode & n , const QString & tagName )
{
QDomElement e = n . firstChildElement ( tagName ) ;
return e . isNull ( ) ? QString ( ) : e . text ( ) ;
}
/** @brief Gets a suitable screenshot path
*
* The < screenshots > element contains zero or more < screenshot >
* elements , which can have a * type * associated with them .
* Scan the screenshot elements , return the < image > path
* for the one labeled with type = default or , if there is no
* default , the first element .
*/
static inline QString
getScreenshotPath ( const QDomNode & n )
{
QDomElement shotsNode = n . firstChildElement ( " screenshots " ) ;
if ( shotsNode . isNull ( ) )
{
return QString ( ) ;
}
const QDomNodeList shotList = shotsNode . childNodes ( ) ;
int firstScreenshot = - 1 ; // Use which screenshot node?
for ( int i = 0 ; i < shotList . count ( ) ; + + i )
{
if ( ! shotList . at ( i ) . isElement ( ) )
{
continue ;
}
QDomElement e = shotList . at ( i ) . toElement ( ) ;
if ( e . tagName ( ) ! = " screenshot " )
{
continue ;
}
// If none has the "type=default" attribute, use the first one
if ( firstScreenshot < 0 )
{
firstScreenshot = i ;
}
// But type=default takes precedence.
if ( e . hasAttribute ( " type " ) & & e . attribute ( " type " ) = = " default " )
{
firstScreenshot = i ;
break ;
}
}
if ( firstScreenshot > = 0 )
{
return shotList . at ( firstScreenshot ) . firstChildElement ( " image " ) . text ( ) ;
}
return QString ( ) ;
}
/** @brief Returns language of the given element @p e
*
* Transforms the attribute value for xml : lang to something
* suitable for TranslatedString ( e . g . [ lang ] ) .
*/
static inline QString
getLanguage ( const QDomElement & e )
{
QString language = e . attribute ( " xml:lang " ) ;
if ( ! language . isEmpty ( ) )
{
language . replace ( ' - ' , ' _ ' ) ;
language . prepend ( ' [ ' ) ;
language . append ( ' ] ' ) ;
}
return language ;
}
/** @brief Scan the list of @p children for @p tagname elements and add them to the map
*
* Uses @ p mapname instead of @ p tagname for the entries in map @ p m
* to allow renaming from XML to map keys ( in particular for
* TranslatedString ) . Also transforms xml : lang attributes to suitable
* key - decorations on @ p mapname .
*/
static inline void
fillMap ( QVariantMap & m , const QDomNodeList & children , const QString & tagname , const QString & mapname )
{
for ( int i = 0 ; i < children . count ( ) ; + + i )
{
if ( ! children . at ( i ) . isElement ( ) )
{
continue ;
}
QDomElement e = children . at ( i ) . toElement ( ) ;
if ( e . tagName ( ) ! = tagname )
{
continue ;
}
m [ mapname + getLanguage ( e ) ] = e . text ( ) ;
}
}
/** @brief gets the <name> and <description> elements
*
* Builds up a map of the < name > elements ( which may have a * lang *
* attribute to indicate translations and paragraphs of the
* < description > element ( also with lang ) . Uses the < summary >
* elements to supplement the description if no description
* is available for a given language .
*
* Returns a map with keys suitable for use by TranslatedString .
*/
static inline QVariantMap
getNameAndSummary ( const QDomNode & n )
{
QVariantMap m ;
const QDomNodeList children = n . childNodes ( ) ;
fillMap ( m , children , " name " , " name " ) ;
fillMap ( m , children , " summary " , " description " ) ;
const QDomElement description = n . firstChildElement ( " description " ) ;
if ( ! description . isNull ( ) )
{
fillMap ( m , description . childNodes ( ) , " p " , " description " ) ;
}
return m ;
}
# endif
PackageItem
@ -129,7 +261,7 @@ PackageItem::fromAppData( const QString& fileName )
{
# ifdef HAVE_XML
cDebug ( ) < < " Loading AppData XML from " < < fileName ;
QDomDocument doc = loadAppData ( fileName ) ;
if ( doc . isNull ( ) )
{
@ -140,13 +272,23 @@ PackageItem::fromAppData( const QString& fileName )
if ( ! componentNode . isNull ( ) & & componentNode . tagName ( ) = = " component " )
{
QString id = getChildText ( componentNode , " id " ) ;
cDebug ( ) < < " Got AppData id " < < id ;
if ( id . isEmpty ( ) )
{
return PackageItem ( ) ;
}
QString screenshotPath = getScreenshotPath ( componentNode ) ;
QVariantMap map = getNameAndSummary ( componentNode ) ;
map . insert ( " id " , id ) ;
map . insert ( " screenshot " , screenshotPath ) ;
return PackageItem ( map ) ;
}
return PackageItem ( ) ;
# else
cWarning ( ) < < " Loading AppData XML is not supported. " ;
return PackageItem ( ) ;
# endif
}