Created
April 15, 2011 21:25
-
-
Save lfranchi/922509 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/resources.qrc b/resources.qrc | |
index 9996e5c..7442790 100644 | |
--- a/resources.qrc | |
+++ b/resources.qrc | |
@@ -88,5 +88,6 @@ | |
<file>./data/www/auth.html</file> | |
<file>./data/www/auth.na.html</file> | |
<file>./data/www/tomahawk_banner_small.png</file> | |
+<file>./data/sql/dbmigrate-22_to_23.sql</file> | |
</qresource> | |
</RCC> | |
diff --git a/src/libtomahawk/database/databasecollection.cpp b/src/libtomahawk/database/databasecollection.cpp | |
index 23e3658..bbcf6da 100644 | |
--- a/src/libtomahawk/database/databasecollection.cpp | |
+++ b/src/libtomahawk/database/databasecollection.cpp | |
@@ -143,11 +143,12 @@ void DatabaseCollection::dynamicPlaylistCreated( const source_ptr& source, const | |
data[1].toString(), //title | |
data[2].toString(), //info | |
data[3].toString(), //creator | |
- data[4].toString(), // dynamic type | |
- static_cast<GeneratorMode>(data[5].toInt()), // dynamic mode | |
- data[6].toBool(), //shared | |
- data[7].toInt(), //lastmod | |
- data[8].toString() ) ); //GUID | |
+ data[4].toUInt(), // createdOn | |
+ data[5].toString(), // dynamic type | |
+ static_cast<GeneratorMode>(data[6].toInt()), // dynamic mode | |
+ data[7].toBool(), //shared | |
+ data[8].toInt(), //lastmod | |
+ data[9].toString() ) ); //GUID | |
addDynamicPlaylist( p ); | |
} | |
diff --git a/src/libtomahawk/database/databasecommand_createdynamicplaylist.cpp b/src/libtomahawk/database/databasecommand_createdynamicplaylist.cpp | |
index f432f3a..31b6751 100644 | |
--- a/src/libtomahawk/database/databasecommand_createdynamicplaylist.cpp | |
+++ b/src/libtomahawk/database/databasecommand_createdynamicplaylist.cpp | |
@@ -1,5 +1,5 @@ | |
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === | |
- * | |
+ * | |
* Copyright 2010-2011, Christian Muehlhaeuser <[email protected]> | |
* | |
* Tomahawk is free software: you can redistribute it and/or modify | |
@@ -53,15 +53,15 @@ DatabaseCommand_CreateDynamicPlaylist::exec( DatabaseImpl* lib ) | |
qDebug() << Q_FUNC_INFO; | |
Q_ASSERT( !( m_playlist.isNull() && m_v.isNull() ) ); | |
Q_ASSERT( !source().isNull() ); | |
- | |
+ | |
DatabaseCommand_CreatePlaylist::createPlaylist( lib, true ); | |
qDebug() << "Created normal playlist, now creating additional dynamic info!"; | |
- | |
+ | |
TomahawkSqlQuery cre = lib->newquery(); | |
cre.prepare( "INSERT INTO dynamic_playlist( guid, pltype, plmode ) " | |
"VALUES( ?, ?, ? )" ); | |
- | |
+ | |
if( m_playlist.isNull() ) { | |
QVariantMap m = m_v.toMap(); | |
cre.addBindValue( m.value( "guid" ) ); | |
@@ -73,22 +73,6 @@ DatabaseCommand_CreateDynamicPlaylist::exec( DatabaseImpl* lib ) | |
cre.addBindValue( m_playlist->mode() ); | |
} | |
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."; | |
return; | |
} | |
- | |
+ | |
if( report() == false ) | |
return; | |
- | |
+ | |
qDebug() << Q_FUNC_INFO << "..reporting.."; | |
if( m_playlist.isNull() ) { | |
source_ptr src = source(); | |
diff --git a/src/libtomahawk/database/databasecommand_createplaylist.cpp b/src/libtomahawk/database/databasecommand_createplaylist.cpp | |
index b5bd2cc..3f52bd9 100644 | |
--- a/src/libtomahawk/database/databasecommand_createplaylist.cpp | |
+++ b/src/libtomahawk/database/databasecommand_createplaylist.cpp | |
@@ -1,5 +1,5 @@ | |
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === | |
- * | |
+ * | |
* Copyright 2010-2011, Christian Muehlhaeuser <[email protected]> | |
* | |
* Tomahawk is free software: you can redistribute it and/or modify | |
@@ -75,25 +75,29 @@ DatabaseCommand_CreatePlaylist::postCommitHook() | |
} else { | |
m_playlist->reportCreated( m_playlist ); | |
} | |
- | |
+ | |
if( source()->isLocal() ) | |
Servent::instance()->triggerDBSync(); | |
} | |
-void | |
+void | |
DatabaseCommand_CreatePlaylist::createPlaylist( DatabaseImpl* lib, bool dynamic) | |
{ | |
qDebug() << Q_FUNC_INFO; | |
Q_ASSERT( !( m_playlist.isNull() && m_v.isNull() ) ); | |
Q_ASSERT( !source().isNull() ); | |
- | |
+ | |
+ uint now = QDateTime::currentDateTime().toTime_t(); | |
+ m_playlist->setCreatedOn( now ); | |
+ | |
TomahawkSqlQuery cre = lib->newquery(); | |
- cre.prepare( "INSERT INTO playlist( guid, source, shared, title, info, creator, lastmodified, dynplaylist) " | |
- "VALUES( :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, :createdOn )" ); | |
+ | |
cre.bindValue( ":source", source()->isLocal() ? QVariant(QVariant::Int) : source()->id() ); | |
cre.bindValue( ":dynplaylist", dynamic ); | |
+ cre.bindValue( ":createdOn", now ); | |
if( !m_playlist.isNull() ) { | |
cre.bindValue( ":guid", m_playlist->guid() ); | |
cre.bindValue( ":shared", m_playlist->shared() ); | |
@@ -111,6 +115,6 @@ DatabaseCommand_CreatePlaylist::createPlaylist( DatabaseImpl* lib, bool dynamic) | |
cre.bindValue( ":lastmodified", m.value( "lastmodified", 0 ) ); | |
} | |
qDebug() << "CREATE PLAYLIST:" << cre.boundValues(); | |
- | |
+ | |
cre.exec(); | |
} | |
diff --git a/src/libtomahawk/database/databasecommand_loadalldynamicplaylists.cpp b/src/libtomahawk/database/databasecommand_loadalldynamicplaylists.cpp | |
index 333b596..8c5a1bd 100644 | |
--- a/src/libtomahawk/database/databasecommand_loadalldynamicplaylists.cpp | |
+++ b/src/libtomahawk/database/databasecommand_loadalldynamicplaylists.cpp | |
@@ -1,5 +1,5 @@ | |
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === | |
- * | |
+ * | |
* Copyright 2010-2011, Christian Muehlhaeuser <[email protected]> | |
* | |
* Tomahawk is free software: you can redistribute it and/or modify | |
@@ -29,28 +29,29 @@ using namespace Tomahawk; | |
void DatabaseCommand_LoadAllDynamicPlaylists::exec( DatabaseImpl* dbi ) | |
{ | |
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" ) | |
.arg( source()->isLocal() ? "IS NULL" : | |
QString( "=%1" ).arg( source()->id() ) | |
) ); | |
- | |
+ | |
QList<dynplaylist_ptr> plists; | |
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(2).toString() //info | |
<< query.value(3).toString() //creator | |
- << query.value(7).toString() // dynamic type | |
- << static_cast<GeneratorMode>(query.value(8).toInt()) // dynamic mode | |
- << query.value(5).toBool() //shared | |
- << query.value(4).toInt() //lastmod | |
+ << query.value(4).toString() //createdOn | |
+ << query.value(8).toString() // dynamic type | |
+ << static_cast<GeneratorMode>(query.value(9).toInt()) // dynamic mode | |
+ << query.value(6).toBool() //shared | |
+ << query.value(5).toInt() //lastmod | |
<< query.value(0).toString(); //GUID | |
emit playlistLoaded( source(), data ); | |
} | |
- | |
+ | |
emit done(); | |
} | |
diff --git a/src/libtomahawk/database/databasecommand_loadallplaylists.cpp b/src/libtomahawk/database/databasecommand_loadallplaylists.cpp | |
index db78657..c2f0782 100644 | |
--- a/src/libtomahawk/database/databasecommand_loadallplaylists.cpp | |
+++ b/src/libtomahawk/database/databasecommand_loadallplaylists.cpp | |
@@ -1,5 +1,5 @@ | |
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === | |
- * | |
+ * | |
* Copyright 2010-2011, Christian Muehlhaeuser <[email protected]> | |
* | |
* 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(); | |
- 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'" ) | |
.arg( source()->isLocal() ? "IS NULL" : | |
QString( "= %1" ).arg( source()->id() ) | |
@@ -44,6 +44,7 @@ void DatabaseCommand_LoadAllPlaylists::exec( DatabaseImpl* dbi ) | |
query.value(1).toString(), //title | |
query.value(2).toString(), //info | |
query.value(3).toString(), //creator | |
+ query.value(7).toInt(), //lastmod | |
query.value(5).toBool(), //shared | |
query.value(4).toInt(), //lastmod | |
query.value(0).toString() //GUID | |
diff --git a/src/libtomahawk/database/databaseimpl.cpp b/src/libtomahawk/database/databaseimpl.cpp | |
index 85615f0..2e2fa69 100644 | |
--- a/src/libtomahawk/database/databaseimpl.cpp | |
+++ b/src/libtomahawk/database/databaseimpl.cpp | |
@@ -1,5 +1,5 @@ | |
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === | |
- * | |
+ * | |
* Copyright 2010-2011, Christian Muehlhaeuser <[email protected]> | |
* | |
* Tomahawk is free software: you can redistribute it and/or modify | |
@@ -30,6 +30,7 @@ | |
#include "result.h" | |
#include "artist.h" | |
#include "album.h" | |
+#include "utils/tomahawkutils.h" | |
/* !!!! You need to manually generate schema.sql.h when the schema changes: | |
cd src/libtomahawk/database | |
@@ -37,7 +38,7 @@ | |
*/ | |
#include "schema.sql.h" | |
-#define CURRENT_SCHEMA_VERSION 22 | |
+#define CURRENT_SCHEMA_VERSION 23 | |
DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent ) | |
@@ -63,21 +64,22 @@ DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent ) | |
int v = qry.value( 0 ).toInt(); | |
qDebug() << "Current schema is" << v << this->thread(); | |
if ( v != CURRENT_SCHEMA_VERSION ) | |
- { | |
+ { | |
QString newname = QString("%1.v%2").arg(dbname).arg(v); | |
qDebug() << endl << "****************************" << endl; | |
qDebug() << "Schema version too old: " << v << ". Current version is:" << CURRENT_SCHEMA_VERSION; | |
qDebug() << "Moving" << dbname << newname; | |
+ qDebug() << "If the migration fails, you can recover your DB by copying" << newname << "back to" << dbname; | |
qDebug() << endl << "****************************" << endl; | |
qry.clear(); | |
qry.finish(); | |
- | |
+ | |
db.close(); | |
db.removeDatabase( "tomahawk" ); | |
- if( QFile::rename( dbname, newname ) ) | |
+ if( QFile::copy( dbname, newname ) ) | |
{ | |
db = QSqlDatabase::addDatabase( "QSQLITE", "tomahawk" ); | |
db.setDatabaseName( dbname ); | |
@@ -87,6 +89,13 @@ DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent ) | |
TomahawkSqlQuery query = newquery(); | |
query.exec( "PRAGMA auto_vacuum = FULL" ); | |
schemaUpdated = updateSchema( v ); | |
+ | |
+ if( !schemaUpdated ) | |
+ { | |
+ Q_ASSERT( false ); | |
+ QTimer::singleShot( 0, qApp, SLOT( quit() ) ); | |
+ } | |
+ | |
} | |
else | |
{ | |
@@ -149,26 +158,70 @@ DatabaseImpl::updateSearchIndex() | |
bool | |
-DatabaseImpl::updateSchema( int currentver ) | |
+DatabaseImpl::updateSchema( int oldVersion ) | |
{ | |
- qDebug() << "Create tables... old version is" << currentver; | |
- QString sql( get_tomahawk_sql() ); | |
- QStringList statements = sql.split( ";", QString::SkipEmptyParts ); | |
- db.transaction(); | |
+ // we are called here with the old database. we must migrate it to the CURRENT_SCHEMA_VERSION from t7he oldVersion | |
+ if ( oldVersion == 0 ) // empty database, so create our tables and stuff | |
+ { | |
+ qDebug() << "Create tables... old version is" << oldVersion; | |
+ QString sql( get_tomahawk_sql() ); | |
+ QStringList statements = sql.split( ";", QString::SkipEmptyParts ); | |
+ db.transaction(); | |
+ | |
+ foreach( const QString& sl, statements ) | |
+ { | |
+ QString s( sl.trimmed() ); | |
+ if( s.length() == 0 ) | |
+ continue; | |
+ | |
+ qDebug() << "Executing:" << s; | |
+ TomahawkSqlQuery query = newquery(); | |
+ query.exec( s ); | |
+ } | |
- foreach( const QString& sl, statements ) | |
+ db.commit(); | |
+ return true; | |
+ } else // update in place! run the proper upgrade script | |
{ | |
- QString s( sl.trimmed() ); | |
- if( s.length() == 0 ) | |
- continue; | |
+ 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 ); | |
- qDebug() << "Executing:" << s; | |
- TomahawkSqlQuery query = newquery(); | |
- query.exec( s ); | |
+ 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(); | |
- return true; | |
+QString | |
+DatabaseImpl::cleanSql( const QString& sql ) | |
+{ | |
+ QString fixed = sql; | |
+ QRegExp r( "--[^\\n]*" ); | |
+ fixed.replace( r, QString() ); | |
+ return fixed.trimmed(); | |
} | |
diff --git a/src/libtomahawk/database/databaseimpl.h b/src/libtomahawk/database/databaseimpl.h | |
index e2965f5..f3551b6 100644 | |
--- a/src/libtomahawk/database/databaseimpl.h | |
+++ b/src/libtomahawk/database/databaseimpl.h | |
@@ -1,5 +1,5 @@ | |
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === | |
- * | |
+ * | |
* Copyright 2010-2011, Christian Muehlhaeuser <[email protected]> | |
* | |
* Tomahawk is free software: you can redistribute it and/or modify | |
@@ -84,9 +84,11 @@ signals: | |
public slots: | |
private: | |
+ QString cleanSql( const QString& sql ); | |
+ | |
bool m_ready; | |
- | |
- bool updateSchema( int currentver ); | |
+ | |
+ bool updateSchema( int oldVersion ); | |
QSqlDatabase db; | |
diff --git a/src/libtomahawk/database/schema.sql b/src/libtomahawk/database/schema.sql | |
index e359735..e2f6ce9 100644 | |
--- a/src/libtomahawk/database/schema.sql | |
+++ b/src/libtomahawk/database/schema.sql | |
@@ -67,13 +67,14 @@ CREATE TABLE IF NOT EXISTS playlist ( | |
creator TEXT, | |
lastmodified INTEGER NOT NULL DEFAULT 0, | |
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); | |
---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); | |
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) | |
-- VALUES('controlid-2', 'dynamic_playlist-guid-11', "artist", 0, "FooArtist" ); | |
- | |
- | |
+ | |
+ | |
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, | |
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 | |
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, | |
url TEXT NOT NULL, -- file:///music/foo/bar.mp3, <guid or hash?> | |
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); | |
--- all other attributes. | |
+-- all other attributes. | |
-- like tags that have a value, eg: | |
-- BPM=120, releaseyear=1980, key=Dminor, composer=Someone | |
-- 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 '' | |
); | |
-INSERT INTO settings(k,v) VALUES('schema_version', '22'); | |
+INSERT INTO settings(k,v) VALUES('schema_version', '23'); | |
diff --git a/src/libtomahawk/database/schema.sql.h b/src/libtomahawk/database/schema.sql.h | |
index dfd468c..864766d 100644 | |
--- a/src/libtomahawk/database/schema.sql.h | |
+++ b/src/libtomahawk/database/schema.sql.h | |
@@ -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 = | |
@@ -51,7 +51,8 @@ static const char * tomahawk_schema_sql = | |
" creator TEXT," | |
" lastmodified INTEGER NOT NULL DEFAULT 0," | |
" 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 (" | |
" guid TEXT PRIMARY KEY," | |
@@ -86,8 +87,6 @@ static const char * tomahawk_schema_sql = | |
" match TEXT," | |
" input TEXT" | |
");" | |
-"" | |
-"" | |
"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," | |
" controls TEXT, " | |
@@ -173,7 +172,7 @@ static const char * tomahawk_schema_sql = | |
" k TEXT NOT NULL PRIMARY KEY," | |
" 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() | |
diff --git a/src/libtomahawk/playlist.cpp b/src/libtomahawk/playlist.cpp | |
index bf65556..4281f72 100644 | |
--- a/src/libtomahawk/playlist.cpp | |
+++ b/src/libtomahawk/playlist.cpp | |
@@ -1,5 +1,5 @@ | |
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === | |
- * | |
+ * | |
* Copyright 2010-2011, Christian Muehlhaeuser <[email protected]> | |
* | |
* 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 ) | |
{ | |
m_query = q; | |
} | |
-const Tomahawk::query_ptr& | |
+const Tomahawk::query_ptr& | |
PlaylistEntry::query() const | |
{ | |
return m_query; | |
} | |
-source_ptr | |
+source_ptr | |
PlaylistEntry::lastSource() const | |
{ | |
return m_lastsource; | |
} | |
-void | |
+void | |
PlaylistEntry::setLastSource( source_ptr s ) | |
{ | |
m_lastsource = s; | |
@@ -99,6 +99,7 @@ Playlist::Playlist( const source_ptr& src, | |
const QString& title, | |
const QString& info, | |
const QString& creator, | |
+ uint createdOn, | |
bool shared, | |
int lastmod, | |
const QString& guid ) | |
@@ -109,6 +110,7 @@ Playlist::Playlist( const source_ptr& src, | |
, m_title( title ) | |
, m_info( info ) | |
, m_creator( creator ) | |
+ , m_createdOn( createdOn ) | |
, m_lastmodified( lastmod ) | |
, m_shared( shared ) | |
{ | |
@@ -129,6 +131,7 @@ Playlist::Playlist( const source_ptr& author, | |
, m_title( title ) | |
, m_info ( info ) | |
, m_creator( creator ) | |
+ , m_createdOn( 0 ) // will be set by db command | |
, m_lastmodified( 0 ) | |
, m_shared( shared ) | |
{ | |
@@ -141,7 +144,7 @@ void | |
Playlist::init() | |
{ | |
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; | |
Q_ASSERT( self.data() == this ); | |
m_source->collection()->deletePlaylist( self ); | |
- | |
+ | |
emit deleted( self ); | |
} | |
@@ -310,24 +313,24 @@ Playlist::setRevision( const QString& rev, | |
); | |
return; | |
} | |
- | |
+ | |
PlaylistRevision pr = setNewRevision( rev, neworderedguids, oldorderedguids, is_newest_rev, addedmap ); | |
- | |
+ | |
if( applied ) | |
m_currentrevision = rev; | |
pr.applied = applied; | |
- | |
+ | |
foreach( const plentry_ptr& entry, m_entries ) | |
{ | |
connect( entry->query().data(), SIGNAL( resultsAdded( QList<Tomahawk::result_ptr> ) ), | |
SLOT( onResultsFound( QList<Tomahawk::result_ptr> ) ), Qt::UniqueConnection ); | |
- | |
+ | |
} | |
emit revisionLoaded( pr ); | |
} | |
-PlaylistRevision | |
+PlaylistRevision | |
Playlist::setNewRevision( const QString& rev, | |
const QList<QString>& neworderedguids, | |
const QList<QString>& oldorderedguids, | |
@@ -340,10 +343,10 @@ Playlist::setNewRevision( const QString& rev, | |
QMap<QString, plentry_ptr> entriesmap; | |
foreach( const plentry_ptr& p, m_entries ) | |
entriesmap.insert( p->guid(), p ); | |
- | |
- | |
+ | |
+ | |
QList<plentry_ptr> entries; | |
- | |
+ | |
foreach( const QString& id, neworderedguids ) | |
{ | |
//qDebug() << "id:" << id; | |
@@ -351,7 +354,7 @@ Playlist::setNewRevision( const QString& rev, | |
//qDebug() << "entriesmap:" << entriesmap.count() << entriesmap; | |
//qDebug() << "addedmap:" << addedmap.count() << addedmap; | |
//qDebug() << "m_entries" << m_entries; | |
- | |
+ | |
if( entriesmap.contains( id ) ) | |
{ | |
entries.append( entriesmap.value( id ) ); | |
@@ -367,13 +370,13 @@ Playlist::setNewRevision( const QString& rev, | |
Q_ASSERT( false ); // XXX | |
} | |
} | |
- | |
+ | |
//qDebug() << Q_FUNC_INFO << rev << entries.length() << applied; | |
- | |
+ | |
PlaylistRevision pr; | |
pr.oldrevisionguid = m_currentrevision; | |
pr.revisionguid = rev; | |
- | |
+ | |
// entries that have been removed: | |
QSet<QString> removedguids = oldorderedguids.toSet().subtract( neworderedguids.toSet() ); | |
//qDebug() << "Removedguids:" << removedguids << "oldorederedguids" << oldorderedguids << "newog" << neworderedguids; | |
@@ -399,10 +402,10 @@ Playlist::setNewRevision( const QString& rev, | |
} | |
} | |
} | |
- | |
+ | |
pr.added = addedmap.values(); | |
- | |
- | |
+ | |
+ | |
pr.newlist = entries; | |
return pr; | |
} | |
@@ -410,12 +413,12 @@ Playlist::setNewRevision( const QString& rev, | |
source_ptr | |
Playlist::author() const | |
-{ | |
- return m_source; | |
+{ | |
+ return m_source; | |
} | |
-void | |
+void | |
Playlist::resolve() | |
{ | |
QList< query_ptr > qlist; | |
@@ -462,7 +465,7 @@ void | |
Playlist::addEntries( const QList<query_ptr>& queries, const QString& oldrev ) | |
{ | |
//qDebug() << Q_FUNC_INFO; | |
- | |
+ | |
QList<plentry_ptr> el = addEntriesInternal( queries ); | |
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 ) | |
{ | |
QList<plentry_ptr> el = entries(); | |
@@ -478,16 +481,16 @@ Playlist::addEntriesInternal( const QList<Tomahawk::query_ptr>& queries ) | |
{ | |
plentry_ptr e( new PlaylistEntry() ); | |
e->setGuid( uuid() ); | |
- | |
+ | |
if ( query->results().count() ) | |
e->setDuration( query->results().at( 0 )->duration() ); | |
else | |
e->setDuration( 0 ); | |
- | |
+ | |
e->setLastmodified( 0 ); | |
e->setAnnotation( "" ); // FIXME | |
e->setQuery( query ); | |
- | |
+ | |
el << e; | |
} | |
return el; | |
@@ -500,14 +503,14 @@ Playlist::newEntries( const QList< plentry_ptr >& entries ) | |
QSet<QString> currentguids; | |
foreach( const plentry_ptr& p, m_entries ) | |
currentguids.insert( p->guid() ); // could be cached as member? | |
- | |
+ | |
// calc list of newly added entries: | |
QList<plentry_ptr> added; | |
foreach( const plentry_ptr& p, entries ) | |
{ | |
if( !currentguids.contains( p->guid() ) ) | |
added << p; | |
- } | |
+ } | |
return added; | |
} | |
diff --git a/src/libtomahawk/playlist.h b/src/libtomahawk/playlist.h | |
index 5147a3d..cb81e1a 100644 | |
--- a/src/libtomahawk/playlist.h | |
+++ b/src/libtomahawk/playlist.h | |
@@ -1,5 +1,5 @@ | |
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === | |
- * | |
+ * | |
* Copyright 2010-2011, Christian Muehlhaeuser <[email protected]> | |
* | |
* Tomahawk is free software: you can redistribute it and/or modify | |
@@ -77,6 +77,7 @@ public: | |
source_ptr lastSource() const; | |
void setLastSource( source_ptr s ); | |
+ | |
private: | |
QString m_guid; | |
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 info READ info WRITE setInfo ) | |
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 ) | |
friend class ::DatabaseCommand_LoadAllPlaylists; | |
@@ -139,6 +141,7 @@ public: | |
QString guid() const { return m_guid; } | |
bool shared() const { return m_shared; } | |
unsigned int lastmodified() const { return m_lastmodified; } | |
+ uint createdOn() const { return m_createdOn; } | |
const QList< plentry_ptr >& entries() { return m_entries; } | |
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 setGuid( const QString& s ) { m_guid = s; } | |
void setShared( bool b ) { m_shared = b; } | |
+ void setCreatedOn( uint createdOn ) { m_createdOn = createdOn; } | |
// </IGNORE> | |
virtual QList<Tomahawk::query_ptr> tracks(); | |
@@ -184,7 +188,7 @@ signals: | |
/// was deleted, eh? | |
void deleted( const Tomahawk::playlist_ptr& pl ); | |
- | |
+ | |
void repeatModeChanged( PlaylistInterface::RepeatMode mode ); | |
void shuffleModeChanged( bool enabled ); | |
@@ -214,6 +218,7 @@ protected: | |
const QString& title, | |
const QString& info, | |
const QString& creator, | |
+ uint createdOn, | |
bool shared, | |
int lastmod, | |
const QString& guid = "" ); // populate db | |
@@ -247,6 +252,7 @@ private: | |
QString m_currentrevision; | |
QString m_guid, m_title, m_info, m_creator; | |
unsigned int m_lastmodified; | |
+ unsigned int m_createdOn; | |
bool m_shared; | |
QList< plentry_ptr > m_entries; | |
diff --git a/src/libtomahawk/playlist/dynamic/DynamicPlaylist.cpp b/src/libtomahawk/playlist/dynamic/DynamicPlaylist.cpp | |
index 6186024..d81c273 100644 | |
--- a/src/libtomahawk/playlist/dynamic/DynamicPlaylist.cpp | |
+++ b/src/libtomahawk/playlist/dynamic/DynamicPlaylist.cpp | |
@@ -1,5 +1,5 @@ | |
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === | |
- * | |
+ * | |
* Copyright 2010-2011, Christian Muehlhaeuser <[email protected]> | |
* | |
* Tomahawk is free software: you can redistribute it and/or modify | |
@@ -43,17 +43,18 @@ DynamicPlaylist::~DynamicPlaylist() | |
} | |
// Called by loadAllPlaylists command | |
-DynamicPlaylist::DynamicPlaylist ( const Tomahawk::source_ptr& src, | |
+DynamicPlaylist::DynamicPlaylist ( const Tomahawk::source_ptr& src, | |
const QString& currentrevision, | |
- const QString& title, | |
- const QString& info, | |
- const QString& creator, | |
- const QString& type, | |
+ const QString& title, | |
+ const QString& info, | |
+ const QString& creator, | |
+ uint createdOn, | |
+ const QString& type, | |
GeneratorMode mode, | |
- bool shared, | |
- int lastmod, | |
+ bool shared, | |
+ int lastmod, | |
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"; | |
// 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) | |
-DynamicPlaylist::DynamicPlaylist ( const Tomahawk::source_ptr& author, | |
- const QString& guid, | |
- const QString& title, | |
- const QString& info, | |
- const QString& creator, | |
- const QString& type, | |
+DynamicPlaylist::DynamicPlaylist ( const Tomahawk::source_ptr& author, | |
+ const QString& guid, | |
+ const QString& title, | |
+ const QString& info, | |
+ const QString& creator, | |
+ const QString& type, | |
bool 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 ) ); | |
} | |
-geninterface_ptr | |
+geninterface_ptr | |
DynamicPlaylist::generator() const | |
{ | |
return m_generator; | |
} | |
-int | |
+int | |
DynamicPlaylist::mode() const | |
{ | |
return m_generator->mode(); | |
} | |
-void | |
+void | |
DynamicPlaylist::setGenerator(const Tomahawk::geninterface_ptr& gen_ptr) | |
{ | |
m_generator = gen_ptr; | |
} | |
-QString | |
+QString | |
DynamicPlaylist::type() const | |
{ | |
return m_generator->type(); | |
} | |
-void | |
+void | |
DynamicPlaylist::setMode( int mode ) | |
{ | |
m_generator->setMode( (GeneratorMode)mode ); | |
@@ -108,27 +109,27 @@ DynamicPlaylist::setMode( int mode ) | |
-dynplaylist_ptr | |
-DynamicPlaylist::create( const Tomahawk::source_ptr& author, | |
- const QString& guid, | |
- const QString& title, | |
- const QString& info, | |
- const QString& creator, | |
+dynplaylist_ptr | |
+DynamicPlaylist::create( const Tomahawk::source_ptr& author, | |
+ const QString& guid, | |
+ const QString& title, | |
+ const QString& info, | |
+ const QString& creator, | |
bool shared ) | |
{ | |
// default generator | |
QString type = ""; | |
dynplaylist_ptr dynplaylist = dynplaylist_ptr( new DynamicPlaylist( author, guid, title, info, creator, type, shared ) ); | |
- | |
+ | |
DatabaseCommand_CreateDynamicPlaylist* cmd = new DatabaseCommand_CreateDynamicPlaylist( author, dynplaylist ); | |
connect( cmd, SIGNAL(finished()), dynplaylist.data(), SIGNAL(created()) ); | |
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>(cmd) ); | |
dynplaylist->reportCreated( dynplaylist ); | |
return dynplaylist; | |
- | |
+ | |
} | |
-void | |
+void | |
DynamicPlaylist::createNewRevision( const QString& newUuid ) | |
{ | |
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 | |
-void | |
-DynamicPlaylist::createNewRevision( const QString& newrev, | |
- const QString& oldrev, | |
- const QString& type, | |
- const QList< dyncontrol_ptr>& controls, | |
+void | |
+DynamicPlaylist::createNewRevision( const QString& newrev, | |
+ const QString& oldrev, | |
+ const QString& type, | |
+ const QList< dyncontrol_ptr>& controls, | |
const QList< plentry_ptr >& entries ) | |
{ | |
// get the newly added tracks | |
QList< plentry_ptr > added = newEntries( entries ); | |
- | |
+ | |
QStringList orderedguids; | |
for( int i = 0; i < entries.size(); ++i ) | |
orderedguids << entries.at(i)->guid(); | |
- | |
+ | |
// no conflict resolution or partial updating for controls. all or nothing baby | |
- | |
+ | |
// source making the change (local user in this case) | |
source_ptr author = SourceList::instance()->getLocal(); | |
// 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 | |
-void | |
-DynamicPlaylist::createNewRevision( const QString& newrev, | |
- const QString& oldrev, | |
- const QString& type, | |
+void | |
+DynamicPlaylist::createNewRevision( const QString& newrev, | |
+ const QString& oldrev, | |
+ const QString& type, | |
const QList< dyncontrol_ptr>& controls ) | |
{ | |
// 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 ) ); | |
} | |
-void | |
+void | |
DynamicPlaylist::loadRevision( const QString& rev ) | |
{ | |
qDebug() << Q_FUNC_INFO << "Loading with:" << ( rev.isEmpty() ? currentrevision() : rev ); | |
- | |
+ | |
DatabaseCommand_LoadDynamicPlaylist* cmd = new DatabaseCommand_LoadDynamicPlaylist( rev.isEmpty() ? currentrevision() : rev ); | |
- | |
+ | |
if( m_generator->mode() == OnDemand ) { | |
connect( cmd, SIGNAL( done( QString, | |
bool, | |
@@ -230,22 +231,22 @@ DynamicPlaylist::loadRevision( const QString& rev ) | |
QList< QVariantMap >, | |
bool, | |
QMap< QString, Tomahawk::plentry_ptr >, | |
- bool ) ) ); | |
- | |
+ bool ) ) ); | |
+ | |
} | |
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) ); | |
} | |
-bool | |
+bool | |
DynamicPlaylist::remove( const Tomahawk::dynplaylist_ptr& playlist ) | |
{ | |
DatabaseCommand_DeletePlaylist* cmd = new DatabaseCommand_DeleteDynamicPlaylist( playlist->author(), playlist->guid() ); | |
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>(cmd) ); | |
- | |
+ | |
return false; | |
} | |
-void | |
+void | |
DynamicPlaylist::reportCreated( const Tomahawk::dynplaylist_ptr& self ) | |
{ | |
qDebug() << Q_FUNC_INFO; | |
@@ -255,26 +256,26 @@ DynamicPlaylist::reportCreated( const Tomahawk::dynplaylist_ptr& self ) | |
// will emit Collection::playlistCreated(...) | |
// qDebug() << "Creating dynplaylist belonging to:" << author().data() << author().isNull(); | |
// 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 ) | |
{ | |
qDebug() << Q_FUNC_INFO; | |
Q_ASSERT( self.data() == this ); | |
// will emit Collection::playlistDeleted(...) | |
- author()->collection()->deleteDynamicPlaylist( self ); | |
- | |
+ author()->collection()->deleteDynamicPlaylist( self ); | |
+ | |
emit deleted( self ); | |
} | |
void DynamicPlaylist::addEntries(const QList< query_ptr >& queries, const QString& oldrev) | |
{ | |
Q_ASSERT( m_generator->mode() == Static ); | |
- | |
+ | |
QList<plentry_ptr> el = addEntriesInternal( queries ); | |
- | |
+ | |
QString newrev = uuid(); | |
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; | |
queries << query; | |
- | |
+ | |
addEntries( queries, oldrev ); | |
} | |
-void DynamicPlaylist::setRevision( const QString& rev, | |
- const QList< QString >& neworderedguids, | |
- const QList< QString >& oldorderedguids, | |
- const QString& type, | |
- const QList< dyncontrol_ptr >& controls, | |
- bool is_newest_rev, | |
- const QMap< QString, plentry_ptr >& addedmap, | |
+void DynamicPlaylist::setRevision( const QString& rev, | |
+ const QList< QString >& neworderedguids, | |
+ const QList< QString >& oldorderedguids, | |
+ const QString& type, | |
+ const QList< dyncontrol_ptr >& controls, | |
+ bool is_newest_rev, | |
+ const QMap< QString, plentry_ptr >& addedmap, | |
bool applied) | |
{ | |
// 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 | |
m_generator = GeneratorFactory::create( type ); | |
} | |
- | |
+ | |
m_generator->setControls( controls ); | |
m_generator->setMode( Static ); | |
- | |
+ | |
DynamicPlaylistRevision dpr = setNewRevision( rev, neworderedguids, oldorderedguids, is_newest_rev, addedmap ); | |
dpr.applied = applied; | |
dpr.controls = controls; | |
dpr.type = type; | |
dpr.mode = Static; | |
- | |
+ | |
if( applied ) { | |
setCurrentrevision( rev ); | |
} | |
// qDebug() << "EMITTING REVISION LOADED 1!"; | |
- emit dynamicRevisionLoaded( dpr ); | |
+ emit dynamicRevisionLoaded( dpr ); | |
} | |
-void | |
-DynamicPlaylist::setRevision( const QString& rev, | |
- const QList< QString >& neworderedguids, | |
- const QList< QString >& oldorderedguids, | |
- const QString& type, | |
- const QList< QVariantMap>& controlsV, | |
- bool is_newest_rev, | |
- const QMap< QString, Tomahawk::plentry_ptr >& addedmap, | |
+void | |
+DynamicPlaylist::setRevision( const QString& rev, | |
+ const QList< QString >& neworderedguids, | |
+ const QList< QString >& oldorderedguids, | |
+ const QString& type, | |
+ const QList< QVariantMap>& controlsV, | |
+ bool is_newest_rev, | |
+ const QMap< QString, Tomahawk::plentry_ptr >& addedmap, | |
bool applied ) | |
{ | |
if( QThread::currentThread() != thread() ) | |
@@ -358,16 +359,16 @@ DynamicPlaylist::setRevision( const QString& rev, | |
Q_ARG( bool, applied ) ); | |
return; | |
} | |
- | |
+ | |
QList<dyncontrol_ptr> controls = variantsToControl( controlsV ); | |
setRevision( rev, neworderedguids, oldorderedguids, type, controls, is_newest_rev, addedmap, applied ); | |
- | |
+ | |
} | |
-void DynamicPlaylist::setRevision( const QString& rev, | |
- bool is_newest_rev, | |
- const QString& type, | |
- const QList< dyncontrol_ptr >& controls, | |
+void DynamicPlaylist::setRevision( const QString& rev, | |
+ bool is_newest_rev, | |
+ const QString& type, | |
+ const QList< dyncontrol_ptr >& controls, | |
bool applied ) | |
{ | |
if( QThread::currentThread() != thread() ) | |
@@ -385,30 +386,30 @@ void DynamicPlaylist::setRevision( const QString& rev, | |
if( m_generator->type() != type ) { // new generator needed | |
m_generator = geninterface_ptr( GeneratorFactory::create( type ) ); | |
} | |
- | |
+ | |
m_generator->setControls( controls ); | |
m_generator->setMode( OnDemand ); | |
- | |
+ | |
DynamicPlaylistRevision dpr; | |
dpr.oldrevisionguid = currentrevision(); | |
dpr.revisionguid = rev; | |
dpr.controls = controls; | |
dpr.type = type; | |
dpr.mode = OnDemand; | |
- | |
+ | |
if( applied ) { | |
setCurrentrevision( rev ); | |
} | |
// qDebug() << "EMITTING REVISION LOADED 2!"; | |
- emit dynamicRevisionLoaded( dpr ); | |
+ emit dynamicRevisionLoaded( dpr ); | |
} | |
-void | |
-DynamicPlaylist::setRevision( const QString& rev, | |
- bool is_newest_rev, | |
- const QString& type, | |
- const QList< QVariantMap >& controlsV, | |
+void | |
+DynamicPlaylist::setRevision( const QString& rev, | |
+ bool is_newest_rev, | |
+ const QString& type, | |
+ const QList< QVariantMap >& controlsV, | |
bool applied ) | |
{ | |
if( QThread::currentThread() != thread() ) | |
@@ -422,8 +423,8 @@ DynamicPlaylist::setRevision( const QString& rev, | |
QGenericArgument( "QList< QVariantMap >" , (const void*)&controlsV ), | |
Q_ARG( bool, applied ) ); | |
return; | |
- } | |
- | |
+ } | |
+ | |
QList<dyncontrol_ptr> controls = variantsToControl( controlsV ); | |
setRevision( rev, is_newest_rev, type, controls, applied ); | |
} | |
diff --git a/src/libtomahawk/playlist/dynamic/DynamicPlaylist.h b/src/libtomahawk/playlist/dynamic/DynamicPlaylist.h | |
index 04cd211..4312d67 100644 | |
--- a/src/libtomahawk/playlist/dynamic/DynamicPlaylist.h | |
+++ b/src/libtomahawk/playlist/dynamic/DynamicPlaylist.h | |
@@ -1,5 +1,5 @@ | |
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === | |
- * | |
+ * | |
* Copyright 2010-2011, Christian Muehlhaeuser <[email protected]> | |
* | |
* Tomahawk is free software: you can redistribute it and/or modify | |
@@ -35,7 +35,7 @@ class DatabaseCommand_CreateDynamicPlaylist; | |
class DatabaseCollection; | |
namespace Tomahawk { | |
- | |
+ | |
/** | |
* 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 | |
@@ -46,35 +46,35 @@ struct DLLEXPORT DynamicPlaylistRevision : PlaylistRevision | |
QList< dyncontrol_ptr > controls; | |
Tomahawk::GeneratorMode mode; | |
QString type; | |
- | |
- DynamicPlaylistRevision( const PlaylistRevision& other ) | |
- { | |
- revisionguid = other.revisionguid; | |
- oldrevisionguid = other.oldrevisionguid; | |
+ | |
+ DynamicPlaylistRevision( const PlaylistRevision& other ) | |
+ { | |
+ revisionguid = other.revisionguid; | |
+ oldrevisionguid = other.oldrevisionguid; | |
newlist = other.newlist; | |
added = other.added; | |
removed = other.removed; | |
- applied = other.applied; | |
+ applied = other.applied; | |
} | |
- | |
+ | |
DynamicPlaylistRevision() {} | |
}; | |
class DLLEXPORT DynamicPlaylist : public Playlist | |
{ | |
Q_OBJECT | |
- | |
+ | |
// :-( int becuase qjson chokes on my enums | |
Q_PROPERTY( int mode WRITE setMode READ mode ) | |
Q_PROPERTY( QString type WRITE setType READ type ) | |
- | |
+ | |
friend class ::DatabaseCommand_SetDynamicPlaylistRevision; | |
friend class ::DatabaseCommand_CreateDynamicPlaylist; | |
friend class ::DatabaseCollection; /// :-( | |
- | |
-public: | |
+ | |
+public: | |
virtual ~DynamicPlaylist(); | |
- | |
+ | |
/// Generate an empty dynamic playlist with default generator | |
static Tomahawk::dynplaylist_ptr create( const source_ptr& author, | |
const QString& guid, | |
@@ -84,21 +84,21 @@ public: | |
bool shared | |
); | |
static bool remove( const dynplaylist_ptr& playlist ); | |
- | |
+ | |
virtual void loadRevision( const QString& rev = "" ); | |
- | |
+ | |
// :-( int becuase qjson chokes on my enums | |
int mode() const; | |
QString type() const; | |
geninterface_ptr generator() const; | |
- | |
+ | |
// 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. | |
void createNewRevision( const QString& uuid = QString() ); | |
- | |
+ | |
virtual void addEntries( const QList< query_ptr >& queries, const QString& oldrev ); | |
virtual void addEntry( const Tomahawk::query_ptr& query, const QString& oldrev ); | |
- | |
+ | |
// <IGNORE hack="true"> | |
// 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. | |
@@ -108,13 +108,13 @@ public: | |
void setType( const QString& /*type*/ ) { /** TODO */; } | |
void setGenerator( const geninterface_ptr& gen_ptr ); | |
// </IGNORE> | |
- | |
+ | |
signals: | |
/// emitted when the playlist revision changes (whenever the playlist changes) | |
void dynamicRevisionLoaded( Tomahawk::DynamicPlaylistRevision ); | |
- | |
+ | |
void deleted( const Tomahawk::dynplaylist_ptr& pl ); | |
- | |
+ | |
public slots: | |
// want to update the playlist from the model? | |
// 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 ); | |
// 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 reportCreated( const Tomahawk::dynplaylist_ptr& self ); | |
void reportDeleted( const Tomahawk::dynplaylist_ptr& self ); | |
- | |
+ | |
// called from setdynamicplaylistrevision db cmd | |
// 4 options, because dbcmds can't create qwidgets: | |
// static version, qvariant controls | |
@@ -147,7 +147,7 @@ public slots: | |
const QList< Tomahawk::dyncontrol_ptr >& controls, | |
bool is_newest_rev, | |
const QMap< QString, Tomahawk::plentry_ptr >& addedmap, | |
- bool applied ); | |
+ bool applied ); | |
// ondemand version | |
void setRevision( const QString& rev, | |
bool is_newest_rev, | |
@@ -166,12 +166,13 @@ private: | |
const QString& title, | |
const QString& info, | |
const QString& creator, | |
+ uint createdOn, | |
const QString& type, | |
GeneratorMode mode, | |
bool shared, | |
int lastmod, | |
const QString& guid = "" ); // populate db | |
- | |
+ | |
// called when creating new playlist | |
explicit DynamicPlaylist( const source_ptr& author, | |
const QString& guid, | |
@@ -180,11 +181,11 @@ private: | |
const QString& creator, | |
const QString& type, | |
bool shared ); | |
- | |
+ | |
private: | |
QList< dyncontrol_ptr > variantsToControl( const QList< QVariantMap >& controlsV ); | |
geninterface_ptr m_generator; | |
- | |
+ | |
}; | |
}; // namespace | |
diff --git a/src/sourcetree/sourcesmodel.cpp b/src/sourcetree/sourcesmodel.cpp | |
index 76f1d23..faca11e 100644 | |
--- a/src/sourcetree/sourcesmodel.cpp | |
+++ b/src/sourcetree/sourcesmodel.cpp | |
@@ -1,5 +1,5 @@ | |
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === | |
- * | |
+ * | |
* Copyright 2010-2011, Christian Muehlhaeuser <[email protected]> | |
* | |
* Tomahawk is free software: you can redistribute it and/or modify | |
@@ -38,6 +38,7 @@ SourcesModel::SourcesModel( SourceTreeView* parent ) | |
, m_parent( parent ) | |
{ | |
setColumnCount( 1 ); | |
+ setSortRole( SortRole ); | |
onSourceAdded( SourceList::instance()->sources() ); | |
connect( SourceList::instance(), SIGNAL( sourceAdded( Tomahawk::source_ptr ) ), SLOT( onSourceAdded( Tomahawk::source_ptr ) ) ); | |
@@ -97,6 +98,40 @@ SourcesModel::data( const QModelIndex& index, int role ) const | |
if ( role == Qt::SizeHintRole ) | |
{ | |
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(); | |
+ qDebug() << "ASKING SORT ROLE FOR COLLECTION>...."; | |
+ if( source.isNull() ) | |
+ { | |
+ qDebug() << "Returning 0 for super coll!"; | |
+ return 0; // Super Collection is first | |
+ } else if( source->isLocal() ) | |
+ { | |
+ qDebug() << "Returning 1 for local col!"; | |
+ return 1; // Then Local collection | |
+ } else // then all the rest | |
+ { | |
+ qDebug() << "Returning 5 for normal col!"; | |
+ return 5; | |
+ } | |
+ } else | |
+ { | |
+ qDebug() << "RETURNING NULL SORT DATA!"; | |
+ return QVariant(); | |
+ } | |
} | |
return QStandardItemModel::data( index, role ); | |
@@ -152,7 +187,7 @@ SourcesModel::appendItem( const source_ptr& source ) | |
connect( source.data(), SIGNAL( playbackStarted( Tomahawk::query_ptr ) ), SLOT( onSourceChanged() ) ); | |
connect( source.data(), SIGNAL( stateChanged() ), SLOT( onSourceChanged() ) ); | |
} | |
- | |
+ | |
return true; // FIXME | |
} | |
@@ -246,7 +281,7 @@ SourcesModel::indexToDynamicPlaylist( const QModelIndex& index ) | |
dynplaylist_ptr res; | |
if ( !index.isValid() ) | |
return res; | |
- | |
+ | |
if ( indexType( index ) == DynamicPlaylistSource ) | |
{ | |
QModelIndex idx = index.model()->index( index.row(), 0, index.parent() ); | |
@@ -255,7 +290,7 @@ SourcesModel::indexToDynamicPlaylist( const QModelIndex& index ) | |
if ( playlist ) | |
return *playlist; | |
} | |
- | |
+ | |
return res; | |
} | |
@@ -311,12 +346,12 @@ SourcesModel::dynamicPlaylistToIndex( const Tomahawk::dynplaylist_ptr& playlist | |
for ( int i = 0; i < rowCount(); i++ ) | |
{ | |
QModelIndex pidx = index( i, 0 ); | |
- | |
+ | |
for ( int j = 0; j < rowCount( pidx ); j++ ) | |
{ | |
QModelIndex idx = index( j, 0, pidx ); | |
SourcesModel::SourceType type = SourcesModel::indexType( idx ); | |
- | |
+ | |
if ( type == SourcesModel::DynamicPlaylistSource ) | |
{ | |
playlist_ptr p = SourcesModel::indexToDynamicPlaylist( idx ); | |
@@ -325,7 +360,7 @@ SourcesModel::dynamicPlaylistToIndex( const Tomahawk::dynplaylist_ptr& playlist | |
} | |
} | |
} | |
- | |
+ | |
return QModelIndex(); | |
} | |
@@ -367,11 +402,11 @@ SourcesModel::setData( const QModelIndex& index, const QVariant& value, int role | |
{ | |
playlist = indexToDynamicPlaylist( index ).staticCast< Playlist >(); | |
} | |
- | |
+ | |
if ( !playlist.isNull() ) | |
{ | |
playlist->rename( value.toString() ); | |
- QStandardItemModel::setData( index, value, Qt::DisplayRole ); | |
+ QStandardItemModel::setData( index, value, Qt::DisplayRole ); | |
return true; | |
} | |
@@ -383,7 +418,7 @@ void | |
SourcesModel::onSourceChanged() | |
{ | |
Source* src = qobject_cast< Source* >( sender() ); | |
- | |
+ | |
for ( int i = 0; i < rowCount(); i++ ) | |
{ | |
QModelIndex idx = index( i, 0 ); | |
diff --git a/src/sourcetree/sourcesmodel.h b/src/sourcetree/sourcesmodel.h | |
index a9ad5d7..79d1238 100644 | |
--- a/src/sourcetree/sourcesmodel.h | |
+++ b/src/sourcetree/sourcesmodel.h | |
@@ -1,5 +1,5 @@ | |
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === | |
- * | |
+ * | |
* Copyright 2010-2011, Christian Muehlhaeuser <[email protected]> | |
* | |
* Tomahawk is free software: you can redistribute it and/or modify | |
@@ -31,15 +31,19 @@ class SourcesModel : public QStandardItemModel | |
{ | |
Q_OBJECT | |
-public: | |
+public: | |
enum SourceType { | |
Invalid = -1, | |
- | |
+ | |
CollectionSource = 0, | |
PlaylistSource = 1, | |
DynamicPlaylistSource = 2 | |
}; | |
- | |
+ | |
+ enum ExtraRoles { | |
+ SortRole = Qt::UserRole + 20, | |
+ }; | |
+ | |
explicit SourcesModel( SourceTreeView* parent = 0 ); | |
virtual QStringList mimeTypes() const; | |
@@ -58,7 +62,7 @@ public: | |
QModelIndex playlistToIndex( const Tomahawk::playlist_ptr& playlist ); | |
QModelIndex dynamicPlaylistToIndex( const Tomahawk::dynplaylist_ptr& playlist ); | |
QModelIndex collectionToIndex( const Tomahawk::collection_ptr& collection ); | |
- | |
+ | |
signals: | |
void clicked( const QModelIndex& ); | |
diff --git a/src/sourcetree/sourcesproxymodel.cpp b/src/sourcetree/sourcesproxymodel.cpp | |
index d93cf09..a53967c 100644 | |
--- a/src/sourcetree/sourcesproxymodel.cpp | |
+++ b/src/sourcetree/sourcesproxymodel.cpp | |
@@ -1,5 +1,5 @@ | |
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === | |
- * | |
+ * | |
* Copyright 2010-2011, Christian Muehlhaeuser <[email protected]> | |
* | |
* Tomahawk is free software: you can redistribute it and/or modify | |
@@ -32,6 +32,7 @@ SourcesProxyModel::SourcesProxyModel( SourcesModel* model, QObject* parent ) | |
{ | |
setDynamicSortFilter( true ); | |
+ setSortRole( SourcesModel::SortRole ); | |
setSourceModel( model ); | |
} | |
@@ -63,7 +64,7 @@ SourcesProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex& sourcePar | |
{ | |
if ( !m_filtered ) | |
return true; | |
- | |
+ | |
SourceTreeItem* sti = m_model->indexToTreeItem( sourceModel()->index( sourceRow, 0, sourceParent ) ); | |
if ( sti ) | |
{ | |
diff --git a/src/sourcetree/sourcesproxymodel.h b/src/sourcetree/sourcesproxymodel.h | |
index add57b2..52b9b69 100644 | |
--- a/src/sourcetree/sourcesproxymodel.h | |
+++ b/src/sourcetree/sourcesproxymodel.h | |
@@ -1,5 +1,5 @@ | |
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === | |
- * | |
+ * | |
* Copyright 2010-2011, Christian Muehlhaeuser <[email protected]> | |
* | |
* Tomahawk is free software: you can redistribute it and/or modify | |
diff --git a/src/sourcetree/sourcetreeview.cpp b/src/sourcetree/sourcetreeview.cpp | |
index 4935b8d..6693bd1 100644 | |
--- a/src/sourcetree/sourcetreeview.cpp | |
+++ b/src/sourcetree/sourcetreeview.cpp | |
@@ -80,6 +80,9 @@ SourceTreeView::SourceTreeView( QWidget* parent ) | |
setIndentation( 16 ); | |
setAnimated( true ); | |
+ setSortingEnabled( true ); | |
+ sortByColumn( 1, Qt::AscendingOrder ); | |
+ | |
setItemDelegate( new SourceDelegate( this ) ); | |
setContextMenuPolicy( Qt::CustomContextMenu ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment