1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-01 20:00:13 +02:00

add a createdOn property to playlists, and sort sourcetree

This commit is contained in:
Leo Franchi
2011-04-15 17:27:27 -04:00
parent e503f74db1
commit 1ecb799694
20 changed files with 359 additions and 255 deletions

View File

@@ -0,0 +1,11 @@
-- Script to migate from db version 22 to 23.
-- Only change in this version is that playlists gained a createdOn date.
-- Set all playlists to created to now.
--
-- Separate each command with %%
ALTER TABLE playlist ADD COLUMN createdOn INTEGER NOT NULL DEFAULT 0;
UPDATE playlist SET createdOn = strftime( '%s','now' );
UPDATE settings SET v = '23' WHERE k == 'schema_version';

View File

@@ -88,5 +88,6 @@
<file>./data/www/auth.html</file> <file>./data/www/auth.html</file>
<file>./data/www/auth.na.html</file> <file>./data/www/auth.na.html</file>
<file>./data/www/tomahawk_banner_small.png</file> <file>./data/www/tomahawk_banner_small.png</file>
<file>./data/sql/dbmigrate-22_to_23.sql</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@@ -143,11 +143,12 @@ void DatabaseCollection::dynamicPlaylistCreated( const source_ptr& source, const
data[1].toString(), //title data[1].toString(), //title
data[2].toString(), //info data[2].toString(), //info
data[3].toString(), //creator data[3].toString(), //creator
data[4].toString(), // dynamic type data[4].toUInt(), // createdOn
static_cast<GeneratorMode>(data[5].toInt()), // dynamic mode data[5].toString(), // dynamic type
data[6].toBool(), //shared static_cast<GeneratorMode>(data[6].toInt()), // dynamic mode
data[7].toInt(), //lastmod data[7].toBool(), //shared
data[8].toString() ) ); //GUID data[8].toInt(), //lastmod
data[9].toString() ) ); //GUID
addDynamicPlaylist( p ); addDynamicPlaylist( p );
} }

View File

@@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
* *
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org> * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* *
* Tomahawk is free software: you can redistribute it and/or modify * Tomahawk is free software: you can redistribute it and/or modify
@@ -53,15 +53,15 @@ DatabaseCommand_CreateDynamicPlaylist::exec( DatabaseImpl* lib )
qDebug() << Q_FUNC_INFO; qDebug() << Q_FUNC_INFO;
Q_ASSERT( !( m_playlist.isNull() && m_v.isNull() ) ); Q_ASSERT( !( m_playlist.isNull() && m_v.isNull() ) );
Q_ASSERT( !source().isNull() ); Q_ASSERT( !source().isNull() );
DatabaseCommand_CreatePlaylist::createPlaylist( lib, true ); DatabaseCommand_CreatePlaylist::createPlaylist( lib, true );
qDebug() << "Created normal playlist, now creating additional dynamic info!"; qDebug() << "Created normal playlist, now creating additional dynamic info!";
TomahawkSqlQuery cre = lib->newquery(); TomahawkSqlQuery cre = lib->newquery();
cre.prepare( "INSERT INTO dynamic_playlist( guid, pltype, plmode ) " cre.prepare( "INSERT INTO dynamic_playlist( guid, pltype, plmode ) "
"VALUES( ?, ?, ? )" ); "VALUES( ?, ?, ? )" );
if( m_playlist.isNull() ) { if( m_playlist.isNull() ) {
QVariantMap m = m_v.toMap(); QVariantMap m = m_v.toMap();
cre.addBindValue( m.value( "guid" ) ); cre.addBindValue( m.value( "guid" ) );
@@ -73,22 +73,6 @@ DatabaseCommand_CreateDynamicPlaylist::exec( DatabaseImpl* lib )
cre.addBindValue( m_playlist->mode() ); cre.addBindValue( m_playlist->mode() );
} }
cre.exec(); cre.exec();
// save the controls -- wait, no controls in a new playlist :P
// cre = lib->newquery();
// cre.prepare( "INSERT INTO dynamic_playlist_controls( id, selectedType, match, input) "
// "VALUES( :id, :selectedType, :match, :input )" );
// foreach( const dyncontrol_ptr& control, m_playlist->generator()->controls() ) {
//
// cre.bindValue( ":id", control->id() );
// cre.bindValue( ":selectedType", control->selectedType() );
// cre.bindValue( ":match", control->match() );
// cre.bindValue( ":input", control->input() );
//
// qDebug() << "CREATE DYNPLAYLIST CONTROL:" << cre.boundValues();
//
// cre.exec();
// }
} }
@@ -101,10 +85,10 @@ DatabaseCommand_CreateDynamicPlaylist::postCommitHook()
qDebug() << "Source has gone offline, not emitting to GUI."; qDebug() << "Source has gone offline, not emitting to GUI.";
return; return;
} }
if( report() == false ) if( report() == false )
return; return;
qDebug() << Q_FUNC_INFO << "..reporting.."; qDebug() << Q_FUNC_INFO << "..reporting..";
if( m_playlist.isNull() ) { if( m_playlist.isNull() ) {
source_ptr src = source(); source_ptr src = source();

View File

@@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
* *
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org> * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* *
* Tomahawk is free software: you can redistribute it and/or modify * Tomahawk is free software: you can redistribute it and/or modify
@@ -75,25 +75,29 @@ DatabaseCommand_CreatePlaylist::postCommitHook()
} else { } else {
m_playlist->reportCreated( m_playlist ); m_playlist->reportCreated( m_playlist );
} }
if( source()->isLocal() ) if( source()->isLocal() )
Servent::instance()->triggerDBSync(); Servent::instance()->triggerDBSync();
} }
void void
DatabaseCommand_CreatePlaylist::createPlaylist( DatabaseImpl* lib, bool dynamic) DatabaseCommand_CreatePlaylist::createPlaylist( DatabaseImpl* lib, bool dynamic)
{ {
qDebug() << Q_FUNC_INFO; qDebug() << Q_FUNC_INFO;
Q_ASSERT( !( m_playlist.isNull() && m_v.isNull() ) ); Q_ASSERT( !( m_playlist.isNull() && m_v.isNull() ) );
Q_ASSERT( !source().isNull() ); Q_ASSERT( !source().isNull() );
uint now = QDateTime::currentDateTime().toTime_t();
m_playlist->setCreatedOn( now );
TomahawkSqlQuery cre = lib->newquery(); TomahawkSqlQuery cre = lib->newquery();
cre.prepare( "INSERT INTO playlist( guid, source, shared, title, info, creator, lastmodified, dynplaylist) " cre.prepare( "INSERT INTO playlist( guid, source, shared, title, info, creator, lastmodified, dynplaylist, createdOn) "
"VALUES( :guid, :source, :shared, :title, :info, :creator, :lastmodified, :dynplaylist )" ); "VALUES( :guid, :source, :shared, :title, :info, :creator, :lastmodified, :dynplaylist, :createdOn )" );
cre.bindValue( ":source", source()->isLocal() ? QVariant(QVariant::Int) : source()->id() ); cre.bindValue( ":source", source()->isLocal() ? QVariant(QVariant::Int) : source()->id() );
cre.bindValue( ":dynplaylist", dynamic ); cre.bindValue( ":dynplaylist", dynamic );
cre.bindValue( ":createdOn", now );
if( !m_playlist.isNull() ) { if( !m_playlist.isNull() ) {
cre.bindValue( ":guid", m_playlist->guid() ); cre.bindValue( ":guid", m_playlist->guid() );
cre.bindValue( ":shared", m_playlist->shared() ); cre.bindValue( ":shared", m_playlist->shared() );
@@ -111,6 +115,6 @@ DatabaseCommand_CreatePlaylist::createPlaylist( DatabaseImpl* lib, bool dynamic)
cre.bindValue( ":lastmodified", m.value( "lastmodified", 0 ) ); cre.bindValue( ":lastmodified", m.value( "lastmodified", 0 ) );
} }
qDebug() << "CREATE PLAYLIST:" << cre.boundValues(); qDebug() << "CREATE PLAYLIST:" << cre.boundValues();
cre.exec(); cre.exec();
} }

View File

@@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
* *
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org> * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* *
* Tomahawk is free software: you can redistribute it and/or modify * Tomahawk is free software: you can redistribute it and/or modify
@@ -29,28 +29,29 @@ using namespace Tomahawk;
void DatabaseCommand_LoadAllDynamicPlaylists::exec( DatabaseImpl* dbi ) void DatabaseCommand_LoadAllDynamicPlaylists::exec( DatabaseImpl* dbi )
{ {
TomahawkSqlQuery query = dbi->newquery(); TomahawkSqlQuery query = dbi->newquery();
query.exec( QString( "SELECT playlist.guid as guid, title, info, creator, lastmodified, shared, currentrevision, dynamic_playlist.pltype, dynamic_playlist.plmode " query.exec( QString( "SELECT playlist.guid as guid, title, info, creator, createdOn, lastmodified, shared, currentrevision, dynamic_playlist.pltype, dynamic_playlist.plmode "
"FROM playlist, dynamic_playlist WHERE source %1 AND dynplaylist = 'true' AND playlist.guid = dynamic_playlist.guid" ) "FROM playlist, dynamic_playlist WHERE source %1 AND dynplaylist = 'true' AND playlist.guid = dynamic_playlist.guid" )
.arg( source()->isLocal() ? "IS NULL" : .arg( source()->isLocal() ? "IS NULL" :
QString( "=%1" ).arg( source()->id() ) QString( "=%1" ).arg( source()->id() )
) ); ) );
QList<dynplaylist_ptr> plists; QList<dynplaylist_ptr> plists;
while ( query.next() ) while ( query.next() )
{ {
QVariantList data = QVariantList() << query.value(6).toString() //current rev QVariantList data = QVariantList() << query.value(7).toString() //current rev
<< query.value(1).toString() //title << query.value(1).toString() //title
<< query.value(2).toString() //info << query.value(2).toString() //info
<< query.value(3).toString() //creator << query.value(3).toString() //creator
<< query.value(7).toString() // dynamic type << query.value(4).toString() //createdOn
<< static_cast<GeneratorMode>(query.value(8).toInt()) // dynamic mode << query.value(8).toString() // dynamic type
<< query.value(5).toBool() //shared << static_cast<GeneratorMode>(query.value(9).toInt()) // dynamic mode
<< query.value(4).toInt() //lastmod << query.value(6).toBool() //shared
<< query.value(5).toInt() //lastmod
<< query.value(0).toString(); //GUID << query.value(0).toString(); //GUID
emit playlistLoaded( source(), data ); emit playlistLoaded( source(), data );
} }
emit done(); emit done();
} }

View File

@@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
* *
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org> * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* *
* Tomahawk is free software: you can redistribute it and/or modify * Tomahawk is free software: you can redistribute it and/or modify
@@ -30,7 +30,7 @@ void DatabaseCommand_LoadAllPlaylists::exec( DatabaseImpl* dbi )
{ {
TomahawkSqlQuery query = dbi->newquery(); TomahawkSqlQuery query = dbi->newquery();
query.exec( QString( "SELECT guid, title, info, creator, lastmodified, shared, currentrevision " query.exec( QString( "SELECT guid, title, info, creator, lastmodified, shared, currentrevision, createdOn "
"FROM playlist WHERE source %1 AND dynplaylist = 'false'" ) "FROM playlist WHERE source %1 AND dynplaylist = 'false'" )
.arg( source()->isLocal() ? "IS NULL" : .arg( source()->isLocal() ? "IS NULL" :
QString( "= %1" ).arg( source()->id() ) QString( "= %1" ).arg( source()->id() )
@@ -44,6 +44,7 @@ void DatabaseCommand_LoadAllPlaylists::exec( DatabaseImpl* dbi )
query.value(1).toString(), //title query.value(1).toString(), //title
query.value(2).toString(), //info query.value(2).toString(), //info
query.value(3).toString(), //creator query.value(3).toString(), //creator
query.value(7).toInt(), //lastmod
query.value(5).toBool(), //shared query.value(5).toBool(), //shared
query.value(4).toInt(), //lastmod query.value(4).toInt(), //lastmod
query.value(0).toString() //GUID query.value(0).toString() //GUID

View File

@@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
* *
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org> * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* *
* Tomahawk is free software: you can redistribute it and/or modify * Tomahawk is free software: you can redistribute it and/or modify
@@ -30,6 +30,7 @@
#include "result.h" #include "result.h"
#include "artist.h" #include "artist.h"
#include "album.h" #include "album.h"
#include "utils/tomahawkutils.h"
/* !!!! You need to manually generate schema.sql.h when the schema changes: /* !!!! You need to manually generate schema.sql.h when the schema changes:
cd src/libtomahawk/database cd src/libtomahawk/database
@@ -37,7 +38,7 @@
*/ */
#include "schema.sql.h" #include "schema.sql.h"
#define CURRENT_SCHEMA_VERSION 22 #define CURRENT_SCHEMA_VERSION 23
DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent ) DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent )
@@ -63,21 +64,22 @@ DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent )
int v = qry.value( 0 ).toInt(); int v = qry.value( 0 ).toInt();
qDebug() << "Current schema is" << v << this->thread(); qDebug() << "Current schema is" << v << this->thread();
if ( v != CURRENT_SCHEMA_VERSION ) if ( v != CURRENT_SCHEMA_VERSION )
{ {
QString newname = QString("%1.v%2").arg(dbname).arg(v); QString newname = QString("%1.v%2").arg(dbname).arg(v);
qDebug() << endl << "****************************" << endl; qDebug() << endl << "****************************" << endl;
qDebug() << "Schema version too old: " << v << ". Current version is:" << CURRENT_SCHEMA_VERSION; qDebug() << "Schema version too old: " << v << ". Current version is:" << CURRENT_SCHEMA_VERSION;
qDebug() << "Moving" << dbname << newname; qDebug() << "Moving" << dbname << newname;
qDebug() << "If the migration fails, you can recover your DB by copying" << newname << "back to" << dbname;
qDebug() << endl << "****************************" << endl; qDebug() << endl << "****************************" << endl;
qry.clear(); qry.clear();
qry.finish(); qry.finish();
db.close(); db.close();
db.removeDatabase( "tomahawk" ); db.removeDatabase( "tomahawk" );
if( QFile::rename( dbname, newname ) ) if( QFile::copy( dbname, newname ) )
{ {
db = QSqlDatabase::addDatabase( "QSQLITE", "tomahawk" ); db = QSqlDatabase::addDatabase( "QSQLITE", "tomahawk" );
db.setDatabaseName( dbname ); db.setDatabaseName( dbname );
@@ -87,6 +89,13 @@ DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent )
TomahawkSqlQuery query = newquery(); TomahawkSqlQuery query = newquery();
query.exec( "PRAGMA auto_vacuum = FULL" ); query.exec( "PRAGMA auto_vacuum = FULL" );
schemaUpdated = updateSchema( v ); schemaUpdated = updateSchema( v );
if( !schemaUpdated )
{
Q_ASSERT( false );
QTimer::singleShot( 0, qApp, SLOT( quit() ) );
}
} }
else else
{ {
@@ -149,26 +158,70 @@ DatabaseImpl::updateSearchIndex()
bool bool
DatabaseImpl::updateSchema( int currentver ) DatabaseImpl::updateSchema( int oldVersion )
{ {
qDebug() << "Create tables... old version is" << currentver; // we are called here with the old database. we must migrate it to the CURRENT_SCHEMA_VERSION from t7he oldVersion
QString sql( get_tomahawk_sql() ); if ( oldVersion == 0 ) // empty database, so create our tables and stuff
QStringList statements = sql.split( ";", QString::SkipEmptyParts );
db.transaction();
foreach( const QString& sl, statements )
{ {
QString s( sl.trimmed() ); qDebug() << "Create tables... old version is" << oldVersion;
if( s.length() == 0 ) QString sql( get_tomahawk_sql() );
continue; QStringList statements = sql.split( ";", QString::SkipEmptyParts );
db.transaction();
qDebug() << "Executing:" << s; foreach( const QString& sl, statements )
TomahawkSqlQuery query = newquery(); {
query.exec( s ); QString s( sl.trimmed() );
if( s.length() == 0 )
continue;
qDebug() << "Executing:" << s;
TomahawkSqlQuery query = newquery();
query.exec( s );
}
db.commit();
return true;
} else // update in place! run the proper upgrade script
{
int cur = oldVersion;
db.transaction();
while( cur < CURRENT_SCHEMA_VERSION ) {
cur++;
QString path = QString( RESPATH "sql/dbmigrate-%1_to_%2.sql" ).arg( cur - 1 ).arg( cur );
QFile script( path );
if( !script.exists() || !script.open( QIODevice::ReadOnly ) )
{
qWarning() << "Failed to find or open upgrade script from" << (cur-1) << "to" << cur << " (" << path << ")! Aborting upgrade..";
return false;
}
QString sql = QString::fromUtf8( script.readAll() ).trimmed();
QStringList statements = sql.split( ";", QString::SkipEmptyParts );
foreach( const QString& sql, statements )
{
QString clean = cleanSql( sql ).trimmed();
if( clean.isEmpty() )
continue;
qDebug() << "Executing upgrade statement:" << clean;
TomahawkSqlQuery q = newquery();
q.exec( clean );
}
}
db.commit();
qDebug() << "DB Upgrade successful!";
return true;
} }
}
db.commit(); QString
return true; DatabaseImpl::cleanSql( const QString& sql )
{
QString fixed = sql;
QRegExp r( "--[^\\n]*" );
fixed.replace( r, QString() );
return fixed.trimmed();
} }

View File

@@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
* *
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org> * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* *
* Tomahawk is free software: you can redistribute it and/or modify * Tomahawk is free software: you can redistribute it and/or modify
@@ -84,9 +84,11 @@ signals:
public slots: public slots:
private: private:
QString cleanSql( const QString& sql );
bool m_ready; bool m_ready;
bool updateSchema( int currentver ); bool updateSchema( int oldVersion );
QSqlDatabase db; QSqlDatabase db;

View File

@@ -67,13 +67,14 @@ CREATE TABLE IF NOT EXISTS playlist (
creator TEXT, creator TEXT,
lastmodified INTEGER NOT NULL DEFAULT 0, lastmodified INTEGER NOT NULL DEFAULT 0,
currentrevision TEXT REFERENCES playlist_revision(guid) DEFERRABLE INITIALLY DEFERRED, currentrevision TEXT REFERENCES playlist_revision(guid) DEFERRABLE INITIALLY DEFERRED,
dynplaylist BOOLEAN DEFAULT false dynplaylist BOOLEAN DEFAULT false,
createdOn INTEGER NOT NULL DEFAULT 0
); );
--INSERT INTO playlist(guid, title, info, currentrevision, dynplaylist) --INSERT INTO playlist(guid, title, info, currentrevision, dynplaylist)
--VALUES('dynamic_playlist-guid-1','Test Dynamic Playlist Dynamic','this playlist automatically created and used for testing','revisionguid-1', 1); --VALUES('dynamic_playlist-guid-1','Test Dynamic Playlist Dynamic','this playlist automatically created and used for testing','revisionguid-1', 1);
--INSERT INTO playlist(guid, title, info, currentrevision, dynplaylist) --INSERT INTO playlist(guid, title, info, currentrevision, dynplaylist)
--VALUES('dynamic_playlist-guid-2','Test Dynamic Playlist Static','this playlist automatically created and used for testing','revisionguid-11', 1); --VALUES('dynamic_playlist-guid-2','Test Dynamic Playlist Static','this playlist automatically created and used for testing','revisionguid-11', 1);
CREATE TABLE IF NOT EXISTS playlist_item ( CREATE TABLE IF NOT EXISTS playlist_item (
@@ -129,8 +130,8 @@ CREATE TABLE IF NOT EXISTS dynamic_playlist_controls (
--INSERT INTO dynamic_playlist_controls(id, playlist, selectedType, match, input) --INSERT INTO dynamic_playlist_controls(id, playlist, selectedType, match, input)
-- VALUES('controlid-2', 'dynamic_playlist-guid-11', "artist", 0, "FooArtist" ); -- VALUES('controlid-2', 'dynamic_playlist-guid-11', "artist", 0, "FooArtist" );
CREATE TABLE IF NOT EXISTS dynamic_playlist_revision ( CREATE TABLE IF NOT EXISTS dynamic_playlist_revision (
guid TEXT PRIMARY KEY NOT NULL REFERENCES playlist_revision(guid) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED, guid TEXT PRIMARY KEY NOT NULL REFERENCES playlist_revision(guid) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
controls TEXT, -- qlist( id, id, id ) controls TEXT, -- qlist( id, id, id )
@@ -148,7 +149,7 @@ CREATE TABLE IF NOT EXISTS dynamic_playlist_revision (
-- if source=null, file is local to this machine -- if source=null, file is local to this machine
CREATE TABLE IF NOT EXISTS file ( CREATE TABLE IF NOT EXISTS file (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
source INTEGER REFERENCES source(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED, source INTEGER REFERENCES source(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
url TEXT NOT NULL, -- file:///music/foo/bar.mp3, <guid or hash?> url TEXT NOT NULL, -- file:///music/foo/bar.mp3, <guid or hash?>
size INTEGER NOT NULL, -- in bytes size INTEGER NOT NULL, -- in bytes
@@ -212,7 +213,7 @@ CREATE TABLE IF NOT EXISTS artist_tags (
); );
CREATE INDEX artist_tags_tag ON artist_tags(tag); CREATE INDEX artist_tags_tag ON artist_tags(tag);
-- all other attributes. -- all other attributes.
-- like tags that have a value, eg: -- like tags that have a value, eg:
-- BPM=120, releaseyear=1980, key=Dminor, composer=Someone -- BPM=120, releaseyear=1980, key=Dminor, composer=Someone
-- NB: since all values are text, numeric values should be zero-padded to a set amount -- NB: since all values are text, numeric values should be zero-padded to a set amount
@@ -263,4 +264,4 @@ CREATE TABLE IF NOT EXISTS settings (
v TEXT NOT NULL DEFAULT '' v TEXT NOT NULL DEFAULT ''
); );
INSERT INTO settings(k,v) VALUES('schema_version', '22'); INSERT INTO settings(k,v) VALUES('schema_version', '23');

View File

@@ -1,5 +1,5 @@
/* /*
This file was automatically generated from ./schema.sql on Wed Mar 2 01:40:39 CET 2011. This file was automatically generated from schema.sql on Fri Apr 15 15:55:52 EDT 2011.
*/ */
static const char * tomahawk_schema_sql = static const char * tomahawk_schema_sql =
@@ -51,7 +51,8 @@ static const char * tomahawk_schema_sql =
" creator TEXT," " creator TEXT,"
" lastmodified INTEGER NOT NULL DEFAULT 0," " lastmodified INTEGER NOT NULL DEFAULT 0,"
" currentrevision TEXT REFERENCES playlist_revision(guid) DEFERRABLE INITIALLY DEFERRED," " currentrevision TEXT REFERENCES playlist_revision(guid) DEFERRABLE INITIALLY DEFERRED,"
" dynplaylist BOOLEAN DEFAULT false" " dynplaylist BOOLEAN DEFAULT false,"
" createdOn INTEGER NOT NULL DEFAULT 0"
");" ");"
"CREATE TABLE IF NOT EXISTS playlist_item (" "CREATE TABLE IF NOT EXISTS playlist_item ("
" guid TEXT PRIMARY KEY," " guid TEXT PRIMARY KEY,"
@@ -86,8 +87,6 @@ static const char * tomahawk_schema_sql =
" match TEXT," " match TEXT,"
" input TEXT" " input TEXT"
");" ");"
""
""
"CREATE TABLE IF NOT EXISTS dynamic_playlist_revision (" "CREATE TABLE IF NOT EXISTS dynamic_playlist_revision ("
" guid TEXT PRIMARY KEY NOT NULL REFERENCES playlist_revision(guid) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED," " guid TEXT PRIMARY KEY NOT NULL REFERENCES playlist_revision(guid) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,"
" controls TEXT, " " controls TEXT, "
@@ -173,7 +172,7 @@ static const char * tomahawk_schema_sql =
" k TEXT NOT NULL PRIMARY KEY," " k TEXT NOT NULL PRIMARY KEY,"
" v TEXT NOT NULL DEFAULT ''" " v TEXT NOT NULL DEFAULT ''"
");" ");"
"INSERT INTO settings(k,v) VALUES('schema_version', '22');" "INSERT INTO settings(k,v) VALUES('schema_version', '23');"
; ;
const char * get_tomahawk_sql() const char * get_tomahawk_sql()

View File

@@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
* *
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org> * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* *
* Tomahawk is free software: you can redistribute it and/or modify * Tomahawk is free software: you can redistribute it and/or modify
@@ -57,28 +57,28 @@ PlaylistEntry::queryVariant() const
} }
void void
PlaylistEntry::setQuery( const Tomahawk::query_ptr& q ) PlaylistEntry::setQuery( const Tomahawk::query_ptr& q )
{ {
m_query = q; m_query = q;
} }
const Tomahawk::query_ptr& const Tomahawk::query_ptr&
PlaylistEntry::query() const PlaylistEntry::query() const
{ {
return m_query; return m_query;
} }
source_ptr source_ptr
PlaylistEntry::lastSource() const PlaylistEntry::lastSource() const
{ {
return m_lastsource; return m_lastsource;
} }
void void
PlaylistEntry::setLastSource( source_ptr s ) PlaylistEntry::setLastSource( source_ptr s )
{ {
m_lastsource = s; m_lastsource = s;
@@ -99,6 +99,7 @@ Playlist::Playlist( const source_ptr& src,
const QString& title, const QString& title,
const QString& info, const QString& info,
const QString& creator, const QString& creator,
uint createdOn,
bool shared, bool shared,
int lastmod, int lastmod,
const QString& guid ) const QString& guid )
@@ -109,6 +110,7 @@ Playlist::Playlist( const source_ptr& src,
, m_title( title ) , m_title( title )
, m_info( info ) , m_info( info )
, m_creator( creator ) , m_creator( creator )
, m_createdOn( createdOn )
, m_lastmodified( lastmod ) , m_lastmodified( lastmod )
, m_shared( shared ) , m_shared( shared )
{ {
@@ -129,6 +131,7 @@ Playlist::Playlist( const source_ptr& author,
, m_title( title ) , m_title( title )
, m_info ( info ) , m_info ( info )
, m_creator( creator ) , m_creator( creator )
, m_createdOn( 0 ) // will be set by db command
, m_lastmodified( 0 ) , m_lastmodified( 0 )
, m_shared( shared ) , m_shared( shared )
{ {
@@ -141,7 +144,7 @@ void
Playlist::init() Playlist::init()
{ {
m_locallyChanged = false; m_locallyChanged = false;
connect( Pipeline::instance(), SIGNAL( idle() ), SLOT( onResolvingFinished() ) ); connect( Pipeline::instance(), SIGNAL( idle() ), SLOT( onResolvingFinished() ) );
} }
@@ -229,7 +232,7 @@ Playlist::reportDeleted( const Tomahawk::playlist_ptr& self )
qDebug() << Q_FUNC_INFO; qDebug() << Q_FUNC_INFO;
Q_ASSERT( self.data() == this ); Q_ASSERT( self.data() == this );
m_source->collection()->deletePlaylist( self ); m_source->collection()->deletePlaylist( self );
emit deleted( self ); emit deleted( self );
} }
@@ -310,24 +313,24 @@ Playlist::setRevision( const QString& rev,
); );
return; return;
} }
PlaylistRevision pr = setNewRevision( rev, neworderedguids, oldorderedguids, is_newest_rev, addedmap ); PlaylistRevision pr = setNewRevision( rev, neworderedguids, oldorderedguids, is_newest_rev, addedmap );
if( applied ) if( applied )
m_currentrevision = rev; m_currentrevision = rev;
pr.applied = applied; pr.applied = applied;
foreach( const plentry_ptr& entry, m_entries ) foreach( const plentry_ptr& entry, m_entries )
{ {
connect( entry->query().data(), SIGNAL( resultsAdded( QList<Tomahawk::result_ptr> ) ), connect( entry->query().data(), SIGNAL( resultsAdded( QList<Tomahawk::result_ptr> ) ),
SLOT( onResultsFound( QList<Tomahawk::result_ptr> ) ), Qt::UniqueConnection ); SLOT( onResultsFound( QList<Tomahawk::result_ptr> ) ), Qt::UniqueConnection );
} }
emit revisionLoaded( pr ); emit revisionLoaded( pr );
} }
PlaylistRevision PlaylistRevision
Playlist::setNewRevision( const QString& rev, Playlist::setNewRevision( const QString& rev,
const QList<QString>& neworderedguids, const QList<QString>& neworderedguids,
const QList<QString>& oldorderedguids, const QList<QString>& oldorderedguids,
@@ -340,10 +343,10 @@ Playlist::setNewRevision( const QString& rev,
QMap<QString, plentry_ptr> entriesmap; QMap<QString, plentry_ptr> entriesmap;
foreach( const plentry_ptr& p, m_entries ) foreach( const plentry_ptr& p, m_entries )
entriesmap.insert( p->guid(), p ); entriesmap.insert( p->guid(), p );
QList<plentry_ptr> entries; QList<plentry_ptr> entries;
foreach( const QString& id, neworderedguids ) foreach( const QString& id, neworderedguids )
{ {
//qDebug() << "id:" << id; //qDebug() << "id:" << id;
@@ -351,7 +354,7 @@ Playlist::setNewRevision( const QString& rev,
//qDebug() << "entriesmap:" << entriesmap.count() << entriesmap; //qDebug() << "entriesmap:" << entriesmap.count() << entriesmap;
//qDebug() << "addedmap:" << addedmap.count() << addedmap; //qDebug() << "addedmap:" << addedmap.count() << addedmap;
//qDebug() << "m_entries" << m_entries; //qDebug() << "m_entries" << m_entries;
if( entriesmap.contains( id ) ) if( entriesmap.contains( id ) )
{ {
entries.append( entriesmap.value( id ) ); entries.append( entriesmap.value( id ) );
@@ -367,13 +370,13 @@ Playlist::setNewRevision( const QString& rev,
Q_ASSERT( false ); // XXX Q_ASSERT( false ); // XXX
} }
} }
//qDebug() << Q_FUNC_INFO << rev << entries.length() << applied; //qDebug() << Q_FUNC_INFO << rev << entries.length() << applied;
PlaylistRevision pr; PlaylistRevision pr;
pr.oldrevisionguid = m_currentrevision; pr.oldrevisionguid = m_currentrevision;
pr.revisionguid = rev; pr.revisionguid = rev;
// entries that have been removed: // entries that have been removed:
QSet<QString> removedguids = oldorderedguids.toSet().subtract( neworderedguids.toSet() ); QSet<QString> removedguids = oldorderedguids.toSet().subtract( neworderedguids.toSet() );
//qDebug() << "Removedguids:" << removedguids << "oldorederedguids" << oldorderedguids << "newog" << neworderedguids; //qDebug() << "Removedguids:" << removedguids << "oldorederedguids" << oldorderedguids << "newog" << neworderedguids;
@@ -399,10 +402,10 @@ Playlist::setNewRevision( const QString& rev,
} }
} }
} }
pr.added = addedmap.values(); pr.added = addedmap.values();
pr.newlist = entries; pr.newlist = entries;
return pr; return pr;
} }
@@ -410,12 +413,12 @@ Playlist::setNewRevision( const QString& rev,
source_ptr source_ptr
Playlist::author() const Playlist::author() const
{ {
return m_source; return m_source;
} }
void void
Playlist::resolve() Playlist::resolve()
{ {
QList< query_ptr > qlist; QList< query_ptr > qlist;
@@ -462,7 +465,7 @@ void
Playlist::addEntries( const QList<query_ptr>& queries, const QString& oldrev ) Playlist::addEntries( const QList<query_ptr>& queries, const QString& oldrev )
{ {
//qDebug() << Q_FUNC_INFO; //qDebug() << Q_FUNC_INFO;
QList<plentry_ptr> el = addEntriesInternal( queries ); QList<plentry_ptr> el = addEntriesInternal( queries );
QString newrev = uuid(); QString newrev = uuid();
@@ -470,7 +473,7 @@ Playlist::addEntries( const QList<query_ptr>& queries, const QString& oldrev )
} }
QList<plentry_ptr> QList<plentry_ptr>
Playlist::addEntriesInternal( const QList<Tomahawk::query_ptr>& queries ) Playlist::addEntriesInternal( const QList<Tomahawk::query_ptr>& queries )
{ {
QList<plentry_ptr> el = entries(); QList<plentry_ptr> el = entries();
@@ -478,16 +481,16 @@ Playlist::addEntriesInternal( const QList<Tomahawk::query_ptr>& queries )
{ {
plentry_ptr e( new PlaylistEntry() ); plentry_ptr e( new PlaylistEntry() );
e->setGuid( uuid() ); e->setGuid( uuid() );
if ( query->results().count() ) if ( query->results().count() )
e->setDuration( query->results().at( 0 )->duration() ); e->setDuration( query->results().at( 0 )->duration() );
else else
e->setDuration( 0 ); e->setDuration( 0 );
e->setLastmodified( 0 ); e->setLastmodified( 0 );
e->setAnnotation( "" ); // FIXME e->setAnnotation( "" ); // FIXME
e->setQuery( query ); e->setQuery( query );
el << e; el << e;
} }
return el; return el;
@@ -500,14 +503,14 @@ Playlist::newEntries( const QList< plentry_ptr >& entries )
QSet<QString> currentguids; QSet<QString> currentguids;
foreach( const plentry_ptr& p, m_entries ) foreach( const plentry_ptr& p, m_entries )
currentguids.insert( p->guid() ); // could be cached as member? currentguids.insert( p->guid() ); // could be cached as member?
// calc list of newly added entries: // calc list of newly added entries:
QList<plentry_ptr> added; QList<plentry_ptr> added;
foreach( const plentry_ptr& p, entries ) foreach( const plentry_ptr& p, entries )
{ {
if( !currentguids.contains( p->guid() ) ) if( !currentguids.contains( p->guid() ) )
added << p; added << p;
} }
return added; return added;
} }

View File

@@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
* *
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org> * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* *
* Tomahawk is free software: you can redistribute it and/or modify * Tomahawk is free software: you can redistribute it and/or modify
@@ -77,6 +77,7 @@ public:
source_ptr lastSource() const; source_ptr lastSource() const;
void setLastSource( source_ptr s ); void setLastSource( source_ptr s );
private: private:
QString m_guid; QString m_guid;
Tomahawk::query_ptr m_query; Tomahawk::query_ptr m_query;
@@ -107,6 +108,7 @@ Q_PROPERTY( QString currentrevision READ currentrevision WRITE setCurrentrevi
Q_PROPERTY( QString title READ title WRITE setTitle ) Q_PROPERTY( QString title READ title WRITE setTitle )
Q_PROPERTY( QString info READ info WRITE setInfo ) Q_PROPERTY( QString info READ info WRITE setInfo )
Q_PROPERTY( QString creator READ creator WRITE setCreator ) Q_PROPERTY( QString creator READ creator WRITE setCreator )
Q_PROPERTY( unsigned int createdon READ createdOn WRITE setCreatedOn )
Q_PROPERTY( bool shared READ shared WRITE setShared ) Q_PROPERTY( bool shared READ shared WRITE setShared )
friend class ::DatabaseCommand_LoadAllPlaylists; friend class ::DatabaseCommand_LoadAllPlaylists;
@@ -139,6 +141,7 @@ public:
QString guid() const { return m_guid; } QString guid() const { return m_guid; }
bool shared() const { return m_shared; } bool shared() const { return m_shared; }
unsigned int lastmodified() const { return m_lastmodified; } unsigned int lastmodified() const { return m_lastmodified; }
uint createdOn() const { return m_createdOn; }
const QList< plentry_ptr >& entries() { return m_entries; } const QList< plentry_ptr >& entries() { return m_entries; }
virtual void addEntry( const Tomahawk::query_ptr& query, const QString& oldrev ); virtual void addEntry( const Tomahawk::query_ptr& query, const QString& oldrev );
@@ -155,6 +158,7 @@ public:
void setCreator( const QString& s ) { m_creator = s; } void setCreator( const QString& s ) { m_creator = s; }
void setGuid( const QString& s ) { m_guid = s; } void setGuid( const QString& s ) { m_guid = s; }
void setShared( bool b ) { m_shared = b; } void setShared( bool b ) { m_shared = b; }
void setCreatedOn( uint createdOn ) { m_createdOn = createdOn; }
// </IGNORE> // </IGNORE>
virtual QList<Tomahawk::query_ptr> tracks(); virtual QList<Tomahawk::query_ptr> tracks();
@@ -184,7 +188,7 @@ signals:
/// was deleted, eh? /// was deleted, eh?
void deleted( const Tomahawk::playlist_ptr& pl ); void deleted( const Tomahawk::playlist_ptr& pl );
void repeatModeChanged( PlaylistInterface::RepeatMode mode ); void repeatModeChanged( PlaylistInterface::RepeatMode mode );
void shuffleModeChanged( bool enabled ); void shuffleModeChanged( bool enabled );
@@ -214,6 +218,7 @@ protected:
const QString& title, const QString& title,
const QString& info, const QString& info,
const QString& creator, const QString& creator,
uint createdOn,
bool shared, bool shared,
int lastmod, int lastmod,
const QString& guid = "" ); // populate db const QString& guid = "" ); // populate db
@@ -247,6 +252,7 @@ private:
QString m_currentrevision; QString m_currentrevision;
QString m_guid, m_title, m_info, m_creator; QString m_guid, m_title, m_info, m_creator;
unsigned int m_lastmodified; unsigned int m_lastmodified;
unsigned int m_createdOn;
bool m_shared; bool m_shared;
QList< plentry_ptr > m_entries; QList< plentry_ptr > m_entries;

View File

@@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
* *
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org> * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* *
* Tomahawk is free software: you can redistribute it and/or modify * Tomahawk is free software: you can redistribute it and/or modify
@@ -43,17 +43,18 @@ DynamicPlaylist::~DynamicPlaylist()
} }
// Called by loadAllPlaylists command // Called by loadAllPlaylists command
DynamicPlaylist::DynamicPlaylist ( const Tomahawk::source_ptr& src, DynamicPlaylist::DynamicPlaylist ( const Tomahawk::source_ptr& src,
const QString& currentrevision, const QString& currentrevision,
const QString& title, const QString& title,
const QString& info, const QString& info,
const QString& creator, const QString& creator,
const QString& type, uint createdOn,
const QString& type,
GeneratorMode mode, GeneratorMode mode,
bool shared, bool shared,
int lastmod, int lastmod,
const QString& guid ) const QString& guid )
: Playlist( src, currentrevision, title, info, creator, shared, lastmod, guid ) : Playlist( src, currentrevision, title, info, creator, createdOn, shared, lastmod, guid )
{ {
qDebug() << "Creating Dynamic Playlist 1"; qDebug() << "Creating Dynamic Playlist 1";
// TODO instantiate generator // TODO instantiate generator
@@ -63,12 +64,12 @@ DynamicPlaylist::DynamicPlaylist ( const Tomahawk::source_ptr& src,
// called when a new playlist is created (no currentrevision, new guid) // called when a new playlist is created (no currentrevision, new guid)
DynamicPlaylist::DynamicPlaylist ( const Tomahawk::source_ptr& author, DynamicPlaylist::DynamicPlaylist ( const Tomahawk::source_ptr& author,
const QString& guid, const QString& guid,
const QString& title, const QString& title,
const QString& info, const QString& info,
const QString& creator, const QString& creator,
const QString& type, const QString& type,
bool shared ) bool shared )
: Playlist ( author, guid, title, info, creator, shared ) : Playlist ( author, guid, title, info, creator, shared )
{ {
@@ -76,31 +77,31 @@ DynamicPlaylist::DynamicPlaylist ( const Tomahawk::source_ptr& author,
m_generator = geninterface_ptr( GeneratorFactory::create( type ) ); m_generator = geninterface_ptr( GeneratorFactory::create( type ) );
} }
geninterface_ptr geninterface_ptr
DynamicPlaylist::generator() const DynamicPlaylist::generator() const
{ {
return m_generator; return m_generator;
} }
int int
DynamicPlaylist::mode() const DynamicPlaylist::mode() const
{ {
return m_generator->mode(); return m_generator->mode();
} }
void void
DynamicPlaylist::setGenerator(const Tomahawk::geninterface_ptr& gen_ptr) DynamicPlaylist::setGenerator(const Tomahawk::geninterface_ptr& gen_ptr)
{ {
m_generator = gen_ptr; m_generator = gen_ptr;
} }
QString QString
DynamicPlaylist::type() const DynamicPlaylist::type() const
{ {
return m_generator->type(); return m_generator->type();
} }
void void
DynamicPlaylist::setMode( int mode ) DynamicPlaylist::setMode( int mode )
{ {
m_generator->setMode( (GeneratorMode)mode ); m_generator->setMode( (GeneratorMode)mode );
@@ -108,27 +109,27 @@ DynamicPlaylist::setMode( int mode )
dynplaylist_ptr dynplaylist_ptr
DynamicPlaylist::create( const Tomahawk::source_ptr& author, DynamicPlaylist::create( const Tomahawk::source_ptr& author,
const QString& guid, const QString& guid,
const QString& title, const QString& title,
const QString& info, const QString& info,
const QString& creator, const QString& creator,
bool shared ) bool shared )
{ {
// default generator // default generator
QString type = ""; QString type = "";
dynplaylist_ptr dynplaylist = dynplaylist_ptr( new DynamicPlaylist( author, guid, title, info, creator, type, shared ) ); dynplaylist_ptr dynplaylist = dynplaylist_ptr( new DynamicPlaylist( author, guid, title, info, creator, type, shared ) );
DatabaseCommand_CreateDynamicPlaylist* cmd = new DatabaseCommand_CreateDynamicPlaylist( author, dynplaylist ); DatabaseCommand_CreateDynamicPlaylist* cmd = new DatabaseCommand_CreateDynamicPlaylist( author, dynplaylist );
connect( cmd, SIGNAL(finished()), dynplaylist.data(), SIGNAL(created()) ); connect( cmd, SIGNAL(finished()), dynplaylist.data(), SIGNAL(created()) );
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>(cmd) ); Database::instance()->enqueue( QSharedPointer<DatabaseCommand>(cmd) );
dynplaylist->reportCreated( dynplaylist ); dynplaylist->reportCreated( dynplaylist );
return dynplaylist; return dynplaylist;
} }
void void
DynamicPlaylist::createNewRevision( const QString& newUuid ) DynamicPlaylist::createNewRevision( const QString& newUuid )
{ {
if( mode() == Static ) if( mode() == Static )
@@ -142,22 +143,22 @@ DynamicPlaylist::createNewRevision( const QString& newUuid )
// create a new revision that will be a static playlist, as it has entries // create a new revision that will be a static playlist, as it has entries
void void
DynamicPlaylist::createNewRevision( const QString& newrev, DynamicPlaylist::createNewRevision( const QString& newrev,
const QString& oldrev, const QString& oldrev,
const QString& type, const QString& type,
const QList< dyncontrol_ptr>& controls, const QList< dyncontrol_ptr>& controls,
const QList< plentry_ptr >& entries ) const QList< plentry_ptr >& entries )
{ {
// get the newly added tracks // get the newly added tracks
QList< plentry_ptr > added = newEntries( entries ); QList< plentry_ptr > added = newEntries( entries );
QStringList orderedguids; QStringList orderedguids;
for( int i = 0; i < entries.size(); ++i ) for( int i = 0; i < entries.size(); ++i )
orderedguids << entries.at(i)->guid(); orderedguids << entries.at(i)->guid();
// no conflict resolution or partial updating for controls. all or nothing baby // no conflict resolution or partial updating for controls. all or nothing baby
// source making the change (local user in this case) // source making the change (local user in this case)
source_ptr author = SourceList::instance()->getLocal(); source_ptr author = SourceList::instance()->getLocal();
// command writes new rev to DB and calls setRevision, which emits our signal // command writes new rev to DB and calls setRevision, which emits our signal
@@ -176,10 +177,10 @@ DynamicPlaylist::createNewRevision( const QString& newrev,
} }
// create a new revision that will be an ondemand playlist, as it has no entries // create a new revision that will be an ondemand playlist, as it has no entries
void void
DynamicPlaylist::createNewRevision( const QString& newrev, DynamicPlaylist::createNewRevision( const QString& newrev,
const QString& oldrev, const QString& oldrev,
const QString& type, const QString& type,
const QList< dyncontrol_ptr>& controls ) const QList< dyncontrol_ptr>& controls )
{ {
// can skip the entry stuff. just overwrite with new info // can skip the entry stuff. just overwrite with new info
@@ -196,13 +197,13 @@ DynamicPlaylist::createNewRevision( const QString& newrev,
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) ); Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
} }
void void
DynamicPlaylist::loadRevision( const QString& rev ) DynamicPlaylist::loadRevision( const QString& rev )
{ {
qDebug() << Q_FUNC_INFO << "Loading with:" << ( rev.isEmpty() ? currentrevision() : rev ); qDebug() << Q_FUNC_INFO << "Loading with:" << ( rev.isEmpty() ? currentrevision() : rev );
DatabaseCommand_LoadDynamicPlaylist* cmd = new DatabaseCommand_LoadDynamicPlaylist( rev.isEmpty() ? currentrevision() : rev ); DatabaseCommand_LoadDynamicPlaylist* cmd = new DatabaseCommand_LoadDynamicPlaylist( rev.isEmpty() ? currentrevision() : rev );
if( m_generator->mode() == OnDemand ) { if( m_generator->mode() == OnDemand ) {
connect( cmd, SIGNAL( done( QString, connect( cmd, SIGNAL( done( QString,
bool, bool,
@@ -230,22 +231,22 @@ DynamicPlaylist::loadRevision( const QString& rev )
QList< QVariantMap >, QList< QVariantMap >,
bool, bool,
QMap< QString, Tomahawk::plentry_ptr >, QMap< QString, Tomahawk::plentry_ptr >,
bool ) ) ); bool ) ) );
} }
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) ); Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
} }
bool bool
DynamicPlaylist::remove( const Tomahawk::dynplaylist_ptr& playlist ) DynamicPlaylist::remove( const Tomahawk::dynplaylist_ptr& playlist )
{ {
DatabaseCommand_DeletePlaylist* cmd = new DatabaseCommand_DeleteDynamicPlaylist( playlist->author(), playlist->guid() ); DatabaseCommand_DeletePlaylist* cmd = new DatabaseCommand_DeleteDynamicPlaylist( playlist->author(), playlist->guid() );
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>(cmd) ); Database::instance()->enqueue( QSharedPointer<DatabaseCommand>(cmd) );
return false; return false;
} }
void void
DynamicPlaylist::reportCreated( const Tomahawk::dynplaylist_ptr& self ) DynamicPlaylist::reportCreated( const Tomahawk::dynplaylist_ptr& self )
{ {
qDebug() << Q_FUNC_INFO; qDebug() << Q_FUNC_INFO;
@@ -255,26 +256,26 @@ DynamicPlaylist::reportCreated( const Tomahawk::dynplaylist_ptr& self )
// will emit Collection::playlistCreated(...) // will emit Collection::playlistCreated(...)
// qDebug() << "Creating dynplaylist belonging to:" << author().data() << author().isNull(); // qDebug() << "Creating dynplaylist belonging to:" << author().data() << author().isNull();
// qDebug() << "REPORTING DYNAMIC PLAYLIST CREATED:" << this << author()->friendlyName(); // qDebug() << "REPORTING DYNAMIC PLAYLIST CREATED:" << this << author()->friendlyName();
author()->collection()->addDynamicPlaylist( self ); author()->collection()->addDynamicPlaylist( self );
} }
void void
DynamicPlaylist::reportDeleted( const Tomahawk::dynplaylist_ptr& self ) DynamicPlaylist::reportDeleted( const Tomahawk::dynplaylist_ptr& self )
{ {
qDebug() << Q_FUNC_INFO; qDebug() << Q_FUNC_INFO;
Q_ASSERT( self.data() == this ); Q_ASSERT( self.data() == this );
// will emit Collection::playlistDeleted(...) // will emit Collection::playlistDeleted(...)
author()->collection()->deleteDynamicPlaylist( self ); author()->collection()->deleteDynamicPlaylist( self );
emit deleted( self ); emit deleted( self );
} }
void DynamicPlaylist::addEntries(const QList< query_ptr >& queries, const QString& oldrev) void DynamicPlaylist::addEntries(const QList< query_ptr >& queries, const QString& oldrev)
{ {
Q_ASSERT( m_generator->mode() == Static ); Q_ASSERT( m_generator->mode() == Static );
QList<plentry_ptr> el = addEntriesInternal( queries ); QList<plentry_ptr> el = addEntriesInternal( queries );
QString newrev = uuid(); QString newrev = uuid();
createNewRevision( newrev, oldrev, m_generator->type(), m_generator->controls(), el ); createNewRevision( newrev, oldrev, m_generator->type(), m_generator->controls(), el );
} }
@@ -283,17 +284,17 @@ void DynamicPlaylist::addEntry(const Tomahawk::query_ptr& query, const QString&
{ {
QList<query_ptr> queries; QList<query_ptr> queries;
queries << query; queries << query;
addEntries( queries, oldrev ); addEntries( queries, oldrev );
} }
void DynamicPlaylist::setRevision( const QString& rev, void DynamicPlaylist::setRevision( const QString& rev,
const QList< QString >& neworderedguids, const QList< QString >& neworderedguids,
const QList< QString >& oldorderedguids, const QList< QString >& oldorderedguids,
const QString& type, const QString& type,
const QList< dyncontrol_ptr >& controls, const QList< dyncontrol_ptr >& controls,
bool is_newest_rev, bool is_newest_rev,
const QMap< QString, plentry_ptr >& addedmap, const QMap< QString, plentry_ptr >& addedmap,
bool applied) bool applied)
{ {
// we're probably being called by a database worker thread // we're probably being called by a database worker thread
@@ -315,32 +316,32 @@ void DynamicPlaylist::setRevision( const QString& rev,
if( m_generator->type() != type ) { // new generator needed if( m_generator->type() != type ) { // new generator needed
m_generator = GeneratorFactory::create( type ); m_generator = GeneratorFactory::create( type );
} }
m_generator->setControls( controls ); m_generator->setControls( controls );
m_generator->setMode( Static ); m_generator->setMode( Static );
DynamicPlaylistRevision dpr = setNewRevision( rev, neworderedguids, oldorderedguids, is_newest_rev, addedmap ); DynamicPlaylistRevision dpr = setNewRevision( rev, neworderedguids, oldorderedguids, is_newest_rev, addedmap );
dpr.applied = applied; dpr.applied = applied;
dpr.controls = controls; dpr.controls = controls;
dpr.type = type; dpr.type = type;
dpr.mode = Static; dpr.mode = Static;
if( applied ) { if( applied ) {
setCurrentrevision( rev ); setCurrentrevision( rev );
} }
// qDebug() << "EMITTING REVISION LOADED 1!"; // qDebug() << "EMITTING REVISION LOADED 1!";
emit dynamicRevisionLoaded( dpr ); emit dynamicRevisionLoaded( dpr );
} }
void void
DynamicPlaylist::setRevision( const QString& rev, DynamicPlaylist::setRevision( const QString& rev,
const QList< QString >& neworderedguids, const QList< QString >& neworderedguids,
const QList< QString >& oldorderedguids, const QList< QString >& oldorderedguids,
const QString& type, const QString& type,
const QList< QVariantMap>& controlsV, const QList< QVariantMap>& controlsV,
bool is_newest_rev, bool is_newest_rev,
const QMap< QString, Tomahawk::plentry_ptr >& addedmap, const QMap< QString, Tomahawk::plentry_ptr >& addedmap,
bool applied ) bool applied )
{ {
if( QThread::currentThread() != thread() ) if( QThread::currentThread() != thread() )
@@ -358,16 +359,16 @@ DynamicPlaylist::setRevision( const QString& rev,
Q_ARG( bool, applied ) ); Q_ARG( bool, applied ) );
return; return;
} }
QList<dyncontrol_ptr> controls = variantsToControl( controlsV ); QList<dyncontrol_ptr> controls = variantsToControl( controlsV );
setRevision( rev, neworderedguids, oldorderedguids, type, controls, is_newest_rev, addedmap, applied ); setRevision( rev, neworderedguids, oldorderedguids, type, controls, is_newest_rev, addedmap, applied );
} }
void DynamicPlaylist::setRevision( const QString& rev, void DynamicPlaylist::setRevision( const QString& rev,
bool is_newest_rev, bool is_newest_rev,
const QString& type, const QString& type,
const QList< dyncontrol_ptr >& controls, const QList< dyncontrol_ptr >& controls,
bool applied ) bool applied )
{ {
if( QThread::currentThread() != thread() ) if( QThread::currentThread() != thread() )
@@ -385,30 +386,30 @@ void DynamicPlaylist::setRevision( const QString& rev,
if( m_generator->type() != type ) { // new generator needed if( m_generator->type() != type ) { // new generator needed
m_generator = geninterface_ptr( GeneratorFactory::create( type ) ); m_generator = geninterface_ptr( GeneratorFactory::create( type ) );
} }
m_generator->setControls( controls ); m_generator->setControls( controls );
m_generator->setMode( OnDemand ); m_generator->setMode( OnDemand );
DynamicPlaylistRevision dpr; DynamicPlaylistRevision dpr;
dpr.oldrevisionguid = currentrevision(); dpr.oldrevisionguid = currentrevision();
dpr.revisionguid = rev; dpr.revisionguid = rev;
dpr.controls = controls; dpr.controls = controls;
dpr.type = type; dpr.type = type;
dpr.mode = OnDemand; dpr.mode = OnDemand;
if( applied ) { if( applied ) {
setCurrentrevision( rev ); setCurrentrevision( rev );
} }
// qDebug() << "EMITTING REVISION LOADED 2!"; // qDebug() << "EMITTING REVISION LOADED 2!";
emit dynamicRevisionLoaded( dpr ); emit dynamicRevisionLoaded( dpr );
} }
void void
DynamicPlaylist::setRevision( const QString& rev, DynamicPlaylist::setRevision( const QString& rev,
bool is_newest_rev, bool is_newest_rev,
const QString& type, const QString& type,
const QList< QVariantMap >& controlsV, const QList< QVariantMap >& controlsV,
bool applied ) bool applied )
{ {
if( QThread::currentThread() != thread() ) if( QThread::currentThread() != thread() )
@@ -422,8 +423,8 @@ DynamicPlaylist::setRevision( const QString& rev,
QGenericArgument( "QList< QVariantMap >" , (const void*)&controlsV ), QGenericArgument( "QList< QVariantMap >" , (const void*)&controlsV ),
Q_ARG( bool, applied ) ); Q_ARG( bool, applied ) );
return; return;
} }
QList<dyncontrol_ptr> controls = variantsToControl( controlsV ); QList<dyncontrol_ptr> controls = variantsToControl( controlsV );
setRevision( rev, is_newest_rev, type, controls, applied ); setRevision( rev, is_newest_rev, type, controls, applied );
} }

View File

@@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
* *
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org> * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* *
* Tomahawk is free software: you can redistribute it and/or modify * Tomahawk is free software: you can redistribute it and/or modify
@@ -35,7 +35,7 @@ class DatabaseCommand_CreateDynamicPlaylist;
class DatabaseCollection; class DatabaseCollection;
namespace Tomahawk { namespace Tomahawk {
/** /**
* Subclass of playlist that adds the information needed to store a dynamic playlist. * Subclass of playlist that adds the information needed to store a dynamic playlist.
* It uses normal PlaylistEntries but also has a mode, a generator, and a list of controls * It uses normal PlaylistEntries but also has a mode, a generator, and a list of controls
@@ -46,35 +46,35 @@ struct DLLEXPORT DynamicPlaylistRevision : PlaylistRevision
QList< dyncontrol_ptr > controls; QList< dyncontrol_ptr > controls;
Tomahawk::GeneratorMode mode; Tomahawk::GeneratorMode mode;
QString type; QString type;
DynamicPlaylistRevision( const PlaylistRevision& other ) DynamicPlaylistRevision( const PlaylistRevision& other )
{ {
revisionguid = other.revisionguid; revisionguid = other.revisionguid;
oldrevisionguid = other.oldrevisionguid; oldrevisionguid = other.oldrevisionguid;
newlist = other.newlist; newlist = other.newlist;
added = other.added; added = other.added;
removed = other.removed; removed = other.removed;
applied = other.applied; applied = other.applied;
} }
DynamicPlaylistRevision() {} DynamicPlaylistRevision() {}
}; };
class DLLEXPORT DynamicPlaylist : public Playlist class DLLEXPORT DynamicPlaylist : public Playlist
{ {
Q_OBJECT Q_OBJECT
// :-( int becuase qjson chokes on my enums // :-( int becuase qjson chokes on my enums
Q_PROPERTY( int mode WRITE setMode READ mode ) Q_PROPERTY( int mode WRITE setMode READ mode )
Q_PROPERTY( QString type WRITE setType READ type ) Q_PROPERTY( QString type WRITE setType READ type )
friend class ::DatabaseCommand_SetDynamicPlaylistRevision; friend class ::DatabaseCommand_SetDynamicPlaylistRevision;
friend class ::DatabaseCommand_CreateDynamicPlaylist; friend class ::DatabaseCommand_CreateDynamicPlaylist;
friend class ::DatabaseCollection; /// :-( friend class ::DatabaseCollection; /// :-(
public: public:
virtual ~DynamicPlaylist(); virtual ~DynamicPlaylist();
/// Generate an empty dynamic playlist with default generator /// Generate an empty dynamic playlist with default generator
static Tomahawk::dynplaylist_ptr create( const source_ptr& author, static Tomahawk::dynplaylist_ptr create( const source_ptr& author,
const QString& guid, const QString& guid,
@@ -84,21 +84,21 @@ public:
bool shared bool shared
); );
static bool remove( const dynplaylist_ptr& playlist ); static bool remove( const dynplaylist_ptr& playlist );
virtual void loadRevision( const QString& rev = "" ); virtual void loadRevision( const QString& rev = "" );
// :-( int becuase qjson chokes on my enums // :-( int becuase qjson chokes on my enums
int mode() const; int mode() const;
QString type() const; QString type() const;
geninterface_ptr generator() const; geninterface_ptr generator() const;
// Creates a new revision from the playlist in memory. Use this is you change the controls or // Creates a new revision from the playlist in memory. Use this is you change the controls or
// mode of a playlist and want to save it to db/others. // mode of a playlist and want to save it to db/others.
void createNewRevision( const QString& uuid = QString() ); void createNewRevision( const QString& uuid = QString() );
virtual void addEntries( const QList< query_ptr >& queries, const QString& oldrev ); virtual void addEntries( const QList< query_ptr >& queries, const QString& oldrev );
virtual void addEntry( const Tomahawk::query_ptr& query, const QString& oldrev ); virtual void addEntry( const Tomahawk::query_ptr& query, const QString& oldrev );
// <IGNORE hack="true"> // <IGNORE hack="true">
// these need to exist and be public for the json serialization stuff // these need to exist and be public for the json serialization stuff
// you SHOULD NOT call them. They are used for an alternate CTOR method from json. // you SHOULD NOT call them. They are used for an alternate CTOR method from json.
@@ -108,13 +108,13 @@ public:
void setType( const QString& /*type*/ ) { /** TODO */; } void setType( const QString& /*type*/ ) { /** TODO */; }
void setGenerator( const geninterface_ptr& gen_ptr ); void setGenerator( const geninterface_ptr& gen_ptr );
// </IGNORE> // </IGNORE>
signals: signals:
/// emitted when the playlist revision changes (whenever the playlist changes) /// emitted when the playlist revision changes (whenever the playlist changes)
void dynamicRevisionLoaded( Tomahawk::DynamicPlaylistRevision ); void dynamicRevisionLoaded( Tomahawk::DynamicPlaylistRevision );
void deleted( const Tomahawk::dynplaylist_ptr& pl ); void deleted( const Tomahawk::dynplaylist_ptr& pl );
public slots: public slots:
// want to update the playlist from the model? // want to update the playlist from the model?
// generate a newrev using uuid() and call this: // generate a newrev using uuid() and call this:
@@ -122,10 +122,10 @@ public slots:
void createNewRevision( const QString& newrev, const QString& oldrev, const QString& type, const QList< dyncontrol_ptr>& controls, const QList< plentry_ptr >& entries ); void createNewRevision( const QString& newrev, const QString& oldrev, const QString& type, const QList< dyncontrol_ptr>& controls, const QList< plentry_ptr >& entries );
// if it is ondemand, no entries are needed implicitly sets mode to ondemand // if it is ondemand, no entries are needed implicitly sets mode to ondemand
void createNewRevision( const QString& newrev, const QString& oldrev, const QString& type, const QList< dyncontrol_ptr>& controls ); void createNewRevision( const QString& newrev, const QString& oldrev, const QString& type, const QList< dyncontrol_ptr>& controls );
void reportCreated( const Tomahawk::dynplaylist_ptr& self ); void reportCreated( const Tomahawk::dynplaylist_ptr& self );
void reportDeleted( const Tomahawk::dynplaylist_ptr& self ); void reportDeleted( const Tomahawk::dynplaylist_ptr& self );
// called from setdynamicplaylistrevision db cmd // called from setdynamicplaylistrevision db cmd
// 4 options, because dbcmds can't create qwidgets: // 4 options, because dbcmds can't create qwidgets:
// static version, qvariant controls // static version, qvariant controls
@@ -147,7 +147,7 @@ public slots:
const QList< Tomahawk::dyncontrol_ptr >& controls, const QList< Tomahawk::dyncontrol_ptr >& controls,
bool is_newest_rev, bool is_newest_rev,
const QMap< QString, Tomahawk::plentry_ptr >& addedmap, const QMap< QString, Tomahawk::plentry_ptr >& addedmap,
bool applied ); bool applied );
// ondemand version // ondemand version
void setRevision( const QString& rev, void setRevision( const QString& rev,
bool is_newest_rev, bool is_newest_rev,
@@ -166,12 +166,13 @@ private:
const QString& title, const QString& title,
const QString& info, const QString& info,
const QString& creator, const QString& creator,
uint createdOn,
const QString& type, const QString& type,
GeneratorMode mode, GeneratorMode mode,
bool shared, bool shared,
int lastmod, int lastmod,
const QString& guid = "" ); // populate db const QString& guid = "" ); // populate db
// called when creating new playlist // called when creating new playlist
explicit DynamicPlaylist( const source_ptr& author, explicit DynamicPlaylist( const source_ptr& author,
const QString& guid, const QString& guid,
@@ -180,11 +181,11 @@ private:
const QString& creator, const QString& creator,
const QString& type, const QString& type,
bool shared ); bool shared );
private: private:
QList< dyncontrol_ptr > variantsToControl( const QList< QVariantMap >& controlsV ); QList< dyncontrol_ptr > variantsToControl( const QList< QVariantMap >& controlsV );
geninterface_ptr m_generator; geninterface_ptr m_generator;
}; };
}; // namespace }; // namespace

View File

@@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
* *
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org> * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* *
* Tomahawk is free software: you can redistribute it and/or modify * Tomahawk is free software: you can redistribute it and/or modify
@@ -38,6 +38,7 @@ SourcesModel::SourcesModel( SourceTreeView* parent )
, m_parent( parent ) , m_parent( parent )
{ {
setColumnCount( 1 ); setColumnCount( 1 );
setSortRole( SortRole );
onSourceAdded( SourceList::instance()->sources() ); onSourceAdded( SourceList::instance()->sources() );
connect( SourceList::instance(), SIGNAL( sourceAdded( Tomahawk::source_ptr ) ), SLOT( onSourceAdded( Tomahawk::source_ptr ) ) ); connect( SourceList::instance(), SIGNAL( sourceAdded( Tomahawk::source_ptr ) ), SLOT( onSourceAdded( Tomahawk::source_ptr ) ) );
@@ -97,6 +98,32 @@ SourcesModel::data( const QModelIndex& index, int role ) const
if ( role == Qt::SizeHintRole ) if ( role == Qt::SizeHintRole )
{ {
return QSize( 0, 18 ); return QSize( 0, 18 );
} else if ( role == SortRole )
{
if ( indexType( index ) == PlaylistSource )
{
playlist_ptr playlist = indexToPlaylist( index );
if ( !playlist.isNull() )
return playlist->createdOn();
} else if ( indexType( index ) == DynamicPlaylistSource )
{
dynplaylist_ptr playlist = indexToDynamicPlaylist( index );
if ( !playlist.isNull() )
return playlist->createdOn();
} else if( indexType( index ) == CollectionSource )
{
source_ptr source = indexToTreeItem( index )->source();
if( source.isNull() )
return 0; // Super Collection is first
else if( source->isLocal() )
return 1; // Then Local collection
else // then all the rest
return 5;
} else
{
qDebug() << "RETURNING NULL SORT DATA!";
return QVariant();
}
} }
return QStandardItemModel::data( index, role ); return QStandardItemModel::data( index, role );
@@ -152,7 +179,7 @@ SourcesModel::appendItem( const source_ptr& source )
connect( source.data(), SIGNAL( playbackStarted( Tomahawk::query_ptr ) ), SLOT( onSourceChanged() ) ); connect( source.data(), SIGNAL( playbackStarted( Tomahawk::query_ptr ) ), SLOT( onSourceChanged() ) );
connect( source.data(), SIGNAL( stateChanged() ), SLOT( onSourceChanged() ) ); connect( source.data(), SIGNAL( stateChanged() ), SLOT( onSourceChanged() ) );
} }
return true; // FIXME return true; // FIXME
} }
@@ -246,7 +273,7 @@ SourcesModel::indexToDynamicPlaylist( const QModelIndex& index )
dynplaylist_ptr res; dynplaylist_ptr res;
if ( !index.isValid() ) if ( !index.isValid() )
return res; return res;
if ( indexType( index ) == DynamicPlaylistSource ) if ( indexType( index ) == DynamicPlaylistSource )
{ {
QModelIndex idx = index.model()->index( index.row(), 0, index.parent() ); QModelIndex idx = index.model()->index( index.row(), 0, index.parent() );
@@ -255,7 +282,7 @@ SourcesModel::indexToDynamicPlaylist( const QModelIndex& index )
if ( playlist ) if ( playlist )
return *playlist; return *playlist;
} }
return res; return res;
} }
@@ -311,12 +338,12 @@ SourcesModel::dynamicPlaylistToIndex( const Tomahawk::dynplaylist_ptr& playlist
for ( int i = 0; i < rowCount(); i++ ) for ( int i = 0; i < rowCount(); i++ )
{ {
QModelIndex pidx = index( i, 0 ); QModelIndex pidx = index( i, 0 );
for ( int j = 0; j < rowCount( pidx ); j++ ) for ( int j = 0; j < rowCount( pidx ); j++ )
{ {
QModelIndex idx = index( j, 0, pidx ); QModelIndex idx = index( j, 0, pidx );
SourcesModel::SourceType type = SourcesModel::indexType( idx ); SourcesModel::SourceType type = SourcesModel::indexType( idx );
if ( type == SourcesModel::DynamicPlaylistSource ) if ( type == SourcesModel::DynamicPlaylistSource )
{ {
playlist_ptr p = SourcesModel::indexToDynamicPlaylist( idx ); playlist_ptr p = SourcesModel::indexToDynamicPlaylist( idx );
@@ -325,7 +352,7 @@ SourcesModel::dynamicPlaylistToIndex( const Tomahawk::dynplaylist_ptr& playlist
} }
} }
} }
return QModelIndex(); return QModelIndex();
} }
@@ -367,11 +394,11 @@ SourcesModel::setData( const QModelIndex& index, const QVariant& value, int role
{ {
playlist = indexToDynamicPlaylist( index ).staticCast< Playlist >(); playlist = indexToDynamicPlaylist( index ).staticCast< Playlist >();
} }
if ( !playlist.isNull() ) if ( !playlist.isNull() )
{ {
playlist->rename( value.toString() ); playlist->rename( value.toString() );
QStandardItemModel::setData( index, value, Qt::DisplayRole ); QStandardItemModel::setData( index, value, Qt::DisplayRole );
return true; return true;
} }
@@ -383,7 +410,7 @@ void
SourcesModel::onSourceChanged() SourcesModel::onSourceChanged()
{ {
Source* src = qobject_cast< Source* >( sender() ); Source* src = qobject_cast< Source* >( sender() );
for ( int i = 0; i < rowCount(); i++ ) for ( int i = 0; i < rowCount(); i++ )
{ {
QModelIndex idx = index( i, 0 ); QModelIndex idx = index( i, 0 );

View File

@@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
* *
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org> * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* *
* Tomahawk is free software: you can redistribute it and/or modify * Tomahawk is free software: you can redistribute it and/or modify
@@ -31,15 +31,19 @@ class SourcesModel : public QStandardItemModel
{ {
Q_OBJECT Q_OBJECT
public: public:
enum SourceType { enum SourceType {
Invalid = -1, Invalid = -1,
CollectionSource = 0, CollectionSource = 0,
PlaylistSource = 1, PlaylistSource = 1,
DynamicPlaylistSource = 2 DynamicPlaylistSource = 2
}; };
enum ExtraRoles {
SortRole = Qt::UserRole + 20,
};
explicit SourcesModel( SourceTreeView* parent = 0 ); explicit SourcesModel( SourceTreeView* parent = 0 );
virtual QStringList mimeTypes() const; virtual QStringList mimeTypes() const;
@@ -58,7 +62,7 @@ public:
QModelIndex playlistToIndex( const Tomahawk::playlist_ptr& playlist ); QModelIndex playlistToIndex( const Tomahawk::playlist_ptr& playlist );
QModelIndex dynamicPlaylistToIndex( const Tomahawk::dynplaylist_ptr& playlist ); QModelIndex dynamicPlaylistToIndex( const Tomahawk::dynplaylist_ptr& playlist );
QModelIndex collectionToIndex( const Tomahawk::collection_ptr& collection ); QModelIndex collectionToIndex( const Tomahawk::collection_ptr& collection );
signals: signals:
void clicked( const QModelIndex& ); void clicked( const QModelIndex& );

View File

@@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
* *
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org> * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* *
* Tomahawk is free software: you can redistribute it and/or modify * Tomahawk is free software: you can redistribute it and/or modify
@@ -32,6 +32,7 @@ SourcesProxyModel::SourcesProxyModel( SourcesModel* model, QObject* parent )
{ {
setDynamicSortFilter( true ); setDynamicSortFilter( true );
setSortRole( SourcesModel::SortRole );
setSourceModel( model ); setSourceModel( model );
} }
@@ -63,7 +64,7 @@ SourcesProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex& sourcePar
{ {
if ( !m_filtered ) if ( !m_filtered )
return true; return true;
SourceTreeItem* sti = m_model->indexToTreeItem( sourceModel()->index( sourceRow, 0, sourceParent ) ); SourceTreeItem* sti = m_model->indexToTreeItem( sourceModel()->index( sourceRow, 0, sourceParent ) );
if ( sti ) if ( sti )
{ {

View File

@@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
* *
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org> * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* *
* Tomahawk is free software: you can redistribute it and/or modify * Tomahawk is free software: you can redistribute it and/or modify

View File

@@ -80,6 +80,9 @@ SourceTreeView::SourceTreeView( QWidget* parent )
setIndentation( 16 ); setIndentation( 16 );
setAnimated( true ); setAnimated( true );
setSortingEnabled( true );
sortByColumn( 1, Qt::AscendingOrder );
setItemDelegate( new SourceDelegate( this ) ); setItemDelegate( new SourceDelegate( this ) );
setContextMenuPolicy( Qt::CustomContextMenu ); setContextMenuPolicy( Qt::CustomContextMenu );