"Fossies" - the Fresh Open Source Software Archive

Member "amarok-2.9.0/src/core-impl/playlists/types/file/xspf/XSPFPlaylist.cpp" (28 Feb 2018, 22403 Bytes) of package /linux/misc/amarok-2.9.0.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "XSPFPlaylist.cpp" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes reports: 2.8.90_vs_2.9.0 or 2.8.0_vs_2.9.0.

    1 /****************************************************************************************
    2  * Copyright (c) 2006 Mattias Fliesberg <mattias.fliesberg@gmail.com>                   *
    3  * Copyright (c) 2007 Ian Monroe <ian@monroe.nu>                                        *
    4  * Copyright (c) 2007 Bart Cerneels <bart.cerneels@kde.org>                             *
    5  *                                                                                      *
    6  * This program is free software; you can redistribute it and/or modify it under        *
    7  * the terms of the GNU General Public License as published by the Free Software        *
    8  * Foundation; either version 2 of the License, or (at your option) any later           *
    9  * version.                                                                             *
   10  *                                                                                      *
   11  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
   12  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
   13  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
   14  *                                                                                      *
   15  * You should have received a copy of the GNU General Public License along with         *
   16  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
   17  ****************************************************************************************/
   18 
   19 #define DEBUG_PREFIX "XSPFPlaylist"
   20 
   21 #include "XSPFPlaylist.h"
   22 
   23 #include "core/capabilities/StreamInfoCapability.h"
   24 #include "core/support/Debug.h"
   25 #include "core-impl/collections/support/CollectionManager.h"
   26 #include "core-impl/meta/stream/Stream.h"
   27 #include "playlist/PlaylistController.h"
   28 #include "playlist/PlaylistModelStack.h"
   29 
   30 using namespace Playlists;
   31 using namespace Playlist;
   32 
   33 XSPFPlaylist::XSPFPlaylist( const KUrl &url, Playlists::PlaylistProvider *provider, OnLoadAction onLoad )
   34     : PlaylistFile( url, provider )
   35     , QDomDocument()
   36     , m_autoAppendAfterLoad( onLoad == AppendToPlaylist )
   37 {
   38 }
   39 
   40 XSPFPlaylist::~XSPFPlaylist()
   41 {
   42 }
   43 
   44 void
   45 XSPFPlaylist::savePlaylist(QFile &file)
   46 {
   47     // if trackList item exists than no need to setup new file
   48     if ( documentElement().namedItem( "trackList" ).isNull() )
   49     {
   50         QDomElement root = createElement( "playlist" );
   51 
   52         root.setAttribute( "version", 1 );
   53         root.setAttribute( "xmlns", "http://xspf.org/ns/0/" );
   54 
   55         root.appendChild( createElement( "trackList" ) );
   56 
   57         appendChild( root );
   58     }
   59 
   60     setTrackList( tracks(), false );
   61 
   62     QTextStream stream( &file );
   63     stream.setCodec( "UTF-8" );
   64     QDomDocument::save( stream, 2 /*indent*/, QDomNode::EncodingFromTextStream );
   65 }
   66 
   67 bool
   68 XSPFPlaylist::processContent( QByteArray &content )
   69 {
   70     QString errorMsg;
   71     int errorLine, errorColumn;
   72 
   73     if( !setContent( content, &errorMsg, &errorLine, &errorColumn ) )
   74     {
   75         error() << "Error loading xml file: " "(" << errorMsg << ")"
   76                 << " at line " << errorLine << ", column " << errorColumn;
   77         m_tracksLoaded = false;
   78     }
   79     else
   80         m_tracksLoaded = true;
   81     return m_tracksLoaded;
   82 }
   83 
   84 void
   85 XSPFPlaylist::load()
   86 {
   87     XSPFTrackList xspfTracks = trackList();
   88 
   89     foreach( const XSPFTrack &track, xspfTracks )
   90     {
   91        MetaProxy::TrackPtr proxyTrack( new MetaProxy::Track( track.location ) );
   92        //Fill in values from xspf..
   93        proxyTrack->setTitle( track.title );
   94        proxyTrack->setAlbum( track.album );
   95        proxyTrack->setArtist( track.creator );
   96        proxyTrack->setLength( track.duration );
   97        proxyTrack->setTrackNumber( track.trackNum );
   98        Meta::TrackPtr metaTrack( proxyTrack.data() );
   99        addProxyTrack( metaTrack );
  100      }
  101 
  102     //FIXME: this needs to be moved to whatever is creating the XSPFPlaylist
  103     if( m_autoAppendAfterLoad )
  104         The::playlistController()->insertPlaylist(
  105                     ModelStack::instance()->bottom()->rowCount(),
  106                     Playlists::PlaylistPtr( this )
  107                 );
  108 }
  109 
  110 bool
  111 XSPFPlaylist::loadXSPF( QTextStream &stream )
  112 {
  113     QByteArray content = stream.readAll().toUtf8();
  114     if ( !processContent( content ) )
  115         return false;
  116     load();
  117 
  118     return true;
  119 }
  120 
  121 bool
  122 XSPFPlaylist::loadXSPF( QByteArray &content )
  123 {
  124     if ( !processContent( content ) )
  125         return false;
  126     load();
  127 
  128     return true;
  129 }
  130 
  131 QString
  132 XSPFPlaylist::name() const
  133 {
  134     if ( m_tracksLoaded )
  135         return title();
  136     else
  137         return m_url.fileName();
  138 }
  139 
  140 QString
  141 XSPFPlaylist::title() const
  142 {
  143     return documentElement().namedItem( "title" ).firstChild().nodeValue();
  144 }
  145 
  146 QString
  147 XSPFPlaylist::creator() const
  148 {
  149     return documentElement().namedItem( "creator" ).firstChild().nodeValue();
  150 }
  151 
  152 QString
  153 XSPFPlaylist::annotation() const
  154 {
  155     return documentElement().namedItem( "annotation" ).firstChild().nodeValue();
  156 }
  157 
  158 KUrl
  159 XSPFPlaylist::info() const
  160 {
  161     return KUrl( documentElement().namedItem( "info" ).firstChild().nodeValue() );
  162 }
  163 
  164 KUrl
  165 XSPFPlaylist::location() const
  166 {
  167     return KUrl( documentElement().namedItem( "location" ).firstChild().nodeValue() );
  168 }
  169 
  170 QString
  171 XSPFPlaylist::identifier() const
  172 {
  173     return documentElement().namedItem( "identifier" ).firstChild().nodeValue();
  174 }
  175 
  176 KUrl
  177 XSPFPlaylist::image() const
  178 {
  179     return KUrl( documentElement().namedItem( "image" ).firstChild().nodeValue() );
  180 }
  181 
  182 QDateTime
  183 XSPFPlaylist::date() const
  184 {
  185     return QDateTime::fromString( documentElement().namedItem( "date" ).firstChild().nodeValue(), Qt::ISODate );
  186 }
  187 
  188 KUrl
  189 XSPFPlaylist::license() const
  190 {
  191     return KUrl( documentElement().namedItem( "license" ).firstChild().nodeValue() );
  192 }
  193 
  194 KUrl::List
  195 XSPFPlaylist::attribution() const
  196 {
  197     const QDomNodeList nodes = documentElement().namedItem( "attribution" ).childNodes();
  198     KUrl::List list;
  199 
  200     for( int i = 0, count = nodes.length(); i < count; ++i  )
  201     {
  202         const QDomNode &node = nodes.at( i );
  203         if( !node.firstChild().nodeValue().isNull() )
  204             list.append( node.firstChild().nodeValue() );
  205     }
  206     return list;
  207 }
  208 
  209 KUrl
  210 XSPFPlaylist::link() const
  211 {
  212     return KUrl( documentElement().namedItem( "link" ).firstChild().nodeValue() );
  213 }
  214 
  215 void
  216 XSPFPlaylist::setTitle( const QString &title )
  217 {
  218     QDomNode titleNode = documentElement().namedItem( "title" );
  219     if( titleNode.isNull() || !titleNode.hasChildNodes() )
  220     {
  221         QDomNode node = createElement( "title" );
  222         QDomNode subNode = createTextNode( title );
  223         node.appendChild( subNode );
  224         documentElement().insertBefore( node, documentElement().namedItem( "trackList" ) );
  225     }
  226     else
  227     {
  228         documentElement().namedItem( "title" ).replaceChild( createTextNode( title ),
  229                                     documentElement().namedItem( "title" ).firstChild()
  230                                 );
  231     }
  232     notifyObserversMetadataChanged();
  233     //write changes to file directly if we know where.
  234     if( !m_url.isEmpty() )
  235         PlaylistFile::save( false );
  236 }
  237 
  238 void
  239 XSPFPlaylist::setCreator( const QString &creator )
  240 {
  241     if( documentElement().namedItem( "creator" ).isNull() )
  242     {
  243         QDomNode node = createElement( "creator" );
  244         QDomNode subNode = createTextNode( creator );
  245         node.appendChild( subNode );
  246         documentElement().insertBefore( node, documentElement().namedItem( "trackList" ) );
  247     }
  248     else
  249     {
  250         documentElement().namedItem( "creator" ).replaceChild( createTextNode( creator ),
  251                                             documentElement().namedItem( "creator" ).firstChild() );
  252     }
  253 
  254     //write changes to file directly if we know where
  255     if( !m_url.isEmpty() )
  256         PlaylistFile::save( false );
  257 }
  258 
  259 void
  260 XSPFPlaylist::setAnnotation( const QString &annotation )
  261 {
  262     if( documentElement().namedItem( "annotation" ).isNull() )
  263     {
  264         QDomNode node = createElement( "annotation" );
  265         QDomNode subNode = createTextNode( annotation );
  266         node.appendChild( subNode );
  267         documentElement().insertBefore( node, documentElement().namedItem( "trackList" ) );
  268     }
  269     else
  270     {
  271         documentElement().namedItem( "annotation" ).replaceChild( createTextNode( annotation ),
  272                                         documentElement().namedItem( "annotation" ).firstChild() );
  273     }
  274 
  275     //write changes to file directly if we know where.
  276     if( !m_url.isEmpty() )
  277         PlaylistFile::save( false );
  278 }
  279 
  280 void
  281 XSPFPlaylist::setInfo( const KUrl &info )
  282 {
  283 
  284     if( documentElement().namedItem( "info" ).isNull() )
  285     {
  286         QDomNode node = createElement( "info" );
  287         QDomNode subNode = createTextNode( info.url() );
  288         node.appendChild( subNode );
  289         documentElement().insertBefore( node, documentElement().namedItem( "trackList" ) );
  290     }
  291     else
  292     {
  293         documentElement().namedItem( "info" ).replaceChild( createTextNode( info.url() ),
  294                                             documentElement().namedItem( "info" ).firstChild() );
  295     }
  296 
  297     //write changes to file directly if we know where.
  298     if( !m_url.isEmpty() )
  299         PlaylistFile::save( false );
  300 }
  301 
  302 void
  303 XSPFPlaylist::setLocation( const KUrl &location )
  304 {
  305     if( documentElement().namedItem( "location" ).isNull() )
  306     {
  307         QDomNode node = createElement( "location" );
  308         QDomNode subNode = createTextNode( location.url() );
  309         node.appendChild( subNode );
  310         documentElement().insertBefore( node, documentElement().namedItem( "trackList" ) );
  311     }
  312     else
  313     {
  314         documentElement().namedItem( "location" ).replaceChild( createTextNode( location.url() ),
  315                                         documentElement().namedItem( "location" ).firstChild() );
  316     }
  317 
  318     //write changes to file directly if we know where.
  319     if( !m_url.isEmpty() )
  320         PlaylistFile::save( false );
  321 }
  322 
  323 void
  324 XSPFPlaylist::setIdentifier( const QString &identifier )
  325 {
  326     if( documentElement().namedItem( "identifier" ).isNull() )
  327     {
  328         QDomNode node = createElement( "identifier" );
  329         QDomNode subNode = createTextNode( identifier );
  330         node.appendChild( subNode );
  331         documentElement().insertBefore( node, documentElement().namedItem( "trackList" ) );
  332     }
  333     else
  334     {
  335         documentElement().namedItem( "identifier" ).replaceChild( createTextNode( identifier ),
  336                                         documentElement().namedItem( "identifier" ).firstChild() );
  337     }
  338 
  339     //write changes to file directly if we know where.
  340     if( !m_url.isEmpty() )
  341         PlaylistFile::save( false );
  342 }
  343 
  344 void
  345 XSPFPlaylist::setImage( const KUrl &image )
  346 {
  347     if( documentElement().namedItem( "image" ).isNull() )
  348     {
  349         QDomNode node = createElement( "image" );
  350         QDomNode subNode = createTextNode( image.url() );
  351         node.appendChild( subNode );
  352         documentElement().insertBefore( node, documentElement().namedItem( "trackList" ) );
  353     }
  354     else
  355     {
  356         documentElement().namedItem( "image" ).replaceChild( createTextNode( image.url() ),
  357                                             documentElement().namedItem( "image" ).firstChild() );
  358     }
  359 
  360     //write changes to file directly if we know where.
  361     if( !m_url.isEmpty() )
  362         PlaylistFile::save( false );
  363 }
  364 
  365 void
  366 XSPFPlaylist::setDate( const QDateTime &date )
  367 {
  368     /* date needs timezone info to be compliant with the standard
  369     (ex. 2005-01-08T17:10:47-05:00 ) */
  370 
  371     if( documentElement().namedItem( "date" ).isNull() )
  372     {
  373         QDomNode node = createElement( "date" );
  374         QDomNode subNode = createTextNode( date.toString( "yyyy-MM-ddThh:mm:ss" ) );
  375         node.appendChild( subNode );
  376         documentElement().insertBefore( node, documentElement().namedItem( "trackList" ) );
  377     }
  378     else
  379     {
  380         documentElement().namedItem( "date" )
  381                 .replaceChild( createTextNode( date.toString( "yyyy-MM-ddThh:mm:ss" ) ),
  382                                documentElement().namedItem( "date" ).firstChild() );
  383     }
  384 
  385     //write changes to file directly if we know where.
  386     if( !m_url.isEmpty() )
  387         PlaylistFile::save( false );
  388 }
  389 
  390 void
  391 XSPFPlaylist::setLicense( const KUrl &license )
  392 {
  393     if( documentElement().namedItem( "license" ).isNull() )
  394     {
  395         QDomNode node = createElement( "license" );
  396         QDomNode subNode = createTextNode( license.url() );
  397         node.appendChild( subNode );
  398         documentElement().insertBefore( node, documentElement().namedItem( "trackList" ) );
  399     }
  400     else
  401     {
  402         documentElement().namedItem( "license" ).replaceChild( createTextNode( license.url() ),
  403                                         documentElement().namedItem( "license" ).firstChild() );
  404     }
  405 
  406     //write changes to file directly if we know where.
  407     if( !m_url.isEmpty() )
  408         PlaylistFile::save( false );
  409 }
  410 
  411 void
  412 XSPFPlaylist::setAttribution( const KUrl &attribution, bool append )
  413 {
  414     if( !attribution.isValid() )
  415         return;
  416 
  417     if( documentElement().namedItem( "attribution" ).isNull() )
  418     {
  419         documentElement().insertBefore( createElement( "attribution" ),
  420                                         documentElement().namedItem( "trackList" ) );
  421     }
  422 
  423     if( append )
  424     {
  425         QDomNode subNode = createElement( "location" );
  426         QDomNode subSubNode = createTextNode( attribution.url() );
  427         subNode.appendChild( subSubNode );
  428 
  429         QDomNode first = documentElement().namedItem( "attribution" ).firstChild();
  430         documentElement().namedItem( "attribution" ).insertBefore( subNode, first );
  431     }
  432     else
  433     {
  434         QDomNode node = createElement( "attribution" );
  435         QDomNode subNode = createElement( "location" );
  436         QDomNode subSubNode = createTextNode( attribution.url() );
  437         subNode.appendChild( subSubNode );
  438         node.appendChild( subNode );
  439         documentElement().replaceChild( node, documentElement().namedItem( "attribution" ) );
  440     }
  441 
  442     //write changes to file directly if we know where.
  443     if( !m_url.isEmpty() )
  444         PlaylistFile::save( false );
  445 }
  446 
  447 void
  448 XSPFPlaylist::setLink( const KUrl &link )
  449 {
  450     if( documentElement().namedItem( "link" ).isNull() )
  451     {
  452         QDomNode node = createElement( "link" );
  453         QDomNode subNode = createTextNode( link.url() );
  454         node.appendChild( subNode );
  455         documentElement().insertBefore( node, documentElement().namedItem( "trackList" ) );
  456     }
  457     else
  458     {
  459         documentElement().namedItem( "link" ).replaceChild( createTextNode( link.url() ),
  460                                             documentElement().namedItem( "link" ).firstChild() );
  461     }
  462 
  463     //write changes to file directly if we know where.
  464     if( !m_url.isEmpty() )
  465         PlaylistFile::save( false );
  466 }
  467 
  468 XSPFTrackList
  469 XSPFPlaylist::trackList()
  470 {
  471     XSPFTrackList list;
  472 
  473     QDomNode trackList = documentElement().namedItem( "trackList" );
  474     QDomNode subNode = trackList.firstChild();
  475     QDomNode subSubNode;
  476 
  477     while( !subNode.isNull() )
  478     {
  479         XSPFTrack track;
  480         subSubNode = subNode.firstChild();
  481         if( subNode.nodeName() == "track" )
  482         {
  483             while( !subSubNode.isNull() )
  484             {
  485                 if( subSubNode.nodeName() == "location" )
  486                 {
  487                     QByteArray path = subSubNode.firstChild().nodeValue().toAscii();
  488                     path.replace( '\\', '/' );
  489 
  490                     KUrl url = getAbsolutePath( KUrl::fromEncoded( path ) );
  491                     track.location = url;
  492                 }
  493                 else if( subSubNode.nodeName() == "title" )
  494                     track.title = subSubNode.firstChild().nodeValue();
  495                 else if( subSubNode.nodeName() == "creator" )
  496                     track.creator = subSubNode.firstChild().nodeValue();
  497                 else if( subSubNode.nodeName() == "duration" )
  498                     track.duration = subSubNode.firstChild().nodeValue().toInt();
  499                 else if( subSubNode.nodeName() == "annotation" )
  500                     track.annotation = subSubNode.firstChild().nodeValue();
  501                 else if( subSubNode.nodeName() == "album" )
  502                     track.album = subSubNode.firstChild().nodeValue();
  503                 else if( subSubNode.nodeName() == "trackNum" )
  504                     track.trackNum = (uint)subSubNode.firstChild().nodeValue().toInt();
  505                 else if( subSubNode.nodeName() == "identifier" )
  506                     track.identifier = subSubNode.firstChild().nodeValue();
  507                 else if( subSubNode.nodeName() == "info" )
  508                     track.info = subSubNode.firstChild().nodeValue();
  509                 else if( subSubNode.nodeName() == "image" )
  510                     track.image = subSubNode.firstChild().nodeValue();
  511                 else if( subSubNode.nodeName() == "link" )
  512                     track.link = subSubNode.firstChild().nodeValue();
  513 
  514                 subSubNode = subSubNode.nextSibling();
  515             }
  516         }
  517         list.append( track );
  518         subNode = subNode.nextSibling();
  519     }
  520 
  521     return list;
  522 }
  523 
  524 void
  525 XSPFPlaylist::setTrackList( Meta::TrackList trackList, bool append )
  526 {
  527     //documentation of attributes from http://www.xspf.org/xspf-v1.html
  528 
  529     if( documentElement().namedItem( "trackList" ).isNull() )
  530         documentElement().appendChild( createElement( "trackList" ) );
  531 
  532     QDomNode node = createElement( "trackList" );
  533 
  534     Meta::TrackPtr track;
  535     foreach( track, trackList ) // krazy:exclude=foreach
  536     {
  537         QDomNode subNode = createElement( "track" );
  538 
  539         //URI of resource to be rendered.
  540         QDomNode location = createElement( "location" );
  541 
  542         //Human-readable name of the track that authored the resource
  543         QDomNode title = createElement( "title" );
  544 
  545         //Human-readable name of the entity that authored the resource.
  546         QDomNode creator = createElement( "creator" );
  547 
  548         //A human-readable comment on the track.
  549         QDomNode annotation = createElement( "annotation" );
  550 
  551         //Human-readable name of the collection from which the resource comes
  552         QDomNode album = createElement( "album" );
  553 
  554         //Integer > 0 giving the ordinal position of the media in the album.
  555         QDomNode trackNum = createElement( "trackNum" );
  556 
  557         //The time to render a resource, in milliseconds. It MUST be a nonNegativeInteger.
  558         QDomNode duration = createElement( "duration" );
  559 
  560         //location-independent name, such as a MusicBrainz identifier. MUST be a legal URI.
  561         QDomNode identifier = createElement( "identifier" );
  562 
  563         //info - URI of a place where this resource can be bought or more info can be found.
  564         //QDomNode info = createElement( "info" );
  565 
  566         //image - URI of an image to display for the duration of the track.
  567         //QDomNode image = createElement( "image" );
  568 
  569         //link - element allows XSPF to be extended without the use of XML namespaces.
  570         //QDomNode link = createElement( "link" );
  571 
  572         //QDomNode meta
  573         //amarok specific queue info, see the XSPF specification's meta element
  574         QDomElement queue = createElement( "meta" );
  575         queue.setAttribute( "rel", "http://amarok.kde.org/queue" );
  576 
  577         //QDomNode extension
  578 
  579         #define APPENDNODE( X, Y ) \
  580         { \
  581             X.appendChild( createTextNode( Y ) );    \
  582             subNode.appendChild( X ); \
  583         }
  584 
  585         APPENDNODE( location, trackLocation( track ) )
  586         APPENDNODE( identifier, track->uidUrl() )
  587 
  588         Capabilities::StreamInfoCapability *streamInfo = track->create<Capabilities::StreamInfoCapability>();
  589         if( streamInfo ) // We have a stream, use it's metadata instead of the tracks.
  590         {
  591             if( !streamInfo->streamName().isEmpty() )
  592                 APPENDNODE( title, streamInfo->streamName() )
  593             if( !streamInfo->streamSource().isEmpty() )
  594                 APPENDNODE( creator, streamInfo->streamSource() )
  595 
  596             delete streamInfo;
  597         }
  598         else
  599         {
  600             if( !track->name().isEmpty() )
  601                 APPENDNODE(title, track->name() )
  602             if( track->artist() && !track->artist()->name().isEmpty() )
  603                 APPENDNODE(creator, track->artist()->name() );
  604         }
  605         if( !track->comment().isEmpty() )
  606             APPENDNODE(annotation, track->comment() );
  607         if( track->album() && !track->album()->name().isEmpty() )
  608             APPENDNODE( album, track->album()->name() );
  609         if( track->trackNumber() > 0 )
  610             APPENDNODE( trackNum, QString::number( track->trackNumber() ) );
  611         if( track->length() > 0 )
  612             APPENDNODE( duration, QString::number( track->length() ) );
  613 
  614         node.appendChild( subNode );
  615     }
  616     #undef APPENDNODE
  617 
  618     if( append )
  619     {
  620         while( !node.isNull() )
  621         {
  622             documentElement().namedItem( "trackList" ).appendChild( node.firstChild() );
  623             node = node.nextSibling();
  624         }
  625     }
  626     else
  627         documentElement().replaceChild( node, documentElement().namedItem( "trackList" ) );
  628 }
  629 
  630 void
  631 XSPFPlaylist::setQueue( const QList<int> &queue )
  632 {
  633     QDomElement q = createElement( "queue" );
  634 
  635     foreach( int row, queue )
  636     {
  637         QDomElement qTrack = createElement( "track" );
  638         qTrack.appendChild( createTextNode( QString::number( row ) ) );
  639         q.appendChild( qTrack );
  640     }
  641 
  642     QDomElement extension = createElement( "extension" );
  643     extension.setAttribute( "application", "http://amarok.kde.org" );
  644     extension.appendChild( q );
  645 
  646     QDomNode root = firstChild();
  647     root.appendChild( extension );
  648 }
  649 
  650 QList<int>
  651 XSPFPlaylist::queue()
  652 {
  653     QList<int> tracks;
  654 
  655     QDomElement extension = documentElement().firstChildElement( "extension" );
  656     if( extension.isNull() )
  657         return tracks;
  658 
  659     if( extension.attribute( "application" ) != "http://amarok.kde.org" )
  660         return tracks;
  661 
  662     QDomElement queue = extension.firstChildElement( "queue" );
  663     if( queue.isNull() )
  664         return tracks;
  665 
  666     for( QDomElement trackElem = queue.firstChildElement( "track" );
  667          !trackElem.isNull();
  668          trackElem = trackElem.nextSiblingElement( "track" ) )
  669     {
  670         tracks << trackElem.text().toInt();
  671     }
  672 
  673     return tracks;
  674 }
  675 
  676 void
  677 XSPFPlaylist::setName( const QString &name )
  678 {
  679     PlaylistFile::setName( name );
  680     setTitle( name );
  681 }