Commit 691e1730 authored by Sergey Ivanov's avatar Sergey Ivanov
Browse files

Relative paths support for XSPF playlists.

BUG: 264147
parent feca3faf
......@@ -5,6 +5,7 @@ Amarok ChangeLog
VERSION 2.4.1
BUGFIXES:
* Relative paths support for XSPF playlists. (BR 264147)
* Fix incorrect handling of "Various Artists" node by Collection Browser,
now selection of this node returns "Various Artists" tracks instead of
whole collection. (BR: 263255, BR: 269717)
......
......@@ -51,6 +51,8 @@ namespace Playlists
XSPFPlaylist::XSPFPlaylist()
: QDomDocument()
, m_tracksLoaded( false )
, m_relativePaths( false )
, m_saveLock( false )
{
QDomElement root = createElement( "playlist" );
......@@ -67,6 +69,8 @@ XSPFPlaylist::XSPFPlaylist( const KUrl &url, bool autoAppend )
, m_tracksLoaded( false )
, m_url( url )
, m_autoAppendAfterLoad( autoAppend )
, m_relativePaths( false )
, m_saveLock( false )
{
//check if file is local or remote
if ( m_url.isLocalFile() )
......@@ -91,6 +95,8 @@ XSPFPlaylist::XSPFPlaylist( const KUrl &url, bool autoAppend )
XSPFPlaylist::XSPFPlaylist( Meta::TrackList tracks )
: QDomDocument()
, m_relativePaths( false )
, m_saveLock( false )
{
QDomElement root = createElement( "playlist" );
......@@ -123,12 +129,25 @@ XSPFPlaylist::description() const
bool
XSPFPlaylist::save( const KUrl &location, bool relative )
{
Q_UNUSED( relative );
m_url = location;
//if the location is a directory append the name of this playlist.
if( m_url.fileName( KUrl::ObeyTrailingSlash ).isNull() )
m_url.setFileName( name() );
if( relative )
{
m_relativePaths = true;
m_saveLock = true;
setTrackList( tracks(), false );
m_saveLock = false;
}
else if( m_relativePaths )
{
m_relativePaths = false;
m_saveLock = true;
setTrackList( tracks(), false );
m_saveLock = false;
}
QFile file;
......@@ -663,7 +682,21 @@ XSPFPlaylist::trackList()
while( !subSubNode.isNull() )
{
if( subSubNode.nodeName() == "location" )
track.location = subSubNode.firstChild().nodeValue();
{
QString path = QUrl::fromPercentEncoding( subSubNode.firstChild().nodeValue().toAscii() );
path.replace( '\\', '/' );
KUrl url = path;
if( url.isRelative() )
{
m_relativePaths = true;
url = m_url.directory();
url.addPath( path );
url.cleanPath();
}
track.location = url;
}
else if( subSubNode.nodeName() == "title" )
track.title = subSubNode.firstChild().nodeValue();
else if( subSubNode.nodeName() == "creator" )
......@@ -756,11 +789,7 @@ XSPFPlaylist::setTrackList( Meta::TrackList trackList, bool append )
subNode.appendChild( X ); \
}
if ( !track->playableUrl().url().isEmpty() )
APPENDNODE( location, track->playableUrl().url() )
else
APPENDNODE( location, track->uidUrl() )
APPENDNODE( location, trackLocation( track ) )
APPENDNODE( identifier, track->uidUrl() )
Capabilities::StreamInfoCapability *streamInfo = track->create<Capabilities::StreamInfoCapability>();
......@@ -805,7 +834,7 @@ XSPFPlaylist::setTrackList( Meta::TrackList trackList, bool append )
documentElement().replaceChild( node, documentElement().namedItem( "trackList" ) );
//write changes to file directly if we know where.
if( !m_url.isEmpty() )
if( !m_url.isEmpty() && !m_saveLock )
save( m_url, false );
}
......@@ -901,4 +930,18 @@ XSPFPlaylist::setName( const QString &name )
setTitle( name );
}
QString
XSPFPlaylist::trackLocation( Meta::TrackPtr &track )
{
KUrl path = track->playableUrl();
if( path.isEmpty() )
return track->uidUrl();
if( !m_relativePaths || m_url.isEmpty() || !path.isLocalFile() || !m_url.isLocalFile() )
return path.url();
QDir playlistDir( m_url.directory() );
return QUrl::toPercentEncoding( playlistDir.relativeFilePath( path.path() ), "/" );
}
} //namespace Playlists
......@@ -126,7 +126,7 @@ public:
/** Changes both the filename and the title in XML */
void setName( const QString &name );
bool load( QTextStream &stream ) { return loadXSPF( stream ); }
/** save to location, relative is unused since XSPF mandates absolute paths */
/** save to location */
bool save( const KUrl &location, bool relative );
void setQueue( const QList<int> &queue );
......@@ -134,6 +134,7 @@ public:
private:
XSPFTrackList trackList();
QString trackLocation( Meta::TrackPtr &track );
bool loadXSPF( QTextStream& );
bool m_tracksLoaded;
//cache for the tracklist since a tracks() is a called *a lot*.
......@@ -141,6 +142,8 @@ private:
KUrl m_url;
bool m_autoAppendAfterLoad;
bool m_relativePaths;
bool m_saveLock;
};
}
......
Supports Markdown
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